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 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1768 return handleStaticInstanceMemberAccess( | 1768 return handleStaticInstanceMemberAccess( |
1769 node, memberName, receiverClass, member); | 1769 node, memberName, receiverClass, member); |
1770 } else if (memberName.isPrivate && memberName.library != member.library) { | 1770 } else if (memberName.isPrivate && memberName.library != member.library) { |
1771 return handlePrivateStaticMemberAccess( | 1771 return handlePrivateStaticMemberAccess( |
1772 node, memberName, receiverClass, member); | 1772 node, memberName, receiverClass, member); |
1773 } else { | 1773 } else { |
1774 return handleStaticOrTopLevelAccess(node, memberName, member); | 1774 return handleStaticOrTopLevelAccess(node, memberName, member); |
1775 } | 1775 } |
1776 } | 1776 } |
1777 | 1777 |
| 1778 /// Handle access to a type literal of type variable [element]. Like `T` or |
| 1779 /// `T()` where 'T' is type variable. |
| 1780 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
| 1781 // the [GetStructure]. |
| 1782 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
| 1783 // evaluating constants. |
| 1784 ResolutionResult handleTypeVariableTypeLiteralAccess( |
| 1785 Send node, |
| 1786 Name name, |
| 1787 TypeVariableElement element) { |
| 1788 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { |
| 1789 compiler.reportError(node, |
| 1790 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
| 1791 {'typeVariableName': node.selector}); |
| 1792 // TODO(johnniwinther): Add another access semantics for this. |
| 1793 } |
| 1794 registry.registerClassUsingVariableExpression(element.enclosingClass); |
| 1795 registry.registerTypeVariableExpression(); |
| 1796 |
| 1797 AccessSemantics semantics = |
| 1798 new StaticAccess.typeParameterTypeLiteral(element); |
| 1799 registry.useElement(node, element); |
| 1800 registry.registerTypeLiteral(node, element.type); |
| 1801 |
| 1802 if (node.isCall) { |
| 1803 CallStructure callStructure = |
| 1804 resolveArguments(node.argumentsNode).callStructure; |
| 1805 Selector selector = callStructure.callSelector; |
| 1806 // TODO(johnniwinther): Remove this when all information goes through |
| 1807 // the [SendStructure]. |
| 1808 registry.setSelector(node, selector); |
| 1809 |
| 1810 registry.registerSendStructure(node, |
| 1811 new InvokeStructure(semantics, selector)); |
| 1812 } else { |
| 1813 // TODO(johnniwinther): Avoid the need for a [Selector] here. |
| 1814 registry.registerSendStructure(node, |
| 1815 new GetStructure(semantics, |
| 1816 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS))); |
| 1817 } |
| 1818 return const NoneResult(); |
| 1819 } |
| 1820 |
| 1821 /// Handle access to a constant type literal of [type]. |
| 1822 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
| 1823 // the [GetStructure]. |
| 1824 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
| 1825 // evaluating constants. |
| 1826 ResolutionResult handleConstantTypeLiteralAccess( |
| 1827 Send node, |
| 1828 Name name, |
| 1829 TypeDeclarationElement element, |
| 1830 DartType type, |
| 1831 ConstantAccess semantics) { |
| 1832 registry.useElement(node, element); |
| 1833 registry.registerTypeLiteral(node, type); |
| 1834 |
| 1835 if (node.isCall) { |
| 1836 CallStructure callStructure = |
| 1837 resolveArguments(node.argumentsNode).callStructure; |
| 1838 Selector selector = callStructure.callSelector; |
| 1839 // TODO(johnniwinther): Remove this when all information goes through |
| 1840 // the [SendStructure]. |
| 1841 registry.setSelector(node, selector); |
| 1842 |
| 1843 // The node itself is not a constant but we register the selector (the |
| 1844 // identifier that refers to the class/typedef) as a constant. |
| 1845 registry.useElement(node.selector, element); |
| 1846 analyzeConstantDeferred(node.selector, enforceConst: false); |
| 1847 |
| 1848 registry.registerSendStructure(node, |
| 1849 new InvokeStructure(semantics, selector)); |
| 1850 return const NoneResult(); |
| 1851 } else { |
| 1852 analyzeConstantDeferred(node, enforceConst: false); |
| 1853 |
| 1854 // TODO(johnniwinther): Avoid the need for a [Selector] here. |
| 1855 registry.registerSendStructure(node, |
| 1856 new GetStructure(semantics, |
| 1857 new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS))); |
| 1858 return new ConstantResult(node, semantics.constant); |
| 1859 } |
| 1860 } |
| 1861 |
| 1862 /// Handle access to a type literal of a typedef. Like `F` or |
| 1863 /// `F()` where 'F' is typedef. |
| 1864 ResolutionResult handleTypedefTypeLiteralAccess( |
| 1865 Send node, |
| 1866 Name name, |
| 1867 TypedefElement typdef) { |
| 1868 typdef.ensureResolved(compiler); |
| 1869 DartType type = typdef.rawType; |
| 1870 ConstantExpression constant = new TypeConstantExpression(type); |
| 1871 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
| 1872 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); |
| 1873 } |
| 1874 |
| 1875 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or |
| 1876 /// `dynamic()`. |
| 1877 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { |
| 1878 DartType type = const DynamicType(); |
| 1879 ConstantExpression constant = new TypeConstantExpression( |
| 1880 // TODO(johnniwinther): Use [type] when evaluation of constants is done |
| 1881 // directly on the constant expressions. |
| 1882 node.isCall ? coreTypes.typeType : type); |
| 1883 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); |
| 1884 return handleConstantTypeLiteralAccess( |
| 1885 node, const PublicName('dynamic'), compiler.typeClass, type, semantics); |
| 1886 } |
| 1887 |
| 1888 /// Handle access to a type literal of a class. Like `C` or |
| 1889 /// `C()` where 'C' is class. |
| 1890 ResolutionResult handleClassTypeLiteralAccess( |
| 1891 Send node, |
| 1892 Name name, |
| 1893 ClassElement cls) { |
| 1894 DartType type = cls.rawType; |
| 1895 ConstantExpression constant = new TypeConstantExpression(type); |
| 1896 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
| 1897 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); |
| 1898 } |
| 1899 |
| 1900 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
| 1901 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
| 1902 /// error. |
| 1903 ResolutionResult handleClassSend( |
| 1904 Send node, |
| 1905 Name name, |
| 1906 ClassElement cls) { |
| 1907 cls.ensureResolved(compiler); |
| 1908 if (sendIsMemberAccess) { |
| 1909 registry.useElement(node, cls); |
| 1910 return new ElementResult(cls); |
| 1911 } else { |
| 1912 // `C` or `C()` where 'C' is a class. |
| 1913 return handleClassTypeLiteralAccess(node, name, cls); |
| 1914 } |
| 1915 } |
| 1916 |
1778 /// Handle qualified [Send] where the receiver resolves to a [prefix], | 1917 /// Handle qualified [Send] where the receiver resolves to a [prefix], |
1779 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where | 1918 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where |
1780 /// `prefix` is a library prefix. | 1919 /// `prefix` is a library prefix. |
1781 ResolutionResult handleLibraryPrefixSend( | 1920 ResolutionResult handleLibraryPrefixSend( |
1782 Send node, PrefixElement prefix, Name name) { | 1921 Send node, PrefixElement prefix, Name name) { |
1783 Element member = prefix.lookupLocalMember(name.text); | 1922 Element member = prefix.lookupLocalMember(name.text); |
1784 if (member == null) { | 1923 if (member == null) { |
1785 registry.registerThrowNoSuchMethod(); | 1924 registry.registerThrowNoSuchMethod(); |
1786 Element error = reportAndCreateErroneousElement( | 1925 Element error = reportAndCreateErroneousElement( |
1787 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 1926 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
(...skipping 21 matching lines...) Expand all Loading... |
1809 } | 1948 } |
1810 if (prefix.isDeferred) { | 1949 if (prefix.isDeferred) { |
1811 // TODO(johnniwinther): Remove this when deferred access is detected | 1950 // TODO(johnniwinther): Remove this when deferred access is detected |
1812 // through a [SendStructure]. | 1951 // through a [SendStructure]. |
1813 registry.useElement(node.selector, prefix); | 1952 registry.useElement(node.selector, prefix); |
1814 } | 1953 } |
1815 registry.useElement(node, prefix); | 1954 registry.useElement(node, prefix); |
1816 return new ElementResult(prefix); | 1955 return new ElementResult(prefix); |
1817 } | 1956 } |
1818 | 1957 |
1819 | |
1820 /// Handle qualified [Send] where the receiver resolves to an [Element], like | 1958 /// Handle qualified [Send] where the receiver resolves to an [Element], like |
1821 /// `a.b` where `a` is a local, field, class, or prefix, etc. | 1959 /// `a.b` where `a` is a local, field, class, or prefix, etc. |
1822 ResolutionResult handleResolvedQualifiedSend( | 1960 ResolutionResult handleResolvedQualifiedSend( |
1823 Send node, Name name, Element element) { | 1961 Send node, Name name, Element element) { |
1824 if (element.isPrefix) { | 1962 if (element.isPrefix) { |
1825 return handleLibraryPrefixSend(node, element, name); | 1963 return handleLibraryPrefixSend(node, element, name); |
1826 } else if (element.isClass) { | 1964 } else if (element.isClass) { |
1827 return handleStaticMemberAccess(node, name, element); | 1965 return handleStaticMemberAccess(node, name, element); |
1828 } | 1966 } |
1829 return oldVisitSend(node); | 1967 // TODO(johnniwinther): Use the [element]. |
| 1968 return handleDynamicPropertyAccess(node, name); |
1830 } | 1969 } |
1831 | 1970 |
1832 /// Handle dynamic access of [semantics]. | 1971 /// Handle dynamic access of [semantics]. |
1833 ResolutionResult handleDynamicAccessSemantics( | 1972 ResolutionResult handleDynamicAccessSemantics( |
1834 Send node, Name name, AccessSemantics semantics) { | 1973 Send node, Name name, AccessSemantics semantics) { |
1835 SendStructure sendStructure; | 1974 SendStructure sendStructure; |
1836 Selector selector; | 1975 Selector selector; |
1837 if (node.isCall) { | 1976 if (node.isCall) { |
1838 CallStructure callStructure = | 1977 CallStructure callStructure = |
1839 resolveArguments(node.argumentsNode).callStructure; | 1978 resolveArguments(node.argumentsNode).callStructure; |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2093 } else { | 2232 } else { |
2094 member = abstractField.setter; | 2233 member = abstractField.setter; |
2095 } | 2234 } |
2096 } else { | 2235 } else { |
2097 member = element; | 2236 member = element; |
2098 } | 2237 } |
2099 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2238 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
2100 // of parse errors to make [element] erroneous. Fix this! | 2239 // of parse errors to make [element] erroneous. Fix this! |
2101 member.computeType(compiler); | 2240 member.computeType(compiler); |
2102 | 2241 |
| 2242 |
| 2243 if (member == compiler.mirrorSystemGetNameFunction && |
| 2244 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
| 2245 compiler.reportHint( |
| 2246 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, |
| 2247 {'class': compiler.mirrorSystemClass.name, |
| 2248 'name': compiler.mirrorSystemGetNameFunction.name}); |
| 2249 } |
| 2250 |
2103 Selector selector; | 2251 Selector selector; |
2104 AccessSemantics semantics = | 2252 AccessSemantics semantics = |
2105 computeStaticOrTopLevelAccessSemantics(node, member); | 2253 computeStaticOrTopLevelAccessSemantics(node, member); |
2106 if (node.isCall) { | 2254 if (node.isCall) { |
2107 ArgumentsResult argumentsResult = | 2255 ArgumentsResult argumentsResult = |
2108 resolveArguments(node.argumentsNode); | 2256 resolveArguments(node.argumentsNode); |
2109 CallStructure callStructure = argumentsResult.callStructure; | 2257 CallStructure callStructure = argumentsResult.callStructure; |
2110 selector = new Selector(SelectorKind.CALL, name, callStructure); | 2258 selector = new Selector(SelectorKind.CALL, name, callStructure); |
2111 | 2259 |
2112 bool isIncompatibleInvoke = false; | 2260 bool isIncompatibleInvoke = false; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2225 new StaticAccess.unresolved(element)); | 2373 new StaticAccess.unresolved(element)); |
2226 } | 2374 } |
2227 if (element.isInstanceMember) { | 2375 if (element.isInstanceMember) { |
2228 if (inInstanceContext) { | 2376 if (inInstanceContext) { |
2229 // TODO(johnniwinther): Maybe use the found [element]. | 2377 // TODO(johnniwinther): Maybe use the found [element]. |
2230 return handleThisPropertyAccess(node, name); | 2378 return handleThisPropertyAccess(node, name); |
2231 } else { | 2379 } else { |
2232 return handleStaticInstanceSend(node, name, element); | 2380 return handleStaticInstanceSend(node, name, element); |
2233 } | 2381 } |
2234 } | 2382 } |
2235 if (element.isClass || element.isTypedef) { | 2383 if (element.isClass) { |
2236 return oldVisitSend(node); | 2384 // `C`, `C()`, or 'C.b` where 'C' is a class. |
| 2385 return handleClassSend(node, name, element); |
| 2386 } else if (element.isTypedef) { |
| 2387 // `F` or `F()` where 'F' is a typedef. |
| 2388 return handleTypedefTypeLiteralAccess(node, name, element); |
2237 } else if (element.isTypeVariable) { | 2389 } else if (element.isTypeVariable) { |
2238 return oldVisitSend(node); | 2390 return handleTypeVariableTypeLiteralAccess(node, name, element); |
2239 } else if (element.isPrefix) { | 2391 } else if (element.isPrefix) { |
2240 return handleLibraryPrefix(node, name, element); | 2392 return handleLibraryPrefix(node, name, element); |
2241 } else if (element.isLocal) { | 2393 } else if (element.isLocal) { |
2242 return handleLocalAccess(node, name, element); | 2394 return handleLocalAccess(node, name, element); |
2243 } else if (element.isStatic || element.isTopLevel) { | 2395 } else if (element.isStatic || element.isTopLevel) { |
2244 return handleStaticOrTopLevelAccess(node, name, element); | 2396 return handleStaticOrTopLevelAccess(node, name, element); |
2245 } | 2397 } |
2246 return internalError(node, "Unexpected resolved send: $element"); | 2398 return internalError(node, "Unexpected resolved send: $element"); |
2247 } | 2399 } |
2248 | 2400 |
2249 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 2401 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
2250 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 2402 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
2251 ResolutionResult handleUnqualifiedSend(Send node) { | 2403 ResolutionResult handleUnqualifiedSend(Send node) { |
2252 Identifier selector = node.selector.asIdentifier(); | 2404 Identifier selector = node.selector.asIdentifier(); |
2253 if (selector == null) { | 2405 if (selector == null) { |
2254 // `(){}()` and `(foo)()`. | 2406 // `(){}()` and `(foo)()`. |
2255 return handleExpressionInvoke(node); | 2407 return handleExpressionInvoke(node); |
2256 } | 2408 } |
2257 String text = selector.source; | 2409 String text = selector.source; |
2258 if (text == 'assert') { | 2410 if (text == 'assert') { |
2259 // `assert()`. | 2411 // `assert()`. |
2260 return handleAssert(node); | 2412 return handleAssert(node); |
2261 } else if (text == 'this') { | 2413 } else if (text == 'this') { |
2262 // `this()`. | 2414 // `this()`. |
2263 return handleThisAccess(node); | 2415 return handleThisAccess(node); |
2264 } else if (text == 'dynamic') { | |
2265 // `dynamic` || `dynamic()`. | |
2266 // TODO(johnniwinther): Handle dynamic type literal access. | |
2267 return oldVisitSend(node); | |
2268 } | 2416 } |
2269 // `name` or `name()` | 2417 // `name` or `name()` |
2270 Name name = new Name(text, enclosingElement.library); | 2418 Name name = new Name(text, enclosingElement.library); |
2271 Element element = lookupInScope(compiler, node, scope, text); | 2419 Element element = lookupInScope(compiler, node, scope, text); |
2272 if (element == null) { | 2420 if (element == null) { |
2273 if (inInstanceContext) { | 2421 if (text == 'dynamic') { |
| 2422 // `dynamic` or `dynamic()` where 'dynamic' is not declared in the |
| 2423 // current scope. |
| 2424 return handleDynamicTypeLiteralAccess(node); |
| 2425 } else if (inInstanceContext) { |
2274 // Implicitly `this.name`. | 2426 // Implicitly `this.name`. |
2275 return handleThisPropertyAccess(node, name); | 2427 return handleThisPropertyAccess(node, name); |
2276 } else { | 2428 } else { |
2277 // Create [ErroneousElement] for unresolved access. | 2429 // Create [ErroneousElement] for unresolved access. |
2278 ErroneousElement error = reportCannotResolve(node, text); | 2430 ErroneousElement error = reportCannotResolve(node, text); |
2279 return handleUnresolvedAccess(node, name, error); | 2431 return handleUnresolvedAccess(node, name, error); |
2280 } | 2432 } |
2281 } else { | 2433 } else { |
2282 return handleResolvedSend(node, name, element); | 2434 return handleResolvedSend(node, name, element); |
2283 } | 2435 } |
(...skipping 16 matching lines...) Expand all Loading... |
2300 void registerPotentialAccessInClosure(Send node, Element target) { | 2452 void registerPotentialAccessInClosure(Send node, Element target) { |
2301 if (isPotentiallyMutableTarget(target)) { | 2453 if (isPotentiallyMutableTarget(target)) { |
2302 if (enclosingElement != target.enclosingElement) { | 2454 if (enclosingElement != target.enclosingElement) { |
2303 for (Node scope in promotionScope) { | 2455 for (Node scope in promotionScope) { |
2304 registry.setAccessedByClosureIn(scope, target, node); | 2456 registry.setAccessedByClosureIn(scope, target, node); |
2305 } | 2457 } |
2306 } | 2458 } |
2307 } | 2459 } |
2308 } | 2460 } |
2309 | 2461 |
2310 ResolutionResult oldVisitSend(Send node) { | |
2311 bool oldSendIsMemberAccess = sendIsMemberAccess; | |
2312 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | |
2313 | |
2314 ResolutionResult result = resolveSend(node); | |
2315 sendIsMemberAccess = oldSendIsMemberAccess; | |
2316 | |
2317 Element target = result.element; | |
2318 | |
2319 if (target != null | |
2320 && target == compiler.mirrorSystemGetNameFunction | |
2321 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | |
2322 compiler.reportHint( | |
2323 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | |
2324 {'class': compiler.mirrorSystemClass.name, | |
2325 'name': compiler.mirrorSystemGetNameFunction.name}); | |
2326 } | |
2327 | |
2328 if (target != null) { | |
2329 if (target.isErroneous) { | |
2330 registry.registerThrowNoSuchMethod(); | |
2331 } else if (target.isAbstractField) { | |
2332 AbstractFieldElement field = target; | |
2333 target = field.getter; | |
2334 if (target == null) { | |
2335 if (!inInstanceContext || field.isTopLevel || field.isStatic) { | |
2336 registry.registerThrowNoSuchMethod(); | |
2337 target = reportAndCreateErroneousElement(node.selector, field.name, | |
2338 MessageKind.CANNOT_RESOLVE_GETTER, const {}); | |
2339 } | |
2340 } | |
2341 } else if (target.isTypeVariable) { | |
2342 ClassElement cls = target.enclosingClass; | |
2343 assert(enclosingElement.enclosingClass == cls); | |
2344 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { | |
2345 compiler.reportError(node, | |
2346 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | |
2347 {'typeVariableName': node.selector}); | |
2348 } | |
2349 registry.registerClassUsingVariableExpression(cls); | |
2350 registry.registerTypeVariableExpression(); | |
2351 registerTypeLiteralAccess(node, target); | |
2352 } else if (target.impliesType && (!sendIsMemberAccess || node.isCall)) { | |
2353 registerTypeLiteralAccess(node, target); | |
2354 } | |
2355 registerPotentialAccessInClosure(node, target); | |
2356 } | |
2357 | |
2358 resolveArguments(node.argumentsNode); | |
2359 | |
2360 // If the selector is null, it means that we will not be generating | |
2361 // code for this as a send. | |
2362 Selector selector = registry.getSelector(node); | |
2363 if (selector == null) return const NoneResult(); | |
2364 | |
2365 if (node.isCall) { | |
2366 if (Elements.isUnresolved(target) || | |
2367 target.isGetter || | |
2368 target.isField || | |
2369 Elements.isClosureSend(node, target)) { | |
2370 // If we don't know what we're calling or if we are calling a getter, | |
2371 // we need to register that fact that we may be calling a closure | |
2372 // with the same arguments. | |
2373 Selector call = new Selector.callClosureFrom(selector); | |
2374 registry.registerDynamicInvocation( | |
2375 new UniverseSelector(selector, null)); | |
2376 } else if (target.impliesType) { | |
2377 // We call 'call()' on a Type instance returned from the reference to a | |
2378 // class or typedef literal. We do not need to register this call as a | |
2379 // dynamic invocation, because we statically know what the target is. | |
2380 } else { | |
2381 if (target is FunctionElement) { | |
2382 FunctionElement function = target; | |
2383 function.computeType(compiler); | |
2384 } | |
2385 if (!selector.applies(target, compiler.world)) { | |
2386 registry.registerThrowNoSuchMethod(); | |
2387 if (node.isSuperCall) { | |
2388 internalError(node, "Unexpected super call $node"); | |
2389 } | |
2390 } | |
2391 } | |
2392 | |
2393 handleForeignCall(node, target, selector); | |
2394 } | |
2395 | |
2396 registry.useElement(node, target); | |
2397 registerSend(selector, target); | |
2398 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { | |
2399 registry.registerGetOfStaticFunction(target.declaration); | |
2400 } | |
2401 return node.isPropertyAccess | |
2402 ? new ResolutionResult.forElement(target) : const NoneResult(); | |
2403 } | |
2404 | |
2405 // TODO(johnniwinther): Move this to the backend resolution callbacks. | 2462 // TODO(johnniwinther): Move this to the backend resolution callbacks. |
2406 void handleForeignCall(Send node, Element target, Selector selector) { | 2463 void handleForeignCall(Send node, Element target, Selector selector) { |
2407 if (target != null && compiler.backend.isForeign(target)) { | 2464 if (target != null && compiler.backend.isForeign(target)) { |
2408 if (selector.name == 'JS') { | 2465 if (selector.name == 'JS') { |
2409 registry.registerJsCall(node, this); | 2466 registry.registerJsCall(node, this); |
2410 } else if (selector.name == 'JS_EMBEDDED_GLOBAL') { | 2467 } else if (selector.name == 'JS_EMBEDDED_GLOBAL') { |
2411 registry.registerJsEmbeddedGlobalCall(node, this); | 2468 registry.registerJsEmbeddedGlobalCall(node, this); |
2412 } else if (selector.name == 'JS_BUILTIN') { | 2469 } else if (selector.name == 'JS_BUILTIN') { |
2413 registry.registerJsBuiltinCall(node, this); | 2470 registry.registerJsBuiltinCall(node, this); |
2414 } else if (selector.name == 'JS_INTERCEPTOR_CONSTANT') { | 2471 } else if (selector.name == 'JS_INTERCEPTOR_CONSTANT') { |
(...skipping 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3718 } | 3775 } |
3719 return const NoneResult(); | 3776 return const NoneResult(); |
3720 } | 3777 } |
3721 } | 3778 } |
3722 | 3779 |
3723 /// Looks up [name] in [scope] and unwraps the result. | 3780 /// Looks up [name] in [scope] and unwraps the result. |
3724 Element lookupInScope(Compiler compiler, Node node, | 3781 Element lookupInScope(Compiler compiler, Node node, |
3725 Scope scope, String name) { | 3782 Scope scope, String name) { |
3726 return Elements.unwrap(scope.lookup(name), compiler, node); | 3783 return Elements.unwrap(scope.lookup(name), compiler, node); |
3727 } | 3784 } |
OLD | NEW |