Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: pkg/compiler/lib/src/resolution/members.dart

Issue 1238783003: Handle deferred access as pre-step in SemanticSendVisitor. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/inferrer_visitor.dart ('k') | pkg/compiler/lib/src/resolution/registry.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698