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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 element = reportAndCreateErroneousElement( | 320 element = reportAndCreateErroneousElement( |
321 node, name, MessageKind.GENERIC, | 321 node, name, MessageKind.GENERIC, |
322 // TODO(ahe): Improve error message. Need UX input. | 322 // TODO(ahe): Improve error message. Need UX input. |
323 {'text': "is not an expression $element"}); | 323 {'text': "is not an expression $element"}); |
324 } | 324 } |
325 } | 325 } |
326 if (!Elements.isUnresolved(element) && element.isClass) { | 326 if (!Elements.isUnresolved(element) && element.isClass) { |
327 ClassElement classElement = element; | 327 ClassElement classElement = element; |
328 classElement.ensureResolved(compiler); | 328 classElement.ensureResolved(compiler); |
329 } | 329 } |
330 return new ElementResult(registry.useElement(node, element)); | 330 if (element != null) { |
| 331 registry.useElement(node, element); |
| 332 if (element.isPrefix) { |
| 333 return new PrefixResult(element, null); |
| 334 } else if (element.isClass && sendIsMemberAccess) { |
| 335 return new PrefixResult(null, element); |
| 336 } |
| 337 return new ElementResult(element); |
| 338 } |
| 339 return const NoneResult(); |
331 } | 340 } |
332 } | 341 } |
333 | 342 |
334 TypeResult visitTypeAnnotation(TypeAnnotation node) { | 343 TypeResult visitTypeAnnotation(TypeAnnotation node) { |
335 DartType type = resolveTypeAnnotation(node); | 344 DartType type = resolveTypeAnnotation(node); |
336 if (inCheckContext) { | 345 if (inCheckContext) { |
337 registry.registerIsCheck(type); | 346 registry.registerIsCheck(type); |
338 } | 347 } |
339 return new TypeResult(type); | 348 return new TypeResult(type); |
340 } | 349 } |
(...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1631 } else { | 1640 } else { |
1632 switch (operator.kind) { | 1641 switch (operator.kind) { |
1633 case UnaryOperatorKind.NOT: | 1642 case UnaryOperatorKind.NOT: |
1634 return handleNot(node, operator); | 1643 return handleNot(node, operator); |
1635 case UnaryOperatorKind.COMPLEMENT: | 1644 case UnaryOperatorKind.COMPLEMENT: |
1636 case UnaryOperatorKind.NEGATE: | 1645 case UnaryOperatorKind.NEGATE: |
1637 assert(invariant(node, operator.isUserDefinable, | 1646 assert(invariant(node, operator.isUserDefinable, |
1638 message: "Unexpected unary operator '${operator}'.")); | 1647 message: "Unexpected unary operator '${operator}'.")); |
1639 return handleUserDefinableUnary(node, operator); | 1648 return handleUserDefinableUnary(node, operator); |
1640 } | 1649 } |
1641 return handleUserDefinableUnary(node, operator); | |
1642 } | 1650 } |
1643 } else { | 1651 } else { |
1644 BinaryOperator operator = BinaryOperator.parse(operatorText); | 1652 BinaryOperator operator = BinaryOperator.parse(operatorText); |
1645 if (operator == null) { | 1653 if (operator == null) { |
1646 return handleUnresolvedBinary(node, operatorText); | 1654 return handleUnresolvedBinary(node, operatorText); |
1647 } else { | 1655 } else { |
1648 switch (operator.kind) { | 1656 switch (operator.kind) { |
1649 case BinaryOperatorKind.LOGICAL_AND: | 1657 case BinaryOperatorKind.LOGICAL_AND: |
1650 return handleLogicalAnd(node); | 1658 return handleLogicalAnd(node); |
1651 case BinaryOperatorKind.LOGICAL_OR: | 1659 case BinaryOperatorKind.LOGICAL_OR: |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1900 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 1908 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
1901 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 1909 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
1902 /// error. | 1910 /// error. |
1903 ResolutionResult handleClassSend( | 1911 ResolutionResult handleClassSend( |
1904 Send node, | 1912 Send node, |
1905 Name name, | 1913 Name name, |
1906 ClassElement cls) { | 1914 ClassElement cls) { |
1907 cls.ensureResolved(compiler); | 1915 cls.ensureResolved(compiler); |
1908 if (sendIsMemberAccess) { | 1916 if (sendIsMemberAccess) { |
1909 registry.useElement(node, cls); | 1917 registry.useElement(node, cls); |
1910 return new ElementResult(cls); | 1918 return new PrefixResult(null, cls); |
1911 } else { | 1919 } else { |
1912 // `C` or `C()` where 'C' is a class. | 1920 // `C` or `C()` where 'C' is a class. |
1913 return handleClassTypeLiteralAccess(node, name, cls); | 1921 return handleClassTypeLiteralAccess(node, name, cls); |
1914 } | 1922 } |
1915 } | 1923 } |
1916 | 1924 |
| 1925 /// Compute a [DeferredPrefixStructure] for [node]. |
| 1926 ResolutionResult handleDeferredAccess( |
| 1927 Send node, |
| 1928 PrefixElement prefix, |
| 1929 ResolutionResult result) { |
| 1930 assert(invariant(node, prefix.isDeferred, |
| 1931 message: "Prefix $prefix is not deferred.")); |
| 1932 SendStructure sendStructure = registry.getSendStructure(node); |
| 1933 assert(invariant(node, sendStructure != null, |
| 1934 message: "No SendStructure for $node.")); |
| 1935 registry.registerSendStructure(node, |
| 1936 new DeferredPrefixStructure(prefix, sendStructure)); |
| 1937 if (result.isConstant) { |
| 1938 ConstantExpression constant = |
| 1939 new DeferredConstantExpression(result.constant, prefix); |
| 1940 registry.setConstant(node, constant); |
| 1941 result = new ConstantResult(node, constant); |
| 1942 } |
| 1943 return result; |
| 1944 } |
| 1945 |
1917 /// Handle qualified [Send] where the receiver resolves to a [prefix], | 1946 /// Handle qualified [Send] where the receiver resolves to a [prefix], |
1918 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where | 1947 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where |
1919 /// `prefix` is a library prefix. | 1948 /// `prefix` is a library prefix. |
1920 ResolutionResult handleLibraryPrefixSend( | 1949 ResolutionResult handleLibraryPrefixSend( |
1921 Send node, PrefixElement prefix, Name name) { | 1950 Send node, PrefixElement prefix, Name name) { |
| 1951 ResolutionResult result; |
1922 Element member = prefix.lookupLocalMember(name.text); | 1952 Element member = prefix.lookupLocalMember(name.text); |
1923 if (member == null) { | 1953 if (member == null) { |
1924 registry.registerThrowNoSuchMethod(); | 1954 registry.registerThrowNoSuchMethod(); |
1925 Element error = reportAndCreateErroneousElement( | 1955 Element error = reportAndCreateErroneousElement( |
1926 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 1956 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, |
1927 {'libraryName': prefix.name, 'memberName': name}); | 1957 {'libraryName': prefix.name, 'memberName': name}); |
1928 registry.useElement(node, error); | 1958 result = handleUnresolvedAccess(node, name, error); |
1929 return new ElementResult(error); | |
1930 } else { | 1959 } else { |
1931 return handleResolvedSend(node, name, member); | 1960 result = handleResolvedSend(node, name, member); |
1932 } | 1961 } |
| 1962 if (result.kind == ResultKind.PREFIX) { |
| 1963 // [member] is a class prefix of a static access like `prefix.Class` of |
| 1964 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will |
| 1965 // called on the parent `prefix.Class.foo` node. |
| 1966 result = new PrefixResult(prefix, result.element); |
| 1967 } else if (prefix.isDeferred && |
| 1968 (member == null || !member.isDeferredLoaderGetter)) { |
| 1969 result = handleDeferredAccess(node, prefix, result); |
| 1970 } |
| 1971 return result; |
1933 } | 1972 } |
1934 | 1973 |
1935 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 1974 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
1936 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 1975 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
1937 /// error. | 1976 /// error. |
1938 ResolutionResult handleLibraryPrefix( | 1977 ResolutionResult handleLibraryPrefix( |
1939 Send node, | 1978 Send node, |
1940 Name name, | 1979 Name name, |
1941 PrefixElement prefix) { | 1980 PrefixElement prefix) { |
1942 if ((ElementCategory.PREFIX & allowedCategory) == 0) { | 1981 if ((ElementCategory.PREFIX & allowedCategory) == 0) { |
1943 compiler.reportError( | 1982 compiler.reportError( |
1944 node, | 1983 node, |
1945 MessageKind.PREFIX_AS_EXPRESSION, | 1984 MessageKind.PREFIX_AS_EXPRESSION, |
1946 {'prefix': name}); | 1985 {'prefix': name}); |
1947 return const NoneResult(); | 1986 return const NoneResult(); |
1948 } | 1987 } |
1949 if (prefix.isDeferred) { | 1988 if (prefix.isDeferred) { |
1950 // TODO(johnniwinther): Remove this when deferred access is detected | 1989 // TODO(johnniwinther): Remove this when deferred access is detected |
1951 // through a [SendStructure]. | 1990 // through a [SendStructure]. |
1952 registry.useElement(node.selector, prefix); | 1991 registry.useElement(node.selector, prefix); |
1953 } | 1992 } |
1954 registry.useElement(node, prefix); | 1993 registry.useElement(node, prefix); |
1955 return new ElementResult(prefix); | 1994 return new PrefixResult(prefix, null); |
1956 } | 1995 } |
1957 | 1996 |
1958 /// Handle qualified [Send] where the receiver resolves to an [Element], like | 1997 /// Handle qualified [Send] where the receiver resolves to an [Element], like |
1959 /// `a.b` where `a` is a local, field, class, or prefix, etc. | 1998 /// `a.b` where `a` is a prefix or a class. |
1960 ResolutionResult handleResolvedQualifiedSend( | 1999 ResolutionResult handlePrefixSend( |
1961 Send node, Name name, Element element) { | 2000 Send node, Name name, PrefixResult prefixResult) { |
| 2001 Element element = prefixResult.element; |
1962 if (element.isPrefix) { | 2002 if (element.isPrefix) { |
1963 return handleLibraryPrefixSend(node, element, name); | 2003 return handleLibraryPrefixSend(node, element, name); |
1964 } else if (element.isClass) { | 2004 } else { |
1965 return handleStaticMemberAccess(node, name, element); | 2005 assert(element.isClass); |
| 2006 ResolutionResult result = handleStaticMemberAccess(node, name, element); |
| 2007 if (prefixResult.isDeferred) { |
| 2008 result = handleDeferredAccess(node, prefixResult.prefix, result); |
| 2009 } |
| 2010 return result; |
1966 } | 2011 } |
1967 // TODO(johnniwinther): Use the [element]. | |
1968 return handleDynamicPropertyAccess(node, name); | |
1969 } | 2012 } |
1970 | 2013 |
1971 /// Handle dynamic access of [semantics]. | 2014 /// Handle dynamic access of [semantics]. |
1972 ResolutionResult handleDynamicAccessSemantics( | 2015 ResolutionResult handleDynamicAccessSemantics( |
1973 Send node, Name name, AccessSemantics semantics) { | 2016 Send node, Name name, AccessSemantics semantics) { |
1974 SendStructure sendStructure; | 2017 SendStructure sendStructure; |
1975 Selector selector; | 2018 Selector selector; |
1976 if (node.isCall) { | 2019 if (node.isCall) { |
1977 CallStructure callStructure = | 2020 CallStructure callStructure = |
1978 resolveArguments(node.argumentsNode).callStructure; | 2021 resolveArguments(node.argumentsNode).callStructure; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2038 if (checkThisAccess(node)) { | 2081 if (checkThisAccess(node)) { |
2039 return handleThisPropertyAccess(node, name); | 2082 return handleThisPropertyAccess(node, name); |
2040 } | 2083 } |
2041 // TODO(johnniwinther): Handle invalid this access as an | 2084 // TODO(johnniwinther): Handle invalid this access as an |
2042 // [AccessSemantics]. | 2085 // [AccessSemantics]. |
2043 return const NoneResult(); | 2086 return const NoneResult(); |
2044 } else if (node.isConditional) { | 2087 } else if (node.isConditional) { |
2045 return handleConditionalAccess(node, name); | 2088 return handleConditionalAccess(node, name); |
2046 } | 2089 } |
2047 ResolutionResult result = visitExpressionPrefix(node.receiver); | 2090 ResolutionResult result = visitExpressionPrefix(node.receiver); |
2048 if (result.element != null) { | 2091 if (result.kind == ResultKind.PREFIX) { |
2049 return handleResolvedQualifiedSend(node, name, result.element); | 2092 return handlePrefixSend(node, name, result); |
2050 } else { | 2093 } else { |
| 2094 // TODO(johnniwinther): Use the `element` of [result]. |
2051 return handleDynamicPropertyAccess(node, name); | 2095 return handleDynamicPropertyAccess(node, name); |
2052 } | 2096 } |
2053 } | 2097 } |
2054 | 2098 |
2055 /// Handle access unresolved access to [name] in a non-instance context. | 2099 /// Handle access unresolved access to [name] in a non-instance context. |
2056 ResolutionResult handleUnresolvedAccess( | 2100 ResolutionResult handleUnresolvedAccess( |
2057 Send node, Name name, Element element) { | 2101 Send node, Name name, Element element) { |
2058 // TODO(johnniwinther): Support unresolved top level access as an | 2102 // TODO(johnniwinther): Support unresolved top level access as an |
2059 // [AccessSemantics]. | 2103 // [AccessSemantics]. |
2060 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); | 2104 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2441 return handleOperatorSend(node); | 2485 return handleOperatorSend(node); |
2442 } else if (node.receiver != null) { | 2486 } else if (node.receiver != null) { |
2443 // `a.b`. | 2487 // `a.b`. |
2444 return handleQualifiedSend(node); | 2488 return handleQualifiedSend(node); |
2445 } else { | 2489 } else { |
2446 // `a`. | 2490 // `a`. |
2447 return handleUnqualifiedSend(node); | 2491 return handleUnqualifiedSend(node); |
2448 } | 2492 } |
2449 } | 2493 } |
2450 | 2494 |
2451 /// Regigster read access of [target] inside a closure. | 2495 /// Register read access of [target] inside a closure. |
2452 void registerPotentialAccessInClosure(Send node, Element target) { | 2496 void registerPotentialAccessInClosure(Send node, Element target) { |
2453 if (isPotentiallyMutableTarget(target)) { | 2497 if (isPotentiallyMutableTarget(target)) { |
2454 if (enclosingElement != target.enclosingElement) { | 2498 if (enclosingElement != target.enclosingElement) { |
2455 for (Node scope in promotionScope) { | 2499 for (Node scope in promotionScope) { |
2456 registry.setAccessedByClosureIn(scope, target, node); | 2500 registry.setAccessedByClosureIn(scope, target, node); |
2457 } | 2501 } |
2458 } | 2502 } |
2459 } | 2503 } |
2460 } | 2504 } |
2461 | 2505 |
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3775 } | 3819 } |
3776 return const NoneResult(); | 3820 return const NoneResult(); |
3777 } | 3821 } |
3778 } | 3822 } |
3779 | 3823 |
3780 /// Looks up [name] in [scope] and unwraps the result. | 3824 /// Looks up [name] in [scope] and unwraps the result. |
3781 Element lookupInScope(Compiler compiler, Node node, | 3825 Element lookupInScope(Compiler compiler, Node node, |
3782 Scope scope, String name) { | 3826 Scope scope, String name) { |
3783 return Elements.unwrap(scope.lookup(name), compiler, node); | 3827 return Elements.unwrap(scope.lookup(name), compiler, node); |
3784 } | 3828 } |
OLD | NEW |