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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/resolution/members.dart
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 96961f3d213ceb3e8fb10c8b5a040cf6468dc1dc..ea44ed2ca41fcd3f3e2761ab40d116fec0303f8c 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -327,7 +327,16 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
ClassElement classElement = element;
classElement.ensureResolved(compiler);
}
- return new ElementResult(registry.useElement(node, element));
+ if (element != null) {
+ registry.useElement(node, element);
+ if (element.isPrefix) {
+ return new PrefixResult(element, null);
+ } else if (element.isClass && sendIsMemberAccess) {
+ return new PrefixResult(null, element);
+ }
+ return new ElementResult(element);
+ }
+ return const NoneResult();
}
}
@@ -1638,7 +1647,6 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
message: "Unexpected unary operator '${operator}'."));
return handleUserDefinableUnary(node, operator);
}
- return handleUserDefinableUnary(node, operator);
}
} else {
BinaryOperator operator = BinaryOperator.parse(operatorText);
@@ -1907,29 +1915,60 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
cls.ensureResolved(compiler);
if (sendIsMemberAccess) {
registry.useElement(node, cls);
- return new ElementResult(cls);
+ return new PrefixResult(null, cls);
} else {
// `C` or `C()` where 'C' is a class.
return handleClassTypeLiteralAccess(node, name, cls);
}
}
+ /// Compute a [DeferredPrefixStructure] for [node].
+ ResolutionResult handleDeferredAccess(
+ Send node,
+ PrefixElement prefix,
+ ResolutionResult result) {
+ assert(invariant(node, prefix.isDeferred,
+ message: "Prefix $prefix is not deferred."));
+ SendStructure sendStructure = registry.getSendStructure(node);
+ assert(invariant(node, sendStructure != null,
+ message: "No SendStructure for $node."));
+ registry.registerSendStructure(node,
+ new DeferredPrefixStructure(prefix, sendStructure));
+ if (result.isConstant) {
+ ConstantExpression constant =
+ new DeferredConstantExpression(result.constant, prefix);
+ registry.setConstant(node, constant);
+ result = new ConstantResult(node, constant);
+ }
+ return result;
+ }
+
/// Handle qualified [Send] where the receiver resolves to a [prefix],
/// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where
/// `prefix` is a library prefix.
ResolutionResult handleLibraryPrefixSend(
Send node, PrefixElement prefix, Name name) {
+ ResolutionResult result;
Element member = prefix.lookupLocalMember(name.text);
if (member == null) {
registry.registerThrowNoSuchMethod();
Element error = reportAndCreateErroneousElement(
node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER,
{'libraryName': prefix.name, 'memberName': name});
- registry.useElement(node, error);
- return new ElementResult(error);
+ result = handleUnresolvedAccess(node, name, error);
} else {
- return handleResolvedSend(node, name, member);
+ result = handleResolvedSend(node, name, member);
+ }
+ if (result.kind == ResultKind.PREFIX) {
+ // [member] is a class prefix of a static access like `prefix.Class` of
+ // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will
+ // called on the parent `prefix.Class.foo` node.
+ result = new PrefixResult(prefix, result.element);
+ } else if (prefix.isDeferred &&
+ (member == null || !member.isDeferredLoaderGetter)) {
+ result = handleDeferredAccess(node, prefix, result);
}
+ return result;
}
/// Handle a [Send] that resolves to a [prefix]. Like `prefix` in
@@ -1952,20 +1991,24 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
registry.useElement(node.selector, prefix);
}
registry.useElement(node, prefix);
- return new ElementResult(prefix);
+ return new PrefixResult(prefix, null);
}
/// Handle qualified [Send] where the receiver resolves to an [Element], like
- /// `a.b` where `a` is a local, field, class, or prefix, etc.
- ResolutionResult handleResolvedQualifiedSend(
- Send node, Name name, Element element) {
+ /// `a.b` where `a` is a prefix or a class.
+ ResolutionResult handlePrefixSend(
+ Send node, Name name, PrefixResult prefixResult) {
+ Element element = prefixResult.element;
if (element.isPrefix) {
return handleLibraryPrefixSend(node, element, name);
- } else if (element.isClass) {
- return handleStaticMemberAccess(node, name, element);
+ } else {
+ assert(element.isClass);
+ ResolutionResult result = handleStaticMemberAccess(node, name, element);
+ if (prefixResult.isDeferred) {
+ result = handleDeferredAccess(node, prefixResult.prefix, result);
+ }
+ return result;
}
- // TODO(johnniwinther): Use the [element].
- return handleDynamicPropertyAccess(node, name);
}
/// Handle dynamic access of [semantics].
@@ -2045,9 +2088,10 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
return handleConditionalAccess(node, name);
}
ResolutionResult result = visitExpressionPrefix(node.receiver);
- if (result.element != null) {
- return handleResolvedQualifiedSend(node, name, result.element);
+ if (result.kind == ResultKind.PREFIX) {
+ return handlePrefixSend(node, name, result);
} else {
+ // TODO(johnniwinther): Use the `element` of [result].
return handleDynamicPropertyAccess(node, name);
}
}
@@ -2448,7 +2492,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
}
}
- /// Regigster read access of [target] inside a closure.
+ /// Register read access of [target] inside a closure.
void registerPotentialAccessInClosure(Send node, Element target) {
if (isPotentiallyMutableTarget(target)) {
if (enclosingElement != target.enclosingElement) {
« 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