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

Side by Side Diff: runtime/vm/parser.cc

Issue 8773026: Canonicalize TypeArguments. (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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/parser.h" 5 #include "vm/parser.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 Array& a = Array::Handle(Array::New(objs.length(), Heap::kOld)); 79 Array& a = Array::Handle(Array::New(objs.length(), Heap::kOld));
80 for (int i = 0; i < objs.length(); i++) { 80 for (int i = 0; i < objs.length(); i++) {
81 a.SetAt(i, *objs[i]); 81 a.SetAt(i, *objs[i]);
82 } 82 }
83 return a.raw(); 83 return a.raw();
84 } 84 }
85 85
86 86
87 static RawTypeArguments* NewTypeArguments( 87 static RawTypeArguments* NewTypeArguments(
88 const GrowableArray<AbstractType*>& objs) { 88 const GrowableArray<AbstractType*>& objs) {
89 TypeArguments& a = TypeArguments::Handle(TypeArguments::New(objs.length())); 89 const TypeArguments& a =
90 TypeArguments::Handle(TypeArguments::New(objs.length()));
90 for (int i = 0; i < objs.length(); i++) { 91 for (int i = 0; i < objs.length(); i++) {
91 a.SetTypeAt(i, *objs[i]); 92 a.SetTypeAt(i, *objs[i]);
92 } 93 }
94 // Cannot canonicalize TypeArgument yet as its types may not have been
95 // finalized yet.
93 return a.raw(); 96 return a.raw();
94 } 97 }
95 98
96 99
97 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, 100 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos,
98 const Instance& instance) { 101 const Instance& instance) {
99 UnhandledException& excp = UnhandledException::Handle(); 102 UnhandledException& excp = UnhandledException::Handle();
100 excp ^= instance.raw(); 103 excp ^= instance.raw();
101 const Instance& exception = Instance::ZoneHandle(excp.exception()); 104 const Instance& exception = Instance::ZoneHandle(excp.exception());
102 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace()); 105 const Instance& stack_trace = Instance::ZoneHandle(excp.stacktrace());
(...skipping 6628 matching lines...) Expand 10 before | Expand all | Expand 10 after
6731 literal_factory_class.LookupFactory(literal_list_factory_name)); 6734 literal_factory_class.LookupFactory(literal_list_factory_name));
6732 ASSERT(!literal_list_factory.IsNull()); 6735 ASSERT(!literal_list_factory.IsNull());
6733 if (!type_arguments.IsNull() && 6736 if (!type_arguments.IsNull() &&
6734 !type_arguments.IsInstantiated() && 6737 !type_arguments.IsInstantiated() &&
6735 (current_block_->scope->function_level() > 0)) { 6738 (current_block_->scope->function_level() > 0)) {
6736 // Make sure that the instantiator is captured. 6739 // Make sure that the instantiator is captured.
6737 CaptureReceiver(); 6740 CaptureReceiver();
6738 } 6741 }
6739 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); 6742 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
6740 factory_param->Add(list); 6743 factory_param->Add(list);
6741 return new ConstructorCallNode( 6744 AbstractTypeArguments& canonical_type_arguments =
6742 literal_pos, type_arguments, literal_list_factory, factory_param); 6745 AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize());
6746 return new ConstructorCallNode(literal_pos,
6747 canonical_type_arguments,
6748 literal_list_factory,
6749 factory_param);
6743 } 6750 }
6744 } 6751 }
6745 6752
6746 6753
6747 static void AddKeyValuePair(ArrayNode* pairs, 6754 static void AddKeyValuePair(ArrayNode* pairs,
6748 bool is_const, 6755 bool is_const,
6749 AstNode* key, 6756 AstNode* key,
6750 AstNode* value) { 6757 AstNode* value) {
6751 if (is_const) { 6758 if (is_const) {
6752 ASSERT(key->IsLiteralNode()); 6759 ASSERT(key->IsLiteralNode());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
6800 "the key type of a map literal is implicitly 'String'"); 6807 "the key type of a map literal is implicitly 'String'");
6801 } 6808 }
6802 Warning(type_pos, 6809 Warning(type_pos,
6803 "a map literal takes one type argument specifying " 6810 "a map literal takes one type argument specifying "
6804 "the value type"); 6811 "the value type");
6805 value_type = map_type_arguments.TypeAt(1); 6812 value_type = map_type_arguments.TypeAt(1);
6806 } else { 6813 } else {
6807 TypeArguments& type_array = TypeArguments::Handle(TypeArguments::New(2)); 6814 TypeArguments& type_array = TypeArguments::Handle(TypeArguments::New(2));
6808 type_array.SetTypeAt(0, Type::Handle(Type::StringInterface())); 6815 type_array.SetTypeAt(0, Type::Handle(Type::StringInterface()));
6809 type_array.SetTypeAt(1, value_type); 6816 type_array.SetTypeAt(1, value_type);
6810 map_type_arguments = type_array.raw(); 6817 map_type_arguments = type_array.Canonicalize();
regis 2011/12/05 23:16:35 Is this necessary? You canonicalize below as well.
srdjan 2011/12/06 17:24:15 Removed, doing it later
6811 } 6818 }
6812 if (is_const && !value_type.IsInstantiated()) { 6819 if (is_const && !value_type.IsInstantiated()) {
6813 ErrorMsg(type_pos, 6820 ErrorMsg(type_pos,
6814 "the type argument of a constant map literal cannot include " 6821 "the type argument of a constant map literal cannot include "
6815 "a type variable"); 6822 "a type variable");
6816 } 6823 }
6817 } 6824 }
6818 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); 6825 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2));
srdjan 2011/12/06 17:24:15 Canonicalizing it here,
6819 6826
6820 // Parse the map entries. Note: there may be an optional extra 6827 // Parse the map entries. Note: there may be an optional extra
6821 // comma after the last entry. 6828 // comma after the last entry.
6822 ArrayNode* kv_pairs = 6829 ArrayNode* kv_pairs =
6823 new ArrayNode(token_index_, TypeArguments::ZoneHandle()); 6830 new ArrayNode(token_index_, TypeArguments::ZoneHandle());
6824 const String& dst_name = String::ZoneHandle( 6831 const String& dst_name = String::ZoneHandle(
6825 String::NewSymbol("list literal element")); 6832 String::NewSymbol("list literal element"));
6826 while (CurrentToken() != Token::kRBRACE) { 6833 while (CurrentToken() != Token::kRBRACE) {
6827 AstNode* key = NULL; 6834 AstNode* key = NULL;
6828 if (CurrentToken() == Token::kSTRING) { 6835 if (CurrentToken() == Token::kSTRING) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
6901 ASSERT(!immutable_map_class.IsNull()); 6908 ASSERT(!immutable_map_class.IsNull());
6902 ArgumentListNode* constr_args = new ArgumentListNode(token_index_); 6909 ArgumentListNode* constr_args = new ArgumentListNode(token_index_);
6903 constr_args->Add(new LiteralNode(literal_pos, key_value_array)); 6910 constr_args->Add(new LiteralNode(literal_pos, key_value_array));
6904 const String& constr_name = 6911 const String& constr_name =
6905 String::Handle(String::NewSymbol(kImmutableMapConstructorName)); 6912 String::Handle(String::NewSymbol(kImmutableMapConstructorName));
6906 const Function& map_constr = Function::ZoneHandle( 6913 const Function& map_constr = Function::ZoneHandle(
6907 immutable_map_class.LookupConstructor(constr_name)); 6914 immutable_map_class.LookupConstructor(constr_name));
6908 ASSERT(!map_constr.IsNull()); 6915 ASSERT(!map_constr.IsNull());
6909 const Instance& const_instance = Instance::ZoneHandle( 6916 const Instance& const_instance = Instance::ZoneHandle(
6910 EvaluateConstConstructorCall(immutable_map_class, 6917 EvaluateConstConstructorCall(immutable_map_class,
6911 map_type_arguments, 6918 map_type_arguments,
regis 2011/12/05 23:16:35 Why not canonicalize here as well?
srdjan 2011/12/06 17:24:15 Done it above
6912 map_constr, 6919 map_constr,
6913 constr_args)); 6920 constr_args));
6914 if (const_instance.IsUnhandledException()) { 6921 if (const_instance.IsUnhandledException()) {
6915 return CreateEvalConstConstructorThrow(literal_pos, const_instance); 6922 return CreateEvalConstConstructorThrow(literal_pos, const_instance);
6916 } else { 6923 } else {
6917 return new LiteralNode(literal_pos, const_instance); 6924 return new LiteralNode(literal_pos, const_instance);
6918 } 6925 }
6919 } else { 6926 } else {
6920 // Factory call at runtime. 6927 // Factory call at runtime.
6921 String& literal_factory_class_name = String::Handle( 6928 String& literal_factory_class_name = String::Handle(
6922 String::NewSymbol(kLiteralFactoryClassName)); 6929 String::NewSymbol(kLiteralFactoryClassName));
6923 const Class& literal_factory_class = 6930 const Class& literal_factory_class =
6924 Class::Handle(LookupCoreClass(literal_factory_class_name)); 6931 Class::Handle(LookupCoreClass(literal_factory_class_name));
6925 ASSERT(!literal_factory_class.IsNull()); 6932 ASSERT(!literal_factory_class.IsNull());
6926 const String& literal_map_factory_name = 6933 const String& literal_map_factory_name =
6927 String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName)); 6934 String::Handle(String::NewSymbol(kLiteralFactoryMapFromLiteralName));
6928 const Function& literal_map_factory = Function::ZoneHandle( 6935 const Function& literal_map_factory = Function::ZoneHandle(
6929 literal_factory_class.LookupFactory(literal_map_factory_name)); 6936 literal_factory_class.LookupFactory(literal_map_factory_name));
6930 ASSERT(!literal_map_factory.IsNull()); 6937 ASSERT(!literal_map_factory.IsNull());
6931 if (!map_type_arguments.IsNull() && 6938 if (!map_type_arguments.IsNull() &&
6932 !map_type_arguments.IsInstantiated() && 6939 !map_type_arguments.IsInstantiated() &&
6933 (current_block_->scope->function_level() > 0)) { 6940 (current_block_->scope->function_level() > 0)) {
6934 // Make sure that the instantiator is captured. 6941 // Make sure that the instantiator is captured.
6935 CaptureReceiver(); 6942 CaptureReceiver();
6936 } 6943 }
6937 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos); 6944 ArgumentListNode* factory_param = new ArgumentListNode(literal_pos);
6938 factory_param->Add(kv_pairs); 6945 factory_param->Add(kv_pairs);
6939 return new ConstructorCallNode( 6946 AbstractTypeArguments& canonical_map_type_arguments =
6940 literal_pos, map_type_arguments, literal_map_factory, factory_param); 6947 AbstractTypeArguments::ZoneHandle(map_type_arguments.Canonicalize());
srdjan 2011/12/06 17:24:15 Reverted this.
6948 return new ConstructorCallNode(literal_pos,
6949 canonical_map_type_arguments,
6950 literal_map_factory,
6951 factory_param);
6941 } 6952 }
6942 } 6953 }
6943 6954
6944 6955
6945 AstNode* Parser::ParseCompoundLiteral() { 6956 AstNode* Parser::ParseCompoundLiteral() {
6946 bool is_const = false; 6957 bool is_const = false;
6947 if (CurrentToken() == Token::kCONST) { 6958 if (CurrentToken() == Token::kCONST) {
6948 is_const = true; 6959 is_const = true;
6949 ConsumeToken(); 6960 ConsumeToken();
6950 } 6961 }
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
7146 7157
7147 // Make the constructor call. 7158 // Make the constructor call.
7148 AstNode* new_object = NULL; 7159 AstNode* new_object = NULL;
7149 if (is_const) { 7160 if (is_const) {
7150 if (!constructor.is_const()) { 7161 if (!constructor.is_const()) {
7151 ErrorMsg("'const' requires const constructor: '%s'", 7162 ErrorMsg("'const' requires const constructor: '%s'",
7152 String::Handle(constructor.name()).ToCString()); 7163 String::Handle(constructor.name()).ToCString());
7153 } 7164 }
7154 const Instance& const_instance = Instance::ZoneHandle( 7165 const Instance& const_instance = Instance::ZoneHandle(
7155 EvaluateConstConstructorCall(type_class, 7166 EvaluateConstConstructorCall(type_class,
7156 type_arguments, 7167 type_arguments,
regis 2011/12/05 23:16:35 ditto
srdjan 2011/12/06 17:24:15 Done by moving canonicalization before if (is_cons
7157 constructor, 7168 constructor,
7158 arguments)); 7169 arguments));
7159 if (const_instance.IsUnhandledException()) { 7170 if (const_instance.IsUnhandledException()) {
7160 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance); 7171 new_object = CreateEvalConstConstructorThrow(new_pos, const_instance);
7161 } else { 7172 } else {
7162 new_object = new LiteralNode(new_pos, const_instance); 7173 new_object = new LiteralNode(new_pos, const_instance);
7163 } 7174 }
7164 } else { 7175 } else {
7165 CheckFunctionIsCallable(new_pos, constructor); 7176 CheckFunctionIsCallable(new_pos, constructor);
7166 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); 7177 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments);
7167 if (!type_arguments.IsNull() && 7178 if (!type_arguments.IsNull() &&
7168 !type_arguments.IsInstantiated() && 7179 !type_arguments.IsInstantiated() &&
7169 (current_block_->scope->function_level() > 0)) { 7180 (current_block_->scope->function_level() > 0)) {
7170 // Make sure that the instantiator is captured. 7181 // Make sure that the instantiator is captured.
7171 CaptureReceiver(); 7182 CaptureReceiver();
7172 } 7183 }
7184 AbstractTypeArguments& canonical_type_arguments =
7185 AbstractTypeArguments::ZoneHandle(type_arguments.Canonicalize());
7173 new_object = new ConstructorCallNode( 7186 new_object = new ConstructorCallNode(
7174 new_pos, type_arguments, constructor, arguments); 7187 new_pos, canonical_type_arguments, constructor, arguments);
7175 } 7188 }
7176 return new_object; 7189 return new_object;
7177 } 7190 }
7178 7191
7179 7192
7180 // A string literal consists of the concatenation of the next n tokens 7193 // A string literal consists of the concatenation of the next n tokens
7181 // that satisfy the EBNF grammar: 7194 // that satisfy the EBNF grammar:
7182 // literal = kSTRING {{ interpol }+ kSTRING } 7195 // literal = kSTRING {{ interpol }+ kSTRING }
7183 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) 7196 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END)
7184 // In other words, the scanner breaks down interpolated strings so that 7197 // In other words, the scanner breaks down interpolated strings so that
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
7607 } 7620 }
7608 7621
7609 7622
7610 void Parser::SkipNestedExpr() { 7623 void Parser::SkipNestedExpr() {
7611 const bool saved_mode = SetAllowFunctionLiterals(true); 7624 const bool saved_mode = SetAllowFunctionLiterals(true);
7612 SkipExpr(); 7625 SkipExpr();
7613 SetAllowFunctionLiterals(saved_mode); 7626 SetAllowFunctionLiterals(saved_mode);
7614 } 7627 }
7615 7628
7616 } // namespace dart 7629 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698