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

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: Another attempt at implementing private-aware constructor lookup logic - with normalized constructo… Created 8 years, 3 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 | « lib/compiler/implementation/elements/elements.dart ('k') | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/resolver.dart
diff --git a/lib/compiler/implementation/resolver.dart b/lib/compiler/implementation/resolver.dart
index 3de67b305322f456a1d5ef3c13fef8c238b0f5ca..b74185bcb304c73be4c5a3a6015543b898bf211f 100644
--- a/lib/compiler/implementation/resolver.dart
+++ b/lib/compiler/implementation/resolver.dart
@@ -85,12 +85,16 @@ class ResolverTask extends CompilerTask {
});
}
- SourceString getConstructorName(Send node) {
- if (node.receiver !== null) {
- return node.selector.asIdentifier().source;
- } else {
- return const SourceString('');
- }
+ bool isNamedConstructor(Send node) => node.receiver !== null;
+ SourceString getConstructorName(Send node) => node.selector.asIdentifier().source;
kasperl 2012/09/28 08:48:54 Line a bit too long.
+
+ String createConstructorFullName(SourceString className,
+ SourceString constructorName) {
+ String classNameString = className.slowToString();
+ String constructorNameString = constructorName.slowToString();
+ return (constructorName === const SourceString(''))
+ ? classNameString
kasperl 2012/09/28 08:48:54 4 space indent.
+ : "$classNameString.$constructorNameString";
}
FunctionElement resolveConstructorRedirection(FunctionElement constructor) {
@@ -102,10 +106,18 @@ 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,
+ constructor.getLibrary());
kasperl 2012/09/28 08:48:54 I'm still a bit worried about computing the librar
+ } else {
+ selector = new Selector.callDefaultConstructor(
+ classElement.name,
+ constructor.getLibrary());
+ }
+ return classElement.lookupConstructor(selector);
}
return null;
}
@@ -202,8 +214,9 @@ class ResolverTask extends CompilerTask {
} else {
name = constructor.name;
}
- constructor.defaultImplementation = defaultClass.lookupConstructor(name);
-
+ constructor.defaultImplementation = defaultClass.lookupConstructor(
+ new Selector.callDefaultConstructor(name,
+ defaultClass.getLibrary()));
if (constructor.defaultImplementation === null) {
// We failed to find a constructor named either
// "MyInterface.name" or "MyClass.name".
@@ -553,6 +566,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) {
@@ -564,12 +592,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,
@@ -580,55 +637,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]);
+ 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,
@@ -2647,17 +2707,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(
+ 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 == null || !result.modifiers.isConst())) {
error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
« no previous file with comments | « lib/compiler/implementation/elements/elements.dart ('k') | lib/compiler/implementation/ssa/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698