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

Unified Diff: runtime/vm/parser.cc

Issue 8921033: Implement revised factories in the VM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 2391)
+++ runtime/vm/parser.cc (working copy)
@@ -31,9 +31,10 @@
static const char* kAssertionErrorName = "AssertionError";
static const char* kFallThroughErrorName = "FallThroughError";
static const char* kThrowNewName = "_throwNew";
-static const char* kLiteralFactoryClassName = "_LiteralFactory";
-static const char* kLiteralFactoryListFromLiteralName = "List.fromLiteral";
-static const char* kLiteralFactoryMapFromLiteralName = "Map.fromLiteral";
+static const char* kListLiteralFactoryClassName = "_ListLiteralFactory";
+static const char* kListLiteralFactoryName = "List.fromLiteral";
+static const char* kMapLiteralFactoryClassName = "_MapLiteralFactory";
+static const char* kMapLiteralFactoryName = "Map.fromLiteral";
static const char* kImmutableMapName = "ImmutableMap";
static const char* kImmutableMapConstructorName = "ImmutableMap._create";
static const char* kStringClassName = "StringBase";
@@ -566,7 +567,6 @@
case RawFunction::kGetterFunction:
case RawFunction::kSetterFunction:
case RawFunction::kConstructor:
- ASSERT(!func.IsFactory() || (func.signature_class() != Class::null()));
node_sequence = parser.ParseFunc(func, default_parameter_values);
break;
case RawFunction::kImplicitGetter:
@@ -2326,9 +2326,6 @@
member.name = CurrentLiteral();
member.name_pos = this->token_index_;
ConsumeToken();
- // Resolution of the factory result type is always postponed until class
- // finalization, so that the list of type parameters in the factory
- // signature can be checked at the same time.
if (member.has_factory) {
String& qualifier = String::Handle();
if (CurrentToken() == Token::kPERIOD) {
@@ -2341,6 +2338,9 @@
member.name = ExpectIdentifier("identifier expected");
}
}
+ // TODO(regis): Remove support for type parameters on factories.
+ // Once done, stop postponing resolution of the factory result type until
+ // class finalization.
const UnresolvedClass& unresolved_factory_class =
UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos,
qualifier,
@@ -2356,6 +2356,13 @@
member.type = &Type::ZoneHandle(
Type::NewParameterizedType(unresolved_factory_class, args));
ParseTypeParameters(signature_class);
+ if (signature_class.NumTypeParameters() > 0) {
+ Warning("factory method '%s' should not declare type parameters.\n",
+ member.name->ToCString());
+ } else {
+ // Remove factory signature class, since no type parameters declared.
+ unresolved_factory_class.set_factory_signature_class(Class::Handle());
+ }
}
// We must be dealing with a constructor or named constructor.
member.kind = RawFunction::kConstructor;
@@ -2746,7 +2753,12 @@
AddInterfaces(interfaces_pos, interface, interfaces);
}
- if (CurrentToken() == Token::kFACTORY) {
+ // TODO(regis): Remove support for "factory" keyword.
+ if ((CurrentToken() == Token::kDEFAULT) ||
+ (CurrentToken() == Token::kFACTORY)) {
+ if (CurrentToken() == Token::kFACTORY) {
+ Warning("'factory' is obsolete, use 'default' instead.");
+ }
ConsumeToken();
const intptr_t factory_pos = token_index_;
QualIdent factory_name;
@@ -2762,14 +2774,53 @@
}
const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle(
UnresolvedClass::New(factory_pos, qualifier, *(factory_name.ident)));
- const Class& signature_class = Class::Handle(
+ const Class& factory_class = Class::Handle(
Class::New(String::Handle(String::NewSymbol(":factory_signature")),
script_));
- signature_class.set_library(library_);
- signature_class.set_is_finalized();
- ParseTypeParameters(signature_class);
- unresolved_factory_class.set_factory_signature_class(signature_class);
+ factory_class.set_library(library_);
+ factory_class.set_is_finalized();
+ ParseTypeParameters(factory_class);
+ unresolved_factory_class.set_factory_signature_class(factory_class);
interface.set_factory_class(unresolved_factory_class);
+ // Verify that the type parameters of the factory class and of the interface
+ // have identical names.
+ const intptr_t num_type_params = factory_class.NumTypeParameters();
+ bool mismatch = interface.NumTypeParameters() != num_type_params;
+ if (mismatch && (num_type_params == 0)) {
+ // TODO(regis): For now, and until the core lib is fixed, we accept a
+ // factory clause with a class missing its list of type parameters.
+ // See bug 5408808.
+ const String& interface_name = String::Handle(interface.Name());
+ const String& factory_name = String::Handle(factory_class.Name());
+ Warning(factory_pos,
+ "class '%s' in default clause of interface '%s' is "
+ "missing its type parameter list.\n",
+ factory_name.ToCString(),
+ interface_name.ToCString());
+ } else {
+ String& interface_type_param_name = String::Handle();
+ String& factory_type_param_name = String::Handle();
+ const Array& interface_type_param_names =
+ Array::Handle(interface.type_parameters());
+ const Array& factory_type_param_names =
+ Array::Handle(factory_class.type_parameters());
+ for (intptr_t i = 0; !mismatch && (i < num_type_params); i++) {
+ interface_type_param_name ^= interface_type_param_names.At(i);
+ factory_type_param_name ^= factory_type_param_names.At(i);
+ if (!interface_type_param_name.Equals(factory_type_param_name)) {
+ mismatch = true;
+ }
+ }
+ if (mismatch) {
+ const String& interface_name = String::Handle(interface.Name());
+ const String& factory_name = String::Handle(factory_class.Name());
+ ErrorMsg(factory_pos,
+ "mismatch in number or names of type parameters between "
+ "interface '%s' and default factory class '%s'.\n",
+ interface_name.ToCString(),
+ factory_name.ToCString());
+ }
+ }
}
ExpectToken(Token::kLBRACE);
@@ -6162,20 +6213,12 @@
ASSERT(!factory_result_type.IsNull());
const UnresolvedClass& unresolved_factory_class =
UnresolvedClass::Handle(factory_result_type.unresolved_class());
- // TODO(regis): For now, and until the core lib is fixed, we accept a
- // factory method with missing list of type parameters and use the
- // list of the enclosing class.
- // See bug 5408808.
- // Therefore, we temporarily return the current class instead of the
- // factory signature class if the latter one does not declare any type
- // parameters.
- const Class& factory_signature_class =
- Class::Handle(unresolved_factory_class.factory_signature_class());
- if (factory_signature_class.NumTypeParameters() == 0) {
- return current_class().raw();
- } else {
- return factory_signature_class.raw();
+ // TODO(regis): Remove support for type parameters declared by factory
+ // methods.
+ if (unresolved_factory_class.factory_signature_class() != Class::null()) {
+ return unresolved_factory_class.factory_signature_class();
}
+ return current_class().raw();
}
if ((current_member_ == NULL) || !current_member_->has_static) {
return current_class().raw();
@@ -6187,7 +6230,12 @@
outer_function = outer_function.parent_function();
}
if (outer_function.IsFactory()) {
- return outer_function.signature_class();
+ // TODO(regis): Remove support for type parameters declared by factory
+ // methods.
+ if (outer_function.signature_class() != Class::null()) {
+ return outer_function.signature_class();
+ }
+ return current_class().raw();
}
if (!outer_function.is_static()) {
return current_class().raw();
@@ -6205,8 +6253,11 @@
outer_function = outer_function.parent_function();
}
if (outer_function.IsFactory()) {
- const Class& signature_class =
- Class::Handle(outer_function.signature_class());
+ // TODO(regis): Remove support for type parameters on factories.
+ Class& signature_class = Class::Handle(outer_function.signature_class());
+ if (signature_class.IsNull()) {
+ return current_class().NumTypeParameters() > 0;
+ }
return signature_class.NumTypeParameters() > 0;
}
if (!outer_function.is_static()) {
@@ -6619,8 +6670,10 @@
intptr_t pos, Function& constructor,
const AbstractTypeArguments& type_arguments) {
if (!type_arguments.IsNull()) {
+ // TODO(regis): Remove support for type parameters on factories.
Class& signature_class = Class::Handle();
- if (constructor.IsFactory()) {
+ if (constructor.IsFactory() &&
+ (constructor.signature_class() != Class::null())) {
signature_class = constructor.signature_class();
} else {
signature_class = constructor.owner();
@@ -6735,16 +6788,16 @@
return new LiteralNode(literal_pos, const_list);
} else {
// Factory call at runtime.
- String& literal_factory_class_name = String::Handle(
- String::NewSymbol(kLiteralFactoryClassName));
- const Class& literal_factory_class =
- Class::Handle(LookupCoreClass(literal_factory_class_name));
- ASSERT(!literal_factory_class.IsNull());
- const String& literal_list_factory_name =
- String::Handle(String::NewSymbol(kLiteralFactoryListFromLiteralName));
- const Function& literal_list_factory = Function::ZoneHandle(
- literal_factory_class.LookupFactory(literal_list_factory_name));
- ASSERT(!literal_list_factory.IsNull());
+ String& list_literal_factory_class_name = String::Handle(
+ String::NewSymbol(kListLiteralFactoryClassName));
+ const Class& list_literal_factory_class =
+ Class::Handle(LookupCoreClass(list_literal_factory_class_name));
+ ASSERT(!list_literal_factory_class.IsNull());
+ const String& list_literal_factory_name =
+ String::Handle(String::NewSymbol(kListLiteralFactoryName));
+ const Function& list_literal_factory = Function::ZoneHandle(
+ list_literal_factory_class.LookupFactory(list_literal_factory_name));
+ ASSERT(!list_literal_factory.IsNull());
if (!type_arguments.IsNull() &&
!type_arguments.IsInstantiated() &&
(current_block_->scope->function_level() > 0)) {
@@ -6757,7 +6810,7 @@
AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize());
return new ConstructorCallNode(literal_pos,
canonical_type_arguments,
- literal_list_factory,
+ list_literal_factory,
factory_param);
}
}
@@ -6938,16 +6991,16 @@
}
} else {
// Factory call at runtime.
- String& literal_factory_class_name = String::Handle(
- String::NewSymbol(kLiteralFactoryClassName));
- const Class& literal_factory_class =
- Class::Handle(LookupCoreClass(literal_factory_class_name));
- ASSERT(!literal_factory_class.IsNull());
- const String& literal_map_factory_name =
- String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName));
- const Function& literal_map_factory = Function::ZoneHandle(
- literal_factory_class.LookupFactory(literal_map_factory_name));
- ASSERT(!literal_map_factory.IsNull());
+ String& map_literal_factory_class_name = String::Handle(
+ String::NewSymbol(kMapLiteralFactoryClassName));
+ const Class& map_literal_factory_class =
+ Class::Handle(LookupCoreClass(map_literal_factory_class_name));
+ ASSERT(!map_literal_factory_class.IsNull());
+ const String& map_literal_factory_name =
+ String::Handle(String::NewSymbol(kMapLiteralFactoryName));
+ const Function& map_literal_factory = Function::ZoneHandle(
+ map_literal_factory_class.LookupFactory(map_literal_factory_name));
+ ASSERT(!map_literal_factory.IsNull());
if (!map_type_arguments.IsNull() &&
!map_type_arguments.IsInstantiated() &&
(current_block_->scope->function_level() > 0)) {
@@ -6958,7 +7011,7 @@
factory_param->Add(kv_pairs);
return new ConstructorCallNode(literal_pos,
map_type_arguments,
- literal_map_factory,
+ map_literal_factory,
factory_param);
}
}
@@ -7146,8 +7199,10 @@
// Now that the constructor to be called is identified, finalize the type
// argument vector to be passed.
{
+ // TODO(regis): Remove support for type parameters on factories.
Class& signature_class = Class::Handle();
- if (constructor.IsFactory()) {
+ if (constructor.IsFactory() &&
+ (constructor.signature_class() != Class::null())) {
signature_class = constructor.signature_class();
} else {
signature_class = constructor.owner();

Powered by Google App Engine
This is Rietveld 408576698