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

Unified Diff: lib/compiler/implementation/resolver.dart

Issue 10947024: Made dart2js constructor lookup logic "private"-aware, fixed 4740 bug. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use resolver.enclosingElement. Fixed line wrapping. Created 8 years, 2 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
Index: lib/compiler/implementation/resolver.dart
diff --git a/lib/compiler/implementation/resolver.dart b/lib/compiler/implementation/resolver.dart
index 2bcf0aeda550c15a30f896b1913537577a32ac93..6afee2c21dfa6493061f47df9956b1724c4092ba 100644
--- a/lib/compiler/implementation/resolver.dart
+++ b/lib/compiler/implementation/resolver.dart
@@ -87,15 +87,21 @@ class ResolverTask extends CompilerTask {
});
}
- SourceString getConstructorName(Send node) {
- if (node.receiver !== null) {
- return node.selector.asIdentifier().source;
- } else {
- return const SourceString('');
- }
- }
-
- FunctionElement resolveConstructorRedirection(FunctionElement constructor) {
+ bool isNamedConstructor(Send node) => node.receiver !== null;
+ SourceString getConstructorName(Send node) =>
+ node.selector.asIdentifier().source;
+
+ String createConstructorFullName(SourceString className,
+ SourceString constructorName) {
+ String classNameString = className.slowToString();
+ String constructorNameString = constructorName.slowToString();
+ return (constructorName === const SourceString(''))
+ ? classNameString
kasperl 2012/10/08 08:06:41 4 space indent of ? and :.
aam-me 2012/10/09 04:08:42 Done.
+ : "$classNameString.$constructorNameString";
+ }
+
+ FunctionElement resolveConstructorRedirection(InitializerResolver resolver,
+ FunctionElement constructor) {
if (constructor.isPatched) {
checkMatchingPatchSignatures(constructor, constructor.patch);
constructor = constructor.patch;
@@ -109,10 +115,19 @@ class ResolverTask extends CompilerTask {
if (!initializers.isEmpty() &&
Initializers.isConstructorRedirect(initializers.head)) {
final ClassElement classElement = constructor.getEnclosingClass();
- final SourceString constructorName =
- getConstructorName(initializers.head);
- final SourceString className = classElement.name;
- return classElement.lookupConstructor(className, constructorName);
+ Selector selector;
+ if (isNamedConstructor(initializers.head)) {
+ SourceString constructorName = getConstructorName(initializers.head);
+ selector = new Selector.callConstructor(
+ classElement.name,
+ constructorName,
+ resolver.visitor.enclosingElement.getLibrary());
+ } else {
+ selector = new Selector.callDefaultConstructor(
+ classElement.name,
+ resolver.visitor.enclosingElement.getLibrary());
+ }
+ return classElement.lookupConstructor(selector);
}
return null;
}
@@ -129,7 +144,7 @@ class ResolverTask extends CompilerTask {
return;
}
seen.add(redirection);
- redirection = resolveConstructorRedirection(redirection);
+ redirection = resolveConstructorRedirection(resolver, redirection);
}
}
@@ -220,8 +235,10 @@ class ResolverTask extends CompilerTask {
} else {
name = constructor.name;
}
- constructor.defaultImplementation = defaultClass.lookupConstructor(name);
+ constructor.defaultImplementation = defaultClass.lookupConstructor(
ahe 2012/10/08 08:25:43 Currently, lookupConstructor expects something lik
aam-me 2012/10/08 15:03:35 Peter, I see, but you can have multiple factor
ahe 2012/10/08 16:35:52 I'll send an email to Anton and see if he has time
aam-me 2012/10/09 04:08:42 Thanks, Peter. Further issues down the path of us
+ new Selector.callDefaultConstructor(name,
+ defaultClass.getLibrary()));
if (constructor.defaultImplementation === null) {
// We failed to find a constructor named either
// "MyInterface.name" or "MyClass.name".
@@ -597,6 +614,21 @@ class InitializerResolver {
visitor.visitInStaticContext(init.arguments.head);
}
+ ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
+ bool isSuperCall,
+ Node diagnosticNode) {
+ ClassElement lookupTarget = constructor.getEnclosingClass();
+ if (isSuperCall) {
+ // Calculate correct lookup target and constructor name.
+ if (lookupTarget === visitor.compiler.objectClass) {
+ error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
+ } else {
+ lookupTarget = lookupTarget.supertype.element;
+ }
+ }
+ return lookupTarget;
+ }
+
Element resolveSuperOrThisForSend(FunctionElement constructor,
FunctionExpression functionNode,
Send call) {
@@ -608,12 +640,41 @@ class InitializerResolver {
});
Selector selector = visitor.mapping.getSelector(call);
bool isSuperCall = Initializers.isSuperConstructorCall(call);
- SourceString constructorName = resolver.getConstructorName(call);
- Element result = resolveSuperOrThis(
- constructor, isSuperCall, false, constructorName, selector, call);
- visitor.useElement(call, result);
- visitor.world.registerStaticUse(result);
- return result;
+
+ ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
+ isSuperCall,
+ call);
+ final SourceString className = lookupTarget.name;
+
+ SourceString constructorName;
+ Selector lookupSelector;
+ if (resolver.isNamedConstructor(call)) {
+ constructorName = resolver.getConstructorName(call);
+ lookupSelector = new Selector.callConstructor(
+ className,
+ constructorName,
+ visitor.enclosingElement.getLibrary());
+ } else {
+ constructorName = const SourceString('');
+ lookupSelector = new Selector.callDefaultConstructor(
+ className,
+ visitor.enclosingElement.getLibrary());
+ }
+
+ FunctionElement lookedupConstructor =
+ lookupTarget.lookupConstructor(lookupSelector);
+
+ final bool isImplicitSuperCall = false;
+ verifyThatConstructorMatchesCall(lookedupConstructor,
+ selector,
+ isImplicitSuperCall,
+ call,
+ constructorName,
+ className);
+
+ visitor.useElement(call, lookedupConstructor);
+ visitor.world.registerStaticUse(lookedupConstructor);
+ return lookedupConstructor;
}
void resolveImplicitSuperConstructorSend(FunctionElement constructor,
@@ -624,55 +685,58 @@ class InitializerResolver {
if (classElement != visitor.compiler.objectClass) {
assert(superClass !== null);
assert(superClass.resolutionState == STATE_DONE);
- SourceString name = const SourceString('');
- Selector call = new Selector.call(name, classElement.getLibrary(), 0);
- var element = resolveSuperOrThis(constructor, true, true,
- name, call, functionNode);
- visitor.world.registerStaticUse(element);
- }
- }
-
- Element resolveSuperOrThis(FunctionElement constructor,
- bool isSuperCall,
- bool isImplicitSuperCall,
- SourceString constructorName,
- Selector selector,
- Node diagnosticNode) {
- ClassElement lookupTarget = constructor.getEnclosingClass();
- bool validTarget = true;
- FunctionElement result;
- if (isSuperCall) {
- // Calculate correct lookup target and constructor name.
- if (lookupTarget === visitor.compiler.objectClass) {
- error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
- } else {
- lookupTarget = lookupTarget.supertype.element;
- }
- }
-
- // Lookup constructor and try to match it to the selector.
- ResolverTask resolver = visitor.compiler.resolver;
- final SourceString className = lookupTarget.name;
- result = lookupTarget.lookupConstructor(className, constructorName);
- if (result === null || !result.isGenerativeConstructor()) {
- String classNameString = className.slowToString();
- String constructorNameString = constructorName.slowToString();
- String name = (constructorName === const SourceString(''))
- ? classNameString
- : "$classNameString.$constructorNameString";
+ SourceString constructorName = const SourceString('');
+ Selector callToMatch = new Selector.call(
+ constructorName,
+ classElement.getLibrary(),
+ 0);
+
+ final bool isSuperCall = true;
+ ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
+ isSuperCall,
+ functionNode);
+ final SourceString className = lookupTarget.name;
+ Element calledConstructor = lookupTarget.lookupConstructor(
+ new Selector.callDefaultConstructor(
+ className,
+ visitor.enclosingElement.getLibrary()));
+
+ final bool isImplicitSuperCall = true;
+ verifyThatConstructorMatchesCall(calledConstructor,
+ callToMatch,
+ isImplicitSuperCall,
+ functionNode,
+ className,
+ const SourceString(''));
+
+ visitor.world.registerStaticUse(calledConstructor);
+ }
+ }
+
+ void verifyThatConstructorMatchesCall(
+ FunctionElement lookedupConstructor,
+ Selector call,
+ bool isImplicitSuperCall,
+ Node diagnosticNode,
+ SourceString className,
+ SourceString constructorName) {
+ if (lookedupConstructor === null
+ || !lookedupConstructor.isGenerativeConstructor()) {
+ var fullConstructorName =
+ visitor.compiler.resolver.createConstructorFullName(className,
+ constructorName);
MessageKind kind = isImplicitSuperCall
- ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
- : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
- error(diagnosticNode, kind, [name]);
+ ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT
+ : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
+ error(diagnosticNode, kind, [fullConstructorName]);
} else {
- if (!selector.applies(result, visitor.compiler)) {
+ if (!call.applies(lookedupConstructor, visitor.compiler)) {
MessageKind kind = isImplicitSuperCall
? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
: MessageKind.NO_MATCHING_CONSTRUCTOR;
error(diagnosticNode, kind);
}
}
- return result;
}
FunctionElement resolveRedirection(FunctionElement constructor,
@@ -2717,17 +2781,26 @@ class ConstructorResolver extends CommonResolverVisitor<Element> {
Node diagnosticNode,
SourceString constructorName) {
cls.ensureResolved(compiler);
- Element result = cls.lookupConstructor(cls.name, constructorName);
+ Selector selector =
+ constructorName === const SourceString('')
+ ? new Selector.callDefaultConstructor(
kasperl 2012/10/08 08:06:41 4 space indent of ? and :.
aam-me 2012/10/09 04:08:42 Done.
+ cls.name,
+ resolver.enclosingElement.getLibrary())
+ : new Selector.callConstructor(cls.name,
+ constructorName,
+ resolver.enclosingElement.getLibrary());
+ Element result = cls.lookupConstructor(selector);
if (result === null) {
- String fullConstructorName = cls.name.slowToString();
- if (constructorName !== const SourceString('')) {
- fullConstructorName = '$fullConstructorName'
- '.${constructorName.slowToString()}';
- }
- return failOrReturnErroneousElement(cls, diagnosticNode,
- new SourceString(fullConstructorName),
- MessageKind.CANNOT_FIND_CONSTRUCTOR,
- [fullConstructorName]);
+ String fullConstructorName =
+ resolver.compiler.resolver.createConstructorFullName(
+ cls.name,
+ constructorName);
+ return failOrReturnErroneousElement(
+ cls,
+ diagnosticNode,
+ new SourceString(fullConstructorName),
+ MessageKind.CANNOT_FIND_CONSTRUCTOR,
+ [fullConstructorName]);
} else if (inConstContext && !result.modifiers.isConst()) {
error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
}

Powered by Google App Engine
This is Rietveld 408576698