| Index: pkg/compiler/lib/src/typechecker.dart
|
| diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
|
| index 29c84f0948c9e75e5c8de11c57b6434278f7e0f5..0660e3dc1d19a294eb765e4b5a20496df8efd0aa 100644
|
| --- a/pkg/compiler/lib/src/typechecker.dart
|
| +++ b/pkg/compiler/lib/src/typechecker.dart
|
| @@ -64,7 +64,7 @@ class TypeCheckerTask extends CompilerTask {
|
| compiler, resolvedAst.elements, compiler.types);
|
| if (element.isField) {
|
| visitor.analyzingInitializer = true;
|
| - DartType type =
|
| + ResolutionDartType type =
|
| visitor.analyzeVariableTypeAnnotation(resolvedAst.node);
|
| visitor.analyzeVariableInitializer(element, type, resolvedAst.body);
|
| } else {
|
| @@ -100,7 +100,7 @@ abstract class ElementAccess {
|
|
|
| String get name => element.name;
|
|
|
| - DartType computeType(Resolution resolution);
|
| + ResolutionDartType computeType(Resolution resolution);
|
|
|
| /// Returns [: true :] if the element can be access as an invocation.
|
| bool isCallable(Compiler compiler) {
|
| @@ -124,7 +124,7 @@ class MemberAccess extends ElementAccess {
|
|
|
| Element get element => member.declarations.first.element;
|
|
|
| - DartType computeType(Resolution resolution) => member.type;
|
| + ResolutionDartType computeType(Resolution resolution) => member.type;
|
|
|
| String toString() => 'MemberAccess($member)';
|
| }
|
| @@ -137,7 +137,8 @@ class DynamicAccess implements ElementAccess {
|
|
|
| String get name => 'dynamic';
|
|
|
| - DartType computeType(Resolution resolution) => const DynamicType();
|
| + ResolutionDartType computeType(Resolution resolution) =>
|
| + const ResolutionDynamicType();
|
|
|
| bool isCallable(Compiler compiler) => true;
|
|
|
| @@ -155,18 +156,18 @@ class ResolvedAccess extends ElementAccess {
|
| assert(element != null);
|
| }
|
|
|
| - DartType computeType(Resolution resolution) {
|
| + ResolutionDartType computeType(Resolution resolution) {
|
| if (element.isGetter) {
|
| GetterElement getter = element;
|
| - FunctionType functionType = getter.computeType(resolution);
|
| + ResolutionFunctionType functionType = getter.computeType(resolution);
|
| return functionType.returnType;
|
| } else if (element.isSetter) {
|
| SetterElement setter = element;
|
| - FunctionType functionType = setter.computeType(resolution);
|
| + ResolutionFunctionType functionType = setter.computeType(resolution);
|
| if (functionType.parameterTypes.length != 1) {
|
| // TODO(johnniwinther,karlklose): this happens for malformed static
|
| // setters. Treat them the same as instance members.
|
| - return const DynamicType();
|
| + return const ResolutionDynamicType();
|
| }
|
| return functionType.parameterTypes.first;
|
| } else if (element.isTypedef || element.isClass) {
|
| @@ -186,14 +187,14 @@ class ResolvedAccess extends ElementAccess {
|
| /// An access to a promoted variable.
|
| class PromotedAccess extends ElementAccess {
|
| final VariableElement element;
|
| - final DartType type;
|
| + final ResolutionDartType type;
|
|
|
| - PromotedAccess(VariableElement this.element, DartType this.type) {
|
| + PromotedAccess(VariableElement this.element, ResolutionDartType this.type) {
|
| assert(element != null);
|
| assert(type != null);
|
| }
|
|
|
| - DartType computeType(Resolution resolution) => type;
|
| + ResolutionDartType computeType(Resolution resolution) => type;
|
|
|
| String toString() => 'PromotedAccess($element,$type)';
|
| }
|
| @@ -203,14 +204,14 @@ class PromotedAccess extends ElementAccess {
|
| * access of a resolved element through [:this:].
|
| */
|
| class TypeAccess extends ElementAccess {
|
| - final DartType type;
|
| - TypeAccess(DartType this.type) {
|
| + final ResolutionDartType type;
|
| + TypeAccess(ResolutionDartType this.type) {
|
| assert(type != null);
|
| }
|
|
|
| Element get element => type.element;
|
|
|
| - DartType computeType(Resolution resolution) => type;
|
| + ResolutionDartType computeType(Resolution resolution) => type;
|
|
|
| String toString() => 'TypeAccess($type)';
|
| }
|
| @@ -219,7 +220,7 @@ class TypeAccess extends ElementAccess {
|
| * An access of a type literal.
|
| */
|
| class TypeLiteralAccess extends ElementAccess {
|
| - final DartType type;
|
| + final ResolutionDartType type;
|
|
|
| TypeLiteralAccess(this.type) {
|
| assert(type != null);
|
| @@ -229,7 +230,7 @@ class TypeLiteralAccess extends ElementAccess {
|
|
|
| String get name => type.name;
|
|
|
| - DartType computeType(Resolution resolution) =>
|
| + ResolutionDartType computeType(Resolution resolution) =>
|
| resolution.commonElements.typeType;
|
|
|
| String toString() => 'TypeLiteralAccess($type)';
|
| @@ -238,13 +239,13 @@ class TypeLiteralAccess extends ElementAccess {
|
| /// An access to the 'call' method of a function type.
|
| class FunctionCallAccess implements ElementAccess {
|
| final Element element;
|
| - final DartType type;
|
| + final ResolutionDartType type;
|
|
|
| const FunctionCallAccess(this.element, this.type);
|
|
|
| String get name => 'call';
|
|
|
| - DartType computeType(Resolution resolution) => type;
|
| + ResolutionDartType computeType(Resolution resolution) => type;
|
|
|
| bool isCallable(Compiler compiler) => true;
|
|
|
| @@ -255,7 +256,7 @@ class FunctionCallAccess implements ElementAccess {
|
| class TypePromotion {
|
| final Send node;
|
| final VariableElement variable;
|
| - final DartType type;
|
| + final ResolutionDartType type;
|
| final List<TypePromotionMessage> messages = <TypePromotionMessage>[];
|
|
|
| TypePromotion(this.node, this.variable, this.type);
|
| @@ -284,13 +285,13 @@ class TypePromotionMessage {
|
| TypePromotionMessage(this.hint, this.infos);
|
| }
|
|
|
| -class TypeCheckerVisitor extends Visitor<DartType> {
|
| +class TypeCheckerVisitor extends Visitor<ResolutionDartType> {
|
| final Compiler compiler;
|
| final TreeElements elements;
|
| final Types types;
|
|
|
| Node lastSeenNode;
|
| - DartType expectedReturnType;
|
| + ResolutionDartType expectedReturnType;
|
| AsyncMarker currentAsyncMarker = AsyncMarker.SYNC;
|
|
|
| final ClassElement currentClass;
|
| @@ -304,15 +305,15 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|
|
| Resolution get resolution => compiler.resolution;
|
|
|
| - InterfaceType get intType => commonElements.intType;
|
| - InterfaceType get doubleType => commonElements.doubleType;
|
| - InterfaceType get boolType => commonElements.boolType;
|
| - InterfaceType get stringType => commonElements.stringType;
|
| + ResolutionInterfaceType get intType => commonElements.intType;
|
| + ResolutionInterfaceType get doubleType => commonElements.doubleType;
|
| + ResolutionInterfaceType get boolType => commonElements.boolType;
|
| + ResolutionInterfaceType get stringType => commonElements.stringType;
|
|
|
| - DartType thisType;
|
| - DartType superType;
|
| + ResolutionDartType thisType;
|
| + ResolutionDartType superType;
|
|
|
| - Link<DartType> cascadeTypes = const Link<DartType>();
|
| + Link<ResolutionDartType> cascadeTypes = const Link<ResolutionDartType>();
|
|
|
| bool analyzingInitializer = false;
|
|
|
| @@ -366,7 +367,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return null;
|
| }
|
|
|
| - DartType getKnownType(VariableElement element) {
|
| + ResolutionDartType getKnownType(VariableElement element) {
|
| TypePromotion typePromotion = getKnownTypePromotion(element);
|
| if (typePromotion != null) return typePromotion.type;
|
| return element.type;
|
| @@ -383,8 +384,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| superType = currentClass.supertype;
|
| } else {
|
| // If these are used, an error should have been reported by the resolver.
|
| - thisType = const DynamicType();
|
| - superType = const DynamicType();
|
| + thisType = const ResolutionDynamicType();
|
| + superType = const ResolutionDynamicType();
|
| }
|
| }
|
|
|
| @@ -414,23 +415,24 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| // TODO(karlklose): remove these functions.
|
| - DartType unhandledExpression() => const DynamicType();
|
| + ResolutionDartType unhandledExpression() => const ResolutionDynamicType();
|
|
|
| - DartType analyzeNonVoid(Node node) {
|
| - DartType type = analyze(node);
|
| + ResolutionDartType analyzeNonVoid(Node node) {
|
| + ResolutionDartType type = analyze(node);
|
| if (type.isVoid) {
|
| reportTypeWarning(node, MessageKind.VOID_EXPRESSION);
|
| }
|
| return type;
|
| }
|
|
|
| - DartType analyzeWithDefault(Node node, DartType defaultValue) {
|
| + ResolutionDartType analyzeWithDefault(
|
| + Node node, ResolutionDartType defaultValue) {
|
| return node != null ? analyze(node) : defaultValue;
|
| }
|
|
|
| /// If [inInitializer] is true, assignment should be interpreted as write to
|
| /// a field and not to a setter.
|
| - DartType analyze(Node node,
|
| + ResolutionDartType analyze(Node node,
|
| {bool inInitializer: false, bool mustHaveType: true}) {
|
| if (node == null) {
|
| final String error = 'Unexpected node: null';
|
| @@ -444,7 +446,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| bool previouslyInitializer = analyzingInitializer;
|
| analyzingInitializer = inInitializer;
|
| - DartType result = node.accept(this);
|
| + ResolutionDartType result = node.accept(this);
|
| analyzingInitializer = previouslyInitializer;
|
| if (result == null && mustHaveType) {
|
| reporter.internalError(node, 'Type is null.');
|
| @@ -537,7 +539,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| /// Analyze [node] in the context of the known types shown in [context].
|
| - DartType analyzeInPromotedContext(Node context, Node node,
|
| + ResolutionDartType analyzeInPromotedContext(Node context, Node node,
|
| {bool mustHaveType: true}) {
|
| Link<TypePromotion> knownForNode = const Link<TypePromotion>();
|
| for (TypePromotion typePromotion in getShownTypePromotionsFor(context)) {
|
| @@ -547,7 +549,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| registerKnownTypePromotion(typePromotion);
|
| }
|
|
|
| - final DartType type = analyze(node, mustHaveType: mustHaveType);
|
| + final ResolutionDartType type = analyze(node, mustHaveType: mustHaveType);
|
|
|
| while (!knownForNode.isEmpty) {
|
| unregisterKnownTypePromotion(knownForNode.head);
|
| @@ -562,7 +564,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| * return value of type [to]. If `isConst == true`, an error is emitted in
|
| * checked mode, otherwise a warning is issued.
|
| */
|
| - bool checkAssignable(Spannable spannable, DartType from, DartType to,
|
| + bool checkAssignable(
|
| + Spannable spannable, ResolutionDartType from, ResolutionDartType to,
|
| {bool isConst: false}) {
|
| if (!types.isAssignable(from, to)) {
|
| if (compiler.options.enableTypeAssertions && isConst) {
|
| @@ -581,12 +584,12 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| checkAssignable(condition, analyze(condition), boolType);
|
| }
|
|
|
| - void pushCascadeType(DartType type) {
|
| + void pushCascadeType(ResolutionDartType type) {
|
| cascadeTypes = cascadeTypes.prepend(type);
|
| }
|
|
|
| - DartType popCascadeType() {
|
| - DartType type = cascadeTypes.head;
|
| + ResolutionDartType popCascadeType() {
|
| + ResolutionDartType type = cascadeTypes.head;
|
| cascadeTypes = cascadeTypes.tail;
|
| return type;
|
| }
|
| @@ -600,13 +603,13 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| analyzeUntyped(node.statements);
|
| }
|
|
|
| - DartType visitCascade(Cascade node) {
|
| + ResolutionDartType visitCascade(Cascade node) {
|
| analyze(node.expression);
|
| return popCascadeType();
|
| }
|
|
|
| - DartType visitCascadeReceiver(CascadeReceiver node) {
|
| - DartType type = analyze(node.expression);
|
| + ResolutionDartType visitCascadeReceiver(CascadeReceiver node) {
|
| + ResolutionDartType type = analyze(node.expression);
|
| pushCascadeType(type);
|
| return type;
|
| }
|
| @@ -639,16 +642,16 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| analyze(node.function);
|
| }
|
|
|
| - DartType visitFunctionExpression(FunctionExpression node) {
|
| - DartType type;
|
| - DartType returnType;
|
| + ResolutionDartType visitFunctionExpression(FunctionExpression node) {
|
| + ResolutionDartType type;
|
| + ResolutionDartType returnType;
|
| final FunctionElement element = elements.getFunctionDefinition(node);
|
| assert(invariant(node, element != null,
|
| message: 'FunctionExpression with no element'));
|
| - if (Elements.isUnresolved(element)) return const DynamicType();
|
| + if (Elements.isUnresolved(element)) return const ResolutionDynamicType();
|
| if (element.isGenerativeConstructor) {
|
| - type = const DynamicType();
|
| - returnType = const VoidType();
|
| + type = const ResolutionDynamicType();
|
| + returnType = const ResolutionVoidType();
|
|
|
| element.functionSignature.forEachParameter((ParameterElement parameter) {
|
| if (parameter.isInitializingFormal) {
|
| @@ -661,12 +664,12 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| analyzeUntyped(node.initializers, inInitializer: true);
|
| }
|
| } else {
|
| - FunctionType functionType = element.computeType(resolution);
|
| + ResolutionFunctionType functionType = element.computeType(resolution);
|
| returnType = functionType.returnType;
|
| type = functionType;
|
| }
|
| ExecutableElement previousExecutableContext = executableContext;
|
| - DartType previousReturnType = expectedReturnType;
|
| + ResolutionDartType previousReturnType = expectedReturnType;
|
| expectedReturnType = returnType;
|
| AsyncMarker previousAsyncMarker = currentAsyncMarker;
|
|
|
| @@ -680,7 +683,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return type;
|
| }
|
|
|
| - DartType visitIdentifier(Identifier node) {
|
| + ResolutionDartType visitIdentifier(Identifier node) {
|
| if (node.isThis()) {
|
| return thisType;
|
| } else if (node.isSuper()) {
|
| @@ -716,8 +719,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| }
|
|
|
| - ElementAccess lookupMember(Node node, DartType receiverType, String name,
|
| - MemberKind memberKind, Element receiverElement,
|
| + ElementAccess lookupMember(Node node, ResolutionDartType receiverType,
|
| + String name, MemberKind memberKind, Element receiverElement,
|
| {bool lookupClassMember: false, bool isHint: false}) {
|
| if (receiverType.treatAsDynamic) {
|
| return const DynamicAccess();
|
| @@ -727,7 +730,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| isSetter: memberKind == MemberKind.SETTER);
|
|
|
| // Lookup the class or interface member [name] in [interface].
|
| - MemberSignature lookupMemberSignature(Name name, InterfaceType interface) {
|
| + MemberSignature lookupMemberSignature(
|
| + Name name, ResolutionInterfaceType interface) {
|
| MembersCreator.computeClassMembersByName(
|
| resolution, interface.element, name.text);
|
| return lookupClassMember || analyzingInitializer
|
| @@ -737,8 +741,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|
|
| // Compute the access of [name] on [type]. This function takes the special
|
| // 'call' method into account.
|
| - ElementAccess getAccess(
|
| - Name name, DartType unaliasedBound, InterfaceType interface) {
|
| + ElementAccess getAccess(Name name, ResolutionDartType unaliasedBound,
|
| + ResolutionInterfaceType interface) {
|
| MemberSignature member = lookupMemberSignature(memberName, interface);
|
| if (member != null) {
|
| if (member is ErroneousMember) {
|
| @@ -756,18 +760,18 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // This is an access of the special 'call' method implicitly defined
|
| // on 'Function'. This method can be called with any arguments, which
|
| // we ensure by giving it the type 'dynamic'.
|
| - return new FunctionCallAccess(null, const DynamicType());
|
| + return new FunctionCallAccess(null, const ResolutionDynamicType());
|
| }
|
| }
|
| return null;
|
| }
|
|
|
| - DartType unaliasedBound =
|
| + ResolutionDartType unaliasedBound =
|
| Types.computeUnaliasedBound(resolution, receiverType);
|
| if (unaliasedBound.treatAsDynamic) {
|
| return new DynamicAccess();
|
| }
|
| - InterfaceType interface =
|
| + ResolutionInterfaceType interface =
|
| Types.computeInterfaceType(resolution, unaliasedBound);
|
| ElementAccess access = getAccess(memberName, unaliasedBound, interface);
|
| if (access != null) {
|
| @@ -780,10 +784,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| while (!typePromotions.isEmpty) {
|
| TypePromotion typePromotion = typePromotions.head;
|
| if (!typePromotion.isValid) {
|
| - DartType unaliasedBound =
|
| + ResolutionDartType unaliasedBound =
|
| Types.computeUnaliasedBound(resolution, typePromotion.type);
|
| if (!unaliasedBound.treatAsDynamic) {
|
| - InterfaceType interface =
|
| + ResolutionInterfaceType interface =
|
| Types.computeInterfaceType(resolution, unaliasedBound);
|
| if (getAccess(memberName, unaliasedBound, interface) != null) {
|
| reportTypePromotionHint(typePromotion);
|
| @@ -873,19 +877,19 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return const DynamicAccess();
|
| }
|
|
|
| - DartType lookupMemberType(
|
| - Node node, DartType type, String name, MemberKind memberKind,
|
| + ResolutionDartType lookupMemberType(
|
| + Node node, ResolutionDartType type, String name, MemberKind memberKind,
|
| {bool isHint: false}) {
|
| return lookupMember(node, type, name, memberKind, null, isHint: isHint)
|
| .computeType(resolution);
|
| }
|
|
|
| - void analyzeArguments(Send send, Element element, DartType type,
|
| - [LinkBuilder<DartType> argumentTypes]) {
|
| + void analyzeArguments(Send send, Element element, ResolutionDartType type,
|
| + [LinkBuilder<ResolutionDartType> argumentTypes]) {
|
| Link<Node> arguments = send.arguments;
|
| type.computeUnaliased(resolution);
|
| - DartType unaliasedType = type.unaliased;
|
| - if (identical(unaliasedType.kind, TypeKind.FUNCTION)) {
|
| + ResolutionDartType unaliasedType = type.unaliased;
|
| + if (identical(unaliasedType.kind, ResolutionTypeKind.FUNCTION)) {
|
| /// Report [warning] including info(s) about the declaration of [element]
|
| /// or [type].
|
| void reportWarning(DiagnosticMessage warning) {
|
| @@ -909,17 +913,18 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
|
|
| /// Report a warning on [node] if [argumentType] is not assignable to
|
| /// [parameterType].
|
| - void checkAssignable(
|
| - Spannable node, DartType argumentType, DartType parameterType) {
|
| + void checkAssignable(Spannable node, ResolutionDartType argumentType,
|
| + ResolutionDartType parameterType) {
|
| if (!types.isAssignable(argumentType, parameterType)) {
|
| reportWarning(reporter.createMessage(node, MessageKind.NOT_ASSIGNABLE,
|
| {'fromType': argumentType, 'toType': parameterType}));
|
| }
|
| }
|
|
|
| - FunctionType funType = unaliasedType;
|
| - Iterator<DartType> parameterTypes = funType.parameterTypes.iterator;
|
| - Iterator<DartType> optionalParameterTypes =
|
| + ResolutionFunctionType funType = unaliasedType;
|
| + Iterator<ResolutionDartType> parameterTypes =
|
| + funType.parameterTypes.iterator;
|
| + Iterator<ResolutionDartType> optionalParameterTypes =
|
| funType.optionalParameterTypes.iterator;
|
| while (!arguments.isEmpty) {
|
| Node argument = arguments.head;
|
| @@ -927,7 +932,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| if (namedArgument != null) {
|
| argument = namedArgument.expression;
|
| String argumentName = namedArgument.name.source;
|
| - DartType namedParameterType =
|
| + ResolutionDartType namedParameterType =
|
| funType.getNamedParameterType(argumentName);
|
| if (namedParameterType == null) {
|
| // TODO(johnniwinther): Provide better information on the called
|
| @@ -937,10 +942,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| MessageKind.NAMED_ARGUMENT_NOT_FOUND,
|
| {'argumentName': argumentName}));
|
|
|
| - DartType argumentType = analyze(argument);
|
| + ResolutionDartType argumentType = analyze(argument);
|
| if (argumentTypes != null) argumentTypes.addLast(argumentType);
|
| } else {
|
| - DartType argumentType = analyze(argument);
|
| + ResolutionDartType argumentType = analyze(argument);
|
| if (argumentTypes != null) argumentTypes.addLast(argumentType);
|
| checkAssignable(argument, argumentType, namedParameterType);
|
| }
|
| @@ -952,16 +957,16 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| reportWarning(reporter.createMessage(
|
| argument, MessageKind.ADDITIONAL_ARGUMENT));
|
|
|
| - DartType argumentType = analyze(argument);
|
| + ResolutionDartType argumentType = analyze(argument);
|
| if (argumentTypes != null) argumentTypes.addLast(argumentType);
|
| } else {
|
| - DartType argumentType = analyze(argument);
|
| + ResolutionDartType argumentType = analyze(argument);
|
| if (argumentTypes != null) argumentTypes.addLast(argumentType);
|
| checkAssignable(
|
| argument, argumentType, optionalParameterTypes.current);
|
| }
|
| } else {
|
| - DartType argumentType = analyze(argument);
|
| + ResolutionDartType argumentType = analyze(argument);
|
| if (argumentTypes != null) argumentTypes.addLast(argumentType);
|
| checkAssignable(argument, argumentType, parameterTypes.current);
|
| }
|
| @@ -976,7 +981,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| } else {
|
| while (!arguments.isEmpty) {
|
| - DartType argumentType = analyze(arguments.head);
|
| + ResolutionDartType argumentType = analyze(arguments.head);
|
| if (argumentTypes != null) argumentTypes.addLast(argumentType);
|
| arguments = arguments.tail;
|
| }
|
| @@ -987,24 +992,24 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| //
|
| // If provided [argumentTypes] is filled with the argument types during
|
| // analysis.
|
| - DartType analyzeInvocation(Send node, ElementAccess elementAccess,
|
| - [LinkBuilder<DartType> argumentTypes]) {
|
| - DartType type = elementAccess.computeType(resolution);
|
| + ResolutionDartType analyzeInvocation(Send node, ElementAccess elementAccess,
|
| + [LinkBuilder<ResolutionDartType> argumentTypes]) {
|
| + ResolutionDartType type = elementAccess.computeType(resolution);
|
| if (elementAccess.isCallable(compiler)) {
|
| analyzeArguments(node, elementAccess.element, type, argumentTypes);
|
| } else {
|
| reportTypeWarning(
|
| node, MessageKind.NOT_CALLABLE, {'elementName': elementAccess.name});
|
| - analyzeArguments(
|
| - node, elementAccess.element, const DynamicType(), argumentTypes);
|
| + analyzeArguments(node, elementAccess.element,
|
| + const ResolutionDynamicType(), argumentTypes);
|
| }
|
| type.computeUnaliased(resolution);
|
| type = type.unaliased;
|
| if (type.isFunctionType) {
|
| - FunctionType funType = type;
|
| + ResolutionFunctionType funType = type;
|
| return funType.returnType;
|
| } else {
|
| - return const DynamicType();
|
| + return const ResolutionDynamicType();
|
| }
|
| }
|
|
|
| @@ -1032,7 +1037,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| }
|
| // e.foo() for some expression e.
|
| - DartType receiverType = analyze(node.receiver);
|
| + ResolutionDartType receiverType = analyze(node.receiver);
|
| if (receiverType.treatAsDynamic || receiverType.isVoid) {
|
| return const DynamicAccess();
|
| }
|
| @@ -1104,10 +1109,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| * Computes the type of the access of [name] on the [node] possibly using the
|
| * [element] provided for [node] by the resolver.
|
| */
|
| - DartType computeAccessType(
|
| + ResolutionDartType computeAccessType(
|
| Send node, String name, Element element, MemberKind memberKind,
|
| {bool lookupClassMember: false}) {
|
| - DartType type = computeAccess(node, name, element, memberKind,
|
| + ResolutionDartType type = computeAccess(node, name, element, memberKind,
|
| lookupClassMember: lookupClassMember)
|
| .computeType(resolution);
|
| if (type == null) {
|
| @@ -1120,7 +1125,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| /// This is used to provided better hints when trying to promote a supertype
|
| /// to a raw subtype. For instance trying to promote `Iterable<int>` to `List`
|
| /// we suggest the use of `List<int>`, which would make promotion valid.
|
| - DartType computeMoreSpecificType(DartType shownType, DartType knownType) {
|
| + ResolutionDartType computeMoreSpecificType(
|
| + ResolutionDartType shownType, ResolutionDartType knownType) {
|
| if (knownType.isInterfaceType &&
|
| shownType.isInterfaceType &&
|
| types.isSubtype(shownType.asRaw(), knownType)) {
|
| @@ -1129,14 +1135,14 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // class B<S, U> extends A<S, int> {}
|
| // and a promotion from a [knownType] of `A<double, int>` to a
|
| // [shownType] of `B`.
|
| - InterfaceType knownInterfaceType = knownType;
|
| + ResolutionInterfaceType knownInterfaceType = knownType;
|
| ClassElement shownClass = shownType.element;
|
|
|
| // Compute `B<double, dynamic>` as the subtype of `A<double, int>` using
|
| // the relation between `A<S, int>` and `A<double, int>`.
|
| MoreSpecificSubtypeVisitor visitor =
|
| new MoreSpecificSubtypeVisitor(types);
|
| - InterfaceType shownTypeGeneric =
|
| + ResolutionInterfaceType shownTypeGeneric =
|
| visitor.computeMoreSpecific(shownClass, knownInterfaceType);
|
|
|
| if (shownTypeGeneric != null &&
|
| @@ -1149,11 +1155,11 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return null;
|
| }
|
|
|
| - DartType visitSend(Send node) {
|
| + ResolutionDartType visitSend(Send node) {
|
| Element element = elements[node];
|
|
|
| if (element != null && element.isConstructor) {
|
| - DartType receiverType;
|
| + ResolutionDartType receiverType;
|
| if (node.receiver != null) {
|
| receiverType = analyze(node.receiver);
|
| } else if (node.selector.isSuper()) {
|
| @@ -1163,9 +1169,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| assert(node.selector.isThis());
|
| receiverType = thisType;
|
| }
|
| - DartType constructorType = computeConstructorType(element, receiverType);
|
| + ResolutionDartType constructorType =
|
| + computeConstructorType(element, receiverType);
|
| analyzeArguments(node, element, constructorType);
|
| - return const DynamicType();
|
| + return const ResolutionDynamicType();
|
| }
|
|
|
| Identifier selector = node.selector.asIdentifier();
|
| @@ -1182,12 +1189,12 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| } else {
|
| // exp() where exp is some complex expression like (o) or foo().
|
| - DartType type = analyze(node.selector);
|
| + ResolutionDartType type = analyze(node.selector);
|
| return analyzeInvocation(node, new TypeAccess(type));
|
| }
|
| } else if (Elements.isMalformed(element) && selector == null) {
|
| // exp() where exp is an erroneous construct like `new Unresolved()`.
|
| - DartType type = analyze(node.selector);
|
| + ResolutionDartType type = analyze(node.selector);
|
| return analyzeInvocation(node, new TypeAccess(type));
|
| }
|
|
|
| @@ -1209,9 +1216,10 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| if (variable != null && (variable.isVariable || variable.isParameter)) {
|
| - DartType knownType = getKnownType(variable);
|
| + ResolutionDartType knownType = getKnownType(variable);
|
| if (!knownType.isDynamic) {
|
| - DartType shownType = elements.getType(node.arguments.head);
|
| + ResolutionDartType shownType =
|
| + elements.getType(node.arguments.head);
|
| TypePromotion typePromotion =
|
| new TypePromotion(node, variable, shownType);
|
| if (!types.isMoreSpecific(shownType, knownType)) {
|
| @@ -1224,7 +1232,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| 'knownType': knownType
|
| }));
|
| } else {
|
| - DartType shownTypeSuggestion =
|
| + ResolutionDartType shownTypeSuggestion =
|
| computeMoreSpecificType(shownType, knownType);
|
| if (shownTypeSuggestion != null) {
|
| typePromotion.addHint(reporter.createMessage(
|
| @@ -1255,7 +1263,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return elements.getType(node.arguments.head);
|
| } else if (node.isOperator) {
|
| final Node receiver = node.receiver;
|
| - final DartType receiverType = analyze(receiver);
|
| + final ResolutionDartType receiverType = analyze(receiver);
|
| if (identical(name, '==') ||
|
| identical(name, '!=')
|
| // TODO(johnniwinther): Remove these.
|
| @@ -1268,14 +1276,14 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| } else if (identical(name, '||')) {
|
| checkAssignable(receiver, receiverType, boolType);
|
| final Node argument = node.arguments.head;
|
| - final DartType argumentType = analyze(argument);
|
| + final ResolutionDartType argumentType = analyze(argument);
|
| checkAssignable(argument, argumentType, boolType);
|
| return boolType;
|
| } else if (identical(name, '&&')) {
|
| checkAssignable(receiver, receiverType, boolType);
|
| final Node argument = node.arguments.head;
|
|
|
| - final DartType argumentType =
|
| + final ResolutionDartType argumentType =
|
| analyzeInPromotedContext(receiver, argument);
|
|
|
| reshowTypePromotions(node, receiver, argument);
|
| @@ -1289,7 +1297,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return boolType;
|
| } else if (identical(name, '??')) {
|
| final Node argument = node.arguments.head;
|
| - final DartType argumentType = analyze(argument);
|
| + final ResolutionDartType argumentType = analyze(argument);
|
| return types.computeLeastUpperBound(receiverType, argumentType);
|
| }
|
| String operatorName = selector.source;
|
| @@ -1324,15 +1332,16 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| ? const DynamicAccess()
|
| : lookupMember(
|
| node, receiverType, operatorName, MemberKind.OPERATOR, null);
|
| - LinkBuilder<DartType> argumentTypesBuilder = new LinkBuilder<DartType>();
|
| - DartType resultType =
|
| + LinkBuilder<ResolutionDartType> argumentTypesBuilder =
|
| + new LinkBuilder<ResolutionDartType>();
|
| + ResolutionDartType resultType =
|
| analyzeInvocation(node, access, argumentTypesBuilder);
|
| if (receiverType == intType) {
|
| if (identical(name, '+') ||
|
| identical(operatorName, '-') ||
|
| identical(name, '*') ||
|
| identical(name, '%')) {
|
| - DartType argumentType = argumentTypesBuilder.toLink().head;
|
| + ResolutionDartType argumentType = argumentTypesBuilder.toLink().head;
|
| if (argumentType == intType) {
|
| return intType;
|
| } else if (argumentType == doubleType) {
|
| @@ -1355,16 +1364,16 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| /// Returns the first type in the list or [:dynamic:] if the list is empty.
|
| - DartType firstType(List<DartType> list) {
|
| - return list.isEmpty ? const DynamicType() : list.first;
|
| + ResolutionDartType firstType(List<ResolutionDartType> list) {
|
| + return list.isEmpty ? const ResolutionDynamicType() : list.first;
|
| }
|
|
|
| /**
|
| * Returns the second type in the list or [:dynamic:] if the list is too
|
| * short.
|
| */
|
| - DartType secondType(List<DartType> list) {
|
| - return list.length < 2 ? const DynamicType() : list[1];
|
| + ResolutionDartType secondType(List<ResolutionDartType> list) {
|
| + return list.length < 2 ? const ResolutionDynamicType() : list[1];
|
| }
|
|
|
| /**
|
| @@ -1372,24 +1381,25 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| * of the result. This method also handles increment/decrement expressions
|
| * like [: target++ :].
|
| */
|
| - DartType checkAssignmentOperator(
|
| - SendSet node, String operatorName, Node valueNode, DartType value) {
|
| + ResolutionDartType checkAssignmentOperator(SendSet node, String operatorName,
|
| + Node valueNode, ResolutionDartType value) {
|
| assert(invariant(node, !node.isIndex));
|
| Element setterElement = elements[node];
|
| Element getterElement = elements[node.selector];
|
| Identifier selector = node.selector;
|
| - DartType getter = computeAccessType(
|
| + ResolutionDartType getter = computeAccessType(
|
| node, selector.source, getterElement, MemberKind.GETTER);
|
| - DartType setter = computeAccessType(
|
| + ResolutionDartType setter = computeAccessType(
|
| node, selector.source, setterElement, MemberKind.SETTER);
|
| // [operator] is the type of operator+ or operator- on [target].
|
| - DartType operator =
|
| + ResolutionDartType operator =
|
| lookupMemberType(node, getter, operatorName, MemberKind.OPERATOR);
|
| - if (operator is FunctionType) {
|
| - FunctionType operatorType = operator;
|
| + if (operator is ResolutionFunctionType) {
|
| + ResolutionFunctionType operatorType = operator;
|
| // [result] is the type of target o value.
|
| - DartType result = operatorType.returnType;
|
| - DartType operatorArgument = firstType(operatorType.parameterTypes);
|
| + ResolutionDartType result = operatorType.returnType;
|
| + ResolutionDartType operatorArgument =
|
| + firstType(operatorType.parameterTypes);
|
| // Check target o value.
|
| bool validValue = checkAssignable(valueNode, value, operatorArgument);
|
| if (validValue || !(node.isPrefix || node.isPostfix)) {
|
| @@ -1398,7 +1408,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| return node.isPostfix ? getter : result;
|
| }
|
| - return const DynamicType();
|
| + return const ResolutionDynamicType();
|
| }
|
|
|
| /**
|
| @@ -1406,43 +1416,47 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| * of the result. This method also handles increment/decrement expressions
|
| * like [: base[key]++ :].
|
| */
|
| - DartType checkIndexAssignmentOperator(
|
| - SendSet node, String operatorName, Node valueNode, DartType value) {
|
| + ResolutionDartType checkIndexAssignmentOperator(SendSet node,
|
| + String operatorName, Node valueNode, ResolutionDartType value) {
|
| assert(invariant(node, node.isIndex));
|
| - final DartType base = analyze(node.receiver);
|
| + final ResolutionDartType base = analyze(node.receiver);
|
| final Node keyNode = node.arguments.head;
|
| - final DartType key = analyze(keyNode);
|
| + final ResolutionDartType key = analyze(keyNode);
|
|
|
| // [indexGet] is the type of operator[] on [base].
|
| - DartType indexGet = lookupMemberType(node, base, '[]', MemberKind.OPERATOR);
|
| - if (indexGet is FunctionType) {
|
| - FunctionType indexGetType = indexGet;
|
| - DartType indexGetKey = firstType(indexGetType.parameterTypes);
|
| + ResolutionDartType indexGet =
|
| + lookupMemberType(node, base, '[]', MemberKind.OPERATOR);
|
| + if (indexGet is ResolutionFunctionType) {
|
| + ResolutionFunctionType indexGetType = indexGet;
|
| + ResolutionDartType indexGetKey = firstType(indexGetType.parameterTypes);
|
| // Check base[key].
|
| bool validKey = checkAssignable(keyNode, key, indexGetKey);
|
|
|
| // [element] is the type of base[key].
|
| - DartType element = indexGetType.returnType;
|
| + ResolutionDartType element = indexGetType.returnType;
|
| // [operator] is the type of operator o on [element].
|
| - DartType operator =
|
| + ResolutionDartType operator =
|
| lookupMemberType(node, element, operatorName, MemberKind.OPERATOR);
|
| - if (operator is FunctionType) {
|
| - FunctionType operatorType = operator;
|
| + if (operator is ResolutionFunctionType) {
|
| + ResolutionFunctionType operatorType = operator;
|
|
|
| // Check base[key] o value.
|
| - DartType operatorArgument = firstType(operatorType.parameterTypes);
|
| + ResolutionDartType operatorArgument =
|
| + firstType(operatorType.parameterTypes);
|
| bool validValue = checkAssignable(valueNode, value, operatorArgument);
|
|
|
| // [result] is the type of base[key] o value.
|
| - DartType result = operatorType.returnType;
|
| + ResolutionDartType result = operatorType.returnType;
|
|
|
| // [indexSet] is the type of operator[]= on [base].
|
| - DartType indexSet =
|
| + ResolutionDartType indexSet =
|
| lookupMemberType(node, base, '[]=', MemberKind.OPERATOR);
|
| - if (indexSet is FunctionType) {
|
| - FunctionType indexSetType = indexSet;
|
| - DartType indexSetKey = firstType(indexSetType.parameterTypes);
|
| - DartType indexSetValue = secondType(indexSetType.parameterTypes);
|
| + if (indexSet is ResolutionFunctionType) {
|
| + ResolutionFunctionType indexSetType = indexSet;
|
| + ResolutionDartType indexSetKey =
|
| + firstType(indexSetType.parameterTypes);
|
| + ResolutionDartType indexSetValue =
|
| + secondType(indexSetType.parameterTypes);
|
|
|
| if (validKey || indexGetKey != indexSetKey) {
|
| // Only check base[key] on []= if base[key] was valid for [] or
|
| @@ -1457,7 +1471,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return node.isPostfix ? element : result;
|
| }
|
| }
|
| - return const DynamicType();
|
| + return const ResolutionDynamicType();
|
| }
|
|
|
| visitSendSet(SendSet node) {
|
| @@ -1468,17 +1482,18 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // e1 = value
|
| if (node.isIndex) {
|
| // base[key] = value
|
| - final DartType base = analyze(node.receiver);
|
| + final ResolutionDartType base = analyze(node.receiver);
|
| final Node keyNode = node.arguments.head;
|
| - final DartType key = analyze(keyNode);
|
| + final ResolutionDartType key = analyze(keyNode);
|
| final Node valueNode = node.arguments.tail.head;
|
| - final DartType value = analyze(valueNode);
|
| - DartType indexSet =
|
| + final ResolutionDartType value = analyze(valueNode);
|
| + ResolutionDartType indexSet =
|
| lookupMemberType(node, base, '[]=', MemberKind.OPERATOR);
|
| - DartType indexSetValue = const DynamicType();
|
| - if (indexSet is FunctionType) {
|
| - FunctionType indexSetType = indexSet;
|
| - DartType indexSetKey = firstType(indexSetType.parameterTypes);
|
| + ResolutionDartType indexSetValue = const ResolutionDynamicType();
|
| + if (indexSet is ResolutionFunctionType) {
|
| + ResolutionFunctionType indexSetType = indexSet;
|
| + ResolutionDartType indexSetKey =
|
| + firstType(indexSetType.parameterTypes);
|
| checkAssignable(keyNode, key, indexSetKey);
|
| indexSetValue = secondType(indexSetType.parameterTypes);
|
| checkAssignable(node.assignmentOperator, value, indexSetValue);
|
| @@ -1488,7 +1503,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| : types.computeLeastUpperBound(value, indexSetValue);
|
| } else {
|
| // target = value
|
| - DartType target;
|
| + ResolutionDartType target;
|
| if (analyzingInitializer) {
|
| // Field declaration `Foo target = value;` or initializer
|
| // `this.target = value`. Lookup the getter `target` in the class
|
| @@ -1502,7 +1517,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| node, selector.source, element, MemberKind.SETTER);
|
| }
|
| final Node valueNode = node.arguments.head;
|
| - final DartType value = analyze(valueNode);
|
| + final ResolutionDartType value = analyze(valueNode);
|
| checkAssignable(node.assignmentOperator, value, target);
|
| return identical(name, '=')
|
| ? value
|
| @@ -1563,57 +1578,58 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| if (node.isIndex) {
|
| // base[key] o= value for some operator o.
|
| final Node valueNode = node.arguments.tail.head;
|
| - final DartType value = analyze(valueNode);
|
| + final ResolutionDartType value = analyze(valueNode);
|
| return checkIndexAssignmentOperator(
|
| node, operatorName, valueNode, value);
|
| } else {
|
| // target o= value for some operator o.
|
| final Node valueNode = node.arguments.head;
|
| - final DartType value = analyze(valueNode);
|
| + final ResolutionDartType value = analyze(valueNode);
|
| return checkAssignmentOperator(node, operatorName, valueNode, value);
|
| }
|
| }
|
| }
|
|
|
| - DartType visitLiteralInt(LiteralInt node) {
|
| + ResolutionDartType visitLiteralInt(LiteralInt node) {
|
| return intType;
|
| }
|
|
|
| - DartType visitLiteralDouble(LiteralDouble node) {
|
| + ResolutionDartType visitLiteralDouble(LiteralDouble node) {
|
| return doubleType;
|
| }
|
|
|
| - DartType visitLiteralBool(LiteralBool node) {
|
| + ResolutionDartType visitLiteralBool(LiteralBool node) {
|
| return boolType;
|
| }
|
|
|
| - DartType visitLiteralString(LiteralString node) {
|
| + ResolutionDartType visitLiteralString(LiteralString node) {
|
| return stringType;
|
| }
|
|
|
| - DartType visitStringJuxtaposition(StringJuxtaposition node) {
|
| + ResolutionDartType visitStringJuxtaposition(StringJuxtaposition node) {
|
| analyze(node.first);
|
| analyze(node.second);
|
| return stringType;
|
| }
|
|
|
| - DartType visitLiteralNull(LiteralNull node) {
|
| - return const DynamicType();
|
| + ResolutionDartType visitLiteralNull(LiteralNull node) {
|
| + return const ResolutionDynamicType();
|
| }
|
|
|
| - DartType visitLiteralSymbol(LiteralSymbol node) {
|
| + ResolutionDartType visitLiteralSymbol(LiteralSymbol node) {
|
| return commonElements.symbolType;
|
| }
|
|
|
| - DartType computeConstructorType(
|
| - ConstructorElement constructor, DartType type) {
|
| - if (Elements.isUnresolved(constructor)) return const DynamicType();
|
| - DartType constructorType = constructor.computeType(resolution);
|
| - if (identical(type.kind, TypeKind.INTERFACE)) {
|
| + ResolutionDartType computeConstructorType(
|
| + ConstructorElement constructor, ResolutionDartType type) {
|
| + if (Elements.isUnresolved(constructor))
|
| + return const ResolutionDynamicType();
|
| + ResolutionDartType constructorType = constructor.computeType(resolution);
|
| + if (identical(type.kind, ResolutionTypeKind.INTERFACE)) {
|
| if (constructor.isSynthesized) {
|
| // TODO(johnniwinther): Remove this when synthesized constructors handle
|
| // type variables correctly.
|
| - InterfaceType interfaceType = type;
|
| + ResolutionInterfaceType interfaceType = type;
|
| ClassElement receiverElement = interfaceType.element;
|
| while (receiverElement.isMixinApplication) {
|
| receiverElement = receiverElement.supertype.element;
|
| @@ -1627,28 +1643,29 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| return constructorType;
|
| }
|
|
|
| - DartType visitNewExpression(NewExpression node) {
|
| + ResolutionDartType visitNewExpression(NewExpression node) {
|
| Element element = elements[node.send];
|
| - if (Elements.isUnresolved(element)) return const DynamicType();
|
| + if (Elements.isUnresolved(element)) return const ResolutionDynamicType();
|
|
|
| checkPrivateAccess(node, element, element.name);
|
|
|
| - DartType newType = elements.getType(node);
|
| + ResolutionDartType newType = elements.getType(node);
|
| assert(invariant(node, newType != null,
|
| message: "No new type registered in $elements."));
|
| - DartType constructorType = computeConstructorType(element, newType);
|
| + ResolutionDartType constructorType =
|
| + computeConstructorType(element, newType);
|
| analyzeArguments(node.send, element, constructorType);
|
| return newType;
|
| }
|
|
|
| - DartType visitLiteralList(LiteralList node) {
|
| - InterfaceType listType = elements.getType(node);
|
| - DartType listElementType = firstType(listType.typeArguments);
|
| + ResolutionDartType visitLiteralList(LiteralList node) {
|
| + ResolutionInterfaceType listType = elements.getType(node);
|
| + ResolutionDartType listElementType = firstType(listType.typeArguments);
|
| for (Link<Node> link = node.elements.nodes;
|
| !link.isEmpty;
|
| link = link.tail) {
|
| Node element = link.head;
|
| - DartType elementType = analyze(element);
|
| + ResolutionDartType elementType = analyze(element);
|
| checkAssignable(element, elementType, listElementType,
|
| isConst: node.isConst);
|
| }
|
| @@ -1682,7 +1699,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // if the type of e may not be assigned to the declared return type of the
|
| // immediately enclosing function.
|
| if (expression != null) {
|
| - DartType expressionType = analyze(expression);
|
| + ResolutionDartType expressionType = analyze(expression);
|
| if (executableContext.isGenerativeConstructor) {
|
| // The resolver already emitted an error for this expression.
|
| } else {
|
| @@ -1691,7 +1708,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| commonElements.futureType(types.flatten(expressionType));
|
| }
|
| if (expectedReturnType.isVoid &&
|
| - !types.isAssignable(expressionType, const VoidType())) {
|
| + !types.isAssignable(expressionType, const ResolutionVoidType())) {
|
| reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID);
|
| } else {
|
| checkAssignable(expression, expressionType, expectedReturnType);
|
| @@ -1699,7 +1716,8 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| } else if (currentAsyncMarker != AsyncMarker.SYNC) {
|
| // `return;` is allowed.
|
| - } else if (!types.isAssignable(expectedReturnType, const VoidType())) {
|
| + } else if (!types.isAssignable(
|
| + expectedReturnType, const ResolutionVoidType())) {
|
| // Let f be the function immediately enclosing a return statement of the
|
| // form 'return;' It is a static warning if both of the following
|
| // conditions hold:
|
| @@ -1710,23 +1728,23 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
| }
|
|
|
| - DartType visitThrow(Throw node) {
|
| + ResolutionDartType visitThrow(Throw node) {
|
| // TODO(johnniwinther): Handle reachability.
|
| analyze(node.expression);
|
| - return const DynamicType();
|
| + return const ResolutionDynamicType();
|
| }
|
|
|
| - DartType visitAwait(Await node) {
|
| - DartType expressionType = analyze(node.expression);
|
| + ResolutionDartType visitAwait(Await node) {
|
| + ResolutionDartType expressionType = analyze(node.expression);
|
| if (resolution.target.supportsAsyncAwait) {
|
| return types.flatten(expressionType);
|
| } else {
|
| - return const DynamicType();
|
| + return const ResolutionDynamicType();
|
| }
|
| }
|
|
|
| - DartType visitYield(Yield node) {
|
| - DartType resultType = analyze(node.expression);
|
| + ResolutionDartType visitYield(Yield node) {
|
| + ResolutionDartType resultType = analyze(node.expression);
|
| if (!node.hasStar) {
|
| if (currentAsyncMarker.isAsync) {
|
| resultType = commonElements.streamType(resultType);
|
| @@ -1746,29 +1764,30 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| checkAssignable(node, resultType, expectedReturnType);
|
| }
|
|
|
| - DartType visitTypeAnnotation(TypeAnnotation node) {
|
| + ResolutionDartType visitTypeAnnotation(TypeAnnotation node) {
|
| return elements.getType(node);
|
| }
|
|
|
| - DartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
|
| - DartType type = analyzeWithDefault(node.type, const DynamicType());
|
| + ResolutionDartType analyzeVariableTypeAnnotation(VariableDefinitions node) {
|
| + ResolutionDartType type =
|
| + analyzeWithDefault(node.type, const ResolutionDynamicType());
|
| if (type.isVoid) {
|
| reportTypeWarning(node.type, MessageKind.VOID_VARIABLE);
|
| - type = const DynamicType();
|
| + type = const ResolutionDynamicType();
|
| }
|
| return type;
|
| }
|
|
|
| void analyzeVariableInitializer(
|
| - Spannable spannable, DartType declaredType, Node initializer) {
|
| + Spannable spannable, ResolutionDartType declaredType, Node initializer) {
|
| if (initializer == null) return;
|
|
|
| - DartType expressionType = analyzeNonVoid(initializer);
|
| + ResolutionDartType expressionType = analyzeNonVoid(initializer);
|
| checkAssignable(spannable, expressionType, declaredType);
|
| }
|
|
|
| visitVariableDefinitions(VariableDefinitions node) {
|
| - DartType type = analyzeVariableTypeAnnotation(node);
|
| + ResolutionDartType type = analyzeVariableTypeAnnotation(node);
|
| for (Link<Node> link = node.definitions.nodes;
|
| !link.isEmpty;
|
| link = link.tail) {
|
| @@ -1799,24 +1818,26 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| analyzeUntyped(node.body);
|
| }
|
|
|
| - DartType visitParenthesizedExpression(ParenthesizedExpression node) {
|
| + ResolutionDartType visitParenthesizedExpression(
|
| + ParenthesizedExpression node) {
|
| Expression expression = node.expression;
|
| - DartType type = analyze(expression);
|
| + ResolutionDartType type = analyze(expression);
|
| for (TypePromotion typePromotion in getShownTypePromotionsFor(expression)) {
|
| showTypePromotion(node, typePromotion);
|
| }
|
| return type;
|
| }
|
|
|
| - DartType visitConditional(Conditional node) {
|
| + ResolutionDartType visitConditional(Conditional node) {
|
| Expression condition = node.condition;
|
| Expression thenExpression = node.thenExpression;
|
|
|
| checkCondition(condition);
|
|
|
| - DartType thenType = analyzeInPromotedContext(condition, thenExpression);
|
| + ResolutionDartType thenType =
|
| + analyzeInPromotedContext(condition, thenExpression);
|
|
|
| - DartType elseType = analyze(node.elseExpression);
|
| + ResolutionDartType elseType = analyze(node.elseExpression);
|
| return types.computeLeastUpperBound(thenType, elseType);
|
| }
|
|
|
| @@ -1842,33 +1863,35 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // Nothing to do here.
|
| }
|
|
|
| - DartType computeForInElementType(ForIn node) {
|
| + ResolutionDartType computeForInElementType(ForIn node) {
|
| VariableDefinitions declaredIdentifier =
|
| node.declaredIdentifier.asVariableDefinitions();
|
| if (declaredIdentifier != null) {
|
| - return analyzeWithDefault(declaredIdentifier.type, const DynamicType());
|
| + return analyzeWithDefault(
|
| + declaredIdentifier.type, const ResolutionDynamicType());
|
| } else {
|
| return analyze(node.declaredIdentifier);
|
| }
|
| }
|
|
|
| visitAsyncForIn(AsyncForIn node) {
|
| - DartType elementType = computeForInElementType(node);
|
| - DartType expressionType = analyze(node.expression);
|
| + ResolutionDartType elementType = computeForInElementType(node);
|
| + ResolutionDartType expressionType = analyze(node.expression);
|
| if (resolution.target.supportsAsyncAwait) {
|
| - DartType streamOfDynamic = commonElements.streamType();
|
| + ResolutionDartType streamOfDynamic = commonElements.streamType();
|
| if (!types.isAssignable(expressionType, streamOfDynamic)) {
|
| reportMessage(node.expression, MessageKind.NOT_ASSIGNABLE,
|
| {'fromType': expressionType, 'toType': streamOfDynamic},
|
| isHint: true);
|
| } else {
|
| - InterfaceType interfaceType =
|
| + ResolutionInterfaceType interfaceType =
|
| Types.computeInterfaceType(resolution, expressionType);
|
| if (interfaceType != null) {
|
| - InterfaceType streamType =
|
| + ResolutionInterfaceType streamType =
|
| interfaceType.asInstanceOf(streamOfDynamic.element);
|
| if (streamType != null) {
|
| - DartType streamElementType = streamType.typeArguments.first;
|
| + ResolutionDartType streamElementType =
|
| + streamType.typeArguments.first;
|
| if (!types.isAssignable(streamElementType, elementType)) {
|
| reportMessage(
|
| node.expression,
|
| @@ -1888,11 +1911,11 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| visitSyncForIn(SyncForIn node) {
|
| - DartType elementType = computeForInElementType(node);
|
| - DartType expressionType = analyze(node.expression);
|
| - DartType iteratorType = lookupMemberType(node.expression, expressionType,
|
| - Identifiers.iterator, MemberKind.GETTER);
|
| - DartType currentType = lookupMemberType(
|
| + ResolutionDartType elementType = computeForInElementType(node);
|
| + ResolutionDartType expressionType = analyze(node.expression);
|
| + ResolutionDartType iteratorType = lookupMemberType(node.expression,
|
| + expressionType, Identifiers.iterator, MemberKind.GETTER);
|
| + ResolutionDartType currentType = lookupMemberType(
|
| node.expression, iteratorType, Identifiers.current, MemberKind.GETTER,
|
| isHint: true);
|
| if (!types.isAssignable(currentType, elementType)) {
|
| @@ -1914,17 +1937,17 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| }
|
|
|
| visitLiteralMap(LiteralMap node) {
|
| - InterfaceType mapType = elements.getType(node);
|
| - DartType mapKeyType = firstType(mapType.typeArguments);
|
| - DartType mapValueType = secondType(mapType.typeArguments);
|
| + ResolutionInterfaceType mapType = elements.getType(node);
|
| + ResolutionDartType mapKeyType = firstType(mapType.typeArguments);
|
| + ResolutionDartType mapValueType = secondType(mapType.typeArguments);
|
| bool isConst = node.isConst;
|
| for (Link<Node> link = node.entries.nodes;
|
| !link.isEmpty;
|
| link = link.tail) {
|
| LiteralMapEntry entry = link.head;
|
| - DartType keyType = analyze(entry.key);
|
| + ResolutionDartType keyType = analyze(entry.key);
|
| checkAssignable(entry.key, keyType, mapKeyType, isConst: isConst);
|
| - DartType valueType = analyze(entry.value);
|
| + ResolutionDartType valueType = analyze(entry.value);
|
| checkAssignable(entry.value, valueType, mapValueType, isConst: isConst);
|
| }
|
| return mapType;
|
| @@ -1944,7 +1967,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| // switch cases.
|
| // TODO(johnniwinther): Provide hint of duplicate case constants.
|
|
|
| - DartType expressionType = analyze(node.expression);
|
| + ResolutionDartType expressionType = analyze(node.expression);
|
|
|
| // Check that all the case expressions are assignable to the expression.
|
| bool hasDefaultCase = false;
|
| @@ -1956,7 +1979,7 @@ class TypeCheckerVisitor extends Visitor<DartType> {
|
| CaseMatch caseMatch = labelOrCase.asCaseMatch();
|
| if (caseMatch == null) continue;
|
|
|
| - DartType caseType = analyze(caseMatch.expression);
|
| + ResolutionDartType caseType = analyze(caseMatch.expression);
|
| checkAssignable(caseMatch, expressionType, caseType);
|
| }
|
|
|
|
|