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

Unified Diff: dart/frog/leg/resolver.dart

Issue 9634008: Introduce element categories and move resolver towards being more compositional. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review comments Created 8 years, 9 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 | « dart/frog/leg/elements/elements.dart ('k') | dart/frog/leg/scanner/listener.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dart/frog/leg/resolver.dart
diff --git a/dart/frog/leg/resolver.dart b/dart/frog/leg/resolver.dart
index a8b08665d3ca52510867b1a58e04dd979d6af605..440db0f5471a320a88d045ef28f72a00c3e763cd 100644
--- a/dart/frog/leg/resolver.dart
+++ b/dart/frog/leg/resolver.dart
@@ -533,6 +533,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
ClassElement currentClass;
bool typeRequired = false;
StatementScope statementScope;
+ int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION;
ResolverVisitor(Compiler compiler, Element element)
: this.mapping = new TreeElementMapping(),
@@ -574,7 +575,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
inStaticContext(() => visit(node));
}
- visitIdentifier(Identifier node) {
+ Element visitIdentifier(Identifier node) {
if (node.isThis()) {
if (!inInstanceContext) {
error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]);
@@ -582,11 +583,19 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
return null;
} else if (node.isSuper()) {
if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC);
+ if ((ElementCategory.SUPER & allowedCategory) == 0) {
+ error(node, MessageKind.INVALID_USE_OF_SUPER);
+ }
return null;
} else {
Element element = lookup(node, node.source);
- if (element == null) {
- error(node, MessageKind.CANNOT_RESOLVE, [node]);
+ if (element === null) {
+ if (!inInstanceContext) error(node, MessageKind.CANNOT_RESOLVE, [node]);
+ } else {
+ if ((element.kind.category & allowedCategory) == 0) {
+ // TODO(ahe): Improve error message. Need UX input.
+ error(node, MessageKind.GENERIC, ["is not an expression $element"]);
+ }
}
return useElement(node, element);
}
@@ -611,7 +620,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
} else {
warning(node, MessageKind.CANNOT_RESOLVE_TYPE, [className]);
}
- } else if (!element.isClassOrInterfaceOrTypedef()) {
+ } else if (!element.impliesType()) {
if (typeRequired) {
error(node, MessageKind.NOT_A_TYPE, [className]);
} else {
@@ -742,7 +751,6 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
statementScope = oldScope;
context = context.parent;
- return enclosingElement;
}
visitIf(If node) {
@@ -757,53 +765,46 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
}
Element resolveSend(Send node) {
+ if (node.receiver === null || node.selector.isThis()) {
+ return node.selector.accept(this);
+ }
+ var oldCategory = allowedCategory;
+ allowedCategory |=
+ ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER;
Element resolvedReceiver = visit(node.receiver);
+ allowedCategory = oldCategory;
- Element target = null;
- if (node.selector.asIdentifier() === null) {
- // We are calling a closure returned from an expression.
- assert(node.selector.asExpression() !== null);
- assert(resolvedReceiver === null);
- visit(node.selector);
- } else {
- SourceString name = node.selector.asIdentifier().source;
- if (node.receiver === null) {
- target = lookup(node, name);
- if (target === null && !inInstanceContext) {
- error(node, MessageKind.CANNOT_RESOLVE, [name]);
- }
- } else if (node.isSuperCall) {
- if (currentClass !== null) {
- ClassElement superElement = currentClass.superclass;
- if (superElement !== null) {
- // TODO(ngeoffray): The lookup should continue on super
- // classes.
- target = superElement.lookupLocalMember(name);
- }
- if (target === null) {
- error(node,
- MessageKind.METHOD_NOT_FOUND,
- [superElement.name, name]);
- }
- }
- } else if (resolvedReceiver === null) {
+ Element target;
+ SourceString name = node.selector.asIdentifier().source;
+ if (node.isSuperCall) {
+ if (isUserDefinableOperator(name.stringValue)) {
+ name = Elements.constructOperatorName(const SourceString('operator'),
+ name);
+ }
+ if (!inInstanceContext) {
+ error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, [name]);
return null;
- } else if (resolvedReceiver.kind === ElementKind.CLASS) {
- ClassElement receiverClass = resolvedReceiver;
- target = receiverClass.resolve(compiler).lookupLocalMember(name);
- if (target === null) {
- error(node, MessageKind.METHOD_NOT_FOUND, [receiverClass.name, name]);
- } else if (target.isInstanceMember()) {
- error(node, MessageKind.MEMBER_NOT_STATIC,
- [receiverClass.name, name]);
- }
- } else if (resolvedReceiver.kind === ElementKind.PREFIX) {
- PrefixElement prefix = resolvedReceiver;
- target = prefix.library.lookupLocalMember(name);
- if (target == null) {
- error(node, MessageKind.NO_SUCH_LIBRARY_MEMBER,
- [resolvedReceiver.name, name]);
- }
+ }
+ target = currentClass.lookupSuperMember(name);
+ if (target === null) {
+ error(node.selector, MessageKind.METHOD_NOT_FOUND,
+ [currentClass.superclass.name, name]);
+ }
+ } else if (resolvedReceiver === null) {
+ return null;
+ } else if (resolvedReceiver.kind === ElementKind.CLASS) {
+ ClassElement receiverClass = resolvedReceiver;
+ target = receiverClass.resolve(compiler).lookupLocalMember(name);
+ if (target === null) {
+ error(node, MessageKind.METHOD_NOT_FOUND, [receiverClass.name, name]);
+ } else if (target.isInstanceMember()) {
+ error(node, MessageKind.MEMBER_NOT_STATIC, [receiverClass.name, name]);
+ }
+ } else if (resolvedReceiver.kind === ElementKind.PREFIX) {
+ PrefixElement prefix = resolvedReceiver;
+ target = prefix.lookupLocalMember(name);
+ if (target == null) {
+ error(node, MessageKind.NO_SUCH_LIBRARY_MEMBER, [prefix.name, name]);
}
}
return target;
@@ -864,7 +865,8 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
}
// TODO(ngeoffray): Warn if target is null and the send is
// unqualified.
- return useElement(node, target);
+ useElement(node, target);
+ if (node.isPropertyAccess) return target;
}
visitSendSet(SendSet node) {
@@ -1199,18 +1201,14 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> {
}
Type visitTypeAnnotation(TypeAnnotation node) {
- Identifier name = node.typeName.asIdentifier();
- if (name === null) {
- unimplemented(node.typeName, "prefixes");
- }
- return visit(name);
+ return visit(node.typeName);
}
Type visitIdentifier(Identifier node) {
Element element = context.lookup(node.source);
if (element === null) {
error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
- } else if (!element.isClassOrInterfaceOrTypedef()) {
+ } else if (!element.impliesType()) {
error(node, MessageKind.NOT_A_TYPE, [node]);
} else {
if (element.isClass()) {
@@ -1221,6 +1219,25 @@ class ClassResolverVisitor extends CommonResolverVisitor<Type> {
}
return null;
}
+
+ Type visitSend(Send node) {
+ Identifier prefix = node.receiver.asIdentifier();
+ if (prefix === null) {
+ error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+ return null;
+ }
+ Element element = context.lookup(prefix.source);
+ if (element === null || element.kind !== ElementKind.PREFIX) {
+ error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
+ return null;
+ }
+ var e = element.library.lookupLocalMember(node.selector.source);
+ if (e === null || !e.impliesType()) {
+ error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]);
+ return null;
+ }
+ return e.computeType(compiler);
+ }
}
class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> {
« no previous file with comments | « dart/frog/leg/elements/elements.dart ('k') | dart/frog/leg/scanner/listener.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698