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){ | |
floitsch
2015/07/16 15:24:44
missing space before "{".
Johnni Winther
2015/07/20 08:53:53
Done.
| |
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. | |
1964 result = new PrefixResult(prefix, result.element); | |
floitsch
2015/07/16 15:24:44
If I understand correctly, this is the case where
Johnni Winther
2015/07/20 08:53:53
Done.
| |
1965 } else if (prefix.isDeferred && | |
1966 (member == null || !member.isDeferredLoaderGetter)) { | |
1967 result = handleDeferredAccess(node, prefix, result); | |
1968 } | |
1969 return result; | |
1933 } | 1970 } |
1934 | 1971 |
1935 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 1972 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
1936 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 1973 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
1937 /// error. | 1974 /// error. |
1938 ResolutionResult handleLibraryPrefix( | 1975 ResolutionResult handleLibraryPrefix( |
1939 Send node, | 1976 Send node, |
1940 Name name, | 1977 Name name, |
1941 PrefixElement prefix) { | 1978 PrefixElement prefix) { |
1942 if ((ElementCategory.PREFIX & allowedCategory) == 0) { | 1979 if ((ElementCategory.PREFIX & allowedCategory) == 0) { |
1943 compiler.reportError( | 1980 compiler.reportError( |
1944 node, | 1981 node, |
1945 MessageKind.PREFIX_AS_EXPRESSION, | 1982 MessageKind.PREFIX_AS_EXPRESSION, |
1946 {'prefix': name}); | 1983 {'prefix': name}); |
1947 return const NoneResult(); | 1984 return const NoneResult(); |
1948 } | 1985 } |
1949 if (prefix.isDeferred) { | 1986 if (prefix.isDeferred) { |
1950 // TODO(johnniwinther): Remove this when deferred access is detected | 1987 // TODO(johnniwinther): Remove this when deferred access is detected |
1951 // through a [SendStructure]. | 1988 // through a [SendStructure]. |
1952 registry.useElement(node.selector, prefix); | 1989 registry.useElement(node.selector, prefix); |
1953 } | 1990 } |
1954 registry.useElement(node, prefix); | 1991 registry.useElement(node, prefix); |
1955 return new ElementResult(prefix); | 1992 return new PrefixResult(prefix, null); |
1956 } | 1993 } |
1957 | 1994 |
1958 /// Handle qualified [Send] where the receiver resolves to an [Element], like | 1995 /// Handle qualified [Send] where the receiver resolves to an [Element], like |
1959 /// `a.b` where `a` is a local, field, class, or prefix, etc. | 1996 /// `a.b` where `a` is a prefix or a class. |
1960 ResolutionResult handleResolvedQualifiedSend( | 1997 ResolutionResult handlePrefixSend( |
1961 Send node, Name name, Element element) { | 1998 Send node, Name name, PrefixResult prefixResult) { |
1999 Element element = prefixResult.element; | |
1962 if (element.isPrefix) { | 2000 if (element.isPrefix) { |
1963 return handleLibraryPrefixSend(node, element, name); | 2001 return handleLibraryPrefixSend(node, element, name); |
1964 } else if (element.isClass) { | 2002 } else { |
1965 return handleStaticMemberAccess(node, name, element); | 2003 assert(element.isClass); |
2004 ResolutionResult result = handleStaticMemberAccess(node, name, element); | |
2005 if (prefixResult.isDeferred) { | |
2006 result = handleDeferredAccess(node, prefixResult.prefix, result); | |
2007 } | |
2008 return result; | |
1966 } | 2009 } |
1967 // TODO(johnniwinther): Use the [element]. | |
1968 return handleDynamicPropertyAccess(node, name); | |
1969 } | 2010 } |
1970 | 2011 |
1971 /// Handle dynamic access of [semantics]. | 2012 /// Handle dynamic access of [semantics]. |
1972 ResolutionResult handleDynamicAccessSemantics( | 2013 ResolutionResult handleDynamicAccessSemantics( |
1973 Send node, Name name, AccessSemantics semantics) { | 2014 Send node, Name name, AccessSemantics semantics) { |
1974 SendStructure sendStructure; | 2015 SendStructure sendStructure; |
1975 Selector selector; | 2016 Selector selector; |
1976 if (node.isCall) { | 2017 if (node.isCall) { |
1977 CallStructure callStructure = | 2018 CallStructure callStructure = |
1978 resolveArguments(node.argumentsNode).callStructure; | 2019 resolveArguments(node.argumentsNode).callStructure; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2038 if (checkThisAccess(node)) { | 2079 if (checkThisAccess(node)) { |
2039 return handleThisPropertyAccess(node, name); | 2080 return handleThisPropertyAccess(node, name); |
2040 } | 2081 } |
2041 // TODO(johnniwinther): Handle invalid this access as an | 2082 // TODO(johnniwinther): Handle invalid this access as an |
2042 // [AccessSemantics]. | 2083 // [AccessSemantics]. |
2043 return const NoneResult(); | 2084 return const NoneResult(); |
2044 } else if (node.isConditional) { | 2085 } else if (node.isConditional) { |
2045 return handleConditionalAccess(node, name); | 2086 return handleConditionalAccess(node, name); |
2046 } | 2087 } |
2047 ResolutionResult result = visitExpressionPrefix(node.receiver); | 2088 ResolutionResult result = visitExpressionPrefix(node.receiver); |
2048 if (result.element != null) { | 2089 if (result.kind == ResultKind.PREFIX) { |
2049 return handleResolvedQualifiedSend(node, name, result.element); | 2090 return handlePrefixSend(node, name, result); |
2050 } else { | 2091 } else { |
2092 // TODO(johnniwinther): Use the `element` of [result]. | |
2051 return handleDynamicPropertyAccess(node, name); | 2093 return handleDynamicPropertyAccess(node, name); |
2052 } | 2094 } |
2053 } | 2095 } |
2054 | 2096 |
2055 /// Handle access unresolved access to [name] in a non-instance context. | 2097 /// Handle access unresolved access to [name] in a non-instance context. |
2056 ResolutionResult handleUnresolvedAccess( | 2098 ResolutionResult handleUnresolvedAccess( |
2057 Send node, Name name, Element element) { | 2099 Send node, Name name, Element element) { |
2058 // TODO(johnniwinther): Support unresolved top level access as an | 2100 // TODO(johnniwinther): Support unresolved top level access as an |
2059 // [AccessSemantics]. | 2101 // [AccessSemantics]. |
2060 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); | 2102 AccessSemantics accessSemantics = new StaticAccess.unresolved(element); |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2441 return handleOperatorSend(node); | 2483 return handleOperatorSend(node); |
2442 } else if (node.receiver != null) { | 2484 } else if (node.receiver != null) { |
2443 // `a.b`. | 2485 // `a.b`. |
2444 return handleQualifiedSend(node); | 2486 return handleQualifiedSend(node); |
2445 } else { | 2487 } else { |
2446 // `a`. | 2488 // `a`. |
2447 return handleUnqualifiedSend(node); | 2489 return handleUnqualifiedSend(node); |
2448 } | 2490 } |
2449 } | 2491 } |
2450 | 2492 |
2451 /// Regigster read access of [target] inside a closure. | 2493 /// Register read access of [target] inside a closure. |
2452 void registerPotentialAccessInClosure(Send node, Element target) { | 2494 void registerPotentialAccessInClosure(Send node, Element target) { |
2453 if (isPotentiallyMutableTarget(target)) { | 2495 if (isPotentiallyMutableTarget(target)) { |
2454 if (enclosingElement != target.enclosingElement) { | 2496 if (enclosingElement != target.enclosingElement) { |
2455 for (Node scope in promotionScope) { | 2497 for (Node scope in promotionScope) { |
2456 registry.setAccessedByClosureIn(scope, target, node); | 2498 registry.setAccessedByClosureIn(scope, target, node); |
2457 } | 2499 } |
2458 } | 2500 } |
2459 } | 2501 } |
2460 } | 2502 } |
2461 | 2503 |
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3775 } | 3817 } |
3776 return const NoneResult(); | 3818 return const NoneResult(); |
3777 } | 3819 } |
3778 } | 3820 } |
3779 | 3821 |
3780 /// Looks up [name] in [scope] and unwraps the result. | 3822 /// Looks up [name] in [scope] and unwraps the result. |
3781 Element lookupInScope(Compiler compiler, Node node, | 3823 Element lookupInScope(Compiler compiler, Node node, |
3782 Scope scope, String name) { | 3824 Scope scope, String name) { |
3783 return Elements.unwrap(scope.lookup(name), compiler, node); | 3825 return Elements.unwrap(scope.lookup(name), compiler, node); |
3784 } | 3826 } |
OLD | NEW |