Chromium Code Reviews| 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 resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 /// The state of constants in resolutions. | 7 /// The state of constants in resolutions. |
| 8 enum ConstantState { | 8 enum ConstantState { |
| 9 /// Expressions are not required to be constants. | 9 /// Expressions are not required to be constants. |
| 10 NON_CONSTANT, | 10 NON_CONSTANT, |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 39 /// Whether we are in a context where `this` is accessible (this will be false | 39 /// Whether we are in a context where `this` is accessible (this will be false |
| 40 /// in static contexts, factory methods, and field initializers). | 40 /// in static contexts, factory methods, and field initializers). |
| 41 bool inInstanceContext; | 41 bool inInstanceContext; |
| 42 bool inCheckContext; | 42 bool inCheckContext; |
| 43 bool inCatchBlock; | 43 bool inCatchBlock; |
| 44 ConstantState constantState; | 44 ConstantState constantState; |
| 45 | 45 |
| 46 Scope scope; | 46 Scope scope; |
| 47 ClassElement currentClass; | 47 ClassElement currentClass; |
| 48 ExpressionStatement currentExpressionStatement; | 48 ExpressionStatement currentExpressionStatement; |
| 49 | |
| 50 /// `true` if a [Send] or [SendSet] is visited as the prefix of member access. | |
| 51 /// For instance `Class` in `Class.staticField` or `prefix.Class` in | |
| 52 /// `prefix.Class.staticMethod()`. | |
| 49 bool sendIsMemberAccess = false; | 53 bool sendIsMemberAccess = false; |
| 54 | |
| 50 StatementScope statementScope; | 55 StatementScope statementScope; |
| 51 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 56 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
| 52 | ElementCategory.IMPLIES_TYPE; | 57 | ElementCategory.IMPLIES_TYPE; |
| 53 | 58 |
| 54 /** | 59 /** |
| 55 * Record of argument nodes to JS_INTERCEPTOR_CONSTANT for deferred | 60 * Record of argument nodes to JS_INTERCEPTOR_CONSTANT for deferred |
| 56 * processing. | 61 * processing. |
| 57 */ | 62 */ |
| 58 Set<Node> argumentsToJsInterceptorConstant = null; | 63 Set<Node> argumentsToJsInterceptorConstant = null; |
| 59 | 64 |
| (...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1325 visitExpression(right); | 1330 visitExpression(right); |
| 1326 } else { | 1331 } else { |
| 1327 ResolutionResult leftResult = visitExpression(left); | 1332 ResolutionResult leftResult = visitExpression(left); |
| 1328 ResolutionResult rightResult = visitExpression(right); | 1333 ResolutionResult rightResult = visitExpression(right); |
| 1329 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); | 1334 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); |
| 1330 semantics = new DynamicAccess.dynamicProperty(left); | 1335 semantics = new DynamicAccess.dynamicProperty(left); |
| 1331 | 1336 |
| 1332 if (leftResult.isConstant && rightResult.isConstant) { | 1337 if (leftResult.isConstant && rightResult.isConstant) { |
| 1333 bool isValidConstant; | 1338 bool isValidConstant; |
| 1334 ConstantExpression leftConstant = leftResult.constant; | 1339 ConstantExpression leftConstant = leftResult.constant; |
| 1335 ConstantExpression rightConstant = leftResult.constant; | 1340 ConstantExpression rightConstant = rightResult.constant; |
| 1336 DartType knownLeftType = leftConstant.getKnownType(coreTypes); | 1341 DartType knownLeftType = leftConstant.getKnownType(coreTypes); |
| 1337 DartType knownRightType = rightConstant.getKnownType(coreTypes); | 1342 DartType knownRightType = rightConstant.getKnownType(coreTypes); |
| 1338 switch (operator.kind) { | 1343 switch (operator.kind) { |
| 1339 case BinaryOperatorKind.EQ: | 1344 case BinaryOperatorKind.EQ: |
| 1340 case BinaryOperatorKind.NOT_EQ: | 1345 case BinaryOperatorKind.NOT_EQ: |
| 1341 isValidConstant = | 1346 isValidConstant = |
| 1342 (knownLeftType == coreTypes.intType || | 1347 (knownLeftType == coreTypes.intType || |
| 1343 knownLeftType == coreTypes.doubleType || | 1348 knownLeftType == coreTypes.doubleType || |
| 1344 knownLeftType == coreTypes.stringType || | 1349 knownLeftType == coreTypes.stringType || |
| 1345 knownLeftType == coreTypes.boolType || | 1350 knownLeftType == coreTypes.boolType || |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1763 return handleStaticInstanceMemberAccess( | 1768 return handleStaticInstanceMemberAccess( |
| 1764 node, memberName, receiverClass, member); | 1769 node, memberName, receiverClass, member); |
| 1765 } else if (memberName.isPrivate && memberName.library != member.library) { | 1770 } else if (memberName.isPrivate && memberName.library != member.library) { |
| 1766 return handlePrivateStaticMemberAccess( | 1771 return handlePrivateStaticMemberAccess( |
| 1767 node, memberName, receiverClass, member); | 1772 node, memberName, receiverClass, member); |
| 1768 } else { | 1773 } else { |
| 1769 return handleStaticOrTopLevelAccess(node, memberName, member); | 1774 return handleStaticOrTopLevelAccess(node, memberName, member); |
| 1770 } | 1775 } |
| 1771 } | 1776 } |
| 1772 | 1777 |
| 1778 /// Handle qualified [Send] where the reciever resolves to a [prefix], | |
|
karlklose
2015/07/09 13:42:49
'reciever' -> 'receiver'.
Johnni Winther
2015/07/09 13:52:04
Done.
| |
| 1779 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where | |
| 1780 /// `prefix` is a library prefix. | |
| 1781 ResolutionResult handleLibraryPrefixSend( | |
| 1782 Send node, PrefixElement prefix, Name name) { | |
| 1783 Element member = prefix.lookupLocalMember(name.text); | |
| 1784 if (member == null) { | |
| 1785 registry.registerThrowNoSuchMethod(); | |
| 1786 Element error = reportAndCreateErroneousElement( | |
| 1787 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, | |
| 1788 {'libraryName': prefix.name, 'memberName': name}); | |
| 1789 registry.useElement(node, error); | |
| 1790 return new ElementResult(error); | |
| 1791 } else { | |
| 1792 return handleResolvedSend(node, name, member); | |
| 1793 } | |
| 1794 } | |
| 1795 | |
| 1796 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | |
| 1797 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | |
| 1798 /// error. | |
| 1799 ResolutionResult handleLibraryPrefix( | |
| 1800 Send node, | |
| 1801 Name name, | |
| 1802 PrefixElement prefix) { | |
| 1803 if ((ElementCategory.PREFIX & allowedCategory) == 0) { | |
| 1804 compiler.reportError( | |
| 1805 node, | |
| 1806 MessageKind.PREFIX_AS_EXPRESSION, | |
| 1807 {'prefix': name}); | |
| 1808 return const NoneResult(); | |
| 1809 } | |
| 1810 if (prefix.isDeferred) { | |
| 1811 // TODO(johnniwinther): Remove this when deferred access is detected | |
| 1812 // through a [SendStructure]. | |
| 1813 registry.useElement(node.selector, prefix); | |
| 1814 } | |
| 1815 registry.useElement(node, prefix); | |
| 1816 return new ElementResult(prefix); | |
| 1817 } | |
| 1818 | |
| 1819 | |
| 1773 /// Handle qualified [Send] where the receiver resolves to an [Element], like | 1820 /// Handle qualified [Send] where the receiver resolves to an [Element], like |
| 1774 /// `a.b` where `a` is a local, field, class, or prefix, etc. | 1821 /// `a.b` where `a` is a local, field, class, or prefix, etc. |
| 1775 ResolutionResult handleResolvedQualifiedSend( | 1822 ResolutionResult handleResolvedQualifiedSend( |
| 1776 Send node, Name name, Element element) { | 1823 Send node, Name name, Element element) { |
| 1777 if (element.isPrefix) { | 1824 if (element.isPrefix) { |
| 1778 return oldVisitSend(node); | 1825 return handleLibraryPrefixSend(node, element, name); |
| 1779 } else if (element.isClass) { | 1826 } else if (element.isClass) { |
| 1780 return handleStaticMemberAccess(node, name, element); | 1827 return handleStaticMemberAccess(node, name, element); |
| 1781 } | 1828 } |
| 1782 return oldVisitSend(node); | 1829 return oldVisitSend(node); |
| 1783 } | 1830 } |
| 1784 | 1831 |
| 1785 /// Handle dynamic access of [semantics]. | 1832 /// Handle dynamic access of [semantics]. |
| 1786 ResolutionResult handleDynamicAccessSemantics( | 1833 ResolutionResult handleDynamicAccessSemantics( |
| 1787 Send node, Name name, AccessSemantics semantics) { | 1834 Send node, Name name, AccessSemantics semantics) { |
| 1788 SendStructure sendStructure; | 1835 SendStructure sendStructure; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1902 registry.registerSendStructure(node, sendStructure); | 1949 registry.registerSendStructure(node, sendStructure); |
| 1903 return const NoneResult(); | 1950 return const NoneResult(); |
| 1904 } | 1951 } |
| 1905 | 1952 |
| 1906 /// Handle access to an ambiguous element, that is, a name imported twice. | 1953 /// Handle access to an ambiguous element, that is, a name imported twice. |
| 1907 ResolutionResult handleAmbiguousSend( | 1954 ResolutionResult handleAmbiguousSend( |
| 1908 Send node, | 1955 Send node, |
| 1909 Name name, | 1956 Name name, |
| 1910 AmbiguousElement element) { | 1957 AmbiguousElement element) { |
| 1911 | 1958 |
| 1912 compiler.reportError( | 1959 ErroneousElement error = reportAndCreateErroneousElement( |
| 1913 node, element.messageKind, element.messageArguments); | 1960 node, |
| 1961 name.text, | |
| 1962 element.messageKind, | |
| 1963 element.messageArguments); | |
| 1914 element.diagnose(enclosingElement, compiler); | 1964 element.diagnose(enclosingElement, compiler); |
| 1915 | 1965 registry.registerThrowNoSuchMethod(); |
| 1916 ErroneousElement error = new ErroneousElementX( | |
| 1917 element.messageKind, | |
| 1918 element.messageArguments, | |
| 1919 name.text, | |
| 1920 enclosingElement); | |
| 1921 | 1966 |
| 1922 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 1967 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
| 1923 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); | 1968 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); |
| 1924 return handleErroneousAccess(node, name, error, accessSemantics); | 1969 return handleErroneousAccess(node, name, error, accessSemantics); |
| 1925 } | 1970 } |
| 1926 | 1971 |
| 1927 /// Handle access of an instance [member] from a non-instance context. | 1972 /// Handle access of an instance [member] from a non-instance context. |
| 1928 ResolutionResult handleStaticInstanceSend( | 1973 ResolutionResult handleStaticInstanceSend( |
| 1929 Send node, Name name, MemberElement member) { | 1974 Send node, Name name, MemberElement member) { |
| 1930 compiler.reportError( | 1975 compiler.reportError( |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2185 return handleThisPropertyAccess(node, name); | 2230 return handleThisPropertyAccess(node, name); |
| 2186 } else { | 2231 } else { |
| 2187 return handleStaticInstanceSend(node, name, element); | 2232 return handleStaticInstanceSend(node, name, element); |
| 2188 } | 2233 } |
| 2189 } | 2234 } |
| 2190 if (element.isClass || element.isTypedef) { | 2235 if (element.isClass || element.isTypedef) { |
| 2191 return oldVisitSend(node); | 2236 return oldVisitSend(node); |
| 2192 } else if (element.isTypeVariable) { | 2237 } else if (element.isTypeVariable) { |
| 2193 return oldVisitSend(node); | 2238 return oldVisitSend(node); |
| 2194 } else if (element.isPrefix) { | 2239 } else if (element.isPrefix) { |
| 2195 return oldVisitSend(node); | 2240 return handleLibraryPrefix(node, name, element); |
| 2196 } else if (element.isLocal) { | 2241 } else if (element.isLocal) { |
| 2197 return handleLocalAccess(node, name, element); | 2242 return handleLocalAccess(node, name, element); |
| 2198 } else if (element.isStatic || element.isTopLevel) { | 2243 } else if (element.isStatic || element.isTopLevel) { |
| 2199 return handleStaticOrTopLevelAccess(node, name, element); | 2244 return handleStaticOrTopLevelAccess(node, name, element); |
| 2200 } | 2245 } |
| 2201 return internalError(node, "Unexpected resolved send: $element"); | 2246 return internalError(node, "Unexpected resolved send: $element"); |
| 2202 } | 2247 } |
| 2203 | 2248 |
| 2204 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 2249 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
| 2205 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 2250 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
| (...skipping 1467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3673 } | 3718 } |
| 3674 return const NoneResult(); | 3719 return const NoneResult(); |
| 3675 } | 3720 } |
| 3676 } | 3721 } |
| 3677 | 3722 |
| 3678 /// Looks up [name] in [scope] and unwraps the result. | 3723 /// Looks up [name] in [scope] and unwraps the result. |
| 3679 Element lookupInScope(Compiler compiler, Node node, | 3724 Element lookupInScope(Compiler compiler, Node node, |
| 3680 Scope scope, String name) { | 3725 Scope scope, String name) { |
| 3681 return Elements.unwrap(scope.lookup(name), compiler, node); | 3726 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 3682 } | 3727 } |
| OLD | NEW |