| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart2js; | 5 part of dart2js; |
| 6 | 6 |
| 7 class TypeCheckerTask extends CompilerTask { | 7 class TypeCheckerTask extends CompilerTask { |
| 8 TypeCheckerTask(Compiler compiler) : super(compiler); | 8 TypeCheckerTask(Compiler compiler) : super(compiler); |
| 9 String get name => "Type checker"; | 9 String get name => "Type checker"; |
| 10 | 10 |
| 11 void check(TreeElements elements) { | 11 void check(TreeElements elements) { |
| 12 AstElement element = elements.analyzedElement; | 12 AstElement element = elements.analyzedElement; |
| 13 if (element.isTypedef) return; |
| 14 |
| 13 compiler.withCurrentElement(element, () { | 15 compiler.withCurrentElement(element, () { |
| 14 measure(() { | 16 measure(() { |
| 15 Node tree = element.node; | 17 Node tree = element.node; |
| 16 TypeCheckerVisitor visitor = | 18 TypeCheckerVisitor visitor = |
| 17 new TypeCheckerVisitor(compiler, elements, compiler.types); | 19 new TypeCheckerVisitor(compiler, elements, compiler.types); |
| 18 if (element.isField) { | 20 if (element.isField) { |
| 19 visitor.analyzingInitializer = true; | 21 visitor.analyzingInitializer = true; |
| 20 } | 22 } |
| 21 tree.accept(visitor); | 23 tree.accept(visitor); |
| 22 }); | 24 }); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 /// Returns [: true :] if the element can be access as an invocation. | 56 /// Returns [: true :] if the element can be access as an invocation. |
| 55 bool isCallable(Compiler compiler) { | 57 bool isCallable(Compiler compiler) { |
| 56 if (element != null && element.isAbstractField) { | 58 if (element != null && element.isAbstractField) { |
| 57 AbstractFieldElement abstractFieldElement = element; | 59 AbstractFieldElement abstractFieldElement = element; |
| 58 if (abstractFieldElement.getter == null) { | 60 if (abstractFieldElement.getter == null) { |
| 59 // Setters cannot be invoked as function invocations. | 61 // Setters cannot be invoked as function invocations. |
| 60 return false; | 62 return false; |
| 61 } | 63 } |
| 62 } | 64 } |
| 63 return compiler.types.isAssignable( | 65 return compiler.types.isAssignable( |
| 64 computeType(compiler), compiler.functionClass.computeType(compiler)); | 66 computeType(compiler), compiler.coreTypes.functionType); |
| 65 } | 67 } |
| 66 } | 68 } |
| 67 | 69 |
| 68 /// An access of a instance member. | 70 /// An access of a instance member. |
| 69 class MemberAccess extends ElementAccess { | 71 class MemberAccess extends ElementAccess { |
| 70 final MemberSignature member; | 72 final MemberSignature member; |
| 71 | 73 |
| 72 MemberAccess(MemberSignature this.member); | 74 MemberAccess(MemberSignature this.member); |
| 73 | 75 |
| 74 Element get element => member.declarations.first.element; | 76 Element get element => member.declarations.first.element; |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 final Compiler compiler; | 259 final Compiler compiler; |
| 258 final TreeElements elements; | 260 final TreeElements elements; |
| 259 final Types types; | 261 final Types types; |
| 260 | 262 |
| 261 Node lastSeenNode; | 263 Node lastSeenNode; |
| 262 DartType expectedReturnType; | 264 DartType expectedReturnType; |
| 263 AsyncMarker currentAsyncMarker = AsyncMarker.SYNC; | 265 AsyncMarker currentAsyncMarker = AsyncMarker.SYNC; |
| 264 | 266 |
| 265 final ClassElement currentClass; | 267 final ClassElement currentClass; |
| 266 | 268 |
| 269 /// The immediately enclosing field, method or constructor being analyzed. |
| 270 ExecutableElement executableContext; |
| 271 |
| 272 CoreTypes get coreTypes => compiler.coreTypes; |
| 273 |
| 274 InterfaceType get intType => coreTypes.intType; |
| 275 InterfaceType get doubleType => coreTypes.doubleType; |
| 276 InterfaceType get boolType => coreTypes.boolType; |
| 277 InterfaceType get stringType => coreTypes.stringType; |
| 278 |
| 267 DartType thisType; | 279 DartType thisType; |
| 268 DartType superType; | 280 DartType superType; |
| 269 | 281 |
| 270 Link<DartType> cascadeTypes = const Link<DartType>(); | 282 Link<DartType> cascadeTypes = const Link<DartType>(); |
| 271 | 283 |
| 272 bool analyzingInitializer = false; | 284 bool analyzingInitializer = false; |
| 273 | 285 |
| 274 DartType intType; | |
| 275 DartType doubleType; | |
| 276 DartType boolType; | |
| 277 DartType stringType; | |
| 278 DartType objectType; | |
| 279 DartType listType; | |
| 280 | |
| 281 Map<Node, List<TypePromotion>> shownTypePromotionsMap = | 286 Map<Node, List<TypePromotion>> shownTypePromotionsMap = |
| 282 new Map<Node, List<TypePromotion>>(); | 287 new Map<Node, List<TypePromotion>>(); |
| 283 | 288 |
| 284 Map<VariableElement, Link<TypePromotion>> typePromotionsMap = | 289 Map<VariableElement, Link<TypePromotion>> typePromotionsMap = |
| 285 new Map<VariableElement, Link<TypePromotion>>(); | 290 new Map<VariableElement, Link<TypePromotion>>(); |
| 286 | 291 |
| 287 Set<TypePromotion> reportedTypePromotions = new Set<TypePromotion>(); | 292 Set<TypePromotion> reportedTypePromotions = new Set<TypePromotion>(); |
| 288 | 293 |
| 289 void showTypePromotion(Node node, TypePromotion typePromotion) { | 294 void showTypePromotion(Node node, TypePromotion typePromotion) { |
| 290 List<TypePromotion> shownTypePromotions = | 295 List<TypePromotion> shownTypePromotions = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 330 } | 335 } |
| 331 | 336 |
| 332 DartType getKnownType(VariableElement element) { | 337 DartType getKnownType(VariableElement element) { |
| 333 TypePromotion typePromotion = getKnownTypePromotion(element); | 338 TypePromotion typePromotion = getKnownTypePromotion(element); |
| 334 if (typePromotion != null) return typePromotion.type; | 339 if (typePromotion != null) return typePromotion.type; |
| 335 return element.type; | 340 return element.type; |
| 336 } | 341 } |
| 337 | 342 |
| 338 TypeCheckerVisitor(this.compiler, TreeElements elements, this.types) | 343 TypeCheckerVisitor(this.compiler, TreeElements elements, this.types) |
| 339 : this.elements = elements, | 344 : this.elements = elements, |
| 340 currentClass = elements.analyzedElement != null | 345 this.executableContext = elements.analyzedElement, |
| 346 this.currentClass = elements.analyzedElement != null |
| 341 ? elements.analyzedElement.enclosingClass : null { | 347 ? elements.analyzedElement.enclosingClass : null { |
| 342 intType = compiler.intClass.computeType(compiler); | |
| 343 doubleType = compiler.doubleClass.computeType(compiler); | |
| 344 boolType = compiler.boolClass.computeType(compiler); | |
| 345 stringType = compiler.stringClass.computeType(compiler); | |
| 346 objectType = compiler.objectClass.computeType(compiler); | |
| 347 listType = compiler.listClass.computeType(compiler); | |
| 348 | 348 |
| 349 if (currentClass != null) { | 349 if (currentClass != null) { |
| 350 thisType = currentClass.thisType; | 350 thisType = currentClass.thisType; |
| 351 superType = currentClass.supertype; | 351 superType = currentClass.supertype; |
| 352 } else { | 352 } else { |
| 353 // If these are used, an error should have been reported by the resolver. | 353 // If these are used, an error should have been reported by the resolver. |
| 354 thisType = const DynamicType(); | 354 thisType = const DynamicType(); |
| 355 superType = const DynamicType(); | 355 superType = const DynamicType(); |
| 356 } | 356 } |
| 357 } | 357 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 } | 404 } |
| 405 | 405 |
| 406 /// If [inInitializer] is true, assignment should be interpreted as write to | 406 /// If [inInitializer] is true, assignment should be interpreted as write to |
| 407 /// a field and not to a setter. | 407 /// a field and not to a setter. |
| 408 DartType analyze(Node node, {bool inInitializer: false}) { | 408 DartType analyze(Node node, {bool inInitializer: false}) { |
| 409 if (node == null) { | 409 if (node == null) { |
| 410 final String error = 'Unexpected node: null'; | 410 final String error = 'Unexpected node: null'; |
| 411 if (lastSeenNode != null) { | 411 if (lastSeenNode != null) { |
| 412 compiler.internalError(lastSeenNode, error); | 412 compiler.internalError(lastSeenNode, error); |
| 413 } else { | 413 } else { |
| 414 compiler.internalError(elements.analyzedElement, error); | 414 compiler.internalError(executableContext, error); |
| 415 } | 415 } |
| 416 } else { | 416 } else { |
| 417 lastSeenNode = node; | 417 lastSeenNode = node; |
| 418 } | 418 } |
| 419 bool previouslyInitializer = analyzingInitializer; | 419 bool previouslyInitializer = analyzingInitializer; |
| 420 analyzingInitializer = inInitializer; | 420 analyzingInitializer = inInitializer; |
| 421 DartType result = node.accept(this); | 421 DartType result = node.accept(this); |
| 422 analyzingInitializer = previouslyInitializer; | 422 analyzingInitializer = previouslyInitializer; |
| 423 if (result == null) { | 423 if (result == null) { |
| 424 compiler.internalError(node, 'Type is null.'); | 424 compiler.internalError(node, 'Type is null.'); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 } | 592 } |
| 593 | 593 |
| 594 DartType visitFunctionExpression(FunctionExpression node) { | 594 DartType visitFunctionExpression(FunctionExpression node) { |
| 595 DartType type; | 595 DartType type; |
| 596 DartType returnType; | 596 DartType returnType; |
| 597 DartType previousType; | 597 DartType previousType; |
| 598 final FunctionElement element = elements.getFunctionDefinition(node); | 598 final FunctionElement element = elements.getFunctionDefinition(node); |
| 599 assert(invariant(node, element != null, | 599 assert(invariant(node, element != null, |
| 600 message: 'FunctionExpression with no element')); | 600 message: 'FunctionExpression with no element')); |
| 601 if (Elements.isUnresolved(element)) return const DynamicType(); | 601 if (Elements.isUnresolved(element)) return const DynamicType(); |
| 602 if (identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR) || | 602 if (element.isGenerativeConstructor) { |
| 603 identical(element.kind, ElementKind.GENERATIVE_CONSTRUCTOR_BODY)) { | |
| 604 type = const DynamicType(); | 603 type = const DynamicType(); |
| 605 returnType = const VoidType(); | 604 returnType = const VoidType(); |
| 606 | 605 |
| 607 element.functionSignature.forEachParameter((ParameterElement parameter) { | 606 element.functionSignature.forEachParameter((ParameterElement parameter) { |
| 608 if (parameter.isInitializingFormal) { | 607 if (parameter.isInitializingFormal) { |
| 609 InitializingFormalElement fieldParameter = parameter; | 608 InitializingFormalElement fieldParameter = parameter; |
| 610 checkAssignable(parameter, parameter.type, | 609 checkAssignable(parameter, parameter.type, |
| 611 fieldParameter.fieldElement.computeType(compiler)); | 610 fieldParameter.fieldElement.computeType(compiler)); |
| 612 } | 611 } |
| 613 }); | 612 }); |
| 614 if (node.initializers != null) { | 613 if (node.initializers != null) { |
| 615 analyze(node.initializers, inInitializer: true); | 614 analyze(node.initializers, inInitializer: true); |
| 616 } | 615 } |
| 617 } else { | 616 } else { |
| 618 FunctionType functionType = element.computeType(compiler); | 617 FunctionType functionType = element.computeType(compiler); |
| 619 returnType = functionType.returnType; | 618 returnType = functionType.returnType; |
| 620 type = functionType; | 619 type = functionType; |
| 621 } | 620 } |
| 621 ExecutableElement previousExecutableContext = executableContext; |
| 622 DartType previousReturnType = expectedReturnType; | 622 DartType previousReturnType = expectedReturnType; |
| 623 expectedReturnType = returnType; | 623 expectedReturnType = returnType; |
| 624 AsyncMarker previousAsyncMarker = currentAsyncMarker; | 624 AsyncMarker previousAsyncMarker = currentAsyncMarker; |
| 625 |
| 626 executableContext = element; |
| 625 currentAsyncMarker = element.asyncMarker; | 627 currentAsyncMarker = element.asyncMarker; |
| 626 analyze(node.body); | 628 analyze(node.body); |
| 629 |
| 630 executableContext = previousExecutableContext; |
| 627 expectedReturnType = previousReturnType; | 631 expectedReturnType = previousReturnType; |
| 628 currentAsyncMarker = previousAsyncMarker; | 632 currentAsyncMarker = previousAsyncMarker; |
| 629 return type; | 633 return type; |
| 630 } | 634 } |
| 631 | 635 |
| 632 DartType visitIdentifier(Identifier node) { | 636 DartType visitIdentifier(Identifier node) { |
| 633 if (node.isThis()) { | 637 if (node.isThis()) { |
| 634 return thisType; | 638 return thisType; |
| 635 } else if (node.isSuper()) { | 639 } else if (node.isSuper()) { |
| 636 return superType; | 640 return superType; |
| (...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 DartType visitRethrow(Rethrow node) { | 1572 DartType visitRethrow(Rethrow node) { |
| 1569 return const StatementType(); | 1573 return const StatementType(); |
| 1570 } | 1574 } |
| 1571 | 1575 |
| 1572 /** Dart Programming Language Specification: 11.10 Return */ | 1576 /** Dart Programming Language Specification: 11.10 Return */ |
| 1573 DartType visitReturn(Return node) { | 1577 DartType visitReturn(Return node) { |
| 1574 if (identical(node.beginToken.stringValue, 'native')) { | 1578 if (identical(node.beginToken.stringValue, 'native')) { |
| 1575 return const StatementType(); | 1579 return const StatementType(); |
| 1576 } | 1580 } |
| 1577 | 1581 |
| 1578 final expression = node.expression; | 1582 final Node expression = node.expression; |
| 1579 final isVoidFunction = expectedReturnType.isVoid; | |
| 1580 | 1583 |
| 1581 // Executing a return statement return e; [...] It is a static type warning | 1584 // Executing a return statement return e; [...] It is a static type warning |
| 1582 // if the type of e may not be assigned to the declared return type of the | 1585 // if the type of e may not be assigned to the declared return type of the |
| 1583 // immediately enclosing function. | 1586 // immediately enclosing function. |
| 1584 if (expression != null) { | 1587 if (expression != null) { |
| 1585 final expressionType = analyze(expression); | 1588 DartType expressionType = analyze(expression); |
| 1586 Element element = elements.analyzedElement; | 1589 if (executableContext.isGenerativeConstructor) { |
| 1587 if (element != null && element.isGenerativeConstructor) { | |
| 1588 // The resolver already emitted an error for this expression. | 1590 // The resolver already emitted an error for this expression. |
| 1589 } else if (isVoidFunction | |
| 1590 && !types.isAssignable(expressionType, const VoidType())) { | |
| 1591 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID); | |
| 1592 } else { | 1591 } else { |
| 1593 checkAssignable(expression, expressionType, expectedReturnType); | 1592 if (currentAsyncMarker == AsyncMarker.ASYNC) { |
| 1593 expressionType = coreTypes.futureType(flatten(expressionType)); |
| 1594 } |
| 1595 if (expectedReturnType.isVoid && |
| 1596 !types.isAssignable(expressionType, const VoidType())) { |
| 1597 reportTypeWarning(expression, MessageKind.RETURN_VALUE_IN_VOID); |
| 1598 } else { |
| 1599 checkAssignable(expression, expressionType, expectedReturnType); |
| 1600 } |
| 1594 } | 1601 } |
| 1595 | 1602 |
| 1596 // Let f be the function immediately enclosing a return statement of the | |
| 1597 // form 'return;' It is a static warning if both of the following conditions | |
| 1598 // hold: | |
| 1599 // - f is not a generative constructor. | |
| 1600 // - The return type of f may not be assigned to void. | |
| 1601 } else if (!types.isAssignable(expectedReturnType, const VoidType())) { | 1603 } else if (!types.isAssignable(expectedReturnType, const VoidType())) { |
| 1604 // Let f be the function immediately enclosing a return statement of the |
| 1605 // form 'return;' It is a static warning if both of the following |
| 1606 // conditions hold: |
| 1607 // - f is not a generative constructor. |
| 1608 // - The return type of f may not be assigned to void. |
| 1602 reportTypeWarning(node, MessageKind.RETURN_NOTHING, | 1609 reportTypeWarning(node, MessageKind.RETURN_NOTHING, |
| 1603 {'returnType': expectedReturnType}); | 1610 {'returnType': expectedReturnType}); |
| 1604 } | 1611 } |
| 1605 return const StatementType(); | 1612 return const StatementType(); |
| 1606 } | 1613 } |
| 1607 | 1614 |
| 1608 DartType visitThrow(Throw node) { | 1615 DartType visitThrow(Throw node) { |
| 1609 // TODO(johnniwinther): Handle reachability. | 1616 // TODO(johnniwinther): Handle reachability. |
| 1610 analyze(node.expression); | 1617 analyze(node.expression); |
| 1611 return const DynamicType(); | 1618 return const DynamicType(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1632 | 1639 |
| 1633 DartType visitAwait(Await node) { | 1640 DartType visitAwait(Await node) { |
| 1634 DartType expressionType = analyze(node.expression); | 1641 DartType expressionType = analyze(node.expression); |
| 1635 return flatten(expressionType); | 1642 return flatten(expressionType); |
| 1636 } | 1643 } |
| 1637 | 1644 |
| 1638 DartType visitYield(Yield node) { | 1645 DartType visitYield(Yield node) { |
| 1639 DartType resultType = analyze(node.expression); | 1646 DartType resultType = analyze(node.expression); |
| 1640 if (!node.hasStar) { | 1647 if (!node.hasStar) { |
| 1641 if (currentAsyncMarker.isAsync) { | 1648 if (currentAsyncMarker.isAsync) { |
| 1642 resultType = compiler.coreTypes.streamType(resultType); | 1649 resultType = coreTypes.streamType(resultType); |
| 1643 } else { | 1650 } else { |
| 1644 resultType = compiler.coreTypes.iterableType(resultType); | 1651 resultType = coreTypes.iterableType(resultType); |
| 1645 } | 1652 } |
| 1646 } else { | 1653 } else { |
| 1647 if (currentAsyncMarker.isAsync) { | 1654 if (currentAsyncMarker.isAsync) { |
| 1648 // The static type of expression must be assignable to Stream. | 1655 // The static type of expression must be assignable to Stream. |
| 1649 checkAssignable(node, resultType, compiler.coreTypes.streamType()); | 1656 checkAssignable(node, resultType, coreTypes.streamType()); |
| 1650 } else { | 1657 } else { |
| 1651 // The static type of expression must be assignable to Iterable. | 1658 // The static type of expression must be assignable to Iterable. |
| 1652 checkAssignable(node, resultType, compiler.coreTypes.iterableType()); | 1659 checkAssignable(node, resultType, coreTypes.iterableType()); |
| 1653 } | 1660 } |
| 1654 } | 1661 } |
| 1655 // The static type of the result must be assignable to the declared type. | 1662 // The static type of the result must be assignable to the declared type. |
| 1656 checkAssignable(node, resultType, expectedReturnType); | 1663 checkAssignable(node, resultType, expectedReturnType); |
| 1657 return const StatementType(); | 1664 return const StatementType(); |
| 1658 } | 1665 } |
| 1659 | 1666 |
| 1660 DartType visitTypeAnnotation(TypeAnnotation node) { | 1667 DartType visitTypeAnnotation(TypeAnnotation node) { |
| 1661 return elements.getType(node); | 1668 return elements.getType(node); |
| 1662 } | 1669 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 | 1706 |
| 1700 DartType visitConditional(Conditional node) { | 1707 DartType visitConditional(Conditional node) { |
| 1701 Expression condition = node.condition; | 1708 Expression condition = node.condition; |
| 1702 Expression thenExpression = node.thenExpression; | 1709 Expression thenExpression = node.thenExpression; |
| 1703 | 1710 |
| 1704 checkCondition(condition); | 1711 checkCondition(condition); |
| 1705 | 1712 |
| 1706 DartType thenType = analyzeInPromotedContext(condition, thenExpression); | 1713 DartType thenType = analyzeInPromotedContext(condition, thenExpression); |
| 1707 | 1714 |
| 1708 DartType elseType = analyze(node.elseExpression); | 1715 DartType elseType = analyze(node.elseExpression); |
| 1709 return compiler.types.computeLeastUpperBound(thenType, elseType); | 1716 return types.computeLeastUpperBound(thenType, elseType); |
| 1710 } | 1717 } |
| 1711 | 1718 |
| 1712 visitStringInterpolation(StringInterpolation node) { | 1719 visitStringInterpolation(StringInterpolation node) { |
| 1713 node.visitChildren(this); | 1720 node.visitChildren(this); |
| 1714 return stringType; | 1721 return stringType; |
| 1715 } | 1722 } |
| 1716 | 1723 |
| 1717 visitStringInterpolationPart(StringInterpolationPart node) { | 1724 visitStringInterpolationPart(StringInterpolationPart node) { |
| 1718 node.visitChildren(this); | 1725 node.visitChildren(this); |
| 1719 return stringType; | 1726 return stringType; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 if (caseMatch == null) continue; | 1792 if (caseMatch == null) continue; |
| 1786 | 1793 |
| 1787 DartType caseType = analyze(caseMatch.expression); | 1794 DartType caseType = analyze(caseMatch.expression); |
| 1788 checkAssignable(caseMatch, expressionType, caseType); | 1795 checkAssignable(caseMatch, expressionType, caseType); |
| 1789 } | 1796 } |
| 1790 | 1797 |
| 1791 analyze(switchCase); | 1798 analyze(switchCase); |
| 1792 } | 1799 } |
| 1793 | 1800 |
| 1794 if (!hasDefaultCase && expressionType.isEnumType) { | 1801 if (!hasDefaultCase && expressionType.isEnumType) { |
| 1795 compiler.enqueuer.resolution.addDeferredAction( | 1802 compiler.enqueuer.resolution.addDeferredAction(executableContext, () { |
| 1796 elements.analyzedElement, () { | |
| 1797 Map<ConstantValue, FieldElement> enumValues = | 1803 Map<ConstantValue, FieldElement> enumValues = |
| 1798 <ConstantValue, FieldElement>{}; | 1804 <ConstantValue, FieldElement>{}; |
| 1799 List<FieldElement> unreferencedFields = <FieldElement>[]; | 1805 List<FieldElement> unreferencedFields = <FieldElement>[]; |
| 1800 EnumClassElement enumClass = expressionType.element; | 1806 EnumClassElement enumClass = expressionType.element; |
| 1801 enumClass.enumValues.forEach((FieldElement field) { | 1807 enumClass.enumValues.forEach((FieldElement field) { |
| 1802 ConstantExpression constantExpression = | 1808 ConstantExpression constantExpression = |
| 1803 compiler.constants.getConstantForVariable(field); | 1809 compiler.constants.getConstantForVariable(field); |
| 1804 if (constantExpression == null) { | 1810 if (constantExpression == null) { |
| 1805 // The field might not have been resolved. | 1811 // The field might not have been resolved. |
| 1806 unreferencedFields.add(field); | 1812 unreferencedFields.add(field); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 | 1860 |
| 1855 visitTypedef(Typedef node) { | 1861 visitTypedef(Typedef node) { |
| 1856 // Do not typecheck [Typedef] nodes. | 1862 // Do not typecheck [Typedef] nodes. |
| 1857 } | 1863 } |
| 1858 | 1864 |
| 1859 visitNode(Node node) { | 1865 visitNode(Node node) { |
| 1860 compiler.internalError(node, | 1866 compiler.internalError(node, |
| 1861 'Unexpected node ${node.getObjectDescription()} in the type checker.'); | 1867 'Unexpected node ${node.getObjectDescription()} in the type checker.'); |
| 1862 } | 1868 } |
| 1863 } | 1869 } |
| OLD | NEW |