| 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 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
| 6 | 6 |
| 7 import '../common/names.dart' show | 7 import '../common/names.dart' show |
| 8 Selectors; | 8 Selectors; |
| 9 import '../compiler.dart' show | 9 import '../compiler.dart' show |
| 10 Compiler; | 10 Compiler; |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 } else { | 394 } else { |
| 395 if ((element.kind.category & allowedCategory) == 0) { | 395 if ((element.kind.category & allowedCategory) == 0) { |
| 396 element = reportAndCreateErroneousElement( | 396 element = reportAndCreateErroneousElement( |
| 397 node, name, MessageKind.GENERIC, | 397 node, name, MessageKind.GENERIC, |
| 398 // TODO(ahe): Improve error message. Need UX input. | 398 // TODO(ahe): Improve error message. Need UX input. |
| 399 {'text': "is not an expression $element"}); | 399 {'text': "is not an expression $element"}); |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 if (!Elements.isUnresolved(element) && element.isClass) { | 402 if (!Elements.isUnresolved(element) && element.isClass) { |
| 403 ClassElement classElement = element; | 403 ClassElement classElement = element; |
| 404 classElement.ensureResolved(compiler); | 404 classElement.ensureResolved(resolution); |
| 405 } | 405 } |
| 406 if (element != null) { | 406 if (element != null) { |
| 407 registry.useElement(node, element); | 407 registry.useElement(node, element); |
| 408 if (element.isPrefix) { | 408 if (element.isPrefix) { |
| 409 return new PrefixResult(element, null); | 409 return new PrefixResult(element, null); |
| 410 } else if (element.isClass && sendIsMemberAccess) { | 410 } else if (element.isClass && sendIsMemberAccess) { |
| 411 return new PrefixResult(null, element); | 411 return new PrefixResult(null, element); |
| 412 } | 412 } |
| 413 return new ElementResult(element); | 413 return new ElementResult(element); |
| 414 } | 414 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 430 if (isNamedConstructor(node)) { | 430 if (isNamedConstructor(node)) { |
| 431 String constructorName = node.selector.asIdentifier().source; | 431 String constructorName = node.selector.asIdentifier().source; |
| 432 return new Selector.callConstructor( | 432 return new Selector.callConstructor( |
| 433 new Name(constructorName, enclosingElement.library)); | 433 new Name(constructorName, enclosingElement.library)); |
| 434 } else { | 434 } else { |
| 435 return new Selector.callDefaultConstructor(); | 435 return new Selector.callDefaultConstructor(); |
| 436 } | 436 } |
| 437 } | 437 } |
| 438 | 438 |
| 439 FunctionElement resolveConstructorRedirection(FunctionElementX constructor) { | 439 FunctionElement resolveConstructorRedirection(FunctionElementX constructor) { |
| 440 FunctionExpression node = constructor.parseNode(compiler); | 440 FunctionExpression node = constructor.parseNode(resolution.parsing); |
| 441 | 441 |
| 442 // A synthetic constructor does not have a node. | 442 // A synthetic constructor does not have a node. |
| 443 if (node == null) return null; | 443 if (node == null) return null; |
| 444 if (node.initializers == null) return null; | 444 if (node.initializers == null) return null; |
| 445 Link<Node> initializers = node.initializers.nodes; | 445 Link<Node> initializers = node.initializers.nodes; |
| 446 if (!initializers.isEmpty && | 446 if (!initializers.isEmpty && |
| 447 Initializers.isConstructorRedirect(initializers.head)) { | 447 Initializers.isConstructorRedirect(initializers.head)) { |
| 448 Selector selector = | 448 Selector selector = |
| 449 getRedirectingThisOrSuperConstructorSelector(initializers.head); | 449 getRedirectingThisOrSuperConstructorSelector(initializers.head); |
| 450 final ClassElement classElement = constructor.enclosingClass; | 450 final ClassElement classElement = constructor.enclosingClass; |
| (...skipping 1162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1613 AccessSemantics semantics = checkSuperAccess(node); | 1613 AccessSemantics semantics = checkSuperAccess(node); |
| 1614 if (semantics == null) { | 1614 if (semantics == null) { |
| 1615 semantics = computeSuperAccessSemanticsForSelector( | 1615 semantics = computeSuperAccessSemanticsForSelector( |
| 1616 node, selector, alternateName: name.setter); | 1616 node, selector, alternateName: name.setter); |
| 1617 } | 1617 } |
| 1618 if (node.isCall) { | 1618 if (node.isCall) { |
| 1619 bool isIncompatibleInvoke = false; | 1619 bool isIncompatibleInvoke = false; |
| 1620 switch (semantics.kind) { | 1620 switch (semantics.kind) { |
| 1621 case AccessKind.SUPER_METHOD: | 1621 case AccessKind.SUPER_METHOD: |
| 1622 MethodElementX superMethod = semantics.element; | 1622 MethodElementX superMethod = semantics.element; |
| 1623 superMethod.computeSignature(compiler); | 1623 superMethod.computeType(resolution); |
| 1624 if (!callStructure.signatureApplies( | 1624 if (!callStructure.signatureApplies( |
| 1625 superMethod.functionSignature)) { | 1625 superMethod.functionSignature)) { |
| 1626 registry.registerThrowNoSuchMethod(); | 1626 registry.registerThrowNoSuchMethod(); |
| 1627 registry.registerDynamicInvocation( | 1627 registry.registerDynamicInvocation( |
| 1628 new UniverseSelector(selector, null)); | 1628 new UniverseSelector(selector, null)); |
| 1629 registry.registerSuperNoSuchMethod(); | 1629 registry.registerSuperNoSuchMethod(); |
| 1630 isIncompatibleInvoke = true; | 1630 isIncompatibleInvoke = true; |
| 1631 } else { | 1631 } else { |
| 1632 registry.registerStaticInvocation(semantics.element); | 1632 registry.registerStaticInvocation(semantics.element); |
| 1633 } | 1633 } |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1871 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1871 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
| 1872 // member access. | 1872 // member access. |
| 1873 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 1873 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
| 1874 } | 1874 } |
| 1875 | 1875 |
| 1876 /// Handle qualified access to a static member, like `a.b` or `a.b()` where | 1876 /// Handle qualified access to a static member, like `a.b` or `a.b()` where |
| 1877 /// `a` is a class and `b` is a static member of `a`. | 1877 /// `a` is a class and `b` is a static member of `a`. |
| 1878 ResolutionResult handleStaticMemberAccess( | 1878 ResolutionResult handleStaticMemberAccess( |
| 1879 Send node, Name memberName, ClassElement receiverClass) { | 1879 Send node, Name memberName, ClassElement receiverClass) { |
| 1880 String name = memberName.text; | 1880 String name = memberName.text; |
| 1881 receiverClass.ensureResolved(compiler); | 1881 receiverClass.ensureResolved(resolution); |
| 1882 if (node.isOperator) { | 1882 if (node.isOperator) { |
| 1883 // When the resolved receiver is a class, we can have two cases: | 1883 // When the resolved receiver is a class, we can have two cases: |
| 1884 // 1) a static send: C.foo, or | 1884 // 1) a static send: C.foo, or |
| 1885 // 2) an operator send, where the receiver is a class literal: 'C + 1'. | 1885 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
| 1886 // The following code that looks up the selector on the resolved | 1886 // The following code that looks up the selector on the resolved |
| 1887 // receiver will treat the second as the invocation of a static operator | 1887 // receiver will treat the second as the invocation of a static operator |
| 1888 // if the resolved receiver is not null. | 1888 // if the resolved receiver is not null. |
| 1889 return const NoneResult(); | 1889 return const NoneResult(); |
| 1890 } | 1890 } |
| 1891 MembersCreator.computeClassMembersByName( | 1891 MembersCreator.computeClassMembersByName( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1905 } else { | 1905 } else { |
| 1906 return handleStaticOrTopLevelAccess(node, memberName, member); | 1906 return handleStaticOrTopLevelAccess(node, memberName, member); |
| 1907 } | 1907 } |
| 1908 } | 1908 } |
| 1909 | 1909 |
| 1910 /// Handle qualified update to a static member, like `a.b = c` or `a.b++` | 1910 /// Handle qualified update to a static member, like `a.b = c` or `a.b++` |
| 1911 /// where `a` is a class and `b` is a static member of `a`. | 1911 /// where `a` is a class and `b` is a static member of `a`. |
| 1912 ResolutionResult handleStaticMemberUpdate( | 1912 ResolutionResult handleStaticMemberUpdate( |
| 1913 Send node, Name memberName, ClassElement receiverClass) { | 1913 Send node, Name memberName, ClassElement receiverClass) { |
| 1914 String name = memberName.text; | 1914 String name = memberName.text; |
| 1915 receiverClass.ensureResolved(compiler); | 1915 receiverClass.ensureResolved(resolution); |
| 1916 MembersCreator.computeClassMembersByName( | 1916 MembersCreator.computeClassMembersByName( |
| 1917 compiler, receiverClass.declaration, name); | 1917 compiler, receiverClass.declaration, name); |
| 1918 Element member = receiverClass.lookupLocalMember(name); | 1918 Element member = receiverClass.lookupLocalMember(name); |
| 1919 if (member == null) { | 1919 if (member == null) { |
| 1920 return handleUnresolvedStaticMemberUpdate( | 1920 return handleUnresolvedStaticMemberUpdate( |
| 1921 node, memberName, receiverClass); | 1921 node, memberName, receiverClass); |
| 1922 } else if (member.isAmbiguous) { | 1922 } else if (member.isAmbiguous) { |
| 1923 return handleAmbiguousUpdate(node, memberName, member); | 1923 return handleAmbiguousUpdate(node, memberName, member); |
| 1924 } else if (member.isInstanceMember) { | 1924 } else if (member.isInstanceMember) { |
| 1925 return handleStaticInstanceMemberUpdate( | 1925 return handleStaticInstanceMemberUpdate( |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2102 | 2102 |
| 2103 return handleUpdate(node, name, semantics); | 2103 return handleUpdate(node, name, semantics); |
| 2104 } | 2104 } |
| 2105 | 2105 |
| 2106 /// Handle access to a type literal of a typedef. Like `F` or | 2106 /// Handle access to a type literal of a typedef. Like `F` or |
| 2107 /// `F()` where 'F' is typedef. | 2107 /// `F()` where 'F' is typedef. |
| 2108 ResolutionResult handleTypedefTypeLiteralAccess( | 2108 ResolutionResult handleTypedefTypeLiteralAccess( |
| 2109 Send node, | 2109 Send node, |
| 2110 Name name, | 2110 Name name, |
| 2111 TypedefElement typdef) { | 2111 TypedefElement typdef) { |
| 2112 typdef.ensureResolved(compiler); | 2112 typdef.ensureResolved(resolution); |
| 2113 DartType type = typdef.rawType; | 2113 DartType type = typdef.rawType; |
| 2114 ConstantExpression constant = new TypeConstantExpression(type); | 2114 ConstantExpression constant = new TypeConstantExpression(type); |
| 2115 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); | 2115 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
| 2116 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); | 2116 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); |
| 2117 } | 2117 } |
| 2118 | 2118 |
| 2119 /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or | 2119 /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or |
| 2120 /// `F += b` where 'F' is typedef. | 2120 /// `F += b` where 'F' is typedef. |
| 2121 ResolutionResult handleTypedefTypeLiteralUpdate( | 2121 ResolutionResult handleTypedefTypeLiteralUpdate( |
| 2122 SendSet node, | 2122 SendSet node, |
| 2123 Name name, | 2123 Name name, |
| 2124 TypedefElement typdef) { | 2124 TypedefElement typdef) { |
| 2125 typdef.ensureResolved(compiler); | 2125 typdef.ensureResolved(resolution); |
| 2126 DartType type = typdef.rawType; | 2126 DartType type = typdef.rawType; |
| 2127 ConstantExpression constant = new TypeConstantExpression(type); | 2127 ConstantExpression constant = new TypeConstantExpression(type); |
| 2128 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); | 2128 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
| 2129 return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics); | 2129 return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics); |
| 2130 } | 2130 } |
| 2131 | 2131 |
| 2132 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or | 2132 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or |
| 2133 /// `dynamic()`. | 2133 /// `dynamic()`. |
| 2134 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { | 2134 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { |
| 2135 DartType type = const DynamicType(); | 2135 DartType type = const DynamicType(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2152 return handleConstantTypeLiteralUpdate( | 2152 return handleConstantTypeLiteralUpdate( |
| 2153 node, const PublicName('dynamic'), compiler.typeClass, type, semantics); | 2153 node, const PublicName('dynamic'), compiler.typeClass, type, semantics); |
| 2154 } | 2154 } |
| 2155 | 2155 |
| 2156 /// Handle access to a type literal of a class. Like `C` or | 2156 /// Handle access to a type literal of a class. Like `C` or |
| 2157 /// `C()` where 'C' is class. | 2157 /// `C()` where 'C' is class. |
| 2158 ResolutionResult handleClassTypeLiteralAccess( | 2158 ResolutionResult handleClassTypeLiteralAccess( |
| 2159 Send node, | 2159 Send node, |
| 2160 Name name, | 2160 Name name, |
| 2161 ClassElement cls) { | 2161 ClassElement cls) { |
| 2162 cls.ensureResolved(compiler); | 2162 cls.ensureResolved(resolution); |
| 2163 DartType type = cls.rawType; | 2163 DartType type = cls.rawType; |
| 2164 ConstantExpression constant = new TypeConstantExpression(type); | 2164 ConstantExpression constant = new TypeConstantExpression(type); |
| 2165 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); | 2165 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
| 2166 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); | 2166 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); |
| 2167 } | 2167 } |
| 2168 | 2168 |
| 2169 /// Handle access to a type literal of a class. Like `C = b`, `C++` or | 2169 /// Handle access to a type literal of a class. Like `C = b`, `C++` or |
| 2170 /// `C += b` where 'C' is class. | 2170 /// `C += b` where 'C' is class. |
| 2171 ResolutionResult handleClassTypeLiteralUpdate( | 2171 ResolutionResult handleClassTypeLiteralUpdate( |
| 2172 SendSet node, | 2172 SendSet node, |
| 2173 Name name, | 2173 Name name, |
| 2174 ClassElement cls) { | 2174 ClassElement cls) { |
| 2175 cls.ensureResolved(compiler); | 2175 cls.ensureResolved(resolution); |
| 2176 DartType type = cls.rawType; | 2176 DartType type = cls.rawType; |
| 2177 ConstantExpression constant = new TypeConstantExpression(type); | 2177 ConstantExpression constant = new TypeConstantExpression(type); |
| 2178 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); | 2178 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
| 2179 return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics); | 2179 return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics); |
| 2180 } | 2180 } |
| 2181 | 2181 |
| 2182 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 2182 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
| 2183 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 2183 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
| 2184 /// error. | 2184 /// error. |
| 2185 ResolutionResult handleClassSend( | 2185 ResolutionResult handleClassSend( |
| 2186 Send node, | 2186 Send node, |
| 2187 Name name, | 2187 Name name, |
| 2188 ClassElement cls) { | 2188 ClassElement cls) { |
| 2189 cls.ensureResolved(compiler); | 2189 cls.ensureResolved(resolution); |
| 2190 if (sendIsMemberAccess) { | 2190 if (sendIsMemberAccess) { |
| 2191 registry.useElement(node, cls); | 2191 registry.useElement(node, cls); |
| 2192 return new PrefixResult(null, cls); | 2192 return new PrefixResult(null, cls); |
| 2193 } else { | 2193 } else { |
| 2194 // `C` or `C()` where 'C' is a class. | 2194 // `C` or `C()` where 'C' is a class. |
| 2195 return handleClassTypeLiteralAccess(node, name, cls); | 2195 return handleClassTypeLiteralAccess(node, name, cls); |
| 2196 } | 2196 } |
| 2197 } | 2197 } |
| 2198 | 2198 |
| 2199 /// Compute a [DeferredPrefixStructure] for [node]. | 2199 /// Compute a [DeferredPrefixStructure] for [node]. |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2569 AccessSemantics semantics = computeLocalAccessSemantics(node, element); | 2569 AccessSemantics semantics = computeLocalAccessSemantics(node, element); |
| 2570 Selector selector; | 2570 Selector selector; |
| 2571 if (node.isCall) { | 2571 if (node.isCall) { |
| 2572 CallStructure callStructure = | 2572 CallStructure callStructure = |
| 2573 resolveArguments(node.argumentsNode).callStructure; | 2573 resolveArguments(node.argumentsNode).callStructure; |
| 2574 selector = new Selector.call(name, callStructure); | 2574 selector = new Selector.call(name, callStructure); |
| 2575 bool isIncompatibleInvoke = false; | 2575 bool isIncompatibleInvoke = false; |
| 2576 switch (semantics.kind) { | 2576 switch (semantics.kind) { |
| 2577 case AccessKind.LOCAL_FUNCTION: | 2577 case AccessKind.LOCAL_FUNCTION: |
| 2578 LocalFunctionElementX function = semantics.element; | 2578 LocalFunctionElementX function = semantics.element; |
| 2579 function.computeSignature(compiler); | 2579 function.computeType(resolution); |
| 2580 if (!callStructure.signatureApplies(function.functionSignature)) { | 2580 if (!callStructure.signatureApplies(function.functionSignature)) { |
| 2581 registry.registerThrowNoSuchMethod(); | 2581 registry.registerThrowNoSuchMethod(); |
| 2582 registry.registerDynamicInvocation( | 2582 registry.registerDynamicInvocation( |
| 2583 new UniverseSelector(selector, null)); | 2583 new UniverseSelector(selector, null)); |
| 2584 isIncompatibleInvoke = true; | 2584 isIncompatibleInvoke = true; |
| 2585 } | 2585 } |
| 2586 break; | 2586 break; |
| 2587 case AccessKind.PARAMETER: | 2587 case AccessKind.PARAMETER: |
| 2588 case AccessKind.FINAL_PARAMETER: | 2588 case AccessKind.FINAL_PARAMETER: |
| 2589 case AccessKind.LOCAL_VARIABLE: | 2589 case AccessKind.LOCAL_VARIABLE: |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2717 if (abstractField.getter != null) { | 2717 if (abstractField.getter != null) { |
| 2718 member = abstractField.getter; | 2718 member = abstractField.getter; |
| 2719 } else { | 2719 } else { |
| 2720 member = abstractField.setter; | 2720 member = abstractField.setter; |
| 2721 } | 2721 } |
| 2722 } else { | 2722 } else { |
| 2723 member = element; | 2723 member = element; |
| 2724 } | 2724 } |
| 2725 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2725 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
| 2726 // of parse errors to make [element] erroneous. Fix this! | 2726 // of parse errors to make [element] erroneous. Fix this! |
| 2727 member.computeType(compiler); | 2727 member.computeType(resolution); |
| 2728 | 2728 |
| 2729 | 2729 |
| 2730 if (member == compiler.mirrorSystemGetNameFunction && | 2730 if (member == compiler.mirrorSystemGetNameFunction && |
| 2731 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 2731 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
| 2732 compiler.reportHintMessage( | 2732 compiler.reportHintMessage( |
| 2733 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 2733 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, |
| 2734 {'class': compiler.mirrorSystemClass.name, | 2734 {'class': compiler.mirrorSystemClass.name, |
| 2735 'name': compiler.mirrorSystemGetNameFunction.name}); | 2735 'name': compiler.mirrorSystemGetNameFunction.name}); |
| 2736 } | 2736 } |
| 2737 | 2737 |
| 2738 Selector selector; | 2738 Selector selector; |
| 2739 AccessSemantics semantics = | 2739 AccessSemantics semantics = |
| 2740 computeStaticOrTopLevelAccessSemantics(node, member); | 2740 computeStaticOrTopLevelAccessSemantics(node, member); |
| 2741 if (node.isCall) { | 2741 if (node.isCall) { |
| 2742 ArgumentsResult argumentsResult = | 2742 ArgumentsResult argumentsResult = |
| 2743 resolveArguments(node.argumentsNode); | 2743 resolveArguments(node.argumentsNode); |
| 2744 CallStructure callStructure = argumentsResult.callStructure; | 2744 CallStructure callStructure = argumentsResult.callStructure; |
| 2745 selector = new Selector.call(name, callStructure); | 2745 selector = new Selector.call(name, callStructure); |
| 2746 | 2746 |
| 2747 bool isIncompatibleInvoke = false; | 2747 bool isIncompatibleInvoke = false; |
| 2748 switch (semantics.kind) { | 2748 switch (semantics.kind) { |
| 2749 case AccessKind.STATIC_METHOD: | 2749 case AccessKind.STATIC_METHOD: |
| 2750 case AccessKind.TOPLEVEL_METHOD: | 2750 case AccessKind.TOPLEVEL_METHOD: |
| 2751 MethodElement method = semantics.element; | 2751 MethodElement method = semantics.element; |
| 2752 method.computeType(compiler); | 2752 method.computeType(resolution); |
| 2753 if (!callStructure.signatureApplies(method.functionSignature)) { | 2753 if (!callStructure.signatureApplies(method.functionSignature)) { |
| 2754 registry.registerThrowNoSuchMethod(); | 2754 registry.registerThrowNoSuchMethod(); |
| 2755 registry.registerDynamicInvocation( | 2755 registry.registerDynamicInvocation( |
| 2756 new UniverseSelector(selector, null)); | 2756 new UniverseSelector(selector, null)); |
| 2757 isIncompatibleInvoke = true; | 2757 isIncompatibleInvoke = true; |
| 2758 } else { | 2758 } else { |
| 2759 registry.registerStaticUse(semantics.element); | 2759 registry.registerStaticUse(semantics.element); |
| 2760 handleForeignCall(node, semantics.element, selector); | 2760 handleForeignCall(node, semantics.element, selector); |
| 2761 if (method == compiler.identicalFunction && | 2761 if (method == compiler.identicalFunction && |
| 2762 argumentsResult.isValidAsConstant) { | 2762 argumentsResult.isValidAsConstant) { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2900 // `a = b` where `a` has a setter. | 2900 // `a = b` where `a` has a setter. |
| 2901 semantics = element.isTopLevel | 2901 semantics = element.isTopLevel |
| 2902 ? new StaticAccess.topLevelSetter(abstractField.setter) | 2902 ? new StaticAccess.topLevelSetter(abstractField.setter) |
| 2903 : new StaticAccess.staticSetter(abstractField.setter); | 2903 : new StaticAccess.staticSetter(abstractField.setter); |
| 2904 registry.registerStaticUse(abstractField.setter); | 2904 registry.registerStaticUse(abstractField.setter); |
| 2905 } | 2905 } |
| 2906 } else { | 2906 } else { |
| 2907 MemberElement member = element; | 2907 MemberElement member = element; |
| 2908 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2908 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
| 2909 // of parse errors to make [element] erroneous. Fix this! | 2909 // of parse errors to make [element] erroneous. Fix this! |
| 2910 member.computeType(compiler); | 2910 member.computeType(resolution); |
| 2911 registry.registerStaticUse(member); | 2911 registry.registerStaticUse(member); |
| 2912 if (member.isErroneous) { | 2912 if (member.isErroneous) { |
| 2913 // [member] has parse errors. | 2913 // [member] has parse errors. |
| 2914 semantics = new StaticAccess.unresolved(member); | 2914 semantics = new StaticAccess.unresolved(member); |
| 2915 } else if (member.isFunction) { | 2915 } else if (member.isFunction) { |
| 2916 // `a = b`, `a++` or `a += b` where `a` is a function. | 2916 // `a = b`, `a++` or `a += b` where `a` is a function. |
| 2917 ErroneousElement error = reportAndCreateErroneousElement( | 2917 ErroneousElement error = reportAndCreateErroneousElement( |
| 2918 node.selector, name.text, | 2918 node.selector, name.text, |
| 2919 MessageKind.ASSIGNING_METHOD, const {}); | 2919 MessageKind.ASSIGNING_METHOD, const {}); |
| 2920 registry.registerThrowNoSuchMethod(); | 2920 registry.registerThrowNoSuchMethod(); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3129 } | 3129 } |
| 3130 } | 3130 } |
| 3131 } | 3131 } |
| 3132 | 3132 |
| 3133 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 3133 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
| 3134 DartType resolveTypeFromString(Node node, String typeName) { | 3134 DartType resolveTypeFromString(Node node, String typeName) { |
| 3135 Element element = lookupInScope(compiler, node, scope, typeName); | 3135 Element element = lookupInScope(compiler, node, scope, typeName); |
| 3136 if (element == null) return null; | 3136 if (element == null) return null; |
| 3137 if (element is! ClassElement) return null; | 3137 if (element is! ClassElement) return null; |
| 3138 ClassElement cls = element; | 3138 ClassElement cls = element; |
| 3139 cls.ensureResolved(compiler); | 3139 cls.ensureResolved(resolution); |
| 3140 return cls.computeType(compiler); | 3140 return cls.computeType(resolution); |
| 3141 } | 3141 } |
| 3142 | 3142 |
| 3143 /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`. | 3143 /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`. |
| 3144 ResolutionResult handleIndexSendSet(SendSet node) { | 3144 ResolutionResult handleIndexSendSet(SendSet node) { |
| 3145 String operatorText = node.assignmentOperator.source; | 3145 String operatorText = node.assignmentOperator.source; |
| 3146 Node receiver = node.receiver; | 3146 Node receiver = node.receiver; |
| 3147 Node index = node.arguments.head; | 3147 Node index = node.arguments.head; |
| 3148 visitExpression(receiver); | 3148 visitExpression(receiver); |
| 3149 visitExpression(index); | 3149 visitExpression(index); |
| 3150 AccessSemantics semantics = const DynamicAccess.expression(); | 3150 AccessSemantics semantics = const DynamicAccess.expression(); |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3621 node, | 3621 node, |
| 3622 MessageKind.RETURN_IN_GENERATOR, | 3622 MessageKind.RETURN_IN_GENERATOR, |
| 3623 {'modifier': currentAsyncMarker}); | 3623 {'modifier': currentAsyncMarker}); |
| 3624 } | 3624 } |
| 3625 } | 3625 } |
| 3626 visit(node.expression); | 3626 visit(node.expression); |
| 3627 return const NoneResult(); | 3627 return const NoneResult(); |
| 3628 } | 3628 } |
| 3629 | 3629 |
| 3630 ResolutionResult visitYield(Yield node) { | 3630 ResolutionResult visitYield(Yield node) { |
| 3631 compiler.streamClass.ensureResolved(compiler); | 3631 compiler.streamClass.ensureResolved(resolution); |
| 3632 compiler.iterableClass.ensureResolved(compiler); | 3632 compiler.iterableClass.ensureResolved(resolution); |
| 3633 visit(node.expression); | 3633 visit(node.expression); |
| 3634 return const NoneResult(); | 3634 return const NoneResult(); |
| 3635 } | 3635 } |
| 3636 | 3636 |
| 3637 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 3637 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
| 3638 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 3638 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
| 3639 if (!enclosingElement.isFactoryConstructor) { | 3639 if (!enclosingElement.isFactoryConstructor) { |
| 3640 compiler.reportErrorMessage( | 3640 compiler.reportErrorMessage( |
| 3641 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3641 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
| 3642 compiler.reportHintMessage( | 3642 compiler.reportHintMessage( |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3673 // TODO(johnniwinther): Create constant constructor for this case and | 3673 // TODO(johnniwinther): Create constant constructor for this case and |
| 3674 // let evaluation detect the cyclicity. | 3674 // let evaluation detect the cyclicity. |
| 3675 isValidAsConstant = false; | 3675 isValidAsConstant = false; |
| 3676 } | 3676 } |
| 3677 } | 3677 } |
| 3678 | 3678 |
| 3679 // Check that the target constructor is type compatible with the | 3679 // Check that the target constructor is type compatible with the |
| 3680 // redirecting constructor. | 3680 // redirecting constructor. |
| 3681 ClassElement targetClass = redirectionTarget.enclosingClass; | 3681 ClassElement targetClass = redirectionTarget.enclosingClass; |
| 3682 InterfaceType type = registry.getType(node); | 3682 InterfaceType type = registry.getType(node); |
| 3683 FunctionType targetType = redirectionTarget.computeType(compiler) | 3683 FunctionType targetType = redirectionTarget.computeType(resolution) |
| 3684 .subst(type.typeArguments, targetClass.typeVariables); | 3684 .subst(type.typeArguments, targetClass.typeVariables); |
| 3685 FunctionType constructorType = constructor.computeType(compiler); | 3685 FunctionType constructorType = constructor.computeType(resolution); |
| 3686 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); | 3686 bool isSubtype = compiler.types.isSubtype(targetType, constructorType); |
| 3687 if (!isSubtype) { | 3687 if (!isSubtype) { |
| 3688 compiler.reportWarningMessage( | 3688 compiler.reportWarningMessage( |
| 3689 node, | 3689 node, |
| 3690 MessageKind.NOT_ASSIGNABLE, | 3690 MessageKind.NOT_ASSIGNABLE, |
| 3691 {'fromType': targetType, 'toType': constructorType}); | 3691 {'fromType': targetType, 'toType': constructorType}); |
| 3692 // TODO(johnniwinther): Handle this (potentially) erroneous case. | 3692 // TODO(johnniwinther): Handle this (potentially) erroneous case. |
| 3693 isValidAsConstant = false; | 3693 isValidAsConstant = false; |
| 3694 } | 3694 } |
| 3695 | 3695 |
| 3696 redirectionTarget.computeType(compiler); | 3696 redirectionTarget.computeType(resolution); |
| 3697 FunctionSignature targetSignature = redirectionTarget.functionSignature; | 3697 FunctionSignature targetSignature = redirectionTarget.functionSignature; |
| 3698 constructor.computeType(compiler); | 3698 constructor.computeType(resolution); |
| 3699 FunctionSignature constructorSignature = constructor.functionSignature; | 3699 FunctionSignature constructorSignature = constructor.functionSignature; |
| 3700 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 3700 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
| 3701 assert(!isSubtype); | 3701 assert(!isSubtype); |
| 3702 registry.registerThrowNoSuchMethod(); | 3702 registry.registerThrowNoSuchMethod(); |
| 3703 isValidAsConstant = false; | 3703 isValidAsConstant = false; |
| 3704 } | 3704 } |
| 3705 | 3705 |
| 3706 // Register a post process to check for cycles in the redirection chain and | 3706 // Register a post process to check for cycles in the redirection chain and |
| 3707 // set the actual generative constructor at the end of the chain. | 3707 // set the actual generative constructor at the end of the chain. |
| 3708 addDeferredAction(constructor, () { | 3708 addDeferredAction(constructor, () { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3743 return const NoneResult(); | 3743 return const NoneResult(); |
| 3744 } | 3744 } |
| 3745 | 3745 |
| 3746 ResolutionResult visitThrow(Throw node) { | 3746 ResolutionResult visitThrow(Throw node) { |
| 3747 registry.registerThrowExpression(); | 3747 registry.registerThrowExpression(); |
| 3748 visit(node.expression); | 3748 visit(node.expression); |
| 3749 return const NoneResult(); | 3749 return const NoneResult(); |
| 3750 } | 3750 } |
| 3751 | 3751 |
| 3752 ResolutionResult visitAwait(Await node) { | 3752 ResolutionResult visitAwait(Await node) { |
| 3753 compiler.futureClass.ensureResolved(compiler); | 3753 compiler.futureClass.ensureResolved(resolution); |
| 3754 visit(node.expression); | 3754 visit(node.expression); |
| 3755 return const NoneResult(); | 3755 return const NoneResult(); |
| 3756 } | 3756 } |
| 3757 | 3757 |
| 3758 ResolutionResult visitVariableDefinitions(VariableDefinitions node) { | 3758 ResolutionResult visitVariableDefinitions(VariableDefinitions node) { |
| 3759 DartType type; | 3759 DartType type; |
| 3760 if (node.type != null) { | 3760 if (node.type != null) { |
| 3761 type = resolveTypeAnnotation(node.type); | 3761 type = resolveTypeAnnotation(node.type); |
| 3762 } else { | 3762 } else { |
| 3763 type = const DynamicType(); | 3763 type = const DynamicType(); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3838 if (node.isConst) { | 3838 if (node.isConst) { |
| 3839 argumentsResult = | 3839 argumentsResult = |
| 3840 inConstantContext(() => resolveArguments(node.send.argumentsNode)); | 3840 inConstantContext(() => resolveArguments(node.send.argumentsNode)); |
| 3841 } else { | 3841 } else { |
| 3842 argumentsResult = resolveArguments(node.send.argumentsNode); | 3842 argumentsResult = resolveArguments(node.send.argumentsNode); |
| 3843 } | 3843 } |
| 3844 registry.useElement(node.send, constructor); | 3844 registry.useElement(node.send, constructor); |
| 3845 if (Elements.isUnresolved(constructor)) { | 3845 if (Elements.isUnresolved(constructor)) { |
| 3846 return new ResolutionResult.forElement(constructor); | 3846 return new ResolutionResult.forElement(constructor); |
| 3847 } | 3847 } |
| 3848 constructor.computeType(compiler); | 3848 constructor.computeType(resolution); |
| 3849 if (!callSelector.applies(constructor, compiler.world)) { | 3849 if (!callSelector.applies(constructor, compiler.world)) { |
| 3850 registry.registerThrowNoSuchMethod(); | 3850 registry.registerThrowNoSuchMethod(); |
| 3851 } | 3851 } |
| 3852 | 3852 |
| 3853 // [constructor] might be the implementation element | 3853 // [constructor] might be the implementation element |
| 3854 // and only declaration elements may be registered. | 3854 // and only declaration elements may be registered. |
| 3855 registry.registerStaticUse(constructor.declaration); | 3855 registry.registerStaticUse(constructor.declaration); |
| 3856 ClassElement cls = constructor.enclosingClass; | 3856 ClassElement cls = constructor.enclosingClass; |
| 3857 if (cls.isEnumClass && currentClass != cls) { | 3857 if (cls.isEnumClass && currentClass != cls) { |
| 3858 compiler.reportErrorMessage( | 3858 compiler.reportErrorMessage( |
| (...skipping 868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4727 } | 4727 } |
| 4728 return const NoneResult(); | 4728 return const NoneResult(); |
| 4729 } | 4729 } |
| 4730 } | 4730 } |
| 4731 | 4731 |
| 4732 /// Looks up [name] in [scope] and unwraps the result. | 4732 /// Looks up [name] in [scope] and unwraps the result. |
| 4733 Element lookupInScope(Compiler compiler, Node node, | 4733 Element lookupInScope(Compiler compiler, Node node, |
| 4734 Scope scope, String name) { | 4734 Scope scope, String name) { |
| 4735 return Elements.unwrap(scope.lookup(name), compiler, node); | 4735 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4736 } | 4736 } |
| OLD | NEW |