blob: d0d6c3c0d4121dc0c4839c568aeeb6292cccce7e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 xored software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* xored software, Inc. - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.internal.javascript.ti;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.dltk.annotations.Internal;
import org.eclipse.dltk.compiler.problem.IProblemIdentifier;
import org.eclipse.dltk.internal.javascript.validation.ValidationMessages;
import org.eclipse.dltk.javascript.core.JavaScriptProblems;
import org.eclipse.dltk.javascript.typeinference.IAssignProtection;
import org.eclipse.dltk.javascript.typeinference.ILocationProvider;
import org.eclipse.dltk.javascript.typeinference.IValueCollection;
import org.eclipse.dltk.javascript.typeinference.IValueReference;
import org.eclipse.dltk.javascript.typeinference.ReferenceKind;
import org.eclipse.dltk.javascript.typeinference.ReferenceLocation;
import org.eclipse.dltk.javascript.typeinfo.IMemberEvaluator;
import org.eclipse.dltk.javascript.typeinfo.IRArrayType;
import org.eclipse.dltk.javascript.typeinfo.IRClassType;
import org.eclipse.dltk.javascript.typeinfo.IRElement;
import org.eclipse.dltk.javascript.typeinfo.IRFunctionType;
import org.eclipse.dltk.javascript.typeinfo.IRLocalType;
import org.eclipse.dltk.javascript.typeinfo.IRMapType;
import org.eclipse.dltk.javascript.typeinfo.IRMember;
import org.eclipse.dltk.javascript.typeinfo.IRMethod;
import org.eclipse.dltk.javascript.typeinfo.IRProperty;
import org.eclipse.dltk.javascript.typeinfo.IRRecordMember;
import org.eclipse.dltk.javascript.typeinfo.IRRecordType;
import org.eclipse.dltk.javascript.typeinfo.IRSimpleType;
import org.eclipse.dltk.javascript.typeinfo.IRType;
import org.eclipse.dltk.javascript.typeinfo.IRTypeDeclaration;
import org.eclipse.dltk.javascript.typeinfo.IRUnionType;
import org.eclipse.dltk.javascript.typeinfo.ITypeInfoContext;
import org.eclipse.dltk.javascript.typeinfo.ITypeSystem;
import org.eclipse.dltk.javascript.typeinfo.JSTypeSet;
import org.eclipse.dltk.javascript.typeinfo.MemberPredicate;
import org.eclipse.dltk.javascript.typeinfo.MemberPredicates;
import org.eclipse.dltk.javascript.typeinfo.RSimpleType;
import org.eclipse.dltk.javascript.typeinfo.RTypeMemberQuery;
import org.eclipse.dltk.javascript.typeinfo.RTypes;
import org.eclipse.dltk.javascript.typeinfo.TypeInfoManager;
import org.eclipse.dltk.javascript.typeinfo.TypeUtil;
import org.eclipse.dltk.javascript.typeinfo.model.Element;
import org.eclipse.dltk.javascript.typeinfo.model.Type;
import org.eclipse.dltk.javascript.typeinfo.model.TypeKind;
public abstract class ElementValue implements IValue {
public static IValue findMember(IRType type, String name) {
return findMember(type, name, MemberPredicates.ALWAYS_TRUE);
}
private static class PrototypeType extends RSimpleType {
public PrototypeType(IRTypeDeclaration declaration) {
super(declaration);
}
@Override
public String getName() {
return "prototype<" + getTarget().getName() + ">";
}
@Override
public boolean isExtensible() {
return true;
}
}
static IValue findMemberA(IRType type, String name, boolean resolve) {
final MemberPredicate predicate;
if (type instanceof IRClassType) {
final Type target = ((IRClassType) type).getTarget();
predicate = target != null ? target.memberPredicateFor(type,
MemberPredicates.STATIC) : MemberPredicates.STATIC;
} else if (type instanceof IRSimpleType) {
final Type target = ((IRSimpleType) type).getTarget();
predicate = target != null ? target.memberPredicateFor(type,
MemberPredicates.NON_STATIC) : MemberPredicates.NON_STATIC;
} else if (type instanceof IRUnionType) {
// TODO (alex) use different predicate for each option
predicate = MemberPredicates.ALWAYS_TRUE;
} else {
predicate = MemberPredicates.NON_STATIC;
}
return findMember(type, name, predicate, resolve);
}
public static IValue findMember(IRType type, String name,
MemberPredicate predicate) {
return findMember(type, name, predicate, true);
}
public static IValue findMember(IRType type, String name,
MemberPredicate predicate, boolean resolve) {
if (IValueReference.ARRAY_OP.equals(name)) {
IRType arrayType = TypeUtil.extractArrayItemType(type);
// only give back this a a TypeValue if it is a known and not a
// NoneType
if (arrayType != null
&& TypeUtil.kind(arrayType) != TypeKind.UNKNOWN
&& arrayType != RTypes.none()
&& arrayType != RTypes.arrayOf().getItemType()) {
return new TypeValue(arrayType);
}
}
if (type instanceof IRClassType) {
final IRTypeDeclaration t = ((IRClassType) type).getDeclaration();
if (t != null) {
final List<IRMember> selection = findMembers(t, name, predicate);
if (!selection.isEmpty()) {
if (selection.size() == 1) {
return createElement(t.getTypeSystem(), t,
selection.get(0));
}
return new MemberValue(
selection.toArray(new IRMember[selection.size()]));
}
}
if ((t == null || t.getSource().hasPrototype())
&& predicate.isCompatibleWith(MemberPredicates.STATIC)) {
final List<IRMember> selection = findMembers(
t != null ? t.getTypeSystem().convert(
t.getSource().getPrototypeType())
: RTypes.FUNCTION.getDeclaration(), name,
MemberPredicates.NON_STATIC);
if (!selection.isEmpty()) {
if (selection.size() == 1) {
final IRMember selected = selection.get(0);
if (IRLocalType.PROTOTYPE_PROPERTY.equals(selected
.getName())
&& selected instanceof IRProperty) {
if (t != null) {
return new PrototypePropertyValue(
(IRProperty) selected,
new PrototypeType(t));
} else {
return new PrototypePropertyValue(
(IRProperty) selected,
new PrototypeType(
RTypes.OBJECT.getDeclaration()));
}
}
return createElement(selected);
}
return new MemberValue(
selection.toArray(new IRMember[selection.size()]));
}
}
} else if (type instanceof IRUnionType) {
for (IRType unionTarget : ((IRUnionType) type).getTargets()) {
IValue member = findMember(unionTarget, name, predicate,
resolve);
if (member != null)
return member;
}
} else if (type instanceof IRRecordType) {
final IRRecordMember member = ((IRRecordType) type).getMember(name);
if (member != null) {
return new RTypeValue(member.getType(), member);
}
return findMember(RTypes.OBJECT, name);
} else if (type instanceof IRFunctionType) {
final IRFunctionType functionType = (IRFunctionType) type;
if (FunctionMethod.apply.test(name)) {
return getFunctionMethod(functionType.getTypeSystem(),
functionType, FunctionMethod.apply);
} else if (FunctionMethod.call.test(name)) {
return getFunctionMethod(functionType.getTypeSystem(),
functionType, FunctionMethod.call);
} else {
final List<IRMember> selection = findMembers(
RTypes.FUNCTION.getDeclaration(), name, predicate);
if (!selection.isEmpty()) {
if (selection.size() == 1) {
return createElement(selection.get(0));
}
return new MemberValue(
selection.toArray(new IRMember[selection.size()]));
}
}
} else if (type instanceof IRLocalType) {
final IValueReference child = ((IRLocalType) type)
.getDirectChild(name);
if (child != null) {
final IValue value = ((IValueProvider) child).getValue();
if (value != null)
return value;
}
return findMember(RTypes.OBJECT, name);
} else if (type instanceof IRSimpleType) {
final IRTypeDeclaration t = ((IRSimpleType) type).getDeclaration();
if (t != null) {
final List<IRMember> selection = findMembers(t, name, predicate);
if (!selection.isEmpty()) {
if (selection.size() == 1) {
return createElement(t.getTypeSystem(), t,
selection.get(0));
}
return new MemberValue(
selection.toArray(new IRMember[selection.size()]));
} else if (resolve
&& t.getTypeSystem() instanceof ITypeInfoContext) {
Type target = ((IRSimpleType) type).getTarget();
for (IMemberEvaluator evaluator : TypeInfoManager
.getMemberEvaluators()) {
final IValueCollection collection = evaluator.valueOf(
(ITypeInfoContext) t.getTypeSystem(), target);
if (collection != null) {
if (collection instanceof IValueProvider) {
IValueReference child = collection
.getChild(name);
if (child instanceof IValueProvider) {
return ((IValueProvider) child).getValue();
}
}
}
}
}
}
} else if (type instanceof IRMapType) {
final List<IRMember> selection = findMembers(
RTypes.OBJECT.getDeclaration(), name, predicate);
if (!selection.isEmpty()) {
if (selection.size() == 1) {
return createElement(selection.get(0));
}
return new MemberValue(selection.toArray(new IRMember[selection
.size()]));
}
if (!IValueReference.ARRAY_OP.equals(name)
&& !IValueReference.FUNCTION_OP.equals(name)) {
return new RTypeValue(((IRMapType) type).getValueType(), null);
}
} else if (type == RTypes.any()) {
if (!IValueReference.ARRAY_OP.equals(name)
&& !IValueReference.FUNCTION_OP.equals(name)) {
return PhantomValue.VALUE;
}
}
return null;
}
private static ElementValue getFunctionMethod(ITypeSystem context,
IRFunctionType type, FunctionMethod method) {
if (context != null) {
final FunctionMethodKey key = new FunctionMethodKey(type, method);
ElementValue value = (ElementValue) context.getValue(key);
if (value == null) {
value = new FunctionTypeMethodValue(type, method);
context.setValue(key, value);
}
return value;
} else {
return new FunctionTypeMethodValue(type, method);
}
}
private static class FunctionMethodKey {
private final IRFunctionType type;
private final FunctionMethod method;
public FunctionMethodKey(IRFunctionType type, FunctionMethod method) {
this.type = type;
this.method = method;
}
@Override
public int hashCode() {
return type.hashCode() ^ method.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FunctionMethodKey) {
final FunctionMethodKey other = (FunctionMethodKey) obj;
return type.equals(other.type) && method == other.method;
}
return false;
}
}
private static ElementValue createElement(final IRMember member) {
if (member instanceof IRProperty) {
return new PropertyValue((IRProperty) member);
} else if (member instanceof IRMethod) {
return new MethodValue((IRMethod) member);
} else {
throw new IllegalArgumentException("Unsupported IRMember of type "
+ member.getClass());
}
}
private static ElementValue createElement(ITypeSystem context,
final IRTypeDeclaration type, final IRMember member) {
if (member instanceof IRProperty) {
if (TypeSystemImpl.isContextualizable(member.getType())) {
return new PropertyValue(context.contextualize(
(IRProperty) member, type));
} else {
return new PropertyValue((IRProperty) member);
}
} else if (member instanceof IRMethod) {
if (TypeSystemImpl.isContextualizable(member.getType())) {
return new MethodValue(context.contextualize((IRMethod) member,
type));
} else {
return new MethodValue((IRMethod) member);
}
} else {
return null;
}
}
public static List<IRMember> findMembers(IRTypeDeclaration type,
String name, MemberPredicate predicate) {
final List<IRMember> selection = new ArrayList<IRMember>(4);
for (IRMember member : new RTypeMemberQuery(type, predicate)
.ignoreDuplicates()) {
if (name.equals(member.getName())) {
selection.add(member);
}
}
return selection;
}
public static ElementValue createFor(IRElement element) {
if (element instanceof IRMethod) {
return new MethodValue((IRMethod) element);
} else if (element instanceof IRProperty) {
return new PropertyValue((IRProperty) element);
} else {
final IRTypeDeclaration type = (IRTypeDeclaration) element;
return new TypeValue(RTypes.simple(type));
}
}
public static ElementValue createClass(ITypeSystem context, Type type) {
return new ClassValue(JSTypeSet.singleton(RTypes.classType(context,
type)));
}
static class TypeValue extends ElementValue implements IValue {
private final Map<String, IValue> children = new HashMap<String, IValue>(
4, 0.9f);
private final JSTypeSet types;
public TypeValue(IRType type) {
this.types = JSTypeSet.singleton(type);
}
public TypeValue(JSTypeSet types) {
this.types = types;
}
@Override
public final Set<String> getDirectChildren(int flags) {
if ((flags & NO_LOCAL_TYPES) == 0) {
final Set<String> set = new HashSet<String>();
for (IRType irType : getTypes()) {
if (irType instanceof IRLocalType) {
set.addAll(((IRLocalType) irType).getDirectChildren());
}
}
return set;
} else {
return Collections.emptySet();
}
}
@Override
protected Type[] getElements() {
return types.toArray();
}
public IValue getChild(String name, boolean resolve) {
IValue value = children.get(name);
if (value == null) {
for (IRType type : types) {
value = findMemberA(type, name, resolve);
if (value != null) {
if (value instanceof ElementValue) {
value = ((ElementValue) value).resolveValue();
}
break;
}
}
if (value == null && name.equals(IValueReference.ARRAY_OP)) {
value = new Value();
}
if (value != null) {
children.put(name, value);
}
}
return value;
}
public IRType getDeclaredType() {
return types.toRType();
}
public JSTypeSet getDeclaredTypes() {
return types;
}
@Override
public final JSTypeSet getTypes() {
return types;
}
@Override
public String toString() {
return getClass().getSimpleName() + types;
}
}
private static class ClassValue extends ElementValue implements IValue {
private final JSTypeSet types;
public ClassValue(JSTypeSet types) {
this.types = types;
}
@Override
protected Type[] getElements() {
return types.toArray();
}
public IValue getChild(String name, boolean resolve) {
// just guess that if the child is the function operator it is a new
// expression of this type. return then the none static type.
if (name.equals(IValueReference.FUNCTION_OP)) {
if (types.size() == 1) {
final IRType type = types.toRType();
if (type instanceof IRClassType) {
return new TypeValue(((IRClassType) type).newItemType());
}
}
final JSTypeSet returnTypes = JSTypeSet.create();
for (IRType type : types) {
if (type instanceof IRClassType) {
returnTypes.add(((IRClassType) type).newItemType());
} else {
returnTypes.add(type);
}
}
return new TypeValue(returnTypes);
}
for (IRType type : types) {
IValue child = findMember(type, name, MemberPredicates.STATIC);
if (child != null)
return child;
}
return null;
}
public IRType getDeclaredType() {
return types.toRType();
}
public JSTypeSet getDeclaredTypes() {
return types;
}
@Override
public ReferenceKind getKind() {
return ReferenceKind.TYPE;
}
@Override
public Object getAttribute(String key, boolean includeReferences) {
if (IAssignProtection.ATTRIBUTE.equals(key)) {
return UNASSIGNABLE_CLASS;
}
return super.getAttribute(key, includeReferences);
}
@Override
public String toString() {
return getClass().getSimpleName() + types;
}
}
private static class MethodValue extends ElementValue implements IValue {
private TypeValue functionOperator;
private final IRMethod method;
public MethodValue(IRMethod method) {
this.method = method;
}
@Override
protected IRMethod getElements() {
return method;
}
@Override
public IValue resolveValue() {
final IValue value = resolveValue(method);
if (value != null) {
return value;
}
return this;
}
@Override
public ReferenceKind getKind() {
return ReferenceKind.METHOD;
}
public IValue getChild(String name, boolean resolve) {
if (IValueReference.FUNCTION_OP.equals(name)) {
if (method.getType() != null) {
if (functionOperator == null) {
functionOperator = new TypeValue(
JSTypeSet.singleton(method.getType()));
}
return functionOperator;
}
}
final IValue child = ElementValue.findMemberA(getDeclaredType(),
name, resolve);
if (child != null) {
return child;
}
return null;
}
public IRType getDeclaredType() {
return RTypes.FUNCTION;
}
public JSTypeSet getDeclaredTypes() {
return JSTypeSet.singleton(getDeclaredType());
}
@Override
public Object getAttribute(String key, boolean includeReferences) {
if (IAssignProtection.ATTRIBUTE.equals(key)
&& method.getDeclaringType() == null) {
return UNASSIGNABLE_METHOD;
}
return super.getAttribute(key, includeReferences);
}
@Override
public String toString() {
return getClass().getSimpleName() + '<' + method + '>';
}
}
public static final IAssignProtection READONLY_PROPERTY = new IAssignProtection() {
public IProblemIdentifier problemId() {
return JavaScriptProblems.PROPERTY_READONLY;
}
public String problemMessage() {
return ValidationMessages.AssignmentToReadonlyProperty;
}
};
static final IAssignProtection UNASSIGNABLE_METHOD = new IAssignProtection() {
public IProblemIdentifier problemId() {
return JavaScriptProblems.UNASSIGNABLE_ELEMENT;
}
public String problemMessage() {
return ValidationMessages.UnassignableMethod;
}
};
static final IAssignProtection UNASSIGNABLE_CLASS = new IAssignProtection() {
public IProblemIdentifier problemId() {
return JavaScriptProblems.UNASSIGNABLE_ELEMENT;
}
public String problemMessage() {
return ValidationMessages.UnassignableClass;
}
};
private static class PropertyValue extends ElementValue implements IValue {
private final IRProperty property;
private final Map<String, IValue> children = new HashMap<String, IValue>(
4, 0.9f);
public PropertyValue(IRProperty property) {
this.property = property;
}
@Override
protected IRProperty getElements() {
return property;
}
@Override
public IValue resolveValue() {
final IValue value = resolveValue(property);
if (value != null) {
return value;
}
return this;
}
@Override
public ReferenceKind getKind() {
return ReferenceKind.PROPERTY;
}
@Override
public Set<String> getDirectChildren(int flags) {
IValue value = resolveValue();
if (value != null && value != this) {
return value.getDirectChildren(flags);
}
return super.getDirectChildren(flags);
}
public IValue getChild(String name, boolean resolve) {
IValue child = children.get(name);
if (child == null) {
if (IValueReference.ARRAY_OP.equals(name)
&& property.getType() != null) {
IRType arrayType = null;
if (property.getType() instanceof IRArrayType) {
arrayType = ((IRArrayType) property.getType())
.getItemType();
} else if (property.getType() instanceof IRMapType) {
arrayType = ((IRMapType) property.getType())
.getValueType();
}
if (arrayType != null) {
child = new TypeValue(arrayType);
children.put(name, child);
return child;
}
}
final IRType propType = getDeclaredType();
child = ElementValue.findMemberA(propType, name,
resolve);
if (child instanceof ElementValue) {
child = ((ElementValue) child).resolveValue();
}
if (child != null)
children.put(name, child);
}
return child;
}
public IRType getDeclaredType() {
return property.getType();
}
private JSTypeSet declaredTypes = null;
public JSTypeSet getDeclaredTypes() {
if (declaredTypes == null) {
final IRType type = getDeclaredType();
if (type != null) {
declaredTypes = JSTypeSet.singleton(type);
} else {
declaredTypes = JSTypeSet.emptySet();
}
}
return declaredTypes;
}
@Override
public Object getAttribute(String key, boolean includeReferences) {
if (IAssignProtection.ATTRIBUTE.equals(key)) {
final IRTypeDeclaration declaringType = property
.getDeclaringType();
if (declaringType != null) {
return declaringType.getReadOnlyStatus(property);
} else {
return property.isReadOnly() ? READONLY_PROPERTY : null;
}
}
return super.getAttribute(key, includeReferences);
}
@Override
public String toString() {
return getClass().getSimpleName() + '<' + property + '>';
}
}
private static class PrototypePropertyValue extends PropertyValue {
private final IRType valueType;
public PrototypePropertyValue(IRProperty property, IRType valueType) {
super(property);
this.valueType = valueType;
}
@Override
public IRType getDeclaredType() {
return valueType;
}
}
private static class RTypeValue extends ElementValue implements IValue {
private final IRType type;
private final Map<String, IValue> children = new HashMap<String, IValue>();
private final IRMember element;
public RTypeValue(IRType type, IRMember element) {
this.type = type;
this.element = element;
}
@Override
protected IRMember getElements() {
return element;
}
@Override
public ReferenceKind getKind() {
return ReferenceKind.PROPERTY;
}
public IValue getChild(String name, boolean resolve) {
IValue child = children.get(name);
if (child == null) {
if (IValueReference.ARRAY_OP.equals(name)) {
IRType arrayType = null;
if (type instanceof IRArrayType) {
arrayType = ((IRArrayType) type).getItemType();
} else if (type instanceof IRMapType) {
arrayType = ((IRMapType) type).getValueType();
}
if (arrayType != null) {
ElementValue arrayOpChild = new TypeValue(arrayType);
children.put(name, arrayOpChild);
return arrayOpChild;
}
} else if (IValueReference.FUNCTION_OP.equals(name)) {
if (type instanceof IRFunctionType) {
child = new Value();
child.addType(((IRFunctionType) type).getReturnType());
children.put(name, child);
return child;
}
}
child= ElementValue.findMemberA(type, name, resolve);
if (child instanceof ElementValue) {
child = ((ElementValue) child).resolveValue();
children.put(name, child);
}
}
return child;
}
@Override
public final Set<String> getDirectChildren(int flags) {
if ((flags & NO_LOCAL_TYPES) == 0) {
final Set<String> set = new HashSet<String>();
IRType irType = getDeclaredType();
if (irType instanceof IRLocalType) {
set.addAll(((IRLocalType) irType).getDirectChildren());
}
return set;
} else {
return Collections.emptySet();
}
}
public IRType getDeclaredType() {
return type;
}
public JSTypeSet getDeclaredTypes() {
if (type != null) {
return JSTypeSet.singleton(type);
} else {
return JSTypeSet.emptySet();
}
}
@Override
public ReferenceLocation getLocation() {
if (element != null
&& element.getSource() instanceof ILocationProvider) {
return ((ILocationProvider) element.getSource()).getLocation();
}
return super.getLocation();
}
@Override
public String toString() {
return getClass().getSimpleName() + '<' + type + '>';
}
}
private static class MemberValue extends ElementValue implements IValue {
private TypeValue functionOperator;
private final IRMember[] members;
public MemberValue(IRMember[] members) {
assert members.length > 1;
this.members = members;
}
@Override
protected IRMember[] getElements() {
return members;
}
// @Override
// public IValue resolveValue() {
// if (members.length == 1) {
// final IValue value = resolveValue(members[0]);
// if (value != null) {
// // copy over the properties of this value.
// value.setDeclaredType(getDeclaredType());
// value.setAttribute(IReferenceAttributes.ELEMENT,
// getAttribute(IReferenceAttributes.ELEMENT));
// return value;
// }
// }
// return this;
// }
@Override
public ReferenceKind getKind() {
for (IRMember member : members) {
if (member instanceof IRMethod)
return ReferenceKind.METHOD;
}
return ReferenceKind.PROPERTY;
}
public IValue getChild(String name, boolean resolve) {
if (IValueReference.FUNCTION_OP.equals(name)) {
JSTypeSet types = null;
for (IRMember member : members) {
if (member instanceof IRMethod) {
final IRMethod method = (IRMethod) member;
if (method.getType() != null) {
if (types == null) {
types = JSTypeSet.create();
}
types.add(method.getType());
}
}
}
if (types != null) {
if (functionOperator == null) {
functionOperator = new TypeValue(types);
}
return functionOperator;
}
}
IRType type = getDeclaredType();
if (type != null) {
final IValue child = ElementValue.findMemberA(type, name,
resolve);
if (child != null) {
return child;
}
}
return null;
}
public IRType getDeclaredType() {
for (IRMember member : members) {
if (member instanceof IRProperty) {
final IRProperty property = (IRProperty) member;
if (property.getType() != null) {
return property.getType();
}
} else if (member instanceof IRMethod) {
return RTypes.FUNCTION;
}
}
return null;
}
public JSTypeSet getDeclaredTypes() {
JSTypeSet types = null;
for (IRMember member : members) {
if (member instanceof IRProperty) {
final IRProperty property = (IRProperty) member;
if (property.getType() != null) {
if (types == null) {
types = JSTypeSet.create();
}
types.add(property.getType());
}
} else if (member instanceof IRMethod) {
if (types == null) {
types = JSTypeSet.create();
}
types.add(RTypes.FUNCTION);
}
}
if (types != null) {
return types;
} else {
return JSTypeSet.emptySet();
}
}
@Override
public Object getAttribute(String key, boolean includeReferences) {
if (IAssignProtection.ATTRIBUTE.equals(key)) {
for (IRMember member : members) {
if (member instanceof IRProperty) {
if (((IRProperty) member).isReadOnly()) {
return READONLY_PROPERTY;
}
} else if (member instanceof IRMethod
&& member.getDeclaringType() == null) {
return UNASSIGNABLE_METHOD;
}
}
return null;
}
return super.getAttribute(key, includeReferences);
}
}
public ElementValue() {
}
protected abstract Object getElements();
public IValue resolveValue() {
return this;
}
@Internal
IValue resolveValue(IRMember member) {
final IRTypeDeclaration type = member.getDeclaringType();
final ITypeSystem typeSystem = type != null ? type.getTypeSystem()
: ITypeSystem.CURRENT.get();
return typeSystem != null ? typeSystem.valueOf(member) : null;
}
public final void clear() {
}
public final void addValue(IValue src) {
}
public final void addReference(IValue src) {
}
public void removeReference(IValue value) {
}
public final Object getAttribute(String key) {
return getAttribute(key, false);
}
public Object getAttribute(String key, boolean includeReferences) {
if (IReferenceAttributes.ELEMENT.equals(key)) {
return getElements();
}
if (IReferenceAttributes.HIDE_ALLOWED.equals(key)) {
final Object elements = getElements();
if (elements instanceof IRElement) {
final Object source = ((IRElement) elements).getSource();
if (source instanceof Element) {
if (((Element) source).isHideAllowed()) {
return Boolean.TRUE;
}
}
}
}
return null;
}
public final void setAttribute(String key, Object value) {
}
public final Set<String> getDirectChildren() {
return getDirectChildren(IValue.DEFAULT);
}
public Set<String> getDirectChildren(int flags) {
return Collections.emptySet();
}
public Set<String> getDeletedChildren() {
return Collections.emptySet();
}
public void deleteChild(String name, boolean force) {
}
public final boolean hasChild(String name) {
return false;
}
public final IValue createChild(String name, int flags) {
return getChild(name, true);
// throw new UnsupportedOperationException();
}
public void putChild(String name, IValue value) {
throw new UnsupportedOperationException();
}
public ReferenceKind getKind() {
return ReferenceKind.UNKNOWN;
}
public ReferenceLocation getLocation() {
return ReferenceLocation.UNKNOWN;
}
public JSTypeSet getTypes() {
return JSTypeSet.emptySet();
}
public final void setDeclaredType(IRType declaredType) {
}
public void addType(IRType type) {
}
public final void setKind(ReferenceKind kind) {
}
public final void setLocation(ReferenceLocation location) {
}
}