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

Unified Diff: runtime/vm/parser.cc

Issue 11299020: Make creation of list literal more resilient to changes in the underlying (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 14985)
+++ runtime/vm/parser.cc (working copy)
@@ -1358,7 +1358,7 @@
arguments->Add(new LiteralNode(args_pos, function_name));
// The second argument is an array containing the original function arguments.
ArrayNode* args_array = new ArrayNode(
- args_pos, Type::ZoneHandle(Type::ListInterface()));
+ args_pos, Type::ZoneHandle(Type::ArrayType()));
for (intptr_t i = 1; i < function_args.length(); i++) {
args_array->AddElement(function_args.NodeAt(i));
}
@@ -8707,10 +8707,10 @@
}
}
ASSERT(type_arguments.IsNull() || (type_arguments.Length() == 1));
- const Class& list_class = Class::Handle(
- Type::Handle(Type::ListInterface()).type_class());
+ const Class& array_class = Class::Handle(
+ Type::Handle(Type::ArrayType()).type_class());
siva 2012/11/16 02:24:50 Why not just do const Class& array_class = Class::
regis 2012/11/20 19:37:33 The ListClass helper would be the wrong one here,
Type& type = Type::ZoneHandle(
- Type::New(list_class, type_arguments, type_pos));
+ Type::New(array_class, type_arguments, type_pos));
type ^= ClassFinalizer::FinalizeType(
current_class(), type, ClassFinalizer::kCanonicalize);
ArrayNode* list = new ArrayNode(TokenPos(), type);
@@ -8776,27 +8776,42 @@
return new LiteralNode(literal_pos, const_list);
} else {
// Factory call at runtime.
- String& list_class_name = String::Handle(Symbols::ListImplementation());
- const Class& list_class = Class::Handle(LookupCoreClass(list_class_name));
- ASSERT(!list_class.IsNull());
- const String& list_literal_factory_name =
+ // TODO(regis): Once _ListImpl is removed, use Symbols::List() instead of
+ // Symbols::ListImplementation() on the following line.
+ String& factory_class_name = String::Handle(Symbols::ListImplementation());
+ const Class& factory_class =
+ Class::Handle(LookupCoreClass(factory_class_name));
+ ASSERT(!factory_class.IsNull());
+ const String& factory_method_name =
String::Handle(Symbols::ListLiteralFactory());
- const Function& list_literal_factory = Function::ZoneHandle(
- list_class.LookupFactory(list_literal_factory_name));
- ASSERT(!list_literal_factory.IsNull());
+ const Function& factory_method = Function::ZoneHandle(
+ factory_class.LookupFactory(factory_method_name));
+ ASSERT(!factory_method.IsNull());
if (!type_arguments.IsNull() &&
!type_arguments.IsInstantiated() &&
(current_block_->scope->function_level() > 0)) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
+ AbstractTypeArguments& factory_type_args =
+ AbstractTypeArguments::ZoneHandle(type_arguments.raw());
+ // If the factory class extends other parameterized classes, adjust the
+ // type argument vector.
+ if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) {
+ ASSERT(factory_type_args.Length() == 1);
+ Type& factory_type = Type::Handle(Type::New(
+ factory_class, factory_type_args, type_pos, Heap::kNew));
+ factory_type ^= ClassFinalizer::FinalizeType(
+ current_class(), factory_type, ClassFinalizer::kFinalize);
+ factory_type_args = factory_type.arguments();
+ ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments());
+ }
+ factory_type_args = factory_type_args.Canonicalize();
ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
factory_param->Add(list);
- AbstractTypeArguments& canonical_type_arguments =
- AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize());
return CreateConstructorCallNode(literal_pos,
- canonical_type_arguments,
- list_literal_factory,
+ factory_type_args,
+ factory_method,
factory_param);
}
}
@@ -8897,8 +8912,8 @@
// The kv_pair array is temporary and of element type dynamic. It is passed
// to the factory to initialize a properly typed map.
- ArrayNode* kv_pairs =
- new ArrayNode(TokenPos(), Type::ZoneHandle(Type::ListInterface()));
+ ArrayNode* kv_pairs = new ArrayNode(
+ TokenPos(), Type::ZoneHandle(Type::ArrayType()));
// Parse the map entries. Note: there may be an optional extra
// comma after the last entry.
@@ -8978,6 +8993,9 @@
const Class& immutable_map_class =
Class::Handle(LookupCoreClass(immutable_map_class_name));
ASSERT(!immutable_map_class.IsNull());
+ // If the immutable map class extends other parameterized classes, we need
+ // to adjust the type argument vector. This is currently not the case.
+ ASSERT(immutable_map_class.NumTypeArguments() == 2);
ArgumentListNode* constr_args = new ArgumentListNode(TokenPos());
constr_args->Add(new LiteralNode(literal_pos, key_value_array));
const String& constr_name =
@@ -8999,25 +9017,40 @@
}
} else {
// Factory call at runtime.
- String& map_class_name = String::Handle(Symbols::MapImplementation());
- const Class& map_class = Class::Handle(LookupCoreClass(map_class_name));
- ASSERT(!map_class.IsNull());
- const String& map_literal_factory_name =
+ String& factory_class_name = String::Handle(Symbols::MapImplementation());
+ const Class& factory_class =
+ Class::Handle(LookupCoreClass(factory_class_name));
+ ASSERT(!factory_class.IsNull());
+ const String& factory_method_name =
String::Handle(Symbols::MapLiteralFactory());
- const Function& map_literal_factory = Function::ZoneHandle(
- map_class.LookupFactory(map_literal_factory_name));
- ASSERT(!map_literal_factory.IsNull());
+ const Function& factory_method = Function::ZoneHandle(
+ factory_class.LookupFactory(factory_method_name));
+ ASSERT(!factory_method.IsNull());
if (!map_type_arguments.IsNull() &&
!map_type_arguments.IsInstantiated() &&
(current_block_->scope->function_level() > 0)) {
// Make sure that the instantiator is captured.
CaptureInstantiator();
}
+ AbstractTypeArguments& factory_type_args =
+ AbstractTypeArguments::ZoneHandle(map_type_arguments.raw());
+ // If the factory class extends other parameterized classes, adjust the
+ // type argument vector.
+ if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) {
+ ASSERT(factory_type_args.Length() == 2);
+ Type& factory_type = Type::Handle(Type::New(
+ factory_class, factory_type_args, type_pos, Heap::kNew));
+ factory_type ^= ClassFinalizer::FinalizeType(
+ current_class(), factory_type, ClassFinalizer::kFinalize);
+ factory_type_args = factory_type.arguments();
+ ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments());
+ }
+ factory_type_args = factory_type_args.Canonicalize();
ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
factory_param->Add(kv_pairs);
return CreateConstructorCallNode(literal_pos,
- map_type_arguments,
- map_literal_factory,
+ factory_type_args,
+ factory_method,
factory_param);
}
}
@@ -9469,8 +9502,8 @@
}
// String interpolation needed.
bool is_compiletime_const = true;
- ArrayNode* values = new ArrayNode(TokenPos(),
- Type::ZoneHandle(Type::ListInterface()));
+ ArrayNode* values = new ArrayNode(
+ TokenPos(), Type::ZoneHandle(Type::ArrayType()));
while (CurrentToken() == Token::kSTRING) {
values->AddElement(new LiteralNode(TokenPos(), *CurrentLiteral()));
ConsumeToken();
@@ -9548,7 +9581,7 @@
saved_args_desc_var =
new LocalVariable(owner_function.token_pos(),
saved_args_desc_name,
- Type::ZoneHandle(Type::ListInterface()));
+ Type::ZoneHandle(Type::ArrayType()));
saved_args_desc_var->set_is_final();
// The saved arguments descriptor variable must be added just after the
// formal parameters. This simplifies the 2-step saving of a captured

Powered by Google App Engine
This is Rietveld 408576698