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

Unified Diff: pkg/compiler/lib/src/resolution/constructors.dart

Issue 1437463005: Compute NewStructure in resolution. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 1 month 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/resolution/access_semantics.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/resolution/constructors.dart
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 722d39f4eb4fa730292041468ab383991fa14c13..26e7b48b21e7c040fda020998fcc0a23b922233a 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -503,10 +503,11 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
if (type == null) {
type = new MalformedType(error, null);
}
- return new ConstructorResult(resultKind, error, type);
+ return new ConstructorResult.forError(resultKind, error, type);
}
ConstructorResult resolveConstructor(
+ PrefixElement prefix,
InterfaceType type,
Node diagnosticNode,
String constructorName) {
@@ -528,24 +529,33 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
reporter.reportErrorMessage(
diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
return new ConstructorResult(
- ConstructorResultKind.NON_CONSTANT, constructor, type);
+ ConstructorResultKind.NON_CONSTANT, prefix, constructor, type);
} else {
+ if (cls.isEnumClass && resolver.currentClass != cls) {
+ return reportAndCreateErroneousConstructorElement(
+ diagnosticNode,
+ ConstructorResultKind.INVALID_TYPE, type,
+ cls, constructorName,
+ MessageKind.CANNOT_INSTANTIATE_ENUM,
+ {'enumName': cls.name},
+ isError: true);
+ }
if (constructor.isGenerativeConstructor) {
if (cls.isAbstract) {
reporter.reportWarningMessage(
diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
return new ConstructorResult(
- ConstructorResultKind.ABSTRACT, constructor, type);
+ ConstructorResultKind.ABSTRACT, prefix, constructor, type);
} else {
return new ConstructorResult(
- ConstructorResultKind.GENERATIVE, constructor, type);
+ ConstructorResultKind.GENERATIVE, prefix, constructor, type);
}
} else {
assert(invariant(diagnosticNode, constructor.isFactoryConstructor,
message: "Unexpected constructor $constructor."));
return new ConstructorResult(
- ConstructorResultKind.FACTORY, constructor, type);
+ ConstructorResultKind.FACTORY, prefix, constructor, type);
}
}
}
@@ -576,7 +586,8 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
// class.
if (result.type != null) {
// The unnamed constructor may not exist, so [e] may become unresolved.
- result = resolveConstructor(result.type, diagnosticNode, '');
+ result = resolveConstructor(
+ result.prefix, result.type, diagnosticNode, '');
} else {
Element element = result.element;
if (element.isMalformed) {
@@ -600,7 +611,18 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
node,
malformedIsError: inConstContext,
deferredIsMalformed: false);
- return constructorResultForType(node, type);
+ Send send = node.typeName.asSend();
+ PrefixElement prefix;
+ if (send != null) {
+ // The type name is of the form [: prefix . identifier :].
+ String name = send.receiver.asIdentifier().source;
+ Element element = resolver.reportLookupErrorIfAny(
+ lookupInScope(reporter, send, resolver.scope, name), node, name);
+ if (element != null && element.isPrefix) {
+ prefix = element;
+ }
+ }
+ return constructorResultForType(node, type, prefix: prefix);
}
ConstructorResult visitSend(Send node) {
@@ -621,7 +643,8 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
if (receiver.type != null) {
if (receiver.type.isInterfaceType) {
- return resolveConstructor(receiver.type, name, name.source);
+ return resolveConstructor(
+ receiver.prefix, receiver.type, name, name.source);
} else {
// TODO(johnniwinther): Update the message for the different types.
return reportAndCreateErroneousConstructorElement(
@@ -633,7 +656,8 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
} else if (receiver.element.isPrefix) {
PrefixElement prefix = receiver.element;
Element member = prefix.lookupLocalMember(name.source);
- return constructorResultForElement(node, name.source, member);
+ return constructorResultForElement(
+ node, name.source, member, prefix: prefix);
} else {
return reporter.internalError(
node.receiver, 'unexpected receiver $receiver');
@@ -657,7 +681,8 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
}
ConstructorResult constructorResultForElement(
- Node node, String name, Element element) {
+ Node node, String name, Element element,
+ {PrefixElement prefix}) {
element = Elements.unwrap(element, reporter, node);
if (element == null) {
return reportAndCreateErroneousConstructorElement(
@@ -671,9 +696,9 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
} else if (element.isClass) {
ClassElement cls = element;
cls.computeType(resolution);
- return constructorResultForType(node, cls.rawType);
+ return constructorResultForType(node, cls.rawType, prefix: prefix);
} else if (element.isPrefix) {
- return new ConstructorResult.forElement(element);
+ return new ConstructorResult.forPrefix(element);
} else if (element.isTypedef) {
TypedefElement typdef = element;
typdef.ensureResolved(resolution);
@@ -699,7 +724,7 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
error.name, error);
registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
}
- return new ConstructorResult(
+ return new ConstructorResult.forError(
ConstructorResultKind.INVALID_TYPE,
error,
new MalformedType(error, null));
@@ -707,13 +732,14 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
ConstructorResult constructorResultForType(
Node node,
- DartType type) {
+ DartType type,
+ {PrefixElement prefix}) {
String name = type.name;
if (type.isMalformed) {
- return new ConstructorResult(
+ return new ConstructorResult.forError(
ConstructorResultKind.INVALID_TYPE, type.element, type);
} else if (type.isInterfaceType) {
- return new ConstructorResult.forType(type);
+ return new ConstructorResult.forType(prefix, type);
} else if (type.isTypedef) {
return reportAndCreateErroneousConstructorElement(
node,
@@ -733,40 +759,88 @@ class ConstructorResolver extends CommonResolverVisitor<ConstructorResult> {
}
+/// The kind of constructor found by the [ConstructorResolver].
enum ConstructorResultKind {
+ /// A generative or redirecting generative constructor.
GENERATIVE,
+ /// A factory or redirecting factory constructor.
FACTORY,
+ /// A generative or redirecting generative constructor on an abstract class.
ABSTRACT,
+ /// No constructor was found because the type was invalid, for instance
+ /// unresolved, an enum class, a type variable, a typedef or a non-type.
INVALID_TYPE,
+ /// No constructor of the sought name was found on the class.
UNRESOLVED_CONSTRUCTOR,
+ /// A non-constant constructor was found for a const constructor invocation.
NON_CONSTANT,
}
+/// The (partial) result of the resolution of a new expression used in
+/// [ConstructorResolver].
class ConstructorResult {
+ /// The prefix used to access the constructor. For instance `prefix` in `new
+ /// prefix.Class.constructorName()`.
+ final PrefixElement prefix;
+
+ /// The kind of the found constructor.
final ConstructorResultKind kind;
+
+ /// The currently found element. Since [ConstructorResult] is used for partial
+ /// results, this might be a [PrefixElement], a [ClassElement], a
+ /// [ConstructorElement] or in the negative cases an [ErroneousElement].
final Element element;
- final DartType type;
- ConstructorResult(this.kind, this.element, this.type);
+ /// The type of the new expression. For instance `Foo<String>` in
+ /// `new prefix.Foo<String>.constructorName()`.
+ final DartType type;
- ConstructorResult.forElement(this.element)
- : kind = null,
+ /// Creates a fully resolved constructor access where [element] is resolved
+ /// to a constructor and [type] to an interface type.
+ ConstructorResult(this.kind,
+ this.prefix,
+ ConstructorElement this.element,
+ InterfaceType this.type);
+
+ /// Creates a fully resolved constructor access where [element] is an
+ /// [ErroneousElement].
+ // TODO(johnniwinther): Do we still need the prefix for cases like
+ // `new deferred.Class.unresolvedConstructor()` ?
+ ConstructorResult.forError(
+ this.kind, ErroneousElement this.element, this.type)
+ : prefix = null;
+
+ /// Creates a constructor access that is partially resolved to a prefix. For
+ /// instance `prefix` of `new prefix.Class()`.
+ ConstructorResult.forPrefix(this.element)
+ : prefix = null,
+ kind = null,
type = null;
- ConstructorResult.forType(this.type)
+ /// Creates a constructor access that is partially resolved to a type. For
+ /// instance `Foo<String>` of `new Foo<String>.constructorName()`.
+ ConstructorResult.forType(this.prefix, this.type)
: kind = null,
element = null;
+ bool get isDeferred => prefix != null && prefix.isDeferred;
+
String toString() {
StringBuffer sb = new StringBuffer();
sb.write('ConstructorResult(');
if (kind != null) {
sb.write('kind=$kind,');
+ if (prefix != null) {
+ sb.write('prefix=$prefix,');
+ }
sb.write('element=$element,');
sb.write('type=$type');
} else if (element != null) {
sb.write('element=$element');
} else {
+ if (prefix != null) {
+ sb.write('prefix=$prefix,');
+ }
sb.write('type=$type');
}
sb.write(')');
« no previous file with comments | « pkg/compiler/lib/src/resolution/access_semantics.dart ('k') | pkg/compiler/lib/src/resolution/members.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698