Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Unified Diff: dart/compiler/java/com/google/dart/compiler/type/Types.java

Issue 20722006: Removed compiler/ directory from repository (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: dart/compiler/java/com/google/dart/compiler/type/Types.java
diff --git a/dart/compiler/java/com/google/dart/compiler/type/Types.java b/dart/compiler/java/com/google/dart/compiler/type/Types.java
deleted file mode 100644
index 8e83daf9a3bd62d52752853f8f0741ede31b9d9e..0000000000000000000000000000000000000000
--- a/dart/compiler/java/com/google/dart/compiler/type/Types.java
+++ /dev/null
@@ -1,817 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.FunctionAliasElement;
-import com.google.dart.compiler.resolver.ResolutionErrorListener;
-import com.google.dart.compiler.resolver.TypeVariableElement;
-import com.google.dart.compiler.resolver.VariableElement;
-import com.google.dart.compiler.type.InterfaceType.Member;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Utility class for types.
- */
-public class Types {
- private static Map<Type, Map<TypeQuality, Type>> inferredTypes = new MapMaker().weakKeys().makeMap();
- private final CoreTypeProvider typeProvider;
-
- private Types(CoreTypeProvider typeProvider) { // Prevent subclassing.
- this.typeProvider = typeProvider;
- }
-
- public Type leastUpperBound(Type t, Type s) {
- if (isSubtype(t, s)) {
- return s;
- } else if (isSubtype(s, t)) {
- return t;
- } else {
- List<InterfaceType> tTypes = getSuperTypes(t);
- List<InterfaceType> sTypes = getSuperTypes(s);
- for (InterfaceType tType : tTypes) {
- if (sTypes.contains(tType)) {
- return tType;
- }
- }
- return typeProvider.getObjectType();
- }
- }
-
- public Type intersection(Type t, Type s) {
- return intersection(ImmutableList.of(t, s));
- }
-
- public static TypeQuality getIntersectionQuality(Type t, Type s) {
- return getIntersectionQuality(ImmutableList.of(t, s));
- }
-
- public static TypeQuality getIntersectionQuality(List<Type> types) {
- Type singleType = null;
- for (Type type : types) {
- if (singleType == null) {
- singleType = type;
- } else if (singleType != type) {
- return TypeQuality.INFERRED;
- }
- }
- return TypeQuality.INFERRED_EXACT;
- }
-
- public Type intersection(List<Type> types) {
- // exclude 'dynamic' type
- {
- List<Type> newTypes = Lists.newArrayList();
- for (Type type : types) {
- if (TypeKind.of(type) != TypeKind.DYNAMIC) {
- newTypes.add(type);
- }
- }
- types = newTypes;
- }
- // no types, so Dynamic
- if (types.isEmpty()) {
- return typeProvider.getDynamicType();
- }
- // prepare all super types
- List<List<InterfaceType>> superTypesLists = Lists.newArrayList();
- List<Map<InterfaceType, InterfaceType>> superTypesMaps = Lists.newArrayList();
- for (Type type : types) {
- List<InterfaceType> superTypes = getSuperTypes(type);
- superTypesLists.add(superTypes);
- Map<InterfaceType, InterfaceType> superTypesMap = Maps.newHashMap();
- for (InterfaceType superType : superTypes) {
- superTypesMap.put(superType.asRawType(), superType);
- }
- superTypesMaps.add(superTypesMap);
- }
- // find intersection of super types
- LinkedList<InterfaceType> interTypes = Lists.newLinkedList();
- if (superTypesLists.size() > 0) {
- for (InterfaceType superType : superTypesLists.get(0)) {
- boolean inAll = true;
- for (Map<InterfaceType, InterfaceType> otherTypesMap : superTypesMaps) {
- InterfaceType superTypeRaw = superType.asRawType();
- InterfaceType otherType = otherTypesMap.get(superTypeRaw);
- // no such raw type, exclude from intersection
- if (otherType == null) {
- inAll = false;
- break;
- }
- // if not raw, choose type arguments
- if (!superType.getArguments().isEmpty()) {
- InterfaceType t0 = superType;
- InterfaceType t1 = otherType;
- // if two-way sub-type, then has Dynamic(s), choose with least number
- if (isSubtype(t0, t1) && isSubtype(t1, t0)) {
- int dynamics0 = getDynamicArgumentsCount(t0);
- int dynamics1 = getDynamicArgumentsCount(t1);
- if (dynamics0 < dynamics1) {
- superType = t0;
- } else {
- superType = t1;
- }
- continue;
- }
- // use super-type of t0 and t1
- if (isSubtype(t0, t1)) {
- superType = t1;
- }
- if (isSubtype(t1, t0)) {
- superType = t0;
- }
- }
- }
- if (inAll && !interTypes.contains(superType)) {
- interTypes.add(superType);
- }
- }
- }
- // try to remove sub-types already covered by existing types
- for (Iterator<InterfaceType> i = interTypes.descendingIterator(); i.hasNext();) {
- InterfaceType subType = i.next();
- boolean hasSuperType = false;
- for (InterfaceType superType : interTypes) {
- if (superType != subType && isSubtype(superType, subType)) {
- hasSuperType = true;
- break;
- }
- }
- if (hasSuperType) {
- i.remove();
- }
- }
- // use single type
- if (interTypes.size() == 0) {
- return typeProvider.getObjectType();
- }
- if (interTypes.size() == 1) {
- return interTypes.get(0);
- }
- // create union
- return unionTypes(interTypes);
- }
-
- /**
- * @return the {@link InterfaceType} which is union of given ones.
- */
- public InterfaceType unionTypes(List<InterfaceType> types) {
- return new InterfaceTypeUnionImplementation(types);
- }
-
- /**
- * @return the number of <code>Dynamic</code> type arguments in given {@link InterfaceType}.
- */
- private static int getDynamicArgumentsCount(InterfaceType t) {
- return Iterables.size(Iterables.filter(t.getArguments(), new Predicate<Type>() {
- public boolean apply(Type arg) {
- return TypeKind.of(arg) == TypeKind.DYNAMIC;
- }
- }));
- }
-
- /**
- * @return list of the super-types (if class type given) or super-interfaces (if interface type
- * given) from most specific to least specific.
- */
- private static List<InterfaceType> getSuperTypes(Type type) {
- List<InterfaceType> types = Lists.newArrayList();
- if (type instanceof InterfaceType) {
- InterfaceType interfaceType = (InterfaceType) type;
- types.add(interfaceType);
- for (InterfaceType intf : interfaceType.getElement().getInterfaces()) {
- intf = asSupertype(interfaceType, intf);
- types.addAll(getSuperTypes(intf));
- }
- for (InterfaceType mixin : interfaceType.getElement().getMixins()) {
- mixin = asSupertype(interfaceType, mixin);
- types.add(mixin);
- }
- if (!interfaceType.getElement().isInterface()) {
- InterfaceType superClass = interfaceType.getElement().getSupertype();
- superClass= asSupertype(interfaceType, superClass);
- types.addAll(getSuperTypes(superClass));
- }
- }
- return types;
- }
-
- /**
- * Return an interface type representing the given interface, function or
- * variable type.
- * @return An interface type or null if the argument is neither an interface
- * function or variable type.
- */
- public InterfaceType getInterfaceType(Type type) {
- switch (TypeKind.of(type)) {
- case VARIABLE: {
- TypeVariableElement element = ((TypeVariable) type).getTypeVariableElement();
- if (element.getBound() == null) {
- return typeProvider.getObjectType();
- } else {
- return getInterfaceType(element.getBound());
- }
- }
- case FUNCTION:
- case FUNCTION_ALIAS:
- return typeProvider.getFunctionType();
- case INTERFACE:
- return (InterfaceType) type;
- case DYNAMIC:
- case NONE:
- case VOID:
- default:
- return null;
- }
- }
-
- /**
- * Returns true if t is a subtype of s.
- */
- public boolean isSubtype(Type t, Type s) {
- if (t.getKind().equals(TypeKind.DYNAMIC)) {
- return true;
- }
- switch (s.getKind()) {
- case DYNAMIC:
- return true;
-
- case INTERFACE:
- return isSubtypeOfInterface(t, (InterfaceType) s);
-
- case FUNCTION_ALIAS:
- return isSubtypeOfAlias(t, (FunctionAliasType) s);
-
- case FUNCTION:
- switch (t.getKind()) {
- case FUNCTION_ALIAS:
- return isSubtypeOfFunction(asFunctionType((FunctionAliasType) t), (FunctionType) s);
-
- case FUNCTION:
- return isSubtypeOfFunction((FunctionType) t, (FunctionType) s);
-
- default:
- return false;
- }
-
- case VARIABLE:
- return isSubtypeOfTypeVariable(t, (TypeVariable) s);
-
- case VOID:
- return t.equals(s);
-
- default:
- throw new AssertionError(s.getKind());
- }
- }
-
- static FunctionType asFunctionType(FunctionAliasType alias) {
- FunctionAliasElement element = alias.getElement();
- FunctionType type =
- (FunctionType) element.getFunctionType().subst(alias.getArguments(),
- element.getTypeParameters());
- return type;
- }
-
- private boolean isSubtypeOfAlias(Type t, FunctionAliasType s) {
- if (isSubtypeOfInterface(t, s)) {
- return true;
- }
- if (t.getKind() == TypeKind.VARIABLE) {
- Type bound = ((TypeVariable) t).getTypeVariableElement().getBound();
- if (bound != null) {
- return isSubtype(bound, s);
- }
- return true;
- }
- if (t.getKind() == TypeKind.FUNCTION_ALIAS) {
- return isSubtypeOfFunction(asFunctionType((FunctionAliasType) t), asFunctionType(s));
- }
- // class has method call()
- if (t.getKind() == TypeKind.INTERFACE) {
- InterfaceType ti = (InterfaceType) t;
- Member callMember = ti.lookupMember("call");
- return callMember != null && isSubtype(callMember.getType(), asFunctionType(s));
- }
- return false;
- }
-
- private boolean isSubtypeOfTypeVariable(Type t, TypeVariable sv) {
- // May be same type variable.
- if (sv.equals(t)) {
- return true;
- }
- // May be "T extends S".
- if (t.getKind() == TypeKind.VARIABLE) {
- TypeVariable tv = (TypeVariable) t;
- Type tBound = tv.getTypeVariableElement().getBound();
- if (tBound != null && tBound.getKind() == TypeKind.VARIABLE) {
- // Prevent cycle.
- if (tBound.equals(t)) {
- return false;
- }
- // Check bound.
- return isSubtype(tBound, sv);
- }
- }
- // May be concrete InterfaceType.
- if (t.getKind() == TypeKind.INTERFACE) {
- InterfaceType ti = (InterfaceType) t;
- Type sBound = sv.getTypeVariableElement().getBound();
- if (sBound == null) {
- return true;
- }
- // Prevent cycle.
- if (sBound.equals(sv)) {
- return false;
- }
- if (sBound.getKind() == TypeKind.INTERFACE) {
- return isSubtype(ti, sBound);
- }
- }
- // no
- return false;
- }
-
- private boolean isSubtypeOfInterface(Type t, InterfaceType s) {
- // Special handling for union.
- if (t instanceof InterfaceTypeUnion) {
- InterfaceTypeUnion tUnion = (InterfaceTypeUnion) t;
- for (InterfaceType unionPart : tUnion.getTypes()) {
- if (isSubtype(unionPart, s)) {
- return true;
- }
- }
- return false;
- }
-
- // class "t" implements call() and "s" is Function
- if (TypeKind.of(t) == TypeKind.INTERFACE && typeProvider != null
- && s == typeProvider.getFunctionType()) {
- InterfaceType ti = (InterfaceType) t;
- if (ti.lookupMember("call") != null) {
- return true;
- }
- }
-
- // Try to cast "t" to "s".
- final Type sup = asInstanceOf(t, s.getElement());
- if (TypeKind.of(sup) == TypeKind.INTERFACE) {
- InterfaceType ti = (InterfaceType) sup;
- assert ti.getElement().equals(s.getElement());
- if (ti.isRaw() || s.isRaw()) {
- return true;
- }
- // Type arguments are covariant.
- return areSubtypes(ti.getArguments().iterator(), s.getArguments().iterator());
- }
- return false;
- }
-
- /**
- * Implement the Dart function subtype rule. Unlike the classic arrow rule (return type is
- * covariant, and parameter types are contravariant), in Dart they must just be assignable.
- */
- private boolean isSubtypeOfFunction(FunctionType t, FunctionType s) {
- if (s.getKind() == TypeKind.DYNAMIC || t.getKind() == TypeKind.DYNAMIC) {
- return true;
- }
- // Classic: return type is covariant; Dart: assignable.
- if (!isAssignable(t.getReturnType(), s.getReturnType())) {
- // A function that returns a value can be used as a function where you ignore the value.
- if (!s.getReturnType().equals(typeProvider.getVoidType())) {
- return false;
- }
- }
- Type tRest = t.getRest();
- Type sRest = s.getRest();
- if ((tRest == null) != (sRest == null)) {
- return false;
- }
- if (tRest != null) {
- // Classic: parameter types are contravariant; Dart: assignable.
- if (!isAssignable(sRest, tRest)) {
- return false;
- }
- }
-
- {
- Map<String, Type> sOpti = s.getOptionalParameterTypes();
- Map<String, Type> tOpti = t.getOptionalParameterTypes();
- if (tOpti.size() < sOpti.size()) {
- return false;
- }
- Iterator<Entry<String, Type>> tList = tOpti.entrySet().iterator();
- Iterator<Entry<String, Type>> sList = sOpti.entrySet().iterator();
- while (sList.hasNext()) {
- if (!tList.hasNext()) {
- return false;
- }
- Entry<String, Type> sEntry = sList.next();
- Entry<String, Type> tEntry = tList.next();
- if (!isAssignable(tEntry.getValue(), sEntry.getValue())) {
- return false;
- }
- }
- }
-
- Map<String, Type> tNamed = t.getNamedParameterTypes();
- Map<String, Type> sNamed = s.getNamedParameterTypes();
- if (tNamed.isEmpty() && !sNamed.isEmpty()) {
- return false;
- }
-
- // T's named parameters must be in the same order and assignable to S's but
- // maybe a superset.
- if (!sNamed.isEmpty()) {
- LinkedHashMap<String,Type> tMap = (LinkedHashMap<String, Type>)(tNamed);
- LinkedHashMap<String,Type> sMap = (LinkedHashMap<String, Type>)(sNamed);
- if (!tMap.keySet().containsAll(sMap.keySet())) {
- return false;
- }
- for (Entry<String, Type> entry : sMap.entrySet()) {
- String name = entry.getKey();
- Type sType = sMap.get(name);
- Type tType = tMap.get(name);
- if (!isAssignable(tType, sType)) {
- return false;
- }
- }
-// Iterator<Entry<String, Type>> tList = tMap.entrySet().iterator();
-// Iterator<Entry<String, Type>> sList = sMap.entrySet().iterator();
-// // t named parameters must start with the named parameters of s
-// while (sList.hasNext()) {
-// if (!tList.hasNext()) {
-// return false;
-// }
-// Entry<String, Type> sEntry = sList.next();
-// Entry<String, Type> tEntry = tList.next();
-// if (!sEntry.getKey().equals(tEntry.getKey())) {
-// return false;
-// }
-// // Classic: parameter types are contravariant; Dart: assignable.
-// if (!isAssignable(tEntry.getValue(), sEntry.getValue())) {
-// return false;
-// }
-// }
- }
-
- // Classic: parameter types are contravariant; Dart: assignable.
- return areAssignable(s.getParameterTypes().iterator(), t.getParameterTypes().iterator());
- }
-
- private boolean areSubtypes(Iterator<? extends Type> t, Iterator<? extends Type> s) {
- while (t.hasNext() && s.hasNext()) {
- if (!isSubtype(t.next(), s.next())) {
- return false;
- }
- }
-
- // O(1) check to assert t and s are of same size.
- return t.hasNext() == s.hasNext();
- }
-
- private boolean areAssignable(Iterator<? extends Type> t, Iterator<? extends Type> s) {
- while (t.hasNext() && s.hasNext()) {
- if (!isAssignable(t.next(), s.next())) {
- return false;
- }
- }
-
- // O(1) check to assert t and s are of same size.
- return t.hasNext() == s.hasNext();
- }
-
- /**
- * Returns true if s is assignable to t.
- */
- public boolean isAssignable(Type t, Type s) {
- t.getClass(); // Quick null check.
- s.getClass(); // Quick null check.
- return isSubtype(t, s) || isSubtype(s, t);
- }
-
- /**
- * Translates the given type into an instantiation of the given
- * element. This is done by walking the supertype hierarchy and
- * substituting in the appropriate type arguments.
- *
- * <p>For example, if {@code GrowableArray<T>} is a subtype of
- * {@code Array<T>}, then
- * {@code asInstanceOf("GrowableArray<String>", "Array")} would
- * return {@code Array<String>}
- *
- * @return null if t is not a subtype of element
- */
- @VisibleForTesting
- public InterfaceType asInstanceOf(Type t, ClassElement element) {
- return checkedAsInstanceOf(t, element, new HashSet<TypeVariable>(), new HashSet<Type>());
- }
-
- private InterfaceType checkedAsInstanceOf(Type t, ClassElement element,
- Set<TypeVariable> variablesReferenced, Set<Type> checkedTypes) {
- // check for recursion
- if (checkedTypes.contains(t)) {
- return null;
- }
- checkedTypes.add(t);
- // check current Type
- switch (TypeKind.of(t)) {
- case FUNCTION_ALIAS:
- case INTERFACE: {
- if (t.getElement().equals(element)) {
- return (InterfaceType) t;
- }
- InterfaceType ti = (InterfaceType) t;
- ClassElement tElement = ti.getElement();
- InterfaceType supertype = tElement.getSupertype();
- // super type
- if (supertype != null) {
- InterfaceType result = checkedAsInstanceOf(asSupertype(ti, supertype), element,
- variablesReferenced, checkedTypes);
- if (result != null) {
- return result;
- }
- }
- // interfaces
- for (InterfaceType intf : tElement.getInterfaces()) {
- InterfaceType result = checkedAsInstanceOf(asSupertype(ti, intf), element,
- variablesReferenced, checkedTypes);
- if (result != null) {
- return result;
- }
- }
- // mixins
- for (InterfaceType mixin : tElement.getMixins()) {
- if (mixin.getElement().equals(element)) {
- return asSupertype(ti, mixin);
- }
- }
- // no
- return null;
- }
- case FUNCTION: {
- Element e = t.getElement();
- switch (e.getKind()) {
- case CLASS:
- // e should be the interface Function in the core library. See the
- // documentation comment on FunctionType.
- InterfaceType ti = (InterfaceType) e.getType();
- return checkedAsInstanceOf(ti, element, variablesReferenced, checkedTypes);
- default:
- return null;
- }
- }
- case VARIABLE: {
- TypeVariable v = (TypeVariable) t;
- Type bound = v.getTypeVariableElement().getBound();
- // Check for previously encountered variables to avoid getting stuck in an infinite loop.
- if (variablesReferenced.contains(v)) {
- if (bound instanceof InterfaceType) {
- return (InterfaceType) bound;
- }
- return typeProvider.getObjectType();
- }
- variablesReferenced.add(v);
- return checkedAsInstanceOf(bound, element, variablesReferenced, checkedTypes);
- }
- default:
- return null;
- }
- }
-
- private static InterfaceType asSupertype(InterfaceType type, InterfaceType supertype) {
- if (supertype == null) {
- return null;
- }
- if (type.isRaw()) {
- return supertype.asRawType();
- }
- List<Type> arguments = type.getArguments();
- List<Type> parameters = type.getElement().getTypeParameters();
- return supertype.subst(arguments, parameters);
- }
-
- static void printTypesOn(StringBuilder sb, List<Type> types,
- String start, String end) {
- sb.append(start);
- boolean first = true;
- for (Type argument : types) {
- if (!first) {
- sb.append(", ");
- }
- sb.append(argument);
- first = false;
- }
- sb.append(end);
- }
-
- public static List<Type> subst(List<Type> types,
- List<Type> arguments, List<Type> parameters) {
- ArrayList<Type> result = new ArrayList<Type>(types.size());
- for (Type type : types) {
- result.add(type.subst(arguments, parameters));
- }
- return result;
- }
-
- public static FunctionType makeFunctionType(ResolutionErrorListener listener,
- ClassElement element,
- List<VariableElement> parameters,
- Type returnType) {
- List<Type> parameterTypes = new ArrayList<Type>(parameters.size());
- Map<String, Type> optionalParameterTypes = null;
- Map<String, Type> namedParameterTypes = null;
- Type restParameter = null;
- for (VariableElement parameter : parameters) {
- Type type = parameter.getType();
- // TODO(scheglov) one we will make optional parameter not named,
- // check isOptional() before isNamed()
- if (parameter.isNamed()) {
- if (namedParameterTypes == null) {
- namedParameterTypes = new LinkedHashMap<String, Type>();
- }
- namedParameterTypes.put(parameter.getName(), type);
- } else if (parameter.isOptional()) {
- if (optionalParameterTypes == null) {
- optionalParameterTypes = new LinkedHashMap<String, Type>();
- }
- optionalParameterTypes.put(parameter.getName(), type);
- } else {
- parameterTypes.add(type);
- }
- }
- return FunctionTypeImplementation.of(element, parameterTypes, optionalParameterTypes,
- namedParameterTypes, restParameter, returnType);
- }
-
- public static Types getInstance(CoreTypeProvider typeProvider) {
- return new Types(typeProvider);
- }
-
- public static InterfaceType interfaceType(ClassElement element, List<Type> arguments) {
- return new InterfaceTypeImplementation(element, arguments);
- }
-
- public static FunctionAliasType functionAliasType(FunctionAliasElement element,
- List<TypeVariable> typeVariables) {
- return new FunctionAliasTypeImplementation(element,
- Collections.<Type>unmodifiableList(typeVariables));
- }
-
- public static TypeVariable typeVariable(TypeVariableElement element) {
- return new TypeVariableImplementation(element);
- }
-
- public static DynamicType newDynamicType() {
- return new DynamicTypeImplementation();
- }
-
- public static InterfaceType ensureInterface(Type type) {
- TypeKind kind = TypeKind.of(type);
- switch (kind) {
- case INTERFACE:
- return (InterfaceType) type;
- case NONE:
- case DYNAMIC:
- return null;
- default:
- throw new AssertionError("unexpected kind " + kind);
- }
- }
-
- public static Type newVoidType() {
- return new VoidType();
- }
-
- /**
- * Returns the type node corresponding to the instantiated class or interface.
- */
- public static DartTypeNode constructorTypeNode(DartNewExpression node) {
- DartNode constructor = node.getConstructor();
- if (constructor instanceof DartPropertyAccess) {
- return (DartTypeNode) ((DartPropertyAccess) constructor).getQualifier();
- } else {
- return (DartTypeNode) constructor;
- }
- }
-
- /**
- * Returns the interface type being instantiated by the given node.
- */
- public static InterfaceType constructorType(DartNewExpression node) {
- DartTypeNode typeNode = constructorTypeNode(node);
- return (InterfaceType) typeNode.getType();
- }
-
- /**
- * @return the wrapper of the given {@link Type} with {@link TypeQuality#INFERRED}.
- */
- public static Type makeInferred(Type type) {
- return makeInferred(type, TypeQuality.INFERRED);
- }
-
- /**
- * @return the wrapper of the given {@link Type} with {@link TypeQuality#INFERRED_EXACT}.
- */
- public static Type makeInferredExact(Type type) {
- return makeInferred(type, TypeQuality.INFERRED_EXACT);
- }
-
- /**
- * @return the wrapper of the given {@link Type} with given {@link TypeQuality}.
- */
- public static Type makeInferred(Type type, TypeQuality quality) {
- if (type == null) {
- return null;
- }
- if (type.getQuality().ordinal() > quality.ordinal()) {
- return type;
- }
- if (quality == TypeQuality.EXACT) {
- return type;
- }
- Set<Class<?>> interfaceSet = getAllImplementedInterfaces(type.getClass());
- if (!interfaceSet.isEmpty()) {
- Class<?>[] interfaces = interfaceSet.toArray(new Class[interfaceSet.size()]);
- return makeInferred(type, interfaces, quality);
- }
- return type;
- }
-
- private static Type makeInferred(final Type type, Class<?>[] interfaces, final TypeQuality quality) {
- Map<TypeQuality, Type> inferredMap = inferredTypes.get(type);
- if (inferredMap == null) {
- inferredMap = new MapMaker().weakValues().makeMap();
- inferredTypes.put(type, inferredMap);
- }
- Type inferred = inferredMap.get(quality);
- if (inferred == null) {
- inferred = (Type) Proxy.newProxyInstance(type.getClass().getClassLoader(),
- interfaces, new InvocationHandler() {
- @Override
- @SuppressWarnings("unchecked")
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- if (args == null && method.getName().equals("getQuality")) {
- return quality;
- }
- if (type instanceof FunctionType) {
- if (args == null && method.getName().equals("getParameterTypes")) {
- List<Type> originalTypes = (List<Type>) method.invoke(type, args);
- return Lists.transform(originalTypes, new Function<Type, Type>() {
- public Type apply(Type input) {
- return makeInferred(input, quality);
- }
- });
- }
- }
- return method.invoke(type, args);
- }
- });
- inferredMap.put(quality, inferred);
- }
- return inferred;
- }
-
- /**
- * @return all interfaces implemented by given {@link Class}.
- */
- private static Set<Class<?>> getAllImplementedInterfaces(Class<?> c) {
- Set<Class<?>> result = Sets.newHashSet();
- for (Class<?> intf : c.getInterfaces()) {
- result.add(intf);
- result.addAll(getAllImplementedInterfaces(intf));
- }
- return result;
- }
-}

Powered by Google App Engine
This is Rietveld 408576698