| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 ASSERT(!current_function().IsNull()); | 315 ASSERT(!current_function().IsNull()); |
| 316 if (FLAG_enable_type_checks) { | 316 if (FLAG_enable_type_checks) { |
| 317 EnsureExpressionTemp(); | 317 EnsureExpressionTemp(); |
| 318 } | 318 } |
| 319 } | 319 } |
| 320 | 320 |
| 321 | 321 |
| 322 Parser::~Parser() { | 322 Parser::~Parser() { |
| 323 if (unregister_pending_function_) { | 323 if (unregister_pending_function_) { |
| 324 const GrowableObjectArray& pending_functions = | 324 const GrowableObjectArray& pending_functions = |
| 325 GrowableObjectArray::Handle( | 325 GrowableObjectArray::Handle(I->object_store()->pending_functions()); |
| 326 isolate()->object_store()->pending_functions()); | |
| 327 ASSERT(pending_functions.Length() > 0); | 326 ASSERT(pending_functions.Length() > 0); |
| 328 ASSERT(pending_functions.At(pending_functions.Length()-1) == | 327 ASSERT(pending_functions.At(pending_functions.Length()-1) == |
| 329 current_function().raw()); | 328 current_function().raw()); |
| 330 pending_functions.RemoveLast(); | 329 pending_functions.RemoveLast(); |
| 331 } | 330 } |
| 332 } | 331 } |
| 333 | 332 |
| 334 | 333 |
| 335 void Parser::SetScript(const Script& script, intptr_t token_pos) { | 334 void Parser::SetScript(const Script& script, intptr_t token_pos) { |
| 336 script_ = script.raw(); | 335 script_ = script.raw(); |
| 337 tokens_iterator_.SetStream( | 336 tokens_iterator_.SetStream( |
| 338 TokenStream::Handle(isolate(), script.tokens()), token_pos); | 337 TokenStream::Handle(I, script.tokens()), token_pos); |
| 339 token_kind_ = Token::kILLEGAL; | 338 token_kind_ = Token::kILLEGAL; |
| 340 } | 339 } |
| 341 | 340 |
| 342 | 341 |
| 343 bool Parser::SetAllowFunctionLiterals(bool value) { | 342 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 344 bool current_value = allow_function_literals_; | 343 bool current_value = allow_function_literals_; |
| 345 allow_function_literals_ = value; | 344 allow_function_literals_ = value; |
| 346 return current_value; | 345 return current_value; |
| 347 } | 346 } |
| 348 | 347 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 ASSERT(literal_token_.kind() == Token::kDOUBLE); | 415 ASSERT(literal_token_.kind() == Token::kDOUBLE); |
| 417 return Double::RawCast(literal_token_.value()); | 416 return Double::RawCast(literal_token_.value()); |
| 418 } | 417 } |
| 419 | 418 |
| 420 | 419 |
| 421 RawInteger* Parser::CurrentIntegerLiteral() const { | 420 RawInteger* Parser::CurrentIntegerLiteral() const { |
| 422 literal_token_ ^= tokens_iterator_.CurrentToken(); | 421 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 423 ASSERT(literal_token_.kind() == Token::kINTEGER); | 422 ASSERT(literal_token_.kind() == Token::kINTEGER); |
| 424 RawInteger* ri = Integer::RawCast(literal_token_.value()); | 423 RawInteger* ri = Integer::RawCast(literal_token_.value()); |
| 425 if (FLAG_throw_on_javascript_int_overflow) { | 424 if (FLAG_throw_on_javascript_int_overflow) { |
| 426 const Integer& i = Integer::Handle(isolate(), ri); | 425 const Integer& i = Integer::Handle(I, ri); |
| 427 if (i.CheckJavascriptIntegerOverflow()) { | 426 if (i.CheckJavascriptIntegerOverflow()) { |
| 428 ErrorMsg(TokenPos(), | 427 ErrorMsg(TokenPos(), |
| 429 "Integer literal does not fit in a Javascript integer: %s.", | 428 "Integer literal does not fit in a Javascript integer: %s.", |
| 430 i.ToCString()); | 429 i.ToCString()); |
| 431 } | 430 } |
| 432 } | 431 } |
| 433 return ri; | 432 return ri; |
| 434 } | 433 } |
| 435 | 434 |
| 436 | 435 |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 return error.raw(); | 908 return error.raw(); |
| 910 } | 909 } |
| 911 UNREACHABLE(); | 910 UNREACHABLE(); |
| 912 return Object::null(); | 911 return Object::null(); |
| 913 } | 912 } |
| 914 | 913 |
| 915 | 914 |
| 916 RawArray* Parser::EvaluateMetadata() { | 915 RawArray* Parser::EvaluateMetadata() { |
| 917 CheckToken(Token::kAT, "Metadata character '@' expected"); | 916 CheckToken(Token::kAT, "Metadata character '@' expected"); |
| 918 GrowableObjectArray& meta_values = | 917 GrowableObjectArray& meta_values = |
| 919 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 918 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 920 while (CurrentToken() == Token::kAT) { | 919 while (CurrentToken() == Token::kAT) { |
| 921 ConsumeToken(); | 920 ConsumeToken(); |
| 922 intptr_t expr_pos = TokenPos(); | 921 intptr_t expr_pos = TokenPos(); |
| 923 if (!IsIdentifier()) { | 922 if (!IsIdentifier()) { |
| 924 ExpectIdentifier("identifier expected"); | 923 ExpectIdentifier("identifier expected"); |
| 925 } | 924 } |
| 926 // Reject expressions with deferred library prefix eagerly. | 925 // Reject expressions with deferred library prefix eagerly. |
| 927 Object& obj = Object::Handle(isolate(), | 926 Object& obj = Object::Handle(I, |
| 928 library_.LookupLocalObject(*CurrentLiteral())); | 927 library_.LookupLocalObject(*CurrentLiteral())); |
| 929 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 928 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
| 930 if (LibraryPrefix::Cast(obj).is_deferred_load()) { | 929 if (LibraryPrefix::Cast(obj).is_deferred_load()) { |
| 931 ErrorMsg("Metadata must be compile-time constant"); | 930 ErrorMsg("Metadata must be compile-time constant"); |
| 932 } | 931 } |
| 933 } | 932 } |
| 934 AstNode* expr = NULL; | 933 AstNode* expr = NULL; |
| 935 if ((LookaheadToken(1) == Token::kLPAREN) || | 934 if ((LookaheadToken(1) == Token::kLPAREN) || |
| 936 ((LookaheadToken(1) == Token::kPERIOD) && | 935 ((LookaheadToken(1) == Token::kPERIOD) && |
| 937 (LookaheadToken(3) == Token::kLPAREN)) || | 936 (LookaheadToken(3) == Token::kLPAREN)) || |
| 938 ((LookaheadToken(1) == Token::kPERIOD) && | 937 ((LookaheadToken(1) == Token::kPERIOD) && |
| 939 (LookaheadToken(3) == Token::kPERIOD) && | 938 (LookaheadToken(3) == Token::kPERIOD) && |
| 940 (LookaheadToken(5) == Token::kLPAREN))) { | 939 (LookaheadToken(5) == Token::kLPAREN))) { |
| 941 expr = ParseNewOperator(Token::kCONST); | 940 expr = ParseNewOperator(Token::kCONST); |
| 942 } else { | 941 } else { |
| 943 // Can be x, C.x, or L.C.x. | 942 // Can be x, C.x, or L.C.x. |
| 944 expr = ParsePrimary(); // Consumes x, C or L.C. | 943 expr = ParsePrimary(); // Consumes x, C or L.C. |
| 945 Class& cls = Class::Handle(isolate()); | 944 Class& cls = Class::Handle(I); |
| 946 if (expr->IsPrimaryNode()) { | 945 if (expr->IsPrimaryNode()) { |
| 947 PrimaryNode* primary_node = expr->AsPrimaryNode(); | 946 PrimaryNode* primary_node = expr->AsPrimaryNode(); |
| 948 if (primary_node->primary().IsClass()) { | 947 if (primary_node->primary().IsClass()) { |
| 949 // If the primary node referred to a class we are loading a | 948 // If the primary node referred to a class we are loading a |
| 950 // qualified static field. | 949 // qualified static field. |
| 951 cls ^= primary_node->primary().raw(); | 950 cls ^= primary_node->primary().raw(); |
| 952 } else { | 951 } else { |
| 953 ErrorMsg(expr_pos, "Metadata expressions must refer to a const field " | 952 ErrorMsg(expr_pos, "Metadata expressions must refer to a const field " |
| 954 "or constructor"); | 953 "or constructor"); |
| 955 } | 954 } |
| 956 } | 955 } |
| 957 if (CurrentToken() == Token::kPERIOD) { | 956 if (CurrentToken() == Token::kPERIOD) { |
| 958 // C.x or L.C.X. | 957 // C.x or L.C.X. |
| 959 if (cls.IsNull()) { | 958 if (cls.IsNull()) { |
| 960 ErrorMsg(expr_pos, "Metadata expressions must refer to a const field " | 959 ErrorMsg(expr_pos, "Metadata expressions must refer to a const field " |
| 961 "or constructor"); | 960 "or constructor"); |
| 962 } | 961 } |
| 963 ConsumeToken(); | 962 ConsumeToken(); |
| 964 const intptr_t ident_pos = TokenPos(); | 963 const intptr_t ident_pos = TokenPos(); |
| 965 String* ident = ExpectIdentifier("identifier expected"); | 964 String* ident = ExpectIdentifier("identifier expected"); |
| 966 const Field& field = Field::Handle(isolate(), | 965 const Field& field = Field::Handle(I, cls.LookupStaticField(*ident)); |
| 967 cls.LookupStaticField(*ident)); | |
| 968 if (field.IsNull()) { | 966 if (field.IsNull()) { |
| 969 ErrorMsg(ident_pos, | 967 ErrorMsg(ident_pos, |
| 970 "Class '%s' has no field '%s'", | 968 "Class '%s' has no field '%s'", |
| 971 cls.ToCString(), | 969 cls.ToCString(), |
| 972 ident->ToCString()); | 970 ident->ToCString()); |
| 973 } | 971 } |
| 974 if (!field.is_const()) { | 972 if (!field.is_const()) { |
| 975 ErrorMsg(ident_pos, | 973 ErrorMsg(ident_pos, |
| 976 "Field '%s' of class '%s' is not const", | 974 "Field '%s' of class '%s' is not const", |
| 977 ident->ToCString(), | 975 ident->ToCString(), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 988 } | 986 } |
| 989 return Array::MakeArray(meta_values); | 987 return Array::MakeArray(meta_values); |
| 990 } | 988 } |
| 991 | 989 |
| 992 | 990 |
| 993 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 991 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
| 994 TRACE_PARSER("ParseStaticFinalGetter"); | 992 TRACE_PARSER("ParseStaticFinalGetter"); |
| 995 ParamList params; | 993 ParamList params; |
| 996 ASSERT(func.num_fixed_parameters() == 0); // static. | 994 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 997 ASSERT(!func.HasOptionalParameters()); | 995 ASSERT(!func.HasOptionalParameters()); |
| 998 ASSERT(AbstractType::Handle(isolate(), func.result_type()).IsResolved()); | 996 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 999 | 997 |
| 1000 // Build local scope for function and populate with the formal parameters. | 998 // Build local scope for function and populate with the formal parameters. |
| 1001 OpenFunctionBlock(func); | 999 OpenFunctionBlock(func); |
| 1002 AddFormalParamsToScope(¶ms, current_block_->scope); | 1000 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1003 | 1001 |
| 1004 intptr_t ident_pos = TokenPos(); | 1002 intptr_t ident_pos = TokenPos(); |
| 1005 const String& field_name = *ExpectIdentifier("field name expected"); | 1003 const String& field_name = *ExpectIdentifier("field name expected"); |
| 1006 const Class& field_class = Class::Handle(isolate(), func.Owner()); | 1004 const Class& field_class = Class::Handle(I, func.Owner()); |
| 1007 const Field& field = | 1005 const Field& field = |
| 1008 Field::ZoneHandle(I, field_class.LookupStaticField(field_name)); | 1006 Field::ZoneHandle(I, field_class.LookupStaticField(field_name)); |
| 1009 | 1007 |
| 1010 // Static final fields must have an initializer. | 1008 // Static final fields must have an initializer. |
| 1011 ExpectToken(Token::kASSIGN); | 1009 ExpectToken(Token::kASSIGN); |
| 1012 | 1010 |
| 1013 const intptr_t expr_pos = TokenPos(); | 1011 const intptr_t expr_pos = TokenPos(); |
| 1014 if (field.is_const()) { | 1012 if (field.is_const()) { |
| 1015 // We don't want to use ParseConstExpr() here because we don't want | 1013 // We don't want to use ParseConstExpr() here because we don't want |
| 1016 // the constant folding code to create, compile and execute a code | 1014 // the constant folding code to create, compile and execute a code |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 ident_pos, | 1066 ident_pos, |
| 1069 Token::kEQ_STRICT, | 1067 Token::kEQ_STRICT, |
| 1070 new LoadStaticFieldNode(ident_pos, field), | 1068 new LoadStaticFieldNode(ident_pos, field), |
| 1071 new LiteralNode(ident_pos, Object::sentinel())); | 1069 new LiteralNode(ident_pos, Object::sentinel())); |
| 1072 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL); | 1070 SequenceNode* initialize_field = new SequenceNode(ident_pos, NULL); |
| 1073 initialize_field->Add( | 1071 initialize_field->Add( |
| 1074 new StoreStaticFieldNode( | 1072 new StoreStaticFieldNode( |
| 1075 ident_pos, | 1073 ident_pos, |
| 1076 field, | 1074 field, |
| 1077 new LiteralNode(ident_pos, Object::transition_sentinel()))); | 1075 new LiteralNode(ident_pos, Object::transition_sentinel()))); |
| 1078 const String& init_name = String::Handle(isolate(), Symbols::New( | 1076 const String& init_name = String::Handle(I, Symbols::New( |
| 1079 String::Handle(isolate(), String::Concat( | 1077 String::Handle(I, String::Concat( |
| 1080 Symbols::InitPrefix(), String::Handle(isolate(), field.name()))))); | 1078 Symbols::InitPrefix(), String::Handle(I, field.name()))))); |
| 1081 const Function& init_function = Function::ZoneHandle(I, | 1079 const Function& init_function = Function::ZoneHandle(I, |
| 1082 field_class.LookupStaticFunction(init_name)); | 1080 field_class.LookupStaticFunction(init_name)); |
| 1083 ASSERT(!init_function.IsNull()); | 1081 ASSERT(!init_function.IsNull()); |
| 1084 ArgumentListNode* arguments = new ArgumentListNode(expr_pos); | 1082 ArgumentListNode* arguments = new ArgumentListNode(expr_pos); |
| 1085 StaticCallNode* init_call = | 1083 StaticCallNode* init_call = |
| 1086 new StaticCallNode(expr_pos, init_function, arguments); | 1084 new StaticCallNode(expr_pos, init_function, arguments); |
| 1087 initialize_field->Add(init_call); | 1085 initialize_field->Add(init_call); |
| 1088 | 1086 |
| 1089 AstNode* uninitialized_check = | 1087 AstNode* uninitialized_check = |
| 1090 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); | 1088 new IfNode(ident_pos, compare_uninitialized, initialize_field, NULL); |
| 1091 current_block_->statements->Add(uninitialized_check); | 1089 current_block_->statements->Add(uninitialized_check); |
| 1092 | 1090 |
| 1093 // Generate code returning the field value. | 1091 // Generate code returning the field value. |
| 1094 ReturnNode* return_node = | 1092 ReturnNode* return_node = |
| 1095 new ReturnNode(ident_pos, | 1093 new ReturnNode(ident_pos, |
| 1096 new LoadStaticFieldNode(ident_pos, field)); | 1094 new LoadStaticFieldNode(ident_pos, field)); |
| 1097 current_block_->statements->Add(return_node); | 1095 current_block_->statements->Add(return_node); |
| 1098 } | 1096 } |
| 1099 return CloseBlock(); | 1097 return CloseBlock(); |
| 1100 } | 1098 } |
| 1101 | 1099 |
| 1102 | 1100 |
| 1103 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { | 1101 SequenceNode* Parser::ParseStaticInitializer(const Function& func) { |
| 1104 TRACE_PARSER("ParseStaticInitializer"); | 1102 TRACE_PARSER("ParseStaticInitializer"); |
| 1105 ParamList params; | 1103 ParamList params; |
| 1106 ASSERT(func.num_fixed_parameters() == 0); // static. | 1104 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1107 ASSERT(!func.HasOptionalParameters()); | 1105 ASSERT(!func.HasOptionalParameters()); |
| 1108 ASSERT(AbstractType::Handle(isolate(), func.result_type()).IsResolved()); | 1106 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 1109 | 1107 |
| 1110 // Build local scope for function and populate with the formal parameters. | 1108 // Build local scope for function and populate with the formal parameters. |
| 1111 OpenFunctionBlock(func); | 1109 OpenFunctionBlock(func); |
| 1112 AddFormalParamsToScope(¶ms, current_block_->scope); | 1110 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1113 | 1111 |
| 1114 // Move forward to the start of the initializer expression. | 1112 // Move forward to the start of the initializer expression. |
| 1115 intptr_t ident_pos = TokenPos(); | 1113 intptr_t ident_pos = TokenPos(); |
| 1116 ExpectIdentifier("identifier expected"); | 1114 ExpectIdentifier("identifier expected"); |
| 1117 ExpectToken(Token::kASSIGN); | 1115 ExpectToken(Token::kASSIGN); |
| 1118 intptr_t token_pos = TokenPos(); | 1116 intptr_t token_pos = TokenPos(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1146 } | 1144 } |
| 1147 | 1145 |
| 1148 OpenBlock(); // Start try block. | 1146 OpenBlock(); // Start try block. |
| 1149 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1147 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1150 const Field& field = Field::ZoneHandle(I, func.saved_static_field()); | 1148 const Field& field = Field::ZoneHandle(I, func.saved_static_field()); |
| 1151 ASSERT(!field.is_const()); | 1149 ASSERT(!field.is_const()); |
| 1152 if (FLAG_enable_type_checks) { | 1150 if (FLAG_enable_type_checks) { |
| 1153 expr = new AssignableNode( | 1151 expr = new AssignableNode( |
| 1154 field.token_pos(), | 1152 field.token_pos(), |
| 1155 expr, | 1153 expr, |
| 1156 AbstractType::ZoneHandle(isolate(), field.type()), | 1154 AbstractType::ZoneHandle(I, field.type()), |
| 1157 String::ZoneHandle(isolate(), field.name())); | 1155 String::ZoneHandle(I, field.name())); |
| 1158 } | 1156 } |
| 1159 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(), | 1157 StoreStaticFieldNode* store = new StoreStaticFieldNode(field.token_pos(), |
| 1160 field, | 1158 field, |
| 1161 expr); | 1159 expr); |
| 1162 current_block_->statements->Add(store); | 1160 current_block_->statements->Add(store); |
| 1163 SequenceNode* try_block = CloseBlock(); // End try block. | 1161 SequenceNode* try_block = CloseBlock(); // End try block. |
| 1164 | 1162 |
| 1165 OpenBlock(); // Start catch handler list. | 1163 OpenBlock(); // Start catch handler list. |
| 1166 OpenBlock(); // Start catch clause. | 1164 OpenBlock(); // Start catch clause. |
| 1167 AstNode* compare_transition_sentinel = new ComparisonNode( | 1165 AstNode* compare_transition_sentinel = new ComparisonNode( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1214 // ReturnNode (field's value); | 1212 // ReturnNode (field's value); |
| 1215 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1213 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 1216 TRACE_PARSER("ParseInstanceGetter"); | 1214 TRACE_PARSER("ParseInstanceGetter"); |
| 1217 ParamList params; | 1215 ParamList params; |
| 1218 // func.token_pos() points to the name of the field. | 1216 // func.token_pos() points to the name of the field. |
| 1219 const intptr_t ident_pos = func.token_pos(); | 1217 const intptr_t ident_pos = func.token_pos(); |
| 1220 ASSERT(current_class().raw() == func.Owner()); | 1218 ASSERT(current_class().raw() == func.Owner()); |
| 1221 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1219 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1222 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 1220 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
| 1223 ASSERT(!func.HasOptionalParameters()); | 1221 ASSERT(!func.HasOptionalParameters()); |
| 1224 ASSERT(AbstractType::Handle(isolate(), func.result_type()).IsResolved()); | 1222 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 1225 | 1223 |
| 1226 // Build local scope for function and populate with the formal parameters. | 1224 // Build local scope for function and populate with the formal parameters. |
| 1227 OpenFunctionBlock(func); | 1225 OpenFunctionBlock(func); |
| 1228 AddFormalParamsToScope(¶ms, current_block_->scope); | 1226 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1229 | 1227 |
| 1230 // Receiver is local 0. | 1228 // Receiver is local 0. |
| 1231 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1229 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1232 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1230 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1233 ASSERT(IsIdentifier()); | 1231 ASSERT(IsIdentifier()); |
| 1234 const String& field_name = *CurrentLiteral(); | 1232 const String& field_name = *CurrentLiteral(); |
| 1235 const Class& field_class = Class::Handle(isolate(), func.Owner()); | 1233 const Class& field_class = Class::Handle(I, func.Owner()); |
| 1236 const Field& field = | 1234 const Field& field = |
| 1237 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); | 1235 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); |
| 1238 | 1236 |
| 1239 LoadInstanceFieldNode* load_field = | 1237 LoadInstanceFieldNode* load_field = |
| 1240 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1238 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
| 1241 | 1239 |
| 1242 ReturnNode* return_node = | 1240 ReturnNode* return_node = |
| 1243 new ReturnNode(Scanner::kNoSourcePos, load_field); | 1241 new ReturnNode(Scanner::kNoSourcePos, load_field); |
| 1244 current_block_->statements->Add(return_node); | 1242 current_block_->statements->Add(return_node); |
| 1245 return CloseBlock(); | 1243 return CloseBlock(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1262 const AbstractType& field_type = AbstractType::ZoneHandle(I, field.type()); | 1260 const AbstractType& field_type = AbstractType::ZoneHandle(I, field.type()); |
| 1263 | 1261 |
| 1264 ParamList params; | 1262 ParamList params; |
| 1265 ASSERT(current_class().raw() == func.Owner()); | 1263 ASSERT(current_class().raw() == func.Owner()); |
| 1266 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1264 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1267 params.AddFinalParameter(ident_pos, | 1265 params.AddFinalParameter(ident_pos, |
| 1268 &Symbols::Value(), | 1266 &Symbols::Value(), |
| 1269 &field_type); | 1267 &field_type); |
| 1270 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. | 1268 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. |
| 1271 ASSERT(!func.HasOptionalParameters()); | 1269 ASSERT(!func.HasOptionalParameters()); |
| 1272 ASSERT(AbstractType::Handle(isolate(), func.result_type()).IsVoidType()); | 1270 ASSERT(AbstractType::Handle(I, func.result_type()).IsVoidType()); |
| 1273 | 1271 |
| 1274 // Build local scope for function and populate with the formal parameters. | 1272 // Build local scope for function and populate with the formal parameters. |
| 1275 OpenFunctionBlock(func); | 1273 OpenFunctionBlock(func); |
| 1276 AddFormalParamsToScope(¶ms, current_block_->scope); | 1274 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1277 | 1275 |
| 1278 LoadLocalNode* receiver = | 1276 LoadLocalNode* receiver = |
| 1279 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); | 1277 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); |
| 1280 LoadLocalNode* value = | 1278 LoadLocalNode* value = |
| 1281 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); | 1279 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
| 1282 | 1280 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 | 1360 |
| 1363 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, | 1361 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, |
| 1364 Array* default_values) { | 1362 Array* default_values) { |
| 1365 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1363 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
| 1366 | 1364 |
| 1367 ASSERT(func.IsNoSuchMethodDispatcher()); | 1365 ASSERT(func.IsNoSuchMethodDispatcher()); |
| 1368 intptr_t token_pos = func.token_pos(); | 1366 intptr_t token_pos = func.token_pos(); |
| 1369 ASSERT(func.token_pos() == 0); | 1367 ASSERT(func.token_pos() == 0); |
| 1370 ASSERT(current_class().raw() == func.Owner()); | 1368 ASSERT(current_class().raw() == func.Owner()); |
| 1371 | 1369 |
| 1372 ArgumentsDescriptor desc(Array::Handle(isolate(), func.saved_args_desc())); | 1370 ArgumentsDescriptor desc(Array::Handle(I, func.saved_args_desc())); |
| 1373 ASSERT(desc.Count() > 0); | 1371 ASSERT(desc.Count() > 0); |
| 1374 | 1372 |
| 1375 // Set up scope for this function. | 1373 // Set up scope for this function. |
| 1376 BuildDispatcherScope(func, desc, default_values); | 1374 BuildDispatcherScope(func, desc, default_values); |
| 1377 | 1375 |
| 1378 // Receiver is local 0. | 1376 // Receiver is local 0. |
| 1379 LocalScope* scope = current_block_->scope; | 1377 LocalScope* scope = current_block_->scope; |
| 1380 ArgumentListNode* func_args = new ArgumentListNode(token_pos); | 1378 ArgumentListNode* func_args = new ArgumentListNode(token_pos); |
| 1381 for (intptr_t i = 0; i < desc.Count(); ++i) { | 1379 for (intptr_t i = 0; i < desc.Count(); ++i) { |
| 1382 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1380 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
| 1383 } | 1381 } |
| 1384 | 1382 |
| 1385 if (desc.NamedCount() > 0) { | 1383 if (desc.NamedCount() > 0) { |
| 1386 const Array& arg_names = | 1384 const Array& arg_names = |
| 1387 Array::ZoneHandle(I, Array::New(desc.NamedCount())); | 1385 Array::ZoneHandle(I, Array::New(desc.NamedCount())); |
| 1388 for (intptr_t i = 0; i < arg_names.Length(); ++i) { | 1386 for (intptr_t i = 0; i < arg_names.Length(); ++i) { |
| 1389 arg_names.SetAt(i, String::Handle(isolate(), desc.NameAt(i))); | 1387 arg_names.SetAt(i, String::Handle(I, desc.NameAt(i))); |
| 1390 } | 1388 } |
| 1391 func_args->set_names(arg_names); | 1389 func_args->set_names(arg_names); |
| 1392 } | 1390 } |
| 1393 | 1391 |
| 1394 const String& func_name = String::ZoneHandle(I, func.name()); | 1392 const String& func_name = String::ZoneHandle(I, func.name()); |
| 1395 ArgumentListNode* arguments = BuildNoSuchMethodArguments( | 1393 ArgumentListNode* arguments = BuildNoSuchMethodArguments( |
| 1396 token_pos, func_name, *func_args, NULL, false); | 1394 token_pos, func_name, *func_args, NULL, false); |
| 1397 const Function& no_such_method = Function::ZoneHandle(I, | 1395 const Function& no_such_method = Function::ZoneHandle(I, |
| 1398 Resolver::ResolveDynamicAnyArgs(Class::Handle( | 1396 Resolver::ResolveDynamicAnyArgs(Class::Handle( |
| 1399 isolate(), func.Owner()), Symbols::NoSuchMethod())); | 1397 I, func.Owner()), Symbols::NoSuchMethod())); |
| 1400 StaticCallNode* call = | 1398 StaticCallNode* call = |
| 1401 new StaticCallNode(token_pos, no_such_method, arguments); | 1399 new StaticCallNode(token_pos, no_such_method, arguments); |
| 1402 | 1400 |
| 1403 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1401 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1404 current_block_->statements->Add(return_node); | 1402 current_block_->statements->Add(return_node); |
| 1405 return CloseBlock(); | 1403 return CloseBlock(); |
| 1406 } | 1404 } |
| 1407 | 1405 |
| 1408 | 1406 |
| 1409 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, | 1407 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, |
| 1410 Array* default_values) { | 1408 Array* default_values) { |
| 1411 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1409 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
| 1412 | 1410 |
| 1413 ASSERT(func.IsInvokeFieldDispatcher()); | 1411 ASSERT(func.IsInvokeFieldDispatcher()); |
| 1414 intptr_t token_pos = func.token_pos(); | 1412 intptr_t token_pos = func.token_pos(); |
| 1415 ASSERT(func.token_pos() == 0); | 1413 ASSERT(func.token_pos() == 0); |
| 1416 ASSERT(current_class().raw() == func.Owner()); | 1414 ASSERT(current_class().raw() == func.Owner()); |
| 1417 | 1415 |
| 1418 const Array& args_desc = Array::Handle(isolate(), func.saved_args_desc()); | 1416 const Array& args_desc = Array::Handle(I, func.saved_args_desc()); |
| 1419 ArgumentsDescriptor desc(args_desc); | 1417 ArgumentsDescriptor desc(args_desc); |
| 1420 ASSERT(desc.Count() > 0); | 1418 ASSERT(desc.Count() > 0); |
| 1421 | 1419 |
| 1422 // Set up scope for this function. | 1420 // Set up scope for this function. |
| 1423 BuildDispatcherScope(func, desc, default_values); | 1421 BuildDispatcherScope(func, desc, default_values); |
| 1424 | 1422 |
| 1425 // Receiver is local 0. | 1423 // Receiver is local 0. |
| 1426 LocalScope* scope = current_block_->scope; | 1424 LocalScope* scope = current_block_->scope; |
| 1427 ArgumentListNode* no_args = new ArgumentListNode(token_pos); | 1425 ArgumentListNode* no_args = new ArgumentListNode(token_pos); |
| 1428 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0)); | 1426 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0)); |
| 1429 | 1427 |
| 1430 const String& name = String::Handle(isolate(), func.name()); | 1428 const String& name = String::Handle(I, func.name()); |
| 1431 const String& getter_name = String::ZoneHandle(I, | 1429 const String& getter_name = String::ZoneHandle(I, |
| 1432 Symbols::New(String::Handle(isolate(), Field::GetterName(name)))); | 1430 Symbols::New(String::Handle(I, Field::GetterName(name)))); |
| 1433 InstanceCallNode* getter_call = new(isolate()) InstanceCallNode( | 1431 InstanceCallNode* getter_call = new(I) InstanceCallNode( |
| 1434 token_pos, receiver, getter_name, no_args); | 1432 token_pos, receiver, getter_name, no_args); |
| 1435 | 1433 |
| 1436 // Pass arguments 1..n to the closure call. | 1434 // Pass arguments 1..n to the closure call. |
| 1437 ArgumentListNode* args = new ArgumentListNode(token_pos); | 1435 ArgumentListNode* args = new(I) ArgumentListNode(token_pos); |
| 1438 const Array& names = Array::Handle( | 1436 const Array& names = Array::Handle( |
| 1439 isolate(), Array::New(desc.NamedCount(), Heap::kOld)); | 1437 I, Array::New(desc.NamedCount(), Heap::kOld)); |
| 1440 // Positional parameters. | 1438 // Positional parameters. |
| 1441 intptr_t i = 1; | 1439 intptr_t i = 1; |
| 1442 for (; i < desc.PositionalCount(); ++i) { | 1440 for (; i < desc.PositionalCount(); ++i) { |
| 1443 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1441 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
| 1444 } | 1442 } |
| 1445 // Named parameters. | 1443 // Named parameters. |
| 1446 for (; i < desc.Count(); i++) { | 1444 for (; i < desc.Count(); i++) { |
| 1447 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1445 args->Add(new(I) LoadLocalNode(token_pos, scope->VariableAt(i))); |
| 1448 intptr_t index = i - desc.PositionalCount(); | 1446 intptr_t index = i - desc.PositionalCount(); |
| 1449 names.SetAt(index, String::Handle(isolate(), desc.NameAt(index))); | 1447 names.SetAt(index, String::Handle(I, desc.NameAt(index))); |
| 1450 } | 1448 } |
| 1451 args->set_names(names); | 1449 args->set_names(names); |
| 1452 | 1450 |
| 1453 const Class& owner = Class::Handle(isolate(), func.Owner()); | 1451 const Class& owner = Class::Handle(I, func.Owner()); |
| 1454 ASSERT(!owner.IsNull()); | 1452 ASSERT(!owner.IsNull()); |
| 1455 AstNode* result = NULL; | 1453 AstNode* result = NULL; |
| 1456 if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) { | 1454 if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) { |
| 1457 EnsureSavedCurrentContext(); | 1455 EnsureSavedCurrentContext(); |
| 1458 result = new ClosureCallNode(token_pos, getter_call, args); | 1456 result = new ClosureCallNode(token_pos, getter_call, args); |
| 1459 } else { | 1457 } else { |
| 1460 result = BuildClosureCall(token_pos, getter_call, args); | 1458 result = BuildClosureCall(token_pos, getter_call, args); |
| 1461 } | 1459 } |
| 1462 | 1460 |
| 1463 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1461 ReturnNode* return_node = new ReturnNode(token_pos, result); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1618 } | 1616 } |
| 1619 } | 1617 } |
| 1620 | 1618 |
| 1621 if (CurrentToken() == Token::kLPAREN) { | 1619 if (CurrentToken() == Token::kLPAREN) { |
| 1622 // This parameter is probably a closure. If we saw the keyword 'var' | 1620 // This parameter is probably a closure. If we saw the keyword 'var' |
| 1623 // or 'final', a closure is not legal here and we ignore the | 1621 // or 'final', a closure is not legal here and we ignore the |
| 1624 // opening parens. | 1622 // opening parens. |
| 1625 if (!var_seen && !parameter.is_final) { | 1623 if (!var_seen && !parameter.is_final) { |
| 1626 // The parsed parameter type is actually the function result type. | 1624 // The parsed parameter type is actually the function result type. |
| 1627 const AbstractType& result_type = | 1625 const AbstractType& result_type = |
| 1628 AbstractType::Handle(isolate(), parameter.type->raw()); | 1626 AbstractType::Handle(I, parameter.type->raw()); |
| 1629 | 1627 |
| 1630 // Finish parsing the function type parameter. | 1628 // Finish parsing the function type parameter. |
| 1631 ParamList func_params; | 1629 ParamList func_params; |
| 1632 | 1630 |
| 1633 // Add implicit closure object parameter. | 1631 // Add implicit closure object parameter. |
| 1634 func_params.AddFinalParameter( | 1632 func_params.AddFinalParameter( |
| 1635 TokenPos(), | 1633 TokenPos(), |
| 1636 &Symbols::ClosureParameter(), | 1634 &Symbols::ClosureParameter(), |
| 1637 &Type::ZoneHandle(I, Type::DynamicType())); | 1635 &Type::ZoneHandle(I, Type::DynamicType())); |
| 1638 | 1636 |
| 1639 const bool no_explicit_default_values = false; | 1637 const bool no_explicit_default_values = false; |
| 1640 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 1638 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
| 1641 | 1639 |
| 1642 // The field 'is_static' has no meaning for signature functions. | 1640 // The field 'is_static' has no meaning for signature functions. |
| 1643 const Function& signature_function = Function::Handle(isolate(), | 1641 const Function& signature_function = Function::Handle(I, |
| 1644 Function::New(*parameter.name, | 1642 Function::New(*parameter.name, |
| 1645 RawFunction::kSignatureFunction, | 1643 RawFunction::kSignatureFunction, |
| 1646 /* is_static = */ false, | 1644 /* is_static = */ false, |
| 1647 /* is_const = */ false, | 1645 /* is_const = */ false, |
| 1648 /* is_abstract = */ false, | 1646 /* is_abstract = */ false, |
| 1649 /* is_external = */ false, | 1647 /* is_external = */ false, |
| 1650 /* is_native = */ false, | 1648 /* is_native = */ false, |
| 1651 current_class(), | 1649 current_class(), |
| 1652 parameter.name_pos)); | 1650 parameter.name_pos)); |
| 1653 signature_function.set_result_type(result_type); | 1651 signature_function.set_result_type(result_type); |
| 1654 AddFormalParamsToFunction(&func_params, signature_function); | 1652 AddFormalParamsToFunction(&func_params, signature_function); |
| 1655 const String& signature = String::Handle(isolate(), | 1653 const String& signature = String::Handle(I, |
| 1656 signature_function.Signature()); | 1654 signature_function.Signature()); |
| 1657 // Lookup the signature class, i.e. the class whose name is the signature. | 1655 // Lookup the signature class, i.e. the class whose name is the signature. |
| 1658 // We only lookup in the current library, but not in its imports, and only | 1656 // We only lookup in the current library, but not in its imports, and only |
| 1659 // create a new canonical signature class if it does not exist yet. | 1657 // create a new canonical signature class if it does not exist yet. |
| 1660 Class& signature_class = Class::ZoneHandle(I, | 1658 Class& signature_class = Class::ZoneHandle(I, |
| 1661 library_.LookupLocalClass(signature)); | 1659 library_.LookupLocalClass(signature)); |
| 1662 if (signature_class.IsNull()) { | 1660 if (signature_class.IsNull()) { |
| 1663 signature_class = Class::NewSignatureClass(signature, | 1661 signature_class = Class::NewSignatureClass(signature, |
| 1664 signature_function, | 1662 signature_function, |
| 1665 script_, | 1663 script_, |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 | 1805 |
| 1808 // Resolve and return the dynamic function of the given name in the superclass. | 1806 // Resolve and return the dynamic function of the given name in the superclass. |
| 1809 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1807 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1810 // the same name. If it is still not found, return noSuchMethod and | 1808 // the same name. If it is still not found, return noSuchMethod and |
| 1811 // set is_no_such_method to true.. | 1809 // set is_no_such_method to true.. |
| 1812 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1810 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1813 const String& name, | 1811 const String& name, |
| 1814 ArgumentListNode* arguments, | 1812 ArgumentListNode* arguments, |
| 1815 bool resolve_getter, | 1813 bool resolve_getter, |
| 1816 bool* is_no_such_method) { | 1814 bool* is_no_such_method) { |
| 1817 const Class& super_class = Class::Handle( | 1815 const Class& super_class = Class::Handle(I, current_class().SuperClass()); |
| 1818 isolate(), current_class().SuperClass()); | |
| 1819 if (super_class.IsNull()) { | 1816 if (super_class.IsNull()) { |
| 1820 ErrorMsg(token_pos, "class '%s' does not have a superclass", | 1817 ErrorMsg(token_pos, "class '%s' does not have a superclass", |
| 1821 String::Handle(isolate(), current_class().Name()).ToCString()); | 1818 String::Handle(I, current_class().Name()).ToCString()); |
| 1822 } | 1819 } |
| 1823 Function& super_func = Function::Handle(isolate(), | 1820 Function& super_func = Function::Handle(I, |
| 1824 Resolver::ResolveDynamicAnyArgs(super_class, name)); | 1821 Resolver::ResolveDynamicAnyArgs(super_class, name)); |
| 1825 if (!super_func.IsNull() && | 1822 if (!super_func.IsNull() && |
| 1826 !super_func.AreValidArguments(arguments->length(), | 1823 !super_func.AreValidArguments(arguments->length(), |
| 1827 arguments->names(), | 1824 arguments->names(), |
| 1828 NULL)) { | 1825 NULL)) { |
| 1829 super_func = Function::null(); | 1826 super_func = Function::null(); |
| 1830 } else if (super_func.IsNull() && resolve_getter) { | 1827 } else if (super_func.IsNull() && resolve_getter) { |
| 1831 const String& getter_name = String::ZoneHandle(I, Field::GetterName(name)); | 1828 const String& getter_name = String::ZoneHandle(I, Field::GetterName(name)); |
| 1832 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); | 1829 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); |
| 1833 ASSERT(super_func.IsNull() || | 1830 ASSERT(super_func.IsNull() || |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2057 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, | 2054 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
| 2058 intptr_t token_pos, | 2055 intptr_t token_pos, |
| 2059 AstNode* receiver) { | 2056 AstNode* receiver) { |
| 2060 Function& implicit_closure_function = | 2057 Function& implicit_closure_function = |
| 2061 Function::ZoneHandle(I, func.ImplicitClosureFunction()); | 2058 Function::ZoneHandle(I, func.ImplicitClosureFunction()); |
| 2062 if (receiver != NULL) { | 2059 if (receiver != NULL) { |
| 2063 // If we create an implicit instance closure from inside a closure of a | 2060 // If we create an implicit instance closure from inside a closure of a |
| 2064 // parameterized class, make sure that the receiver is captured as | 2061 // parameterized class, make sure that the receiver is captured as |
| 2065 // instantiator. | 2062 // instantiator. |
| 2066 if (current_block_->scope->function_level() > 0) { | 2063 if (current_block_->scope->function_level() > 0) { |
| 2067 const Class& signature_class = Class::Handle(isolate(), | 2064 const Class& signature_class = Class::Handle(I, |
| 2068 implicit_closure_function.signature_class()); | 2065 implicit_closure_function.signature_class()); |
| 2069 if (signature_class.NumTypeParameters() > 0) { | 2066 if (signature_class.NumTypeParameters() > 0) { |
| 2070 CaptureInstantiator(); | 2067 CaptureInstantiator(); |
| 2071 } | 2068 } |
| 2072 } | 2069 } |
| 2073 } | 2070 } |
| 2074 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2071 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 2075 } | 2072 } |
| 2076 | 2073 |
| 2077 | 2074 |
| 2078 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2075 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
| 2079 intptr_t field_pos) { | 2076 intptr_t field_pos) { |
| 2080 TRACE_PARSER("ParseSuperFieldAccess"); | 2077 TRACE_PARSER("ParseSuperFieldAccess"); |
| 2081 const Class& super_class = Class::ZoneHandle(I, current_class().SuperClass()); | 2078 const Class& super_class = Class::ZoneHandle(I, current_class().SuperClass()); |
| 2082 if (super_class.IsNull()) { | 2079 if (super_class.IsNull()) { |
| 2083 ErrorMsg("class '%s' does not have a superclass", | 2080 ErrorMsg("class '%s' does not have a superclass", |
| 2084 String::Handle(isolate(), current_class().Name()).ToCString()); | 2081 String::Handle(I, current_class().Name()).ToCString()); |
| 2085 } | 2082 } |
| 2086 AstNode* implicit_argument = LoadReceiver(field_pos); | 2083 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 2087 | 2084 |
| 2088 const String& getter_name = | 2085 const String& getter_name = |
| 2089 String::ZoneHandle(I, Field::GetterName(field_name)); | 2086 String::ZoneHandle(I, Field::GetterName(field_name)); |
| 2090 const Function& super_getter = Function::ZoneHandle(I, | 2087 const Function& super_getter = Function::ZoneHandle(I, |
| 2091 Resolver::ResolveDynamicAnyArgs(super_class, getter_name)); | 2088 Resolver::ResolveDynamicAnyArgs(super_class, getter_name)); |
| 2092 if (super_getter.IsNull()) { | 2089 if (super_getter.IsNull()) { |
| 2093 const String& setter_name = | 2090 const String& setter_name = |
| 2094 String::ZoneHandle(I, Field::SetterName(field_name)); | 2091 String::ZoneHandle(I, Field::SetterName(field_name)); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2114 } | 2111 } |
| 2115 return new StaticGetterNode( | 2112 return new StaticGetterNode( |
| 2116 field_pos, implicit_argument, true, super_class, field_name); | 2113 field_pos, implicit_argument, true, super_class, field_name); |
| 2117 } | 2114 } |
| 2118 | 2115 |
| 2119 | 2116 |
| 2120 void Parser::GenerateSuperConstructorCall(const Class& cls, | 2117 void Parser::GenerateSuperConstructorCall(const Class& cls, |
| 2121 intptr_t supercall_pos, | 2118 intptr_t supercall_pos, |
| 2122 LocalVariable* receiver, | 2119 LocalVariable* receiver, |
| 2123 ArgumentListNode* forwarding_args) { | 2120 ArgumentListNode* forwarding_args) { |
| 2124 const Class& super_class = Class::Handle(isolate(), cls.SuperClass()); | 2121 const Class& super_class = Class::Handle(I, cls.SuperClass()); |
| 2125 // Omit the implicit super() if there is no super class (i.e. | 2122 // Omit the implicit super() if there is no super class (i.e. |
| 2126 // we're not compiling class Object), or if the super class is an | 2123 // we're not compiling class Object), or if the super class is an |
| 2127 // artificially generated "wrapper class" that has no constructor. | 2124 // artificially generated "wrapper class" that has no constructor. |
| 2128 if (super_class.IsNull() || | 2125 if (super_class.IsNull() || |
| 2129 (super_class.num_native_fields() > 0 && | 2126 (super_class.num_native_fields() > 0 && |
| 2130 Class::Handle(isolate(), super_class.SuperClass()).IsObjectClass())) { | 2127 Class::Handle(I, super_class.SuperClass()).IsObjectClass())) { |
| 2131 return; | 2128 return; |
| 2132 } | 2129 } |
| 2133 String& super_ctor_name = String::Handle(isolate(), super_class.Name()); | 2130 String& super_ctor_name = String::Handle(I, super_class.Name()); |
| 2134 super_ctor_name = String::Concat(super_ctor_name, Symbols::Dot()); | 2131 super_ctor_name = String::Concat(super_ctor_name, Symbols::Dot()); |
| 2135 | 2132 |
| 2136 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2133 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 2137 // Implicit 'this' parameter is the first argument. | 2134 // Implicit 'this' parameter is the first argument. |
| 2138 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2135 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
| 2139 arguments->Add(implicit_argument); | 2136 arguments->Add(implicit_argument); |
| 2140 // Implicit construction phase parameter is second argument. | 2137 // Implicit construction phase parameter is second argument. |
| 2141 AstNode* phase_parameter = | 2138 AstNode* phase_parameter = |
| 2142 new LiteralNode(supercall_pos, | 2139 new LiteralNode(supercall_pos, |
| 2143 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll))); | 2140 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll))); |
| 2144 arguments->Add(phase_parameter); | 2141 arguments->Add(phase_parameter); |
| 2145 | 2142 |
| 2146 // If this is a super call in a forwarding constructor, add the user- | 2143 // If this is a super call in a forwarding constructor, add the user- |
| 2147 // defined arguments to the super call and adjust the the super | 2144 // defined arguments to the super call and adjust the the super |
| 2148 // constructor name to the respective named constructor if necessary. | 2145 // constructor name to the respective named constructor if necessary. |
| 2149 if (forwarding_args != NULL) { | 2146 if (forwarding_args != NULL) { |
| 2150 for (int i = 0; i < forwarding_args->length(); i++) { | 2147 for (int i = 0; i < forwarding_args->length(); i++) { |
| 2151 arguments->Add(forwarding_args->NodeAt(i)); | 2148 arguments->Add(forwarding_args->NodeAt(i)); |
| 2152 } | 2149 } |
| 2153 String& ctor_name = String::Handle(isolate(), current_function().name()); | 2150 String& ctor_name = String::Handle(I, current_function().name()); |
| 2154 String& class_name = String::Handle(isolate(), cls.Name()); | 2151 String& class_name = String::Handle(I, cls.Name()); |
| 2155 if (ctor_name.Length() > class_name.Length() + 1) { | 2152 if (ctor_name.Length() > class_name.Length() + 1) { |
| 2156 // Generating a forwarding call to a named constructor 'C.n'. | 2153 // Generating a forwarding call to a named constructor 'C.n'. |
| 2157 // Add the constructor name 'n' to the super constructor. | 2154 // Add the constructor name 'n' to the super constructor. |
| 2158 ctor_name = String::SubString(ctor_name, class_name.Length() + 1); | 2155 ctor_name = String::SubString(ctor_name, class_name.Length() + 1); |
| 2159 super_ctor_name = String::Concat(super_ctor_name, ctor_name); | 2156 super_ctor_name = String::Concat(super_ctor_name, ctor_name); |
| 2160 } | 2157 } |
| 2161 } | 2158 } |
| 2162 | 2159 |
| 2163 // Resolve super constructor function and check arguments. | 2160 // Resolve super constructor function and check arguments. |
| 2164 const Function& super_ctor = Function::ZoneHandle(I, | 2161 const Function& super_ctor = Function::ZoneHandle(I, |
| 2165 super_class.LookupConstructor(super_ctor_name)); | 2162 super_class.LookupConstructor(super_ctor_name)); |
| 2166 if (super_ctor.IsNull()) { | 2163 if (super_ctor.IsNull()) { |
| 2167 ErrorMsg(supercall_pos, | 2164 ErrorMsg(supercall_pos, |
| 2168 "unresolved implicit call to super constructor '%s()'", | 2165 "unresolved implicit call to super constructor '%s()'", |
| 2169 String::Handle(isolate(), super_class.Name()).ToCString()); | 2166 String::Handle(I, super_class.Name()).ToCString()); |
| 2170 } | 2167 } |
| 2171 if (current_function().is_const() && !super_ctor.is_const()) { | 2168 if (current_function().is_const() && !super_ctor.is_const()) { |
| 2172 ErrorMsg(supercall_pos, "implicit call to non-const super constructor"); | 2169 ErrorMsg(supercall_pos, "implicit call to non-const super constructor"); |
| 2173 } | 2170 } |
| 2174 | 2171 |
| 2175 String& error_message = String::Handle(isolate()); | 2172 String& error_message = String::Handle(I); |
| 2176 if (!super_ctor.AreValidArguments(arguments->length(), | 2173 if (!super_ctor.AreValidArguments(arguments->length(), |
| 2177 arguments->names(), | 2174 arguments->names(), |
| 2178 &error_message)) { | 2175 &error_message)) { |
| 2179 ErrorMsg(supercall_pos, | 2176 ErrorMsg(supercall_pos, |
| 2180 "invalid arguments passed to super constructor '%s()': %s", | 2177 "invalid arguments passed to super constructor '%s()': %s", |
| 2181 String::Handle(isolate(), super_class.Name()).ToCString(), | 2178 String::Handle(I, super_class.Name()).ToCString(), |
| 2182 error_message.ToCString()); | 2179 error_message.ToCString()); |
| 2183 } | 2180 } |
| 2184 current_block_->statements->Add( | 2181 current_block_->statements->Add( |
| 2185 new StaticCallNode(supercall_pos, super_ctor, arguments)); | 2182 new StaticCallNode(supercall_pos, super_ctor, arguments)); |
| 2186 } | 2183 } |
| 2187 | 2184 |
| 2188 | 2185 |
| 2189 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 2186 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
| 2190 LocalVariable* receiver) { | 2187 LocalVariable* receiver) { |
| 2191 TRACE_PARSER("ParseSuperInitializer"); | 2188 TRACE_PARSER("ParseSuperInitializer"); |
| 2192 ASSERT(CurrentToken() == Token::kSUPER); | 2189 ASSERT(CurrentToken() == Token::kSUPER); |
| 2193 const intptr_t supercall_pos = TokenPos(); | 2190 const intptr_t supercall_pos = TokenPos(); |
| 2194 ConsumeToken(); | 2191 ConsumeToken(); |
| 2195 const Class& super_class = Class::Handle(isolate(), cls.SuperClass()); | 2192 const Class& super_class = Class::Handle(I, cls.SuperClass()); |
| 2196 ASSERT(!super_class.IsNull()); | 2193 ASSERT(!super_class.IsNull()); |
| 2197 String& ctor_name = String::Handle(isolate(), super_class.Name()); | 2194 String& ctor_name = String::Handle(I, super_class.Name()); |
| 2198 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 2195 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 2199 if (CurrentToken() == Token::kPERIOD) { | 2196 if (CurrentToken() == Token::kPERIOD) { |
| 2200 ConsumeToken(); | 2197 ConsumeToken(); |
| 2201 ctor_name = String::Concat(ctor_name, | 2198 ctor_name = String::Concat(ctor_name, |
| 2202 *ExpectIdentifier("constructor name expected")); | 2199 *ExpectIdentifier("constructor name expected")); |
| 2203 } | 2200 } |
| 2204 CheckToken(Token::kLPAREN, "parameter list expected"); | 2201 CheckToken(Token::kLPAREN, "parameter list expected"); |
| 2205 | 2202 |
| 2206 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2203 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 2207 // 'this' parameter is the first argument to super class constructor. | 2204 // 'this' parameter is the first argument to super class constructor. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2224 const Function& super_ctor = Function::ZoneHandle(I, | 2221 const Function& super_ctor = Function::ZoneHandle(I, |
| 2225 super_class.LookupConstructor(ctor_name)); | 2222 super_class.LookupConstructor(ctor_name)); |
| 2226 if (super_ctor.IsNull()) { | 2223 if (super_ctor.IsNull()) { |
| 2227 ErrorMsg(supercall_pos, | 2224 ErrorMsg(supercall_pos, |
| 2228 "super class constructor '%s' not found", | 2225 "super class constructor '%s' not found", |
| 2229 ctor_name.ToCString()); | 2226 ctor_name.ToCString()); |
| 2230 } | 2227 } |
| 2231 if (current_function().is_const() && !super_ctor.is_const()) { | 2228 if (current_function().is_const() && !super_ctor.is_const()) { |
| 2232 ErrorMsg(supercall_pos, "super constructor must be const"); | 2229 ErrorMsg(supercall_pos, "super constructor must be const"); |
| 2233 } | 2230 } |
| 2234 String& error_message = String::Handle(isolate()); | 2231 String& error_message = String::Handle(I); |
| 2235 if (!super_ctor.AreValidArguments(arguments->length(), | 2232 if (!super_ctor.AreValidArguments(arguments->length(), |
| 2236 arguments->names(), | 2233 arguments->names(), |
| 2237 &error_message)) { | 2234 &error_message)) { |
| 2238 ErrorMsg(supercall_pos, | 2235 ErrorMsg(supercall_pos, |
| 2239 "invalid arguments passed to super class constructor '%s': %s", | 2236 "invalid arguments passed to super class constructor '%s': %s", |
| 2240 ctor_name.ToCString(), | 2237 ctor_name.ToCString(), |
| 2241 error_message.ToCString()); | 2238 error_message.ToCString()); |
| 2242 } | 2239 } |
| 2243 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2240 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 2244 } | 2241 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2275 field_name.ToCString()); | 2272 field_name.ToCString()); |
| 2276 } | 2273 } |
| 2277 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); | 2274 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); |
| 2278 AstNode* instance = new LoadLocalNode(field_pos, receiver); | 2275 AstNode* instance = new LoadLocalNode(field_pos, receiver); |
| 2279 EnsureExpressionTemp(); | 2276 EnsureExpressionTemp(); |
| 2280 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); | 2277 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); |
| 2281 } | 2278 } |
| 2282 | 2279 |
| 2283 | 2280 |
| 2284 void Parser::CheckFieldsInitialized(const Class& cls) { | 2281 void Parser::CheckFieldsInitialized(const Class& cls) { |
| 2285 const Array& fields = Array::Handle(isolate(), cls.fields()); | 2282 const Array& fields = Array::Handle(I, cls.fields()); |
| 2286 Field& field = Field::Handle(isolate()); | 2283 Field& field = Field::Handle(I); |
| 2287 SequenceNode* initializers = current_block_->statements; | 2284 SequenceNode* initializers = current_block_->statements; |
| 2288 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 2285 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
| 2289 field ^= fields.At(field_num); | 2286 field ^= fields.At(field_num); |
| 2290 if (field.is_static()) { | 2287 if (field.is_static()) { |
| 2291 continue; | 2288 continue; |
| 2292 } | 2289 } |
| 2293 | 2290 |
| 2294 bool found = false; | 2291 bool found = false; |
| 2295 for (int i = 0; i < initializers->length(); i++) { | 2292 for (int i = 0; i < initializers->length(); i++) { |
| 2296 found = false; | 2293 found = false; |
| 2297 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { | 2294 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { |
| 2298 StoreInstanceFieldNode* initializer = | 2295 StoreInstanceFieldNode* initializer = |
| 2299 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); | 2296 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); |
| 2300 if (initializer->field().raw() == field.raw()) { | 2297 if (initializer->field().raw() == field.raw()) { |
| 2301 found = true; | 2298 found = true; |
| 2302 break; | 2299 break; |
| 2303 } | 2300 } |
| 2304 } | 2301 } |
| 2305 } | 2302 } |
| 2306 | 2303 |
| 2307 if (found) continue; | 2304 if (found) continue; |
| 2308 | 2305 |
| 2309 field.RecordStore(Object::Handle(isolate())); | 2306 field.RecordStore(Object::Handle(I)); |
| 2310 } | 2307 } |
| 2311 } | 2308 } |
| 2312 | 2309 |
| 2313 | 2310 |
| 2314 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2311 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
| 2315 // Only use this function if the initialized field originates | 2312 // Only use this function if the initialized field originates |
| 2316 // from a different class. We need to save and restore current | 2313 // from a different class. We need to save and restore current |
| 2317 // class, library, and token stream (script). | 2314 // class, library, and token stream (script). |
| 2318 ASSERT(current_class().raw() != field.origin()); | 2315 ASSERT(current_class().raw() != field.origin()); |
| 2319 const Class& saved_class = Class::Handle(isolate(), current_class().raw()); | 2316 const Class& saved_class = Class::Handle(I, current_class().raw()); |
| 2320 const Library& saved_library = Library::Handle(isolate(), library().raw()); | 2317 const Library& saved_library = Library::Handle(I, library().raw()); |
| 2321 const Script& saved_script = Script::Handle(isolate(), script().raw()); | 2318 const Script& saved_script = Script::Handle(I, script().raw()); |
| 2322 const intptr_t saved_token_pos = TokenPos(); | 2319 const intptr_t saved_token_pos = TokenPos(); |
| 2323 | 2320 |
| 2324 set_current_class(Class::Handle(isolate(), field.origin())); | 2321 set_current_class(Class::Handle(I, field.origin())); |
| 2325 set_library(Library::Handle(isolate(), current_class().library())); | 2322 set_library(Library::Handle(I, current_class().library())); |
| 2326 SetScript(Script::Handle(isolate(), current_class().script()), | 2323 SetScript(Script::Handle(I, current_class().script()), |
| 2327 field.token_pos()); | 2324 field.token_pos()); |
| 2328 | 2325 |
| 2329 ASSERT(IsIdentifier()); | 2326 ASSERT(IsIdentifier()); |
| 2330 ConsumeToken(); | 2327 ConsumeToken(); |
| 2331 ExpectToken(Token::kASSIGN); | 2328 ExpectToken(Token::kASSIGN); |
| 2332 AstNode* init_expr = NULL; | 2329 AstNode* init_expr = NULL; |
| 2333 intptr_t expr_pos = TokenPos(); | 2330 intptr_t expr_pos = TokenPos(); |
| 2334 if (field.is_const()) { | 2331 if (field.is_const()) { |
| 2335 init_expr = ParseConstExpr(); | 2332 init_expr = ParseConstExpr(); |
| 2336 } else { | 2333 } else { |
| 2337 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2334 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2338 if (init_expr->EvalConstExpr() != NULL) { | 2335 if (init_expr->EvalConstExpr() != NULL) { |
| 2339 init_expr = | 2336 init_expr = |
| 2340 new LiteralNode(field.token_pos(), | 2337 new LiteralNode(field.token_pos(), |
| 2341 EvaluateConstExpr(expr_pos, init_expr)); | 2338 EvaluateConstExpr(expr_pos, init_expr)); |
| 2342 } | 2339 } |
| 2343 } | 2340 } |
| 2344 set_current_class(saved_class); | 2341 set_current_class(saved_class); |
| 2345 set_library(saved_library); | 2342 set_library(saved_library); |
| 2346 SetScript(saved_script, saved_token_pos); | 2343 SetScript(saved_script, saved_token_pos); |
| 2347 return init_expr; | 2344 return init_expr; |
| 2348 } | 2345 } |
| 2349 | 2346 |
| 2350 | 2347 |
| 2351 void Parser::ParseInitializedInstanceFields(const Class& cls, | 2348 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 2352 LocalVariable* receiver, | 2349 LocalVariable* receiver, |
| 2353 GrowableArray<Field*>* initialized_fields) { | 2350 GrowableArray<Field*>* initialized_fields) { |
| 2354 TRACE_PARSER("ParseInitializedInstanceFields"); | 2351 TRACE_PARSER("ParseInitializedInstanceFields"); |
| 2355 const Array& fields = Array::Handle(isolate(), cls.fields()); | 2352 const Array& fields = Array::Handle(I, cls.fields()); |
| 2356 Field& f = Field::Handle(isolate()); | 2353 Field& f = Field::Handle(I); |
| 2357 const intptr_t saved_pos = TokenPos(); | 2354 const intptr_t saved_pos = TokenPos(); |
| 2358 for (int i = 0; i < fields.Length(); i++) { | 2355 for (int i = 0; i < fields.Length(); i++) { |
| 2359 f ^= fields.At(i); | 2356 f ^= fields.At(i); |
| 2360 if (!f.is_static() && f.has_initializer()) { | 2357 if (!f.is_static() && f.has_initializer()) { |
| 2361 Field& field = Field::ZoneHandle(I); | 2358 Field& field = Field::ZoneHandle(I); |
| 2362 field ^= fields.At(i); | 2359 field ^= fields.At(i); |
| 2363 if (field.is_final()) { | 2360 if (field.is_final()) { |
| 2364 // Final fields with initializer expression may not be initialized | 2361 // Final fields with initializer expression may not be initialized |
| 2365 // again by constructors. Remember that this field is already | 2362 // again by constructors. Remember that this field is already |
| 2366 // initialized. | 2363 // initialized. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2402 | 2399 |
| 2403 void Parser::CheckDuplicateFieldInit(intptr_t init_pos, | 2400 void Parser::CheckDuplicateFieldInit(intptr_t init_pos, |
| 2404 GrowableArray<Field*>* initialized_fields, | 2401 GrowableArray<Field*>* initialized_fields, |
| 2405 Field* field) { | 2402 Field* field) { |
| 2406 ASSERT(!field->is_static()); | 2403 ASSERT(!field->is_static()); |
| 2407 for (int i = 0; i < initialized_fields->length(); i++) { | 2404 for (int i = 0; i < initialized_fields->length(); i++) { |
| 2408 Field* initialized_field = (*initialized_fields)[i]; | 2405 Field* initialized_field = (*initialized_fields)[i]; |
| 2409 if (initialized_field->raw() == field->raw()) { | 2406 if (initialized_field->raw() == field->raw()) { |
| 2410 ErrorMsg(init_pos, | 2407 ErrorMsg(init_pos, |
| 2411 "duplicate initialization for field %s", | 2408 "duplicate initialization for field %s", |
| 2412 String::Handle(isolate(), field->name()).ToCString()); | 2409 String::Handle(I, field->name()).ToCString()); |
| 2413 } | 2410 } |
| 2414 } | 2411 } |
| 2415 initialized_fields->Add(field); | 2412 initialized_fields->Add(field); |
| 2416 } | 2413 } |
| 2417 | 2414 |
| 2418 | 2415 |
| 2419 void Parser::ParseInitializers(const Class& cls, | 2416 void Parser::ParseInitializers(const Class& cls, |
| 2420 LocalVariable* receiver, | 2417 LocalVariable* receiver, |
| 2421 GrowableArray<Field*>* initialized_fields) { | 2418 GrowableArray<Field*>* initialized_fields) { |
| 2422 TRACE_PARSER("ParseInitializers"); | 2419 TRACE_PARSER("ParseInitializers"); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2446 } | 2443 } |
| 2447 | 2444 |
| 2448 | 2445 |
| 2449 void Parser::ParseConstructorRedirection(const Class& cls, | 2446 void Parser::ParseConstructorRedirection(const Class& cls, |
| 2450 LocalVariable* receiver) { | 2447 LocalVariable* receiver) { |
| 2451 TRACE_PARSER("ParseConstructorRedirection"); | 2448 TRACE_PARSER("ParseConstructorRedirection"); |
| 2452 ExpectToken(Token::kCOLON); | 2449 ExpectToken(Token::kCOLON); |
| 2453 ASSERT(CurrentToken() == Token::kTHIS); | 2450 ASSERT(CurrentToken() == Token::kTHIS); |
| 2454 const intptr_t call_pos = TokenPos(); | 2451 const intptr_t call_pos = TokenPos(); |
| 2455 ConsumeToken(); | 2452 ConsumeToken(); |
| 2456 String& ctor_name = String::Handle(isolate(), cls.Name()); | 2453 String& ctor_name = String::Handle(I, cls.Name()); |
| 2457 | 2454 |
| 2458 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 2455 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 2459 if (CurrentToken() == Token::kPERIOD) { | 2456 if (CurrentToken() == Token::kPERIOD) { |
| 2460 ConsumeToken(); | 2457 ConsumeToken(); |
| 2461 ctor_name = String::Concat(ctor_name, | 2458 ctor_name = String::Concat(ctor_name, |
| 2462 *ExpectIdentifier("constructor name expected")); | 2459 *ExpectIdentifier("constructor name expected")); |
| 2463 } | 2460 } |
| 2464 CheckToken(Token::kLPAREN, "parameter list expected"); | 2461 CheckToken(Token::kLPAREN, "parameter list expected"); |
| 2465 | 2462 |
| 2466 ArgumentListNode* arguments = new ArgumentListNode(call_pos); | 2463 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
| 2467 // 'this' parameter is the first argument to constructor. | 2464 // 'this' parameter is the first argument to constructor. |
| 2468 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); | 2465 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); |
| 2469 arguments->Add(implicit_argument); | 2466 arguments->Add(implicit_argument); |
| 2470 // Construction phase parameter is second argument. | 2467 // Construction phase parameter is second argument. |
| 2471 LocalVariable* phase_param = LookupPhaseParameter(); | 2468 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2472 ASSERT(phase_param != NULL); | 2469 ASSERT(phase_param != NULL); |
| 2473 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); | 2470 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); |
| 2474 arguments->Add(phase_argument); | 2471 arguments->Add(phase_argument); |
| 2475 receiver->set_invisible(true); | 2472 receiver->set_invisible(true); |
| 2476 ParseActualParameters(arguments, kAllowConst); | 2473 ParseActualParameters(arguments, kAllowConst); |
| 2477 receiver->set_invisible(false); | 2474 receiver->set_invisible(false); |
| 2478 // Resolve the constructor. | 2475 // Resolve the constructor. |
| 2479 const Function& redirect_ctor = Function::ZoneHandle(I, | 2476 const Function& redirect_ctor = Function::ZoneHandle(I, |
| 2480 cls.LookupConstructor(ctor_name)); | 2477 cls.LookupConstructor(ctor_name)); |
| 2481 if (redirect_ctor.IsNull()) { | 2478 if (redirect_ctor.IsNull()) { |
| 2482 ErrorMsg(call_pos, "constructor '%s' not found", ctor_name.ToCString()); | 2479 ErrorMsg(call_pos, "constructor '%s' not found", ctor_name.ToCString()); |
| 2483 } | 2480 } |
| 2484 String& error_message = String::Handle(isolate()); | 2481 String& error_message = String::Handle(I); |
| 2485 if (!redirect_ctor.AreValidArguments(arguments->length(), | 2482 if (!redirect_ctor.AreValidArguments(arguments->length(), |
| 2486 arguments->names(), | 2483 arguments->names(), |
| 2487 &error_message)) { | 2484 &error_message)) { |
| 2488 ErrorMsg(call_pos, | 2485 ErrorMsg(call_pos, |
| 2489 "invalid arguments passed to constructor '%s': %s", | 2486 "invalid arguments passed to constructor '%s': %s", |
| 2490 ctor_name.ToCString(), | 2487 ctor_name.ToCString(), |
| 2491 error_message.ToCString()); | 2488 error_message.ToCString()); |
| 2492 } | 2489 } |
| 2493 current_block_->statements->Add( | 2490 current_block_->statements->Add( |
| 2494 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 2491 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2570 | 2567 |
| 2571 // Empty constructor body. | 2568 // Empty constructor body. |
| 2572 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 2569 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); |
| 2573 SequenceNode* statements = CloseBlock(); | 2570 SequenceNode* statements = CloseBlock(); |
| 2574 return statements; | 2571 return statements; |
| 2575 } | 2572 } |
| 2576 | 2573 |
| 2577 | 2574 |
| 2578 void Parser::CheckRecursiveInvocation() { | 2575 void Parser::CheckRecursiveInvocation() { |
| 2579 const GrowableObjectArray& pending_functions = | 2576 const GrowableObjectArray& pending_functions = |
| 2580 GrowableObjectArray::Handle(isolate(), | 2577 GrowableObjectArray::Handle(I, |
| 2581 isolate()->object_store()->pending_functions()); | 2578 I->object_store()->pending_functions()); |
| 2582 for (int i = 0; i < pending_functions.Length(); i++) { | 2579 for (int i = 0; i < pending_functions.Length(); i++) { |
| 2583 if (pending_functions.At(i) == current_function().raw()) { | 2580 if (pending_functions.At(i) == current_function().raw()) { |
| 2584 const String& fname = | 2581 const String& fname = |
| 2585 String::Handle(isolate(), current_function().UserVisibleName()); | 2582 String::Handle(I, current_function().UserVisibleName()); |
| 2586 ErrorMsg("circular dependency for function %s", fname.ToCString()); | 2583 ErrorMsg("circular dependency for function %s", fname.ToCString()); |
| 2587 } | 2584 } |
| 2588 } | 2585 } |
| 2589 ASSERT(!unregister_pending_function_); | 2586 ASSERT(!unregister_pending_function_); |
| 2590 pending_functions.Add(current_function()); | 2587 pending_functions.Add(current_function()); |
| 2591 unregister_pending_function_ = true; | 2588 unregister_pending_function_ = true; |
| 2592 } | 2589 } |
| 2593 | 2590 |
| 2594 | 2591 |
| 2595 // Parser is at the opening parenthesis of the formal parameter declaration | 2592 // Parser is at the opening parenthesis of the formal parameter declaration |
| 2596 // of function. Parse the formal parameters, initializers and code. | 2593 // of function. Parse the formal parameters, initializers and code. |
| 2597 SequenceNode* Parser::ParseConstructor(const Function& func, | 2594 SequenceNode* Parser::ParseConstructor(const Function& func, |
| 2598 Array* default_parameter_values) { | 2595 Array* default_parameter_values) { |
| 2599 TRACE_PARSER("ParseConstructor"); | 2596 TRACE_PARSER("ParseConstructor"); |
| 2600 ASSERT(func.IsConstructor()); | 2597 ASSERT(func.IsConstructor()); |
| 2601 ASSERT(!func.IsFactory()); | 2598 ASSERT(!func.IsFactory()); |
| 2602 ASSERT(!func.is_static()); | 2599 ASSERT(!func.is_static()); |
| 2603 ASSERT(!func.IsLocalFunction()); | 2600 ASSERT(!func.IsLocalFunction()); |
| 2604 const Class& cls = Class::Handle(isolate(), func.Owner()); | 2601 const Class& cls = Class::Handle(I, func.Owner()); |
| 2605 ASSERT(!cls.IsNull()); | 2602 ASSERT(!cls.IsNull()); |
| 2606 | 2603 |
| 2607 CheckRecursiveInvocation(); | 2604 CheckRecursiveInvocation(); |
| 2608 | 2605 |
| 2609 if (func.IsImplicitConstructor()) { | 2606 if (func.IsImplicitConstructor()) { |
| 2610 // Special case: implicit constructor. | 2607 // Special case: implicit constructor. |
| 2611 // The parser adds an implicit default constructor when a class | 2608 // The parser adds an implicit default constructor when a class |
| 2612 // does not have any explicit constructor or factory (see | 2609 // does not have any explicit constructor or factory (see |
| 2613 // Parser::AddImplicitConstructor). | 2610 // Parser::AddImplicitConstructor). |
| 2614 // There is no source text to parse. We just build the | 2611 // There is no source text to parse. We just build the |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2631 TokenPos(), | 2628 TokenPos(), |
| 2632 &Symbols::PhaseParameter(), | 2629 &Symbols::PhaseParameter(), |
| 2633 &Type::ZoneHandle(I, Type::SmiType())); | 2630 &Type::ZoneHandle(I, Type::SmiType())); |
| 2634 | 2631 |
| 2635 if (func.is_const()) { | 2632 if (func.is_const()) { |
| 2636 params.SetImplicitlyFinal(); | 2633 params.SetImplicitlyFinal(); |
| 2637 } | 2634 } |
| 2638 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 2635 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 2639 | 2636 |
| 2640 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2637 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 2641 ASSERT(AbstractType::Handle(isolate(), func.result_type()).IsResolved()); | 2638 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 2642 ASSERT(func.NumParameters() == params.parameters->length()); | 2639 ASSERT(func.NumParameters() == params.parameters->length()); |
| 2643 | 2640 |
| 2644 // Now populate function scope with the formal parameters. | 2641 // Now populate function scope with the formal parameters. |
| 2645 AddFormalParamsToScope(¶ms, current_block_->scope); | 2642 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2646 | 2643 |
| 2647 const bool is_redirecting_constructor = | 2644 const bool is_redirecting_constructor = |
| 2648 (CurrentToken() == Token::kCOLON) && | 2645 (CurrentToken() == Token::kCOLON) && |
| 2649 ((LookaheadToken(1) == Token::kTHIS) && | 2646 ((LookaheadToken(1) == Token::kTHIS) && |
| 2650 ((LookaheadToken(2) == Token::kLPAREN) || | 2647 ((LookaheadToken(2) == Token::kLPAREN) || |
| 2651 ((LookaheadToken(2) == Token::kPERIOD) && | 2648 ((LookaheadToken(2) == Token::kPERIOD) && |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2894 } | 2891 } |
| 2895 | 2892 |
| 2896 | 2893 |
| 2897 // Parser is at the opening parenthesis of the formal parameter | 2894 // Parser is at the opening parenthesis of the formal parameter |
| 2898 // declaration of the function or constructor. | 2895 // declaration of the function or constructor. |
| 2899 // Parse the formal parameters and code. | 2896 // Parse the formal parameters and code. |
| 2900 SequenceNode* Parser::ParseFunc(const Function& func, | 2897 SequenceNode* Parser::ParseFunc(const Function& func, |
| 2901 Array* default_parameter_values) { | 2898 Array* default_parameter_values) { |
| 2902 TRACE_PARSER("ParseFunc"); | 2899 TRACE_PARSER("ParseFunc"); |
| 2903 Function& saved_innermost_function = | 2900 Function& saved_innermost_function = |
| 2904 Function::Handle(isolate(), innermost_function().raw()); | 2901 Function::Handle(I, innermost_function().raw()); |
| 2905 innermost_function_ = func.raw(); | 2902 innermost_function_ = func.raw(); |
| 2906 | 2903 |
| 2907 // Save current try index. Try index starts at zero for each function. | 2904 // Save current try index. Try index starts at zero for each function. |
| 2908 intptr_t saved_try_index = last_used_try_index_; | 2905 intptr_t saved_try_index = last_used_try_index_; |
| 2909 last_used_try_index_ = 0; | 2906 last_used_try_index_ = 0; |
| 2910 | 2907 |
| 2911 // TODO(12455) : Need better validation mechanism. | 2908 // TODO(12455) : Need better validation mechanism. |
| 2912 | 2909 |
| 2913 if (func.IsConstructor()) { | 2910 if (func.IsConstructor()) { |
| 2914 SequenceNode* statements = ParseConstructor(func, default_parameter_values); | 2911 SequenceNode* statements = ParseConstructor(func, default_parameter_values); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2950 AddFormalParamsToScope(¶ms, current_block_->scope); | 2947 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2951 } else { | 2948 } else { |
| 2952 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 2949 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 2953 | 2950 |
| 2954 // The number of parameters and their type are not yet set in local | 2951 // The number of parameters and their type are not yet set in local |
| 2955 // functions, since they are not 'top-level' parsed. | 2952 // functions, since they are not 'top-level' parsed. |
| 2956 if (func.IsLocalFunction()) { | 2953 if (func.IsLocalFunction()) { |
| 2957 AddFormalParamsToFunction(¶ms, func); | 2954 AddFormalParamsToFunction(¶ms, func); |
| 2958 } | 2955 } |
| 2959 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2956 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 2960 ASSERT(AbstractType::Handle(isolate(), func.result_type()).IsResolved()); | 2957 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 2961 ASSERT(func.NumParameters() == params.parameters->length()); | 2958 ASSERT(func.NumParameters() == params.parameters->length()); |
| 2962 | 2959 |
| 2963 // Check whether the function has any field initializer formal parameters, | 2960 // Check whether the function has any field initializer formal parameters, |
| 2964 // which are not allowed in non-constructor functions. | 2961 // which are not allowed in non-constructor functions. |
| 2965 if (params.has_field_initializer) { | 2962 if (params.has_field_initializer) { |
| 2966 for (int i = 0; i < params.parameters->length(); i++) { | 2963 for (int i = 0; i < params.parameters->length(); i++) { |
| 2967 ParamDesc& param = (*params.parameters)[i]; | 2964 ParamDesc& param = (*params.parameters)[i]; |
| 2968 if (param.is_field_initializer) { | 2965 if (param.is_field_initializer) { |
| 2969 ErrorMsg(param.name_pos, | 2966 ErrorMsg(param.name_pos, |
| 2970 "field initializer only allowed in constructors"); | 2967 "field initializer only allowed in constructors"); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2985 // instantiate types. | 2982 // instantiate types. |
| 2986 CaptureInstantiator(); | 2983 CaptureInstantiator(); |
| 2987 } | 2984 } |
| 2988 } | 2985 } |
| 2989 } | 2986 } |
| 2990 | 2987 |
| 2991 OpenBlock(); // Open a nested scope for the outermost function block. | 2988 OpenBlock(); // Open a nested scope for the outermost function block. |
| 2992 intptr_t end_token_pos = 0; | 2989 intptr_t end_token_pos = 0; |
| 2993 if (CurrentToken() == Token::kLBRACE) { | 2990 if (CurrentToken() == Token::kLBRACE) { |
| 2994 ConsumeToken(); | 2991 ConsumeToken(); |
| 2995 if (String::Handle(isolate(), func.name()).Equals( | 2992 if (String::Handle(I, func.name()).Equals( |
| 2996 Symbols::EqualOperator())) { | 2993 Symbols::EqualOperator())) { |
| 2997 const Class& owner = Class::Handle(isolate(), func.Owner()); | 2994 const Class& owner = Class::Handle(I, func.Owner()); |
| 2998 if (!owner.IsObjectClass()) { | 2995 if (!owner.IsObjectClass()) { |
| 2999 AddEqualityNullCheck(); | 2996 AddEqualityNullCheck(); |
| 3000 } | 2997 } |
| 3001 } | 2998 } |
| 3002 ParseStatementSequence(); | 2999 ParseStatementSequence(); |
| 3003 end_token_pos = TokenPos(); | 3000 end_token_pos = TokenPos(); |
| 3004 ExpectToken(Token::kRBRACE); | 3001 ExpectToken(Token::kRBRACE); |
| 3005 } else if (CurrentToken() == Token::kARROW) { | 3002 } else if (CurrentToken() == Token::kARROW) { |
| 3006 ConsumeToken(); | 3003 ConsumeToken(); |
| 3007 if (String::Handle(isolate(), func.name()).Equals( | 3004 if (String::Handle(I, func.name()).Equals( |
| 3008 Symbols::EqualOperator())) { | 3005 Symbols::EqualOperator())) { |
| 3009 const Class& owner = Class::Handle(isolate(), func.Owner()); | 3006 const Class& owner = Class::Handle(I, func.Owner()); |
| 3010 if (!owner.IsObjectClass()) { | 3007 if (!owner.IsObjectClass()) { |
| 3011 AddEqualityNullCheck(); | 3008 AddEqualityNullCheck(); |
| 3012 } | 3009 } |
| 3013 } | 3010 } |
| 3014 const intptr_t expr_pos = TokenPos(); | 3011 const intptr_t expr_pos = TokenPos(); |
| 3015 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 3012 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 3016 ASSERT(expr != NULL); | 3013 ASSERT(expr != NULL); |
| 3017 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3014 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 3018 end_token_pos = TokenPos(); | 3015 end_token_pos = TokenPos(); |
| 3019 } else if (IsLiteral("native")) { | 3016 } else if (IsLiteral("native")) { |
| 3020 if (String::Handle(isolate(), func.name()).Equals( | 3017 if (String::Handle(I, func.name()).Equals( |
| 3021 Symbols::EqualOperator())) { | 3018 Symbols::EqualOperator())) { |
| 3022 const Class& owner = Class::Handle(isolate(), func.Owner()); | 3019 const Class& owner = Class::Handle(I, func.Owner()); |
| 3023 if (!owner.IsObjectClass()) { | 3020 if (!owner.IsObjectClass()) { |
| 3024 AddEqualityNullCheck(); | 3021 AddEqualityNullCheck(); |
| 3025 } | 3022 } |
| 3026 } | 3023 } |
| 3027 ParseNativeFunctionBlock(¶ms, func); | 3024 ParseNativeFunctionBlock(¶ms, func); |
| 3028 end_token_pos = TokenPos(); | 3025 end_token_pos = TokenPos(); |
| 3029 ExpectSemicolon(); | 3026 ExpectSemicolon(); |
| 3030 } else if (func.is_external()) { | 3027 } else if (func.is_external()) { |
| 3031 // Body of an external method contains a single throw. | 3028 // Body of an external method contains a single throw. |
| 3032 const String& function_name = String::ZoneHandle(I, func.name()); | 3029 const String& function_name = String::ZoneHandle(I, func.name()); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3144 if (is_top_level_ || | 3141 if (is_top_level_ || |
| 3145 !ResolveIdentInLocalScope(qual_ident->ident_pos, | 3142 !ResolveIdentInLocalScope(qual_ident->ident_pos, |
| 3146 *(qual_ident->ident), | 3143 *(qual_ident->ident), |
| 3147 NULL)) { | 3144 NULL)) { |
| 3148 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(I); | 3145 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(I); |
| 3149 if (!current_class().IsMixinApplication()) { | 3146 if (!current_class().IsMixinApplication()) { |
| 3150 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 3147 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 3151 } else { | 3148 } else { |
| 3152 // TODO(hausner): Should we resolve the prefix via the library scope | 3149 // TODO(hausner): Should we resolve the prefix via the library scope |
| 3153 // rather than via the class? | 3150 // rather than via the class? |
| 3154 Class& cls = Class::Handle(isolate(), | 3151 Class& cls = Class::Handle(I, parsed_function()->function().origin()); |
| 3155 parsed_function()->function().origin()); | |
| 3156 lib_prefix = cls.LookupLibraryPrefix(*(qual_ident->ident)); | 3152 lib_prefix = cls.LookupLibraryPrefix(*(qual_ident->ident)); |
| 3157 } | 3153 } |
| 3158 if (!lib_prefix.IsNull()) { | 3154 if (!lib_prefix.IsNull()) { |
| 3159 // We have a library prefix qualified identifier, unless the prefix is | 3155 // We have a library prefix qualified identifier, unless the prefix is |
| 3160 // shadowed by a type parameter in scope. | 3156 // shadowed by a type parameter in scope. |
| 3161 if (current_class().IsNull() || | 3157 if (current_class().IsNull() || |
| 3162 (current_class().LookupTypeParameter(*(qual_ident->ident)) == | 3158 (current_class().LookupTypeParameter(*(qual_ident->ident)) == |
| 3163 TypeParameter::null())) { | 3159 TypeParameter::null())) { |
| 3164 ConsumeToken(); // Consume the kPERIOD token. | 3160 ConsumeToken(); // Consume the kPERIOD token. |
| 3165 qual_ident->lib_prefix = &lib_prefix; | 3161 qual_ident->lib_prefix = &lib_prefix; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 method->name = &String::ZoneHandle(I, Field::SetterSymbol(*method->name)); | 3258 method->name = &String::ZoneHandle(I, Field::SetterSymbol(*method->name)); |
| 3263 } | 3259 } |
| 3264 if ((method->params.num_fixed_parameters != expected_num_parameters) || | 3260 if ((method->params.num_fixed_parameters != expected_num_parameters) || |
| 3265 (method->params.num_optional_parameters != 0)) { | 3261 (method->params.num_optional_parameters != 0)) { |
| 3266 ErrorMsg(method->name_pos, "illegal %s parameters", | 3262 ErrorMsg(method->name_pos, "illegal %s parameters", |
| 3267 method->IsGetter() ? "getter" : "setter"); | 3263 method->IsGetter() ? "getter" : "setter"); |
| 3268 } | 3264 } |
| 3269 } | 3265 } |
| 3270 | 3266 |
| 3271 // Parse redirecting factory constructor. | 3267 // Parse redirecting factory constructor. |
| 3272 Type& redirection_type = Type::Handle(isolate()); | 3268 Type& redirection_type = Type::Handle(I); |
| 3273 String& redirection_identifier = String::Handle(isolate()); | 3269 String& redirection_identifier = String::Handle(I); |
| 3274 bool is_redirecting = false; | 3270 bool is_redirecting = false; |
| 3275 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { | 3271 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
| 3276 // Default parameter values are disallowed in redirecting factories. | 3272 // Default parameter values are disallowed in redirecting factories. |
| 3277 if (method->params.has_explicit_default_values) { | 3273 if (method->params.has_explicit_default_values) { |
| 3278 ErrorMsg("redirecting factory '%s' may not specify default values " | 3274 ErrorMsg("redirecting factory '%s' may not specify default values " |
| 3279 "for optional parameters", | 3275 "for optional parameters", |
| 3280 method->name->ToCString()); | 3276 method->name->ToCString()); |
| 3281 } | 3277 } |
| 3282 if (method->has_external) { | 3278 if (method->has_external) { |
| 3283 ErrorMsg(TokenPos(), | 3279 ErrorMsg(TokenPos(), |
| 3284 "external factory constructor '%s' may not have redirection", | 3280 "external factory constructor '%s' may not have redirection", |
| 3285 method->name->ToCString()); | 3281 method->name->ToCString()); |
| 3286 } | 3282 } |
| 3287 ConsumeToken(); | 3283 ConsumeToken(); |
| 3288 const intptr_t type_pos = TokenPos(); | 3284 const intptr_t type_pos = TokenPos(); |
| 3289 is_redirecting = true; | 3285 is_redirecting = true; |
| 3290 const AbstractType& type = AbstractType::Handle(isolate(), | 3286 const AbstractType& type = AbstractType::Handle(I, |
| 3291 ParseType(ClassFinalizer::kResolveTypeParameters)); | 3287 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 3292 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3288 if (!type.IsMalformed() && type.IsTypeParameter()) { |
| 3293 // Replace the type with a malformed type and compile a throw when called. | 3289 // Replace the type with a malformed type and compile a throw when called. |
| 3294 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 3290 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
| 3295 Error::Handle(isolate()), // No previous error. | 3291 Error::Handle(I), // No previous error. |
| 3296 script_, | 3292 script_, |
| 3297 type_pos, | 3293 type_pos, |
| 3298 "factory '%s' may not redirect to type parameter '%s'", | 3294 "factory '%s' may not redirect to type parameter '%s'", |
| 3299 method->name->ToCString(), | 3295 method->name->ToCString(), |
| 3300 String::Handle(isolate(), type.UserVisibleName()).ToCString()); | 3296 String::Handle(I, type.UserVisibleName()).ToCString()); |
| 3301 } else { | 3297 } else { |
| 3302 // We handle malformed and malbounded redirection type at run time. | 3298 // We handle malformed and malbounded redirection type at run time. |
| 3303 redirection_type ^= type.raw(); | 3299 redirection_type ^= type.raw(); |
| 3304 } | 3300 } |
| 3305 if (CurrentToken() == Token::kPERIOD) { | 3301 if (CurrentToken() == Token::kPERIOD) { |
| 3306 // Named constructor or factory. | 3302 // Named constructor or factory. |
| 3307 ConsumeToken(); | 3303 ConsumeToken(); |
| 3308 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); | 3304 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
| 3309 } | 3305 } |
| 3310 } else if (CurrentToken() == Token::kCOLON) { | 3306 } else if (CurrentToken() == Token::kCOLON) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3450 RawFunction::Kind function_kind; | 3446 RawFunction::Kind function_kind; |
| 3451 if (method->IsFactoryOrConstructor()) { | 3447 if (method->IsFactoryOrConstructor()) { |
| 3452 function_kind = RawFunction::kConstructor; | 3448 function_kind = RawFunction::kConstructor; |
| 3453 } else if (method->IsGetter()) { | 3449 } else if (method->IsGetter()) { |
| 3454 function_kind = RawFunction::kGetterFunction; | 3450 function_kind = RawFunction::kGetterFunction; |
| 3455 } else if (method->IsSetter()) { | 3451 } else if (method->IsSetter()) { |
| 3456 function_kind = RawFunction::kSetterFunction; | 3452 function_kind = RawFunction::kSetterFunction; |
| 3457 } else { | 3453 } else { |
| 3458 function_kind = RawFunction::kRegularFunction; | 3454 function_kind = RawFunction::kRegularFunction; |
| 3459 } | 3455 } |
| 3460 Function& func = Function::Handle(isolate(), | 3456 Function& func = Function::Handle(I, |
| 3461 Function::New(*method->name, | 3457 Function::New(*method->name, |
| 3462 function_kind, | 3458 function_kind, |
| 3463 method->has_static, | 3459 method->has_static, |
| 3464 method->has_const, | 3460 method->has_const, |
| 3465 method->has_abstract, | 3461 method->has_abstract, |
| 3466 method->has_external, | 3462 method->has_external, |
| 3467 method->has_native, | 3463 method->has_native, |
| 3468 current_class(), | 3464 current_class(), |
| 3469 method->decl_begin_pos)); | 3465 method->decl_begin_pos)); |
| 3470 func.set_result_type(*method->type); | 3466 func.set_result_type(*method->type); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3516 } | 3512 } |
| 3517 if (field->has_external) { | 3513 if (field->has_external) { |
| 3518 ErrorMsg("keyword 'external' not allowed in field declaration"); | 3514 ErrorMsg("keyword 'external' not allowed in field declaration"); |
| 3519 } | 3515 } |
| 3520 if (field->has_factory) { | 3516 if (field->has_factory) { |
| 3521 ErrorMsg("keyword 'factory' not allowed in field declaration"); | 3517 ErrorMsg("keyword 'factory' not allowed in field declaration"); |
| 3522 } | 3518 } |
| 3523 if (!field->has_static && field->has_const) { | 3519 if (!field->has_static && field->has_const) { |
| 3524 ErrorMsg(field->name_pos, "instance field may not be 'const'"); | 3520 ErrorMsg(field->name_pos, "instance field may not be 'const'"); |
| 3525 } | 3521 } |
| 3526 Function& getter = Function::Handle(isolate()); | 3522 Function& getter = Function::Handle(I); |
| 3527 Function& setter = Function::Handle(isolate()); | 3523 Function& setter = Function::Handle(I); |
| 3528 Field& class_field = Field::ZoneHandle(I); | 3524 Field& class_field = Field::ZoneHandle(I); |
| 3529 Instance& init_value = Instance::Handle(isolate()); | 3525 Instance& init_value = Instance::Handle(I); |
| 3530 while (true) { | 3526 while (true) { |
| 3531 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3527 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3532 bool has_simple_literal = false; | 3528 bool has_simple_literal = false; |
| 3533 if (has_initializer) { | 3529 if (has_initializer) { |
| 3534 ConsumeToken(); | 3530 ConsumeToken(); |
| 3535 init_value = Object::sentinel().raw(); | 3531 init_value = Object::sentinel().raw(); |
| 3536 // For static fields, the initialization expression will be parsed | 3532 // For static fields, the initialization expression will be parsed |
| 3537 // through the kImplicitStaticFinalGetter method invocation/compilation. | 3533 // through the kImplicitStaticFinalGetter method invocation/compilation. |
| 3538 // For instance fields, the expression is parsed when a constructor | 3534 // For instance fields, the expression is parsed when a constructor |
| 3539 // is compiled. | 3535 // is compiled. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3580 // and rules out many fields from being unnecessary unboxing candidates. | 3576 // and rules out many fields from being unnecessary unboxing candidates. |
| 3581 if (!field->has_static && has_initializer && has_simple_literal) { | 3577 if (!field->has_static && has_initializer && has_simple_literal) { |
| 3582 class_field.RecordStore(init_value); | 3578 class_field.RecordStore(init_value); |
| 3583 } | 3579 } |
| 3584 | 3580 |
| 3585 // For static final fields (this includes static const fields), set value to | 3581 // For static final fields (this includes static const fields), set value to |
| 3586 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. | 3582 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. |
| 3587 if (field->has_static && has_initializer) { | 3583 if (field->has_static && has_initializer) { |
| 3588 class_field.set_value(init_value); | 3584 class_field.set_value(init_value); |
| 3589 if (!has_simple_literal) { | 3585 if (!has_simple_literal) { |
| 3590 String& getter_name = String::Handle(isolate(), | 3586 String& getter_name = String::Handle(I, |
| 3591 Field::GetterSymbol(*field->name)); | 3587 Field::GetterSymbol(*field->name)); |
| 3592 getter = Function::New(getter_name, | 3588 getter = Function::New(getter_name, |
| 3593 RawFunction::kImplicitStaticFinalGetter, | 3589 RawFunction::kImplicitStaticFinalGetter, |
| 3594 field->has_static, | 3590 field->has_static, |
| 3595 field->has_const, | 3591 field->has_const, |
| 3596 /* is_abstract = */ false, | 3592 /* is_abstract = */ false, |
| 3597 /* is_external = */ false, | 3593 /* is_external = */ false, |
| 3598 /* is_native = */ false, | 3594 /* is_native = */ false, |
| 3599 current_class(), | 3595 current_class(), |
| 3600 field->name_pos); | 3596 field->name_pos); |
| 3601 getter.set_result_type(*field->type); | 3597 getter.set_result_type(*field->type); |
| 3602 members->AddFunction(getter); | 3598 members->AddFunction(getter); |
| 3603 | 3599 |
| 3604 // Create initializer function for non-const fields. | 3600 // Create initializer function for non-const fields. |
| 3605 if (!class_field.is_const()) { | 3601 if (!class_field.is_const()) { |
| 3606 const Function& init_function = Function::ZoneHandle(I, | 3602 const Function& init_function = Function::ZoneHandle(I, |
| 3607 Function::NewStaticInitializer(class_field)); | 3603 Function::NewStaticInitializer(class_field)); |
| 3608 members->AddFunction(init_function); | 3604 members->AddFunction(init_function); |
| 3609 } | 3605 } |
| 3610 } | 3606 } |
| 3611 } | 3607 } |
| 3612 | 3608 |
| 3613 // For instance fields, we create implicit getter and setter methods. | 3609 // For instance fields, we create implicit getter and setter methods. |
| 3614 if (!field->has_static) { | 3610 if (!field->has_static) { |
| 3615 String& getter_name = String::Handle(isolate(), | 3611 String& getter_name = String::Handle(I, |
| 3616 Field::GetterSymbol(*field->name)); | 3612 Field::GetterSymbol(*field->name)); |
| 3617 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 3613 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
| 3618 field->has_static, | 3614 field->has_static, |
| 3619 field->has_final, | 3615 field->has_final, |
| 3620 /* is_abstract = */ false, | 3616 /* is_abstract = */ false, |
| 3621 /* is_external = */ false, | 3617 /* is_external = */ false, |
| 3622 /* is_native = */ false, | 3618 /* is_native = */ false, |
| 3623 current_class(), | 3619 current_class(), |
| 3624 field->name_pos); | 3620 field->name_pos); |
| 3625 ParamList params; | 3621 ParamList params; |
| 3626 ASSERT(current_class().raw() == getter.Owner()); | 3622 ASSERT(current_class().raw() == getter.Owner()); |
| 3627 params.AddReceiver(ReceiverType(current_class()), field->name_pos); | 3623 params.AddReceiver(ReceiverType(current_class()), field->name_pos); |
| 3628 getter.set_result_type(*field->type); | 3624 getter.set_result_type(*field->type); |
| 3629 AddFormalParamsToFunction(¶ms, getter); | 3625 AddFormalParamsToFunction(¶ms, getter); |
| 3630 members->AddFunction(getter); | 3626 members->AddFunction(getter); |
| 3631 if (!field->has_final) { | 3627 if (!field->has_final) { |
| 3632 // Build a setter accessor for non-const fields. | 3628 // Build a setter accessor for non-const fields. |
| 3633 String& setter_name = String::Handle(isolate(), | 3629 String& setter_name = String::Handle(I, |
| 3634 Field::SetterSymbol(*field->name)); | 3630 Field::SetterSymbol(*field->name)); |
| 3635 setter = Function::New(setter_name, RawFunction::kImplicitSetter, | 3631 setter = Function::New(setter_name, RawFunction::kImplicitSetter, |
| 3636 field->has_static, | 3632 field->has_static, |
| 3637 field->has_final, | 3633 field->has_final, |
| 3638 /* is_abstract = */ false, | 3634 /* is_abstract = */ false, |
| 3639 /* is_external = */ false, | 3635 /* is_external = */ false, |
| 3640 /* is_native = */ false, | 3636 /* is_native = */ false, |
| 3641 current_class(), | 3637 current_class(), |
| 3642 field->name_pos); | 3638 field->name_pos); |
| 3643 ParamList params; | 3639 ParamList params; |
| 3644 ASSERT(current_class().raw() == setter.Owner()); | 3640 ASSERT(current_class().raw() == setter.Owner()); |
| 3645 params.AddReceiver(ReceiverType(current_class()), field->name_pos); | 3641 params.AddReceiver(ReceiverType(current_class()), field->name_pos); |
| 3646 params.AddFinalParameter(TokenPos(), | 3642 params.AddFinalParameter(TokenPos(), |
| 3647 &Symbols::Value(), | 3643 &Symbols::Value(), |
| 3648 field->type); | 3644 field->type); |
| 3649 setter.set_result_type(Type::Handle(isolate(), Type::VoidType())); | 3645 setter.set_result_type(Type::Handle(I, Type::VoidType())); |
| 3650 AddFormalParamsToFunction(¶ms, setter); | 3646 AddFormalParamsToFunction(¶ms, setter); |
| 3651 members->AddFunction(setter); | 3647 members->AddFunction(setter); |
| 3652 } | 3648 } |
| 3653 } | 3649 } |
| 3654 | 3650 |
| 3655 if (CurrentToken() != Token::kCOMMA) { | 3651 if (CurrentToken() != Token::kCOMMA) { |
| 3656 break; | 3652 break; |
| 3657 } | 3653 } |
| 3658 ConsumeToken(); | 3654 ConsumeToken(); |
| 3659 field->name_pos = this->TokenPos(); | 3655 field->name_pos = this->TokenPos(); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3803 members->class_name().ToCString()); | 3799 members->class_name().ToCString()); |
| 3804 } | 3800 } |
| 3805 } else if (member.has_static) { | 3801 } else if (member.has_static) { |
| 3806 ErrorMsg(member.name_pos, "constructor cannot be static"); | 3802 ErrorMsg(member.name_pos, "constructor cannot be static"); |
| 3807 } | 3803 } |
| 3808 if (member.type != NULL) { | 3804 if (member.type != NULL) { |
| 3809 ErrorMsg(member.name_pos, "constructor must not specify return type"); | 3805 ErrorMsg(member.name_pos, "constructor must not specify return type"); |
| 3810 } | 3806 } |
| 3811 // Do not bypass class resolution by using current_class() directly, since | 3807 // Do not bypass class resolution by using current_class() directly, since |
| 3812 // it may be a patch class. | 3808 // it may be a patch class. |
| 3813 const Object& result_type_class = Object::Handle(isolate(), | 3809 const Object& result_type_class = Object::Handle(I, |
| 3814 UnresolvedClass::New(LibraryPrefix::Handle(isolate()), | 3810 UnresolvedClass::New(LibraryPrefix::Handle(I), |
| 3815 *member.name, | 3811 *member.name, |
| 3816 member.name_pos)); | 3812 member.name_pos)); |
| 3817 // The type arguments of the result type are the type parameters of the | 3813 // The type arguments of the result type are the type parameters of the |
| 3818 // current class. Note that in the case of a patch class, they are copied | 3814 // current class. Note that in the case of a patch class, they are copied |
| 3819 // from the class being patched. | 3815 // from the class being patched. |
| 3820 member.type = &Type::ZoneHandle(I, Type::New( | 3816 member.type = &Type::ZoneHandle(I, Type::New( |
| 3821 result_type_class, | 3817 result_type_class, |
| 3822 TypeArguments::Handle(isolate(), current_class().type_parameters()), | 3818 TypeArguments::Handle(I, current_class().type_parameters()), |
| 3823 member.name_pos)); | 3819 member.name_pos)); |
| 3824 | 3820 |
| 3825 // We must be dealing with a constructor or named constructor. | 3821 // We must be dealing with a constructor or named constructor. |
| 3826 member.kind = RawFunction::kConstructor; | 3822 member.kind = RawFunction::kConstructor; |
| 3827 *member.name = String::Concat(*member.name, Symbols::Dot()); | 3823 *member.name = String::Concat(*member.name, Symbols::Dot()); |
| 3828 if (CurrentToken() == Token::kPERIOD) { | 3824 if (CurrentToken() == Token::kPERIOD) { |
| 3829 // Named constructor. | 3825 // Named constructor. |
| 3830 ConsumeToken(); | 3826 ConsumeToken(); |
| 3831 member.dict_name = ExpectIdentifier("identifier expected"); | 3827 member.dict_name = ExpectIdentifier("identifier expected"); |
| 3832 *member.name = String::Concat(*member.name, *member.dict_name); | 3828 *member.name = String::Concat(*member.name, *member.dict_name); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3935 } else if (CurrentToken() == Token::kABSTRACT) { | 3931 } else if (CurrentToken() == Token::kABSTRACT) { |
| 3936 is_abstract = true; | 3932 is_abstract = true; |
| 3937 ConsumeToken(); | 3933 ConsumeToken(); |
| 3938 } | 3934 } |
| 3939 ExpectToken(Token::kCLASS); | 3935 ExpectToken(Token::kCLASS); |
| 3940 const intptr_t classname_pos = TokenPos(); | 3936 const intptr_t classname_pos = TokenPos(); |
| 3941 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 3937 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 3942 if (FLAG_trace_parser) { | 3938 if (FLAG_trace_parser) { |
| 3943 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 3939 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 3944 } | 3940 } |
| 3945 Class& cls = Class::Handle(isolate()); | 3941 Class& cls = Class::Handle(I); |
| 3946 TypeArguments& orig_type_parameters = TypeArguments::Handle(isolate()); | 3942 TypeArguments& orig_type_parameters = TypeArguments::Handle(I); |
| 3947 Object& obj = Object::Handle(isolate(), | 3943 Object& obj = Object::Handle(I, |
| 3948 library_.LookupLocalObject(class_name)); | 3944 library_.LookupLocalObject(class_name)); |
| 3949 if (obj.IsNull()) { | 3945 if (obj.IsNull()) { |
| 3950 if (is_patch) { | 3946 if (is_patch) { |
| 3951 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", | 3947 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", |
| 3952 class_name.ToCString()); | 3948 class_name.ToCString()); |
| 3953 } | 3949 } |
| 3954 cls = Class::New(class_name, script_, classname_pos); | 3950 cls = Class::New(class_name, script_, classname_pos); |
| 3955 library_.AddClass(cls); | 3951 library_.AddClass(cls); |
| 3956 } else { | 3952 } else { |
| 3957 if (!obj.IsClass()) { | 3953 if (!obj.IsClass()) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3982 cls.set_token_pos(classname_pos); | 3978 cls.set_token_pos(classname_pos); |
| 3983 } | 3979 } |
| 3984 } | 3980 } |
| 3985 ASSERT(!cls.IsNull()); | 3981 ASSERT(!cls.IsNull()); |
| 3986 ASSERT(cls.functions() == Object::empty_array().raw()); | 3982 ASSERT(cls.functions() == Object::empty_array().raw()); |
| 3987 set_current_class(cls); | 3983 set_current_class(cls); |
| 3988 ParseTypeParameters(cls); | 3984 ParseTypeParameters(cls); |
| 3989 if (is_patch) { | 3985 if (is_patch) { |
| 3990 // Check that the new type parameters are identical to the original ones. | 3986 // Check that the new type parameters are identical to the original ones. |
| 3991 const TypeArguments& new_type_parameters = | 3987 const TypeArguments& new_type_parameters = |
| 3992 TypeArguments::Handle(isolate(), cls.type_parameters()); | 3988 TypeArguments::Handle(I, cls.type_parameters()); |
| 3993 const int new_type_params_count = | 3989 const int new_type_params_count = |
| 3994 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); | 3990 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); |
| 3995 const int orig_type_params_count = | 3991 const int orig_type_params_count = |
| 3996 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); | 3992 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); |
| 3997 if (new_type_params_count != orig_type_params_count) { | 3993 if (new_type_params_count != orig_type_params_count) { |
| 3998 ErrorMsg(classname_pos, | 3994 ErrorMsg(classname_pos, |
| 3999 "class '%s' must be patched with identical type parameters", | 3995 "class '%s' must be patched with identical type parameters", |
| 4000 class_name.ToCString()); | 3996 class_name.ToCString()); |
| 4001 } | 3997 } |
| 4002 TypeParameter& new_type_param = TypeParameter::Handle(isolate()); | 3998 TypeParameter& new_type_param = TypeParameter::Handle(I); |
| 4003 TypeParameter& orig_type_param = TypeParameter::Handle(isolate()); | 3999 TypeParameter& orig_type_param = TypeParameter::Handle(I); |
| 4004 String& new_name = String::Handle(isolate()); | 4000 String& new_name = String::Handle(I); |
| 4005 String& orig_name = String::Handle(isolate()); | 4001 String& orig_name = String::Handle(I); |
| 4006 AbstractType& new_bound = AbstractType::Handle(isolate()); | 4002 AbstractType& new_bound = AbstractType::Handle(I); |
| 4007 AbstractType& orig_bound = AbstractType::Handle(isolate()); | 4003 AbstractType& orig_bound = AbstractType::Handle(I); |
| 4008 for (int i = 0; i < new_type_params_count; i++) { | 4004 for (int i = 0; i < new_type_params_count; i++) { |
| 4009 new_type_param ^= new_type_parameters.TypeAt(i); | 4005 new_type_param ^= new_type_parameters.TypeAt(i); |
| 4010 orig_type_param ^= orig_type_parameters.TypeAt(i); | 4006 orig_type_param ^= orig_type_parameters.TypeAt(i); |
| 4011 new_name = new_type_param.name(); | 4007 new_name = new_type_param.name(); |
| 4012 orig_name = orig_type_param.name(); | 4008 orig_name = orig_type_param.name(); |
| 4013 if (!new_name.Equals(orig_name)) { | 4009 if (!new_name.Equals(orig_name)) { |
| 4014 ErrorMsg(new_type_param.token_pos(), | 4010 ErrorMsg(new_type_param.token_pos(), |
| 4015 "type parameter '%s' of patch class '%s' does not match " | 4011 "type parameter '%s' of patch class '%s' does not match " |
| 4016 "original type parameter '%s'", | 4012 "original type parameter '%s'", |
| 4017 new_name.ToCString(), | 4013 new_name.ToCString(), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4040 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); | 4036 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 4041 } | 4037 } |
| 4042 | 4038 |
| 4043 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | 4039 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
| 4044 if (is_mixin_declaration && is_patch) { | 4040 if (is_mixin_declaration && is_patch) { |
| 4045 ErrorMsg(classname_pos, | 4041 ErrorMsg(classname_pos, |
| 4046 "mixin application '%s' may not be a patch class", | 4042 "mixin application '%s' may not be a patch class", |
| 4047 class_name.ToCString()); | 4043 class_name.ToCString()); |
| 4048 } | 4044 } |
| 4049 | 4045 |
| 4050 AbstractType& super_type = Type::Handle(isolate()); | 4046 AbstractType& super_type = Type::Handle(I); |
| 4051 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 4047 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
| 4052 ConsumeToken(); // extends or = | 4048 ConsumeToken(); // extends or = |
| 4053 const intptr_t type_pos = TokenPos(); | 4049 const intptr_t type_pos = TokenPos(); |
| 4054 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4050 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4055 if (super_type.IsMalformedOrMalbounded()) { | 4051 if (super_type.IsMalformedOrMalbounded()) { |
| 4056 ErrorMsg(Error::Handle(isolate(), super_type.error())); | 4052 ErrorMsg(Error::Handle(I, super_type.error())); |
| 4057 } | 4053 } |
| 4058 if (super_type.IsDynamicType()) { | 4054 if (super_type.IsDynamicType()) { |
| 4059 // Unlikely here, since super type is not resolved yet. | 4055 // Unlikely here, since super type is not resolved yet. |
| 4060 ErrorMsg(type_pos, | 4056 ErrorMsg(type_pos, |
| 4061 "class '%s' may not extend 'dynamic'", | 4057 "class '%s' may not extend 'dynamic'", |
| 4062 class_name.ToCString()); | 4058 class_name.ToCString()); |
| 4063 } | 4059 } |
| 4064 if (super_type.IsTypeParameter()) { | 4060 if (super_type.IsTypeParameter()) { |
| 4065 ErrorMsg(type_pos, | 4061 ErrorMsg(type_pos, |
| 4066 "class '%s' may not extend type parameter '%s'", | 4062 "class '%s' may not extend type parameter '%s'", |
| 4067 class_name.ToCString(), | 4063 class_name.ToCString(), |
| 4068 String::Handle(isolate(), | 4064 String::Handle(I, |
| 4069 super_type.UserVisibleName()).ToCString()); | 4065 super_type.UserVisibleName()).ToCString()); |
| 4070 } | 4066 } |
| 4071 // The class finalizer will check whether the super type is malbounded. | 4067 // The class finalizer will check whether the super type is malbounded. |
| 4072 if (is_mixin_declaration) { | 4068 if (is_mixin_declaration) { |
| 4073 if (CurrentToken() != Token::kWITH) { | 4069 if (CurrentToken() != Token::kWITH) { |
| 4074 ErrorMsg("mixin application clause 'with type' expected"); | 4070 ErrorMsg("mixin application clause 'with type' expected"); |
| 4075 } | 4071 } |
| 4076 cls.set_is_mixin_app_alias(); | 4072 cls.set_is_mixin_app_alias(); |
| 4077 cls.set_is_synthesized_class(); | 4073 cls.set_is_synthesized_class(); |
| 4078 } | 4074 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4111 ExpectToken(Token::kRBRACE); | 4107 ExpectToken(Token::kRBRACE); |
| 4112 } | 4108 } |
| 4113 } | 4109 } |
| 4114 | 4110 |
| 4115 | 4111 |
| 4116 void Parser::ParseClassDefinition(const Class& cls) { | 4112 void Parser::ParseClassDefinition(const Class& cls) { |
| 4117 TRACE_PARSER("ParseClassDefinition"); | 4113 TRACE_PARSER("ParseClassDefinition"); |
| 4118 CompilerStats::num_classes_compiled++; | 4114 CompilerStats::num_classes_compiled++; |
| 4119 set_current_class(cls); | 4115 set_current_class(cls); |
| 4120 is_top_level_ = true; | 4116 is_top_level_ = true; |
| 4121 String& class_name = String::Handle(isolate(), cls.Name()); | 4117 String& class_name = String::Handle(I, cls.Name()); |
| 4122 const intptr_t class_pos = TokenPos(); | 4118 const intptr_t class_pos = TokenPos(); |
| 4123 ClassDesc members(cls, class_name, false, class_pos); | 4119 ClassDesc members(cls, class_name, false, class_pos); |
| 4124 while (CurrentToken() != Token::kLBRACE) { | 4120 while (CurrentToken() != Token::kLBRACE) { |
| 4125 ConsumeToken(); | 4121 ConsumeToken(); |
| 4126 } | 4122 } |
| 4127 ExpectToken(Token::kLBRACE); | 4123 ExpectToken(Token::kLBRACE); |
| 4128 while (CurrentToken() != Token::kRBRACE) { | 4124 while (CurrentToken() != Token::kRBRACE) { |
| 4129 intptr_t metadata_pos = SkipMetadata(); | 4125 intptr_t metadata_pos = SkipMetadata(); |
| 4130 ParseClassMemberDefinition(&members, metadata_pos); | 4126 ParseClassMemberDefinition(&members, metadata_pos); |
| 4131 } | 4127 } |
| 4132 ExpectToken(Token::kRBRACE); | 4128 ExpectToken(Token::kRBRACE); |
| 4133 | 4129 |
| 4134 CheckConstructors(&members); | 4130 CheckConstructors(&members); |
| 4135 | 4131 |
| 4136 // Need to compute this here since MakeArray() will clear the | 4132 // Need to compute this here since MakeArray() will clear the |
| 4137 // functions array in members. | 4133 // functions array in members. |
| 4138 const bool need_implicit_constructor = | 4134 const bool need_implicit_constructor = |
| 4139 !members.has_constructor() && !cls.is_patch(); | 4135 !members.has_constructor() && !cls.is_patch(); |
| 4140 | 4136 |
| 4141 cls.AddFields(members.fields()); | 4137 cls.AddFields(members.fields()); |
| 4142 | 4138 |
| 4143 // Creating a new array for functions marks the class as parsed. | 4139 // Creating a new array for functions marks the class as parsed. |
| 4144 const Array& array = Array::Handle(isolate(), | 4140 const Array& array = Array::Handle(I, |
| 4145 Array::MakeArray(members.functions())); | 4141 Array::MakeArray(members.functions())); |
| 4146 cls.SetFunctions(array); | 4142 cls.SetFunctions(array); |
| 4147 | 4143 |
| 4148 // Add an implicit constructor if no explicit constructor is present. | 4144 // Add an implicit constructor if no explicit constructor is present. |
| 4149 // No implicit constructors are needed for patch classes. | 4145 // No implicit constructors are needed for patch classes. |
| 4150 if (need_implicit_constructor) { | 4146 if (need_implicit_constructor) { |
| 4151 AddImplicitConstructor(cls); | 4147 AddImplicitConstructor(cls); |
| 4152 } | 4148 } |
| 4153 | 4149 |
| 4154 if (cls.is_patch()) { | 4150 if (cls.is_patch()) { |
| 4155 // Apply the changes to the patched class looked up above. | 4151 // Apply the changes to the patched class looked up above. |
| 4156 Object& obj = Object::Handle(isolate(), | 4152 Object& obj = Object::Handle(I, |
| 4157 library_.LookupLocalObject(class_name)); | 4153 library_.LookupLocalObject(class_name)); |
| 4158 // The patched class must not be finalized yet. | 4154 // The patched class must not be finalized yet. |
| 4159 const Class& orig_class = Class::Cast(obj); | 4155 const Class& orig_class = Class::Cast(obj); |
| 4160 ASSERT(!orig_class.is_finalized()); | 4156 ASSERT(!orig_class.is_finalized()); |
| 4161 Error& error = Error::Handle(isolate()); | 4157 Error& error = Error::Handle(I); |
| 4162 if (!orig_class.ApplyPatch(cls, &error)) { | 4158 if (!orig_class.ApplyPatch(cls, &error)) { |
| 4163 AppendErrorMsg(error, class_pos, "applying patch failed"); | 4159 AppendErrorMsg(error, class_pos, "applying patch failed"); |
| 4164 } | 4160 } |
| 4165 } | 4161 } |
| 4166 } | 4162 } |
| 4167 | 4163 |
| 4168 | 4164 |
| 4169 // Add an implicit constructor to the given class. | 4165 // Add an implicit constructor to the given class. |
| 4170 void Parser::AddImplicitConstructor(const Class& cls) { | 4166 void Parser::AddImplicitConstructor(const Class& cls) { |
| 4171 // The implicit constructor is unnamed, has no explicit parameter. | 4167 // The implicit constructor is unnamed, has no explicit parameter. |
| 4172 String& ctor_name = String::ZoneHandle(I, cls.Name()); | 4168 String& ctor_name = String::ZoneHandle(I, cls.Name()); |
| 4173 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 4169 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 4174 ctor_name = Symbols::New(ctor_name); | 4170 ctor_name = Symbols::New(ctor_name); |
| 4175 // To indicate that this is an implicit constructor, we set the | 4171 // To indicate that this is an implicit constructor, we set the |
| 4176 // token position and end token position of the function | 4172 // token position and end token position of the function |
| 4177 // to the token position of the class. | 4173 // to the token position of the class. |
| 4178 Function& ctor = Function::Handle(isolate(), | 4174 Function& ctor = Function::Handle(I, |
| 4179 Function::New(ctor_name, | 4175 Function::New(ctor_name, |
| 4180 RawFunction::kConstructor, | 4176 RawFunction::kConstructor, |
| 4181 /* is_static = */ false, | 4177 /* is_static = */ false, |
| 4182 /* is_const = */ false, | 4178 /* is_const = */ false, |
| 4183 /* is_abstract = */ false, | 4179 /* is_abstract = */ false, |
| 4184 /* is_external = */ false, | 4180 /* is_external = */ false, |
| 4185 /* is_native = */ false, | 4181 /* is_native = */ false, |
| 4186 cls, | 4182 cls, |
| 4187 cls.token_pos())); | 4183 cls.token_pos())); |
| 4188 ctor.set_end_token_pos(ctor.token_pos()); | 4184 ctor.set_end_token_pos(ctor.token_pos()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4242 const GrowableObjectArray& pending_classes, | 4238 const GrowableObjectArray& pending_classes, |
| 4243 const Class& toplevel_class, | 4239 const Class& toplevel_class, |
| 4244 intptr_t metadata_pos) { | 4240 intptr_t metadata_pos) { |
| 4245 TRACE_PARSER("ParseMixinAppAlias"); | 4241 TRACE_PARSER("ParseMixinAppAlias"); |
| 4246 const intptr_t classname_pos = TokenPos(); | 4242 const intptr_t classname_pos = TokenPos(); |
| 4247 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4243 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4248 if (FLAG_trace_parser) { | 4244 if (FLAG_trace_parser) { |
| 4249 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4245 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
| 4250 class_name.ToCString()); | 4246 class_name.ToCString()); |
| 4251 } | 4247 } |
| 4252 const Object& obj = Object::Handle(isolate(), | 4248 const Object& obj = Object::Handle(I, |
| 4253 library_.LookupLocalObject(class_name)); | 4249 library_.LookupLocalObject(class_name)); |
| 4254 if (!obj.IsNull()) { | 4250 if (!obj.IsNull()) { |
| 4255 ErrorMsg(classname_pos, "'%s' is already defined", | 4251 ErrorMsg(classname_pos, "'%s' is already defined", |
| 4256 class_name.ToCString()); | 4252 class_name.ToCString()); |
| 4257 } | 4253 } |
| 4258 const Class& mixin_application = | 4254 const Class& mixin_application = |
| 4259 Class::Handle(isolate(), Class::New(class_name, script_, classname_pos)); | 4255 Class::Handle(I, Class::New(class_name, script_, classname_pos)); |
| 4260 mixin_application.set_is_mixin_app_alias(); | 4256 mixin_application.set_is_mixin_app_alias(); |
| 4261 library_.AddClass(mixin_application); | 4257 library_.AddClass(mixin_application); |
| 4262 set_current_class(mixin_application); | 4258 set_current_class(mixin_application); |
| 4263 ParseTypeParameters(mixin_application); | 4259 ParseTypeParameters(mixin_application); |
| 4264 | 4260 |
| 4265 ExpectToken(Token::kASSIGN); | 4261 ExpectToken(Token::kASSIGN); |
| 4266 | 4262 |
| 4267 if (CurrentToken() == Token::kABSTRACT) { | 4263 if (CurrentToken() == Token::kABSTRACT) { |
| 4268 mixin_application.set_is_abstract(); | 4264 mixin_application.set_is_abstract(); |
| 4269 ConsumeToken(); | 4265 ConsumeToken(); |
| 4270 } | 4266 } |
| 4271 | 4267 |
| 4272 const intptr_t type_pos = TokenPos(); | 4268 const intptr_t type_pos = TokenPos(); |
| 4273 AbstractType& type = | 4269 AbstractType& type = |
| 4274 AbstractType::Handle(isolate(), | 4270 AbstractType::Handle(I, |
| 4275 ParseType(ClassFinalizer::kResolveTypeParameters)); | 4271 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 4276 if (type.IsTypeParameter()) { | 4272 if (type.IsTypeParameter()) { |
| 4277 ErrorMsg(type_pos, | 4273 ErrorMsg(type_pos, |
| 4278 "class '%s' may not extend type parameter '%s'", | 4274 "class '%s' may not extend type parameter '%s'", |
| 4279 class_name.ToCString(), | 4275 class_name.ToCString(), |
| 4280 String::Handle(isolate(), type.UserVisibleName()).ToCString()); | 4276 String::Handle(I, type.UserVisibleName()).ToCString()); |
| 4281 } | 4277 } |
| 4282 | 4278 |
| 4283 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 4279 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
| 4284 type = ParseMixins(type); | 4280 type = ParseMixins(type); |
| 4285 | 4281 |
| 4286 mixin_application.set_super_type(type); | 4282 mixin_application.set_super_type(type); |
| 4287 mixin_application.set_is_synthesized_class(); | 4283 mixin_application.set_is_synthesized_class(); |
| 4288 | 4284 |
| 4289 // This mixin application alias needs an implicit constructor, but it is | 4285 // This mixin application alias needs an implicit constructor, but it is |
| 4290 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4286 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4348 | 4344 |
| 4349 if (IsMixinAppAlias()) { | 4345 if (IsMixinAppAlias()) { |
| 4350 if (FLAG_warn_mixin_typedef) { | 4346 if (FLAG_warn_mixin_typedef) { |
| 4351 Warning("deprecated mixin application typedef"); | 4347 Warning("deprecated mixin application typedef"); |
| 4352 } | 4348 } |
| 4353 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); | 4349 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); |
| 4354 return; | 4350 return; |
| 4355 } | 4351 } |
| 4356 | 4352 |
| 4357 // Parse the result type of the function type. | 4353 // Parse the result type of the function type. |
| 4358 AbstractType& result_type = Type::Handle(isolate(), Type::DynamicType()); | 4354 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); |
| 4359 if (CurrentToken() == Token::kVOID) { | 4355 if (CurrentToken() == Token::kVOID) { |
| 4360 ConsumeToken(); | 4356 ConsumeToken(); |
| 4361 result_type = Type::VoidType(); | 4357 result_type = Type::VoidType(); |
| 4362 } else if (!IsFunctionTypeAliasName()) { | 4358 } else if (!IsFunctionTypeAliasName()) { |
| 4363 // Type annotations in typedef are never ignored, even in production mode. | 4359 // Type annotations in typedef are never ignored, even in production mode. |
| 4364 // Wait until we have an owner class before resolving the result type. | 4360 // Wait until we have an owner class before resolving the result type. |
| 4365 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 4361 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 4366 } | 4362 } |
| 4367 | 4363 |
| 4368 const intptr_t alias_name_pos = TokenPos(); | 4364 const intptr_t alias_name_pos = TokenPos(); |
| 4369 const String* alias_name = | 4365 const String* alias_name = |
| 4370 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 4366 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
| 4371 | 4367 |
| 4372 // Lookup alias name and report an error if it is already defined in | 4368 // Lookup alias name and report an error if it is already defined in |
| 4373 // the library scope. | 4369 // the library scope. |
| 4374 const Object& obj = Object::Handle(isolate(), | 4370 const Object& obj = Object::Handle(I, |
| 4375 library_.LookupLocalObject(*alias_name)); | 4371 library_.LookupLocalObject(*alias_name)); |
| 4376 if (!obj.IsNull()) { | 4372 if (!obj.IsNull()) { |
| 4377 ErrorMsg(alias_name_pos, | 4373 ErrorMsg(alias_name_pos, |
| 4378 "'%s' is already defined", alias_name->ToCString()); | 4374 "'%s' is already defined", alias_name->ToCString()); |
| 4379 } | 4375 } |
| 4380 | 4376 |
| 4381 // Create the function type alias signature class. It will be linked to its | 4377 // Create the function type alias signature class. It will be linked to its |
| 4382 // signature function after it has been parsed. The type parameters, in order | 4378 // signature function after it has been parsed. The type parameters, in order |
| 4383 // to be properly finalized, need to be associated to this signature class as | 4379 // to be properly finalized, need to be associated to this signature class as |
| 4384 // they are parsed. | 4380 // they are parsed. |
| 4385 const Class& function_type_alias = Class::Handle(isolate(), | 4381 const Class& function_type_alias = Class::Handle(I, |
| 4386 Class::NewSignatureClass(*alias_name, | 4382 Class::NewSignatureClass(*alias_name, |
| 4387 Function::Handle(isolate()), | 4383 Function::Handle(I), |
| 4388 script_, | 4384 script_, |
| 4389 alias_name_pos)); | 4385 alias_name_pos)); |
| 4390 library_.AddClass(function_type_alias); | 4386 library_.AddClass(function_type_alias); |
| 4391 set_current_class(function_type_alias); | 4387 set_current_class(function_type_alias); |
| 4392 // Parse the type parameters of the function type. | 4388 // Parse the type parameters of the function type. |
| 4393 ParseTypeParameters(function_type_alias); | 4389 ParseTypeParameters(function_type_alias); |
| 4394 // At this point, the type parameters have been parsed, so we can resolve the | 4390 // At this point, the type parameters have been parsed, so we can resolve the |
| 4395 // result type. | 4391 // result type. |
| 4396 if (!result_type.IsNull()) { | 4392 if (!result_type.IsNull()) { |
| 4397 ResolveTypeFromClass(function_type_alias, | 4393 ResolveTypeFromClass(function_type_alias, |
| 4398 ClassFinalizer::kResolveTypeParameters, | 4394 ClassFinalizer::kResolveTypeParameters, |
| 4399 &result_type); | 4395 &result_type); |
| 4400 } | 4396 } |
| 4401 // Parse the formal parameters of the function type. | 4397 // Parse the formal parameters of the function type. |
| 4402 CheckToken(Token::kLPAREN, "formal parameter list expected"); | 4398 CheckToken(Token::kLPAREN, "formal parameter list expected"); |
| 4403 ParamList func_params; | 4399 ParamList func_params; |
| 4404 | 4400 |
| 4405 // Add implicit closure object parameter. | 4401 // Add implicit closure object parameter. |
| 4406 func_params.AddFinalParameter( | 4402 func_params.AddFinalParameter( |
| 4407 TokenPos(), | 4403 TokenPos(), |
| 4408 &Symbols::ClosureParameter(), | 4404 &Symbols::ClosureParameter(), |
| 4409 &Type::ZoneHandle(I, Type::DynamicType())); | 4405 &Type::ZoneHandle(I, Type::DynamicType())); |
| 4410 | 4406 |
| 4411 const bool no_explicit_default_values = false; | 4407 const bool no_explicit_default_values = false; |
| 4412 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 4408 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
| 4413 ExpectSemicolon(); | 4409 ExpectSemicolon(); |
| 4414 // The field 'is_static' has no meaning for signature functions. | 4410 // The field 'is_static' has no meaning for signature functions. |
| 4415 Function& signature_function = Function::Handle(isolate(), | 4411 Function& signature_function = Function::Handle(I, |
| 4416 Function::New(*alias_name, | 4412 Function::New(*alias_name, |
| 4417 RawFunction::kSignatureFunction, | 4413 RawFunction::kSignatureFunction, |
| 4418 /* is_static = */ false, | 4414 /* is_static = */ false, |
| 4419 /* is_const = */ false, | 4415 /* is_const = */ false, |
| 4420 /* is_abstract = */ false, | 4416 /* is_abstract = */ false, |
| 4421 /* is_external = */ false, | 4417 /* is_external = */ false, |
| 4422 /* is_native = */ false, | 4418 /* is_native = */ false, |
| 4423 function_type_alias, | 4419 function_type_alias, |
| 4424 alias_name_pos)); | 4420 alias_name_pos)); |
| 4425 signature_function.set_result_type(result_type); | 4421 signature_function.set_result_type(result_type); |
| 4426 AddFormalParamsToFunction(&func_params, signature_function); | 4422 AddFormalParamsToFunction(&func_params, signature_function); |
| 4427 | 4423 |
| 4428 // Patch the signature function in the signature class. | 4424 // Patch the signature function in the signature class. |
| 4429 function_type_alias.PatchSignatureFunction(signature_function); | 4425 function_type_alias.PatchSignatureFunction(signature_function); |
| 4430 | 4426 |
| 4431 const String& signature = String::Handle(isolate(), | 4427 const String& signature = String::Handle(I, |
| 4432 signature_function.Signature()); | 4428 signature_function.Signature()); |
| 4433 if (FLAG_trace_parser) { | 4429 if (FLAG_trace_parser) { |
| 4434 OS::Print("TopLevel parsing function type alias '%s'\n", | 4430 OS::Print("TopLevel parsing function type alias '%s'\n", |
| 4435 signature.ToCString()); | 4431 signature.ToCString()); |
| 4436 } | 4432 } |
| 4437 // Lookup the signature class, i.e. the class whose name is the signature. | 4433 // Lookup the signature class, i.e. the class whose name is the signature. |
| 4438 // We only lookup in the current library, but not in its imports, and only | 4434 // We only lookup in the current library, but not in its imports, and only |
| 4439 // create a new canonical signature class if it does not exist yet. | 4435 // create a new canonical signature class if it does not exist yet. |
| 4440 Class& signature_class = Class::ZoneHandle(I, | 4436 Class& signature_class = Class::ZoneHandle(I, |
| 4441 library_.LookupLocalClass(signature)); | 4437 library_.LookupLocalClass(signature)); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4535 } | 4531 } |
| 4536 SkipTypeArguments(); | 4532 SkipTypeArguments(); |
| 4537 } | 4533 } |
| 4538 } | 4534 } |
| 4539 | 4535 |
| 4540 | 4536 |
| 4541 void Parser::ParseTypeParameters(const Class& cls) { | 4537 void Parser::ParseTypeParameters(const Class& cls) { |
| 4542 TRACE_PARSER("ParseTypeParameters"); | 4538 TRACE_PARSER("ParseTypeParameters"); |
| 4543 if (CurrentToken() == Token::kLT) { | 4539 if (CurrentToken() == Token::kLT) { |
| 4544 const GrowableObjectArray& type_parameters_array = | 4540 const GrowableObjectArray& type_parameters_array = |
| 4545 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 4541 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 4546 intptr_t index = 0; | 4542 intptr_t index = 0; |
| 4547 TypeParameter& type_parameter = TypeParameter::Handle(isolate()); | 4543 TypeParameter& type_parameter = TypeParameter::Handle(I); |
| 4548 TypeParameter& existing_type_parameter = TypeParameter::Handle(isolate()); | 4544 TypeParameter& existing_type_parameter = TypeParameter::Handle(I); |
| 4549 String& existing_type_parameter_name = String::Handle(isolate()); | 4545 String& existing_type_parameter_name = String::Handle(I); |
| 4550 AbstractType& type_parameter_bound = Type::Handle(isolate()); | 4546 AbstractType& type_parameter_bound = Type::Handle(I); |
| 4551 do { | 4547 do { |
| 4552 ConsumeToken(); | 4548 ConsumeToken(); |
| 4553 const intptr_t metadata_pos = SkipMetadata(); | 4549 const intptr_t metadata_pos = SkipMetadata(); |
| 4554 const intptr_t type_parameter_pos = TokenPos(); | 4550 const intptr_t type_parameter_pos = TokenPos(); |
| 4555 String& type_parameter_name = | 4551 String& type_parameter_name = |
| 4556 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 4552 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
| 4557 // Check for duplicate type parameters. | 4553 // Check for duplicate type parameters. |
| 4558 for (intptr_t i = 0; i < index; i++) { | 4554 for (intptr_t i = 0; i < index; i++) { |
| 4559 existing_type_parameter ^= type_parameters_array.At(i); | 4555 existing_type_parameter ^= type_parameters_array.At(i); |
| 4560 existing_type_parameter_name = existing_type_parameter.name(); | 4556 existing_type_parameter_name = existing_type_parameter.name(); |
| 4561 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 4557 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
| 4562 ErrorMsg(type_parameter_pos, "duplicate type parameter '%s'", | 4558 ErrorMsg(type_parameter_pos, "duplicate type parameter '%s'", |
| 4563 type_parameter_name.ToCString()); | 4559 type_parameter_name.ToCString()); |
| 4564 } | 4560 } |
| 4565 } | 4561 } |
| 4566 if (CurrentToken() == Token::kEXTENDS) { | 4562 if (CurrentToken() == Token::kEXTENDS) { |
| 4567 ConsumeToken(); | 4563 ConsumeToken(); |
| 4568 // A bound may refer to the owner of the type parameter it applies to, | 4564 // A bound may refer to the owner of the type parameter it applies to, |
| 4569 // i.e. to the class or interface currently being parsed. | 4565 // i.e. to the class or interface currently being parsed. |
| 4570 // Postpone resolution in order to avoid resolving the class and its | 4566 // Postpone resolution in order to avoid resolving the class and its |
| 4571 // type parameters, as they are not fully parsed yet. | 4567 // type parameters, as they are not fully parsed yet. |
| 4572 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 4568 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
| 4573 } else { | 4569 } else { |
| 4574 type_parameter_bound = isolate()->object_store()->object_type(); | 4570 type_parameter_bound = I->object_store()->object_type(); |
| 4575 } | 4571 } |
| 4576 type_parameter = TypeParameter::New(cls, | 4572 type_parameter = TypeParameter::New(cls, |
| 4577 index, | 4573 index, |
| 4578 type_parameter_name, | 4574 type_parameter_name, |
| 4579 type_parameter_bound, | 4575 type_parameter_bound, |
| 4580 type_parameter_pos); | 4576 type_parameter_pos); |
| 4581 type_parameters_array.Add(type_parameter); | 4577 type_parameters_array.Add(type_parameter); |
| 4582 if (metadata_pos >= 0) { | 4578 if (metadata_pos >= 0) { |
| 4583 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 4579 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
| 4584 } | 4580 } |
| 4585 index++; | 4581 index++; |
| 4586 } while (CurrentToken() == Token::kCOMMA); | 4582 } while (CurrentToken() == Token::kCOMMA); |
| 4587 Token::Kind token = CurrentToken(); | 4583 Token::Kind token = CurrentToken(); |
| 4588 if ((token == Token::kGT) || (token == Token::kSHR)) { | 4584 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 4589 ConsumeRightAngleBracket(); | 4585 ConsumeRightAngleBracket(); |
| 4590 } else { | 4586 } else { |
| 4591 ErrorMsg("right angle bracket expected"); | 4587 ErrorMsg("right angle bracket expected"); |
| 4592 } | 4588 } |
| 4593 const TypeArguments& type_parameters = | 4589 const TypeArguments& type_parameters = |
| 4594 TypeArguments::Handle(isolate(), | 4590 TypeArguments::Handle(I, |
| 4595 NewTypeArguments(type_parameters_array)); | 4591 NewTypeArguments(type_parameters_array)); |
| 4596 cls.set_type_parameters(type_parameters); | 4592 cls.set_type_parameters(type_parameters); |
| 4597 // Try to resolve the upper bounds, which will at least resolve the | 4593 // Try to resolve the upper bounds, which will at least resolve the |
| 4598 // referenced type parameters. | 4594 // referenced type parameters. |
| 4599 const intptr_t num_types = type_parameters.Length(); | 4595 const intptr_t num_types = type_parameters.Length(); |
| 4600 for (intptr_t i = 0; i < num_types; i++) { | 4596 for (intptr_t i = 0; i < num_types; i++) { |
| 4601 type_parameter ^= type_parameters.TypeAt(i); | 4597 type_parameter ^= type_parameters.TypeAt(i); |
| 4602 type_parameter_bound = type_parameter.bound(); | 4598 type_parameter_bound = type_parameter.bound(); |
| 4603 ResolveTypeFromClass(cls, | 4599 ResolveTypeFromClass(cls, |
| 4604 ClassFinalizer::kResolveTypeParameters, | 4600 ClassFinalizer::kResolveTypeParameters, |
| 4605 &type_parameter_bound); | 4601 &type_parameter_bound); |
| 4606 type_parameter.set_bound(type_parameter_bound); | 4602 type_parameter.set_bound(type_parameter_bound); |
| 4607 } | 4603 } |
| 4608 } | 4604 } |
| 4609 } | 4605 } |
| 4610 | 4606 |
| 4611 | 4607 |
| 4612 RawTypeArguments* Parser::ParseTypeArguments( | 4608 RawTypeArguments* Parser::ParseTypeArguments( |
| 4613 ClassFinalizer::FinalizationKind finalization) { | 4609 ClassFinalizer::FinalizationKind finalization) { |
| 4614 TRACE_PARSER("ParseTypeArguments"); | 4610 TRACE_PARSER("ParseTypeArguments"); |
| 4615 if (CurrentToken() == Token::kLT) { | 4611 if (CurrentToken() == Token::kLT) { |
| 4616 const GrowableObjectArray& types = | 4612 const GrowableObjectArray& types = |
| 4617 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 4613 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 4618 AbstractType& type = AbstractType::Handle(isolate()); | 4614 AbstractType& type = AbstractType::Handle(I); |
| 4619 do { | 4615 do { |
| 4620 ConsumeToken(); | 4616 ConsumeToken(); |
| 4621 type = ParseType(finalization); | 4617 type = ParseType(finalization); |
| 4622 // Map a malformed type argument to dynamic. | 4618 // Map a malformed type argument to dynamic. |
| 4623 if (type.IsMalformed()) { | 4619 if (type.IsMalformed()) { |
| 4624 type = Type::DynamicType(); | 4620 type = Type::DynamicType(); |
| 4625 } | 4621 } |
| 4626 types.Add(type); | 4622 types.Add(type); |
| 4627 } while (CurrentToken() == Token::kCOMMA); | 4623 } while (CurrentToken() == Token::kCOMMA); |
| 4628 Token::Kind token = CurrentToken(); | 4624 Token::Kind token = CurrentToken(); |
| 4629 if ((token == Token::kGT) || (token == Token::kSHR)) { | 4625 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 4630 ConsumeRightAngleBracket(); | 4626 ConsumeRightAngleBracket(); |
| 4631 } else { | 4627 } else { |
| 4632 ErrorMsg("right angle bracket expected"); | 4628 ErrorMsg("right angle bracket expected"); |
| 4633 } | 4629 } |
| 4634 if (finalization != ClassFinalizer::kIgnore) { | 4630 if (finalization != ClassFinalizer::kIgnore) { |
| 4635 return NewTypeArguments(types); | 4631 return NewTypeArguments(types); |
| 4636 } | 4632 } |
| 4637 } | 4633 } |
| 4638 return TypeArguments::null(); | 4634 return TypeArguments::null(); |
| 4639 } | 4635 } |
| 4640 | 4636 |
| 4641 | 4637 |
| 4642 // Parse interface list and add to class cls. | 4638 // Parse interface list and add to class cls. |
| 4643 void Parser::ParseInterfaceList(const Class& cls) { | 4639 void Parser::ParseInterfaceList(const Class& cls) { |
| 4644 TRACE_PARSER("ParseInterfaceList"); | 4640 TRACE_PARSER("ParseInterfaceList"); |
| 4645 ASSERT(CurrentToken() == Token::kIMPLEMENTS); | 4641 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
| 4646 const GrowableObjectArray& all_interfaces = | 4642 const GrowableObjectArray& all_interfaces = |
| 4647 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 4643 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 4648 AbstractType& interface = AbstractType::Handle(isolate()); | 4644 AbstractType& interface = AbstractType::Handle(I); |
| 4649 // First get all the interfaces already implemented by class. | 4645 // First get all the interfaces already implemented by class. |
| 4650 Array& cls_interfaces = Array::Handle(isolate(), cls.interfaces()); | 4646 Array& cls_interfaces = Array::Handle(I, cls.interfaces()); |
| 4651 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 4647 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 4652 interface ^= cls_interfaces.At(i); | 4648 interface ^= cls_interfaces.At(i); |
| 4653 all_interfaces.Add(interface); | 4649 all_interfaces.Add(interface); |
| 4654 } | 4650 } |
| 4655 // Now parse and add the new interfaces. | 4651 // Now parse and add the new interfaces. |
| 4656 do { | 4652 do { |
| 4657 ConsumeToken(); | 4653 ConsumeToken(); |
| 4658 intptr_t interface_pos = TokenPos(); | 4654 intptr_t interface_pos = TokenPos(); |
| 4659 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 4655 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4660 if (interface.IsTypeParameter()) { | 4656 if (interface.IsTypeParameter()) { |
| 4661 ErrorMsg(interface_pos, | 4657 ErrorMsg(interface_pos, |
| 4662 "type parameter '%s' may not be used in interface list", | 4658 "type parameter '%s' may not be used in interface list", |
| 4663 String::Handle(isolate(), | 4659 String::Handle(I, |
| 4664 interface.UserVisibleName()).ToCString()); | 4660 interface.UserVisibleName()).ToCString()); |
| 4665 } | 4661 } |
| 4666 all_interfaces.Add(interface); | 4662 all_interfaces.Add(interface); |
| 4667 } while (CurrentToken() == Token::kCOMMA); | 4663 } while (CurrentToken() == Token::kCOMMA); |
| 4668 cls_interfaces = Array::MakeArray(all_interfaces); | 4664 cls_interfaces = Array::MakeArray(all_interfaces); |
| 4669 cls.set_interfaces(cls_interfaces); | 4665 cls.set_interfaces(cls_interfaces); |
| 4670 } | 4666 } |
| 4671 | 4667 |
| 4672 | 4668 |
| 4673 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 4669 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
| 4674 TRACE_PARSER("ParseMixins"); | 4670 TRACE_PARSER("ParseMixins"); |
| 4675 ASSERT(CurrentToken() == Token::kWITH); | 4671 ASSERT(CurrentToken() == Token::kWITH); |
| 4676 const GrowableObjectArray& mixin_types = | 4672 const GrowableObjectArray& mixin_types = |
| 4677 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 4673 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 4678 AbstractType& mixin_type = AbstractType::Handle(isolate()); | 4674 AbstractType& mixin_type = AbstractType::Handle(I); |
| 4679 do { | 4675 do { |
| 4680 ConsumeToken(); | 4676 ConsumeToken(); |
| 4681 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4677 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4682 if (mixin_type.IsDynamicType()) { | 4678 if (mixin_type.IsDynamicType()) { |
| 4683 // The string 'dynamic' is not resolved yet at this point, but a malformed | 4679 // The string 'dynamic' is not resolved yet at this point, but a malformed |
| 4684 // type mapped to dynamic can be encountered here. | 4680 // type mapped to dynamic can be encountered here. |
| 4685 ErrorMsg(mixin_type.token_pos(), "illegal mixin of a malformed type"); | 4681 ErrorMsg(mixin_type.token_pos(), "illegal mixin of a malformed type"); |
| 4686 } | 4682 } |
| 4687 if (mixin_type.IsTypeParameter()) { | 4683 if (mixin_type.IsTypeParameter()) { |
| 4688 ErrorMsg(mixin_type.token_pos(), | 4684 ErrorMsg(mixin_type.token_pos(), |
| 4689 "mixin type '%s' may not be a type parameter", | 4685 "mixin type '%s' may not be a type parameter", |
| 4690 String::Handle(isolate(), | 4686 String::Handle(I, |
| 4691 mixin_type.UserVisibleName()).ToCString()); | 4687 mixin_type.UserVisibleName()).ToCString()); |
| 4692 } | 4688 } |
| 4693 mixin_types.Add(mixin_type); | 4689 mixin_types.Add(mixin_type); |
| 4694 } while (CurrentToken() == Token::kCOMMA); | 4690 } while (CurrentToken() == Token::kCOMMA); |
| 4695 return MixinAppType::New(super_type, | 4691 return MixinAppType::New(super_type, |
| 4696 Array::Handle(isolate(), Array::MakeArray(mixin_types))); | 4692 Array::Handle(I, Array::MakeArray(mixin_types))); |
| 4697 } | 4693 } |
| 4698 | 4694 |
| 4699 | 4695 |
| 4700 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 4696 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
| 4701 intptr_t metadata_pos) { | 4697 intptr_t metadata_pos) { |
| 4702 TRACE_PARSER("ParseTopLevelVariable"); | 4698 TRACE_PARSER("ParseTopLevelVariable"); |
| 4703 const bool is_const = (CurrentToken() == Token::kCONST); | 4699 const bool is_const = (CurrentToken() == Token::kCONST); |
| 4704 // Const fields are implicitly final. | 4700 // Const fields are implicitly final. |
| 4705 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 4701 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 4706 const bool is_static = true; | 4702 const bool is_static = true; |
| 4707 const AbstractType& type = AbstractType::ZoneHandle(I, | 4703 const AbstractType& type = AbstractType::ZoneHandle(I, |
| 4708 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 4704 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
| 4709 Field& field = Field::Handle(isolate()); | 4705 Field& field = Field::Handle(I); |
| 4710 Function& getter = Function::Handle(isolate()); | 4706 Function& getter = Function::Handle(I); |
| 4711 while (true) { | 4707 while (true) { |
| 4712 const intptr_t name_pos = TokenPos(); | 4708 const intptr_t name_pos = TokenPos(); |
| 4713 String& var_name = *ExpectIdentifier("variable name expected"); | 4709 String& var_name = *ExpectIdentifier("variable name expected"); |
| 4714 | 4710 |
| 4715 if (library_.LookupLocalObject(var_name) != Object::null()) { | 4711 if (library_.LookupLocalObject(var_name) != Object::null()) { |
| 4716 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 4712 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 4717 } | 4713 } |
| 4718 | 4714 |
| 4719 // Check whether a getter or setter for this name exists. A const | 4715 // Check whether a getter or setter for this name exists. A const |
| 4720 // or final field implies a setter which throws a NoSuchMethodError, | 4716 // or final field implies a setter which throws a NoSuchMethodError, |
| 4721 // thus we need to check for conflicts with existing setters and | 4717 // thus we need to check for conflicts with existing setters and |
| 4722 // getters. | 4718 // getters. |
| 4723 String& accessor_name = String::Handle(isolate(), | 4719 String& accessor_name = String::Handle(I, |
| 4724 Field::GetterName(var_name)); | 4720 Field::GetterName(var_name)); |
| 4725 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4721 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 4726 ErrorMsg(name_pos, "getter for '%s' is already defined", | 4722 ErrorMsg(name_pos, "getter for '%s' is already defined", |
| 4727 var_name.ToCString()); | 4723 var_name.ToCString()); |
| 4728 } | 4724 } |
| 4729 accessor_name = Field::SetterName(var_name); | 4725 accessor_name = Field::SetterName(var_name); |
| 4730 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4726 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 4731 ErrorMsg(name_pos, "setter for '%s' is already defined", | 4727 ErrorMsg(name_pos, "setter for '%s' is already defined", |
| 4732 var_name.ToCString()); | 4728 var_name.ToCString()); |
| 4733 } | 4729 } |
| 4734 | 4730 |
| 4735 field = Field::New(var_name, is_static, is_final, is_const, | 4731 field = Field::New(var_name, is_static, is_final, is_const, |
| 4736 current_class(), name_pos); | 4732 current_class(), name_pos); |
| 4737 field.set_type(type); | 4733 field.set_type(type); |
| 4738 field.set_value(Instance::Handle(isolate(), Instance::null())); | 4734 field.set_value(Instance::Handle(I, Instance::null())); |
| 4739 top_level->fields.Add(field); | 4735 top_level->fields.Add(field); |
| 4740 library_.AddObject(field, var_name); | 4736 library_.AddObject(field, var_name); |
| 4741 if (metadata_pos >= 0) { | 4737 if (metadata_pos >= 0) { |
| 4742 library_.AddFieldMetadata(field, metadata_pos); | 4738 library_.AddFieldMetadata(field, metadata_pos); |
| 4743 } | 4739 } |
| 4744 if (CurrentToken() == Token::kASSIGN) { | 4740 if (CurrentToken() == Token::kASSIGN) { |
| 4745 ConsumeToken(); | 4741 ConsumeToken(); |
| 4746 Instance& field_value = Instance::Handle(isolate(), | 4742 Instance& field_value = Instance::Handle(I, |
| 4747 Object::sentinel().raw()); | 4743 Object::sentinel().raw()); |
| 4748 bool has_simple_literal = false; | 4744 bool has_simple_literal = false; |
| 4749 if (LookaheadToken(1) == Token::kSEMICOLON) { | 4745 if (LookaheadToken(1) == Token::kSEMICOLON) { |
| 4750 has_simple_literal = IsSimpleLiteral(type, &field_value); | 4746 has_simple_literal = IsSimpleLiteral(type, &field_value); |
| 4751 } | 4747 } |
| 4752 SkipExpr(); | 4748 SkipExpr(); |
| 4753 field.set_value(field_value); | 4749 field.set_value(field_value); |
| 4754 if (!has_simple_literal) { | 4750 if (!has_simple_literal) { |
| 4755 // Create a static final getter. | 4751 // Create a static final getter. |
| 4756 String& getter_name = String::Handle(isolate(), | 4752 String& getter_name = String::Handle(I, |
| 4757 Field::GetterSymbol(var_name)); | 4753 Field::GetterSymbol(var_name)); |
| 4758 getter = Function::New(getter_name, | 4754 getter = Function::New(getter_name, |
| 4759 RawFunction::kImplicitStaticFinalGetter, | 4755 RawFunction::kImplicitStaticFinalGetter, |
| 4760 is_static, | 4756 is_static, |
| 4761 is_const, | 4757 is_const, |
| 4762 /* is_abstract = */ false, | 4758 /* is_abstract = */ false, |
| 4763 /* is_external = */ false, | 4759 /* is_external = */ false, |
| 4764 /* is_native = */ false, | 4760 /* is_native = */ false, |
| 4765 current_class(), | 4761 current_class(), |
| 4766 name_pos); | 4762 name_pos); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4787 ExpectSemicolon(); // Reports error. | 4783 ExpectSemicolon(); // Reports error. |
| 4788 } | 4784 } |
| 4789 } | 4785 } |
| 4790 } | 4786 } |
| 4791 | 4787 |
| 4792 | 4788 |
| 4793 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 4789 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
| 4794 intptr_t metadata_pos) { | 4790 intptr_t metadata_pos) { |
| 4795 TRACE_PARSER("ParseTopLevelFunction"); | 4791 TRACE_PARSER("ParseTopLevelFunction"); |
| 4796 const intptr_t decl_begin_pos = TokenPos(); | 4792 const intptr_t decl_begin_pos = TokenPos(); |
| 4797 AbstractType& result_type = Type::Handle(isolate(), Type::DynamicType()); | 4793 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); |
| 4798 const bool is_static = true; | 4794 const bool is_static = true; |
| 4799 bool is_external = false; | 4795 bool is_external = false; |
| 4800 bool is_patch = false; | 4796 bool is_patch = false; |
| 4801 if (is_patch_source() && | 4797 if (is_patch_source() && |
| 4802 (CurrentToken() == Token::kIDENT) && | 4798 (CurrentToken() == Token::kIDENT) && |
| 4803 CurrentLiteral()->Equals("patch") && | 4799 CurrentLiteral()->Equals("patch") && |
| 4804 (LookaheadToken(1) != Token::kLPAREN)) { | 4800 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4805 ConsumeToken(); | 4801 ConsumeToken(); |
| 4806 is_patch = true; | 4802 is_patch = true; |
| 4807 } else if (CurrentToken() == Token::kEXTERNAL) { | 4803 } else if (CurrentToken() == Token::kEXTERNAL) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4820 } | 4816 } |
| 4821 const intptr_t name_pos = TokenPos(); | 4817 const intptr_t name_pos = TokenPos(); |
| 4822 const String& func_name = *ExpectIdentifier("function name expected"); | 4818 const String& func_name = *ExpectIdentifier("function name expected"); |
| 4823 | 4819 |
| 4824 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 4820 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
| 4825 if (found && !is_patch) { | 4821 if (found && !is_patch) { |
| 4826 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); | 4822 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 4827 } else if (!found && is_patch) { | 4823 } else if (!found && is_patch) { |
| 4828 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); | 4824 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); |
| 4829 } | 4825 } |
| 4830 String& accessor_name = String::Handle(isolate(), | 4826 String& accessor_name = String::Handle(I, |
| 4831 Field::GetterName(func_name)); | 4827 Field::GetterName(func_name)); |
| 4832 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4828 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 4833 ErrorMsg(name_pos, "'%s' is already defined as getter", | 4829 ErrorMsg(name_pos, "'%s' is already defined as getter", |
| 4834 func_name.ToCString()); | 4830 func_name.ToCString()); |
| 4835 } | 4831 } |
| 4836 // A setter named x= may co-exist with a function named x, thus we do | 4832 // A setter named x= may co-exist with a function named x, thus we do |
| 4837 // not need to check setters. | 4833 // not need to check setters. |
| 4838 | 4834 |
| 4839 CheckToken(Token::kLPAREN); | 4835 CheckToken(Token::kLPAREN); |
| 4840 const intptr_t function_pos = TokenPos(); | 4836 const intptr_t function_pos = TokenPos(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4857 function_end_pos = TokenPos(); | 4853 function_end_pos = TokenPos(); |
| 4858 ExpectSemicolon(); | 4854 ExpectSemicolon(); |
| 4859 } else if (IsLiteral("native")) { | 4855 } else if (IsLiteral("native")) { |
| 4860 ParseNativeDeclaration(); | 4856 ParseNativeDeclaration(); |
| 4861 function_end_pos = TokenPos(); | 4857 function_end_pos = TokenPos(); |
| 4862 ExpectSemicolon(); | 4858 ExpectSemicolon(); |
| 4863 is_native = true; | 4859 is_native = true; |
| 4864 } else { | 4860 } else { |
| 4865 ErrorMsg("function block expected"); | 4861 ErrorMsg("function block expected"); |
| 4866 } | 4862 } |
| 4867 Function& func = Function::Handle(isolate(), | 4863 Function& func = Function::Handle(I, |
| 4868 Function::New(func_name, | 4864 Function::New(func_name, |
| 4869 RawFunction::kRegularFunction, | 4865 RawFunction::kRegularFunction, |
| 4870 is_static, | 4866 is_static, |
| 4871 /* is_const = */ false, | 4867 /* is_const = */ false, |
| 4872 /* is_abstract = */ false, | 4868 /* is_abstract = */ false, |
| 4873 is_external, | 4869 is_external, |
| 4874 is_native, | 4870 is_native, |
| 4875 current_class(), | 4871 current_class(), |
| 4876 decl_begin_pos)); | 4872 decl_begin_pos)); |
| 4877 func.set_result_type(result_type); | 4873 func.set_result_type(result_type); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4892 } | 4888 } |
| 4893 | 4889 |
| 4894 | 4890 |
| 4895 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 4891 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
| 4896 intptr_t metadata_pos) { | 4892 intptr_t metadata_pos) { |
| 4897 TRACE_PARSER("ParseTopLevelAccessor"); | 4893 TRACE_PARSER("ParseTopLevelAccessor"); |
| 4898 const intptr_t decl_begin_pos = TokenPos(); | 4894 const intptr_t decl_begin_pos = TokenPos(); |
| 4899 const bool is_static = true; | 4895 const bool is_static = true; |
| 4900 bool is_external = false; | 4896 bool is_external = false; |
| 4901 bool is_patch = false; | 4897 bool is_patch = false; |
| 4902 AbstractType& result_type = AbstractType::Handle(isolate()); | 4898 AbstractType& result_type = AbstractType::Handle(I); |
| 4903 if (is_patch_source() && | 4899 if (is_patch_source() && |
| 4904 (CurrentToken() == Token::kIDENT) && | 4900 (CurrentToken() == Token::kIDENT) && |
| 4905 CurrentLiteral()->Equals("patch")) { | 4901 CurrentLiteral()->Equals("patch")) { |
| 4906 ConsumeToken(); | 4902 ConsumeToken(); |
| 4907 is_patch = true; | 4903 is_patch = true; |
| 4908 } else if (CurrentToken() == Token::kEXTERNAL) { | 4904 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 4909 ConsumeToken(); | 4905 ConsumeToken(); |
| 4910 is_external = true; | 4906 is_external = true; |
| 4911 } | 4907 } |
| 4912 bool is_getter = (CurrentToken() == Token::kGET); | 4908 bool is_getter = (CurrentToken() == Token::kGET); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4993 accessor_end_pos = TokenPos(); | 4989 accessor_end_pos = TokenPos(); |
| 4994 ExpectSemicolon(); | 4990 ExpectSemicolon(); |
| 4995 } else if (IsLiteral("native")) { | 4991 } else if (IsLiteral("native")) { |
| 4996 ParseNativeDeclaration(); | 4992 ParseNativeDeclaration(); |
| 4997 accessor_end_pos = TokenPos(); | 4993 accessor_end_pos = TokenPos(); |
| 4998 ExpectSemicolon(); | 4994 ExpectSemicolon(); |
| 4999 is_native = true; | 4995 is_native = true; |
| 5000 } else { | 4996 } else { |
| 5001 ErrorMsg("function block expected"); | 4997 ErrorMsg("function block expected"); |
| 5002 } | 4998 } |
| 5003 Function& func = Function::Handle(isolate(), | 4999 Function& func = Function::Handle(I, |
| 5004 Function::New(accessor_name, | 5000 Function::New(accessor_name, |
| 5005 is_getter ? RawFunction::kGetterFunction : | 5001 is_getter ? RawFunction::kGetterFunction : |
| 5006 RawFunction::kSetterFunction, | 5002 RawFunction::kSetterFunction, |
| 5007 is_static, | 5003 is_static, |
| 5008 /* is_const = */ false, | 5004 /* is_const = */ false, |
| 5009 /* is_abstract = */ false, | 5005 /* is_abstract = */ false, |
| 5010 is_external, | 5006 is_external, |
| 5011 is_native, | 5007 is_native, |
| 5012 current_class(), | 5008 current_class(), |
| 5013 decl_begin_pos)); | 5009 decl_begin_pos)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5026 } | 5022 } |
| 5027 if (metadata_pos >= 0) { | 5023 if (metadata_pos >= 0) { |
| 5028 library_.AddFunctionMetadata(func, metadata_pos); | 5024 library_.AddFunctionMetadata(func, metadata_pos); |
| 5029 } | 5025 } |
| 5030 } | 5026 } |
| 5031 | 5027 |
| 5032 | 5028 |
| 5033 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, | 5029 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, |
| 5034 intptr_t token_pos, | 5030 intptr_t token_pos, |
| 5035 const String& url) { | 5031 const String& url) { |
| 5036 Dart_LibraryTagHandler handler = isolate()->library_tag_handler(); | 5032 Dart_LibraryTagHandler handler = I->library_tag_handler(); |
| 5037 if (handler == NULL) { | 5033 if (handler == NULL) { |
| 5038 if (url.StartsWith(Symbols::DartScheme())) { | 5034 if (url.StartsWith(Symbols::DartScheme())) { |
| 5039 if (tag == Dart_kCanonicalizeUrl) { | 5035 if (tag == Dart_kCanonicalizeUrl) { |
| 5040 return url.raw(); | 5036 return url.raw(); |
| 5041 } | 5037 } |
| 5042 return Object::null(); | 5038 return Object::null(); |
| 5043 } | 5039 } |
| 5044 ErrorMsg(token_pos, "no library handler registered"); | 5040 ErrorMsg(token_pos, "no library handler registered"); |
| 5045 } | 5041 } |
| 5046 // Block class finalization attempts when calling into the library | 5042 // Block class finalization attempts when calling into the library |
| 5047 // tag handler. | 5043 // tag handler. |
| 5048 isolate()->BlockClassFinalization(); | 5044 I->BlockClassFinalization(); |
| 5049 Api::Scope api_scope(isolate()); | 5045 Api::Scope api_scope(I); |
| 5050 Dart_Handle result = handler(tag, | 5046 Dart_Handle result = handler(tag, |
| 5051 Api::NewHandle(isolate(), library_.raw()), | 5047 Api::NewHandle(I, library_.raw()), |
| 5052 Api::NewHandle(isolate(), url.raw())); | 5048 Api::NewHandle(I, url.raw())); |
| 5053 isolate()->UnblockClassFinalization(); | 5049 I->UnblockClassFinalization(); |
| 5054 if (Dart_IsError(result)) { | 5050 if (Dart_IsError(result)) { |
| 5055 // In case of an error we append an explanatory error message to the | 5051 // In case of an error we append an explanatory error message to the |
| 5056 // error obtained from the library tag handler. | 5052 // error obtained from the library tag handler. |
| 5057 Error& prev_error = Error::Handle(isolate()); | 5053 Error& prev_error = Error::Handle(I); |
| 5058 prev_error ^= Api::UnwrapHandle(result); | 5054 prev_error ^= Api::UnwrapHandle(result); |
| 5059 AppendErrorMsg(prev_error, token_pos, "library handler failed"); | 5055 AppendErrorMsg(prev_error, token_pos, "library handler failed"); |
| 5060 } | 5056 } |
| 5061 if (tag == Dart_kCanonicalizeUrl) { | 5057 if (tag == Dart_kCanonicalizeUrl) { |
| 5062 if (!Dart_IsString(result)) { | 5058 if (!Dart_IsString(result)) { |
| 5063 ErrorMsg(token_pos, "library handler failed URI canonicalization"); | 5059 ErrorMsg(token_pos, "library handler failed URI canonicalization"); |
| 5064 } | 5060 } |
| 5065 } | 5061 } |
| 5066 return Api::UnwrapHandle(result); | 5062 return Api::UnwrapHandle(result); |
| 5067 } | 5063 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5113 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 5109 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
| 5114 if (url.Length() == 0) { | 5110 if (url.Length() == 0) { |
| 5115 ErrorMsg("library url expected"); | 5111 ErrorMsg("library url expected"); |
| 5116 } | 5112 } |
| 5117 bool is_deferred_import = false; | 5113 bool is_deferred_import = false; |
| 5118 if (is_import && (IsLiteral("deferred"))) { | 5114 if (is_import && (IsLiteral("deferred"))) { |
| 5119 is_deferred_import = true; | 5115 is_deferred_import = true; |
| 5120 ConsumeToken(); | 5116 ConsumeToken(); |
| 5121 CheckToken(Token::kAS, "'as' expected"); | 5117 CheckToken(Token::kAS, "'as' expected"); |
| 5122 } | 5118 } |
| 5123 String& prefix = String::Handle(isolate()); | 5119 String& prefix = String::Handle(I); |
| 5124 intptr_t prefix_pos = 0; | 5120 intptr_t prefix_pos = 0; |
| 5125 if (is_import && (CurrentToken() == Token::kAS)) { | 5121 if (is_import && (CurrentToken() == Token::kAS)) { |
| 5126 ConsumeToken(); | 5122 ConsumeToken(); |
| 5127 prefix_pos = TokenPos(); | 5123 prefix_pos = TokenPos(); |
| 5128 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 5124 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
| 5129 } | 5125 } |
| 5130 | 5126 |
| 5131 Array& show_names = Array::Handle(isolate()); | 5127 Array& show_names = Array::Handle(I); |
| 5132 Array& hide_names = Array::Handle(isolate()); | 5128 Array& hide_names = Array::Handle(I); |
| 5133 if (is_deferred_import || IsLiteral("show") || IsLiteral("hide")) { | 5129 if (is_deferred_import || IsLiteral("show") || IsLiteral("hide")) { |
| 5134 GrowableObjectArray& show_list = | 5130 GrowableObjectArray& show_list = |
| 5135 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 5131 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 5136 GrowableObjectArray& hide_list = | 5132 GrowableObjectArray& hide_list = |
| 5137 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 5133 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 5138 // Libraries imported through deferred import automatically hide | 5134 // Libraries imported through deferred import automatically hide |
| 5139 // the name 'loadLibrary'. | 5135 // the name 'loadLibrary'. |
| 5140 if (is_deferred_import) { | 5136 if (is_deferred_import) { |
| 5141 hide_list.Add(Symbols::LoadLibrary()); | 5137 hide_list.Add(Symbols::LoadLibrary()); |
| 5142 } | 5138 } |
| 5143 for (;;) { | 5139 for (;;) { |
| 5144 if (IsLiteral("show")) { | 5140 if (IsLiteral("show")) { |
| 5145 ConsumeToken(); | 5141 ConsumeToken(); |
| 5146 ParseIdentList(&show_list); | 5142 ParseIdentList(&show_list); |
| 5147 } else if (IsLiteral("hide")) { | 5143 } else if (IsLiteral("hide")) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5158 hide_names = Array::MakeArray(hide_list); | 5154 hide_names = Array::MakeArray(hide_list); |
| 5159 } | 5155 } |
| 5160 } | 5156 } |
| 5161 ExpectSemicolon(); | 5157 ExpectSemicolon(); |
| 5162 | 5158 |
| 5163 // Canonicalize library URL. | 5159 // Canonicalize library URL. |
| 5164 const String& canon_url = String::CheckedHandle( | 5160 const String& canon_url = String::CheckedHandle( |
| 5165 CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url)); | 5161 CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url)); |
| 5166 | 5162 |
| 5167 // Create a new library if it does not exist yet. | 5163 // Create a new library if it does not exist yet. |
| 5168 Library& library = | 5164 Library& library = Library::Handle(I, Library::LookupLibrary(canon_url)); |
| 5169 Library::Handle(isolate(), Library::LookupLibrary(canon_url)); | |
| 5170 if (library.IsNull()) { | 5165 if (library.IsNull()) { |
| 5171 library = Library::New(canon_url); | 5166 library = Library::New(canon_url); |
| 5172 library.Register(); | 5167 library.Register(); |
| 5173 } | 5168 } |
| 5174 | 5169 |
| 5175 // If loading hasn't been requested yet, and if this is not a deferred | 5170 // If loading hasn't been requested yet, and if this is not a deferred |
| 5176 // library import, call the library tag handler to request loading | 5171 // library import, call the library tag handler to request loading |
| 5177 // the library. | 5172 // the library. |
| 5178 if (library.LoadNotStarted() && !is_deferred_import) { | 5173 if (library.LoadNotStarted() && !is_deferred_import) { |
| 5179 library.SetLoadRequested(); | 5174 library.SetLoadRequested(); |
| 5180 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); | 5175 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); |
| 5181 } | 5176 } |
| 5182 | 5177 |
| 5183 Namespace& ns = Namespace::Handle(isolate(), | 5178 Namespace& ns = Namespace::Handle(I, |
| 5184 Namespace::New(library, show_names, hide_names)); | 5179 Namespace::New(library, show_names, hide_names)); |
| 5185 if (metadata_pos >= 0) { | 5180 if (metadata_pos >= 0) { |
| 5186 ns.AddMetadata(metadata_pos, current_class()); | 5181 ns.AddMetadata(metadata_pos, current_class()); |
| 5187 } | 5182 } |
| 5188 | 5183 |
| 5189 if (is_import) { | 5184 if (is_import) { |
| 5190 // Ensure that private dart:_ libraries are only imported into dart: | 5185 // Ensure that private dart:_ libraries are only imported into dart: |
| 5191 // libraries. | 5186 // libraries. |
| 5192 const String& lib_url = String::Handle(isolate(), library_.url()); | 5187 const String& lib_url = String::Handle(I, library_.url()); |
| 5193 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 5188 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
| 5194 !lib_url.StartsWith(Symbols::DartScheme())) { | 5189 !lib_url.StartsWith(Symbols::DartScheme())) { |
| 5195 ErrorMsg(import_pos, "private library is not accessible"); | 5190 ErrorMsg(import_pos, "private library is not accessible"); |
| 5196 } | 5191 } |
| 5197 if (prefix.IsNull() || (prefix.Length() == 0)) { | 5192 if (prefix.IsNull() || (prefix.Length() == 0)) { |
| 5198 ASSERT(!is_deferred_import); | 5193 ASSERT(!is_deferred_import); |
| 5199 library_.AddImport(ns); | 5194 library_.AddImport(ns); |
| 5200 } else { | 5195 } else { |
| 5201 LibraryPrefix& library_prefix = LibraryPrefix::Handle(isolate()); | 5196 LibraryPrefix& library_prefix = LibraryPrefix::Handle(I); |
| 5202 library_prefix = library_.LookupLocalLibraryPrefix(prefix); | 5197 library_prefix = library_.LookupLocalLibraryPrefix(prefix); |
| 5203 if (!library_prefix.IsNull()) { | 5198 if (!library_prefix.IsNull()) { |
| 5204 // Check that prefix names of deferred import clauses are | 5199 // Check that prefix names of deferred import clauses are |
| 5205 // unique. | 5200 // unique. |
| 5206 if (!is_deferred_import && library_prefix.is_deferred_load()) { | 5201 if (!is_deferred_import && library_prefix.is_deferred_load()) { |
| 5207 ErrorMsg(prefix_pos, | 5202 ErrorMsg(prefix_pos, |
| 5208 "prefix '%s' already used in a deferred import clause", | 5203 "prefix '%s' already used in a deferred import clause", |
| 5209 prefix.ToCString()); | 5204 prefix.ToCString()); |
| 5210 } | 5205 } |
| 5211 if (is_deferred_import) { | 5206 if (is_deferred_import) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5270 } | 5265 } |
| 5271 while ((CurrentToken() == Token::kIMPORT) || | 5266 while ((CurrentToken() == Token::kIMPORT) || |
| 5272 (CurrentToken() == Token::kEXPORT)) { | 5267 (CurrentToken() == Token::kEXPORT)) { |
| 5273 ParseLibraryImportExport(metadata_pos); | 5268 ParseLibraryImportExport(metadata_pos); |
| 5274 rewind_pos = TokenPos(); | 5269 rewind_pos = TokenPos(); |
| 5275 metadata_pos = SkipMetadata(); | 5270 metadata_pos = SkipMetadata(); |
| 5276 } | 5271 } |
| 5277 // Core lib has not been explicitly imported, so we implicitly | 5272 // Core lib has not been explicitly imported, so we implicitly |
| 5278 // import it here. | 5273 // import it here. |
| 5279 if (!library_.ImportsCorelib()) { | 5274 if (!library_.ImportsCorelib()) { |
| 5280 Library& core_lib = Library::Handle(isolate(), Library::CoreLibrary()); | 5275 Library& core_lib = Library::Handle(I, Library::CoreLibrary()); |
| 5281 ASSERT(!core_lib.IsNull()); | 5276 ASSERT(!core_lib.IsNull()); |
| 5282 const Namespace& core_ns = Namespace::Handle(isolate(), | 5277 const Namespace& core_ns = Namespace::Handle(I, |
| 5283 Namespace::New(core_lib, Object::null_array(), Object::null_array())); | 5278 Namespace::New(core_lib, Object::null_array(), Object::null_array())); |
| 5284 library_.AddImport(core_ns); | 5279 library_.AddImport(core_ns); |
| 5285 } | 5280 } |
| 5286 while (CurrentToken() == Token::kPART) { | 5281 while (CurrentToken() == Token::kPART) { |
| 5287 ParseLibraryPart(); | 5282 ParseLibraryPart(); |
| 5288 rewind_pos = TokenPos(); | 5283 rewind_pos = TokenPos(); |
| 5289 metadata_pos = SkipMetadata(); | 5284 metadata_pos = SkipMetadata(); |
| 5290 } | 5285 } |
| 5291 SetPosition(rewind_pos); | 5286 SetPosition(rewind_pos); |
| 5292 } | 5287 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 5309 } | 5304 } |
| 5310 ExpectSemicolon(); | 5305 ExpectSemicolon(); |
| 5311 } | 5306 } |
| 5312 | 5307 |
| 5313 | 5308 |
| 5314 void Parser::ParseTopLevel() { | 5309 void Parser::ParseTopLevel() { |
| 5315 TRACE_PARSER("ParseTopLevel"); | 5310 TRACE_PARSER("ParseTopLevel"); |
| 5316 // Collect the classes found at the top level in this growable array. | 5311 // Collect the classes found at the top level in this growable array. |
| 5317 // They need to be registered with class finalization after parsing | 5312 // They need to be registered with class finalization after parsing |
| 5318 // has been completed. | 5313 // has been completed. |
| 5319 ObjectStore* object_store = isolate()->object_store(); | 5314 ObjectStore* object_store = I->object_store(); |
| 5320 const GrowableObjectArray& pending_classes = | 5315 const GrowableObjectArray& pending_classes = |
| 5321 GrowableObjectArray::Handle(isolate(), object_store->pending_classes()); | 5316 GrowableObjectArray::Handle(I, object_store->pending_classes()); |
| 5322 SetPosition(0); | 5317 SetPosition(0); |
| 5323 is_top_level_ = true; | 5318 is_top_level_ = true; |
| 5324 TopLevel top_level; | 5319 TopLevel top_level; |
| 5325 Class& toplevel_class = Class::Handle(isolate(), | 5320 Class& toplevel_class = Class::Handle(I, |
| 5326 Class::New(Symbols::TopLevel(), script_, TokenPos())); | 5321 Class::New(Symbols::TopLevel(), script_, TokenPos())); |
| 5327 toplevel_class.set_library(library_); | 5322 toplevel_class.set_library(library_); |
| 5328 | 5323 |
| 5329 if (is_library_source() || is_patch_source()) { | 5324 if (is_library_source() || is_patch_source()) { |
| 5330 set_current_class(toplevel_class); | 5325 set_current_class(toplevel_class); |
| 5331 ParseLibraryDefinition(); | 5326 ParseLibraryDefinition(); |
| 5332 } else if (is_part_source()) { | 5327 } else if (is_part_source()) { |
| 5333 ParsePartHeader(); | 5328 ParsePartHeader(); |
| 5334 } | 5329 } |
| 5335 | 5330 |
| 5336 const Class& cls = Class::Handle(isolate()); | 5331 const Class& cls = Class::Handle(I); |
| 5337 while (true) { | 5332 while (true) { |
| 5338 set_current_class(cls); // No current class. | 5333 set_current_class(cls); // No current class. |
| 5339 intptr_t metadata_pos = SkipMetadata(); | 5334 intptr_t metadata_pos = SkipMetadata(); |
| 5340 if (CurrentToken() == Token::kCLASS) { | 5335 if (CurrentToken() == Token::kCLASS) { |
| 5341 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); | 5336 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
| 5342 } else if ((CurrentToken() == Token::kTYPEDEF) && | 5337 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 5343 (LookaheadToken(1) != Token::kLPAREN)) { | 5338 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5344 set_current_class(toplevel_class); | 5339 set_current_class(toplevel_class); |
| 5345 ParseTypedef(pending_classes, toplevel_class, metadata_pos); | 5340 ParseTypedef(pending_classes, toplevel_class, metadata_pos); |
| 5346 } else if ((CurrentToken() == Token::kABSTRACT) && | 5341 } else if ((CurrentToken() == Token::kABSTRACT) && |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5360 } else if (CurrentToken() == Token::kEOS) { | 5355 } else if (CurrentToken() == Token::kEOS) { |
| 5361 break; | 5356 break; |
| 5362 } else { | 5357 } else { |
| 5363 UnexpectedToken(); | 5358 UnexpectedToken(); |
| 5364 } | 5359 } |
| 5365 } | 5360 } |
| 5366 } | 5361 } |
| 5367 if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) { | 5362 if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) { |
| 5368 toplevel_class.AddFields(top_level.fields); | 5363 toplevel_class.AddFields(top_level.fields); |
| 5369 | 5364 |
| 5370 const Array& array = Array::Handle(isolate(), | 5365 const Array& array = Array::Handle(I, |
| 5371 Array::MakeArray(top_level.functions)); | 5366 Array::MakeArray(top_level.functions)); |
| 5372 toplevel_class.SetFunctions(array); | 5367 toplevel_class.SetFunctions(array); |
| 5373 | 5368 |
| 5374 library_.AddAnonymousClass(toplevel_class); | 5369 library_.AddAnonymousClass(toplevel_class); |
| 5375 pending_classes.Add(toplevel_class, Heap::kOld); | 5370 pending_classes.Add(toplevel_class, Heap::kOld); |
| 5376 } | 5371 } |
| 5377 } | 5372 } |
| 5378 | 5373 |
| 5379 | 5374 |
| 5380 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 5375 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
| 5381 Block* block = new(isolate()) Block( | 5376 Block* block = new(I) Block( |
| 5382 current_block_, | 5377 current_block_, |
| 5383 outer_scope, | 5378 outer_scope, |
| 5384 new(isolate()) SequenceNode(TokenPos(), outer_scope)); | 5379 new(I) SequenceNode(TokenPos(), outer_scope)); |
| 5385 current_block_ = block; | 5380 current_block_ = block; |
| 5386 } | 5381 } |
| 5387 | 5382 |
| 5388 | 5383 |
| 5389 void Parser::OpenBlock() { | 5384 void Parser::OpenBlock() { |
| 5390 ASSERT(current_block_ != NULL); | 5385 ASSERT(current_block_ != NULL); |
| 5391 LocalScope* outer_scope = current_block_->scope; | 5386 LocalScope* outer_scope = current_block_->scope; |
| 5392 ChainNewBlock(new(isolate()) LocalScope( | 5387 ChainNewBlock(new(I) LocalScope( |
| 5393 outer_scope, outer_scope->function_level(), outer_scope->loop_level())); | 5388 outer_scope, outer_scope->function_level(), outer_scope->loop_level())); |
| 5394 } | 5389 } |
| 5395 | 5390 |
| 5396 | 5391 |
| 5397 void Parser::OpenLoopBlock() { | 5392 void Parser::OpenLoopBlock() { |
| 5398 ASSERT(current_block_ != NULL); | 5393 ASSERT(current_block_ != NULL); |
| 5399 LocalScope* outer_scope = current_block_->scope; | 5394 LocalScope* outer_scope = current_block_->scope; |
| 5400 ChainNewBlock(new(isolate()) LocalScope( | 5395 ChainNewBlock(new(I) LocalScope( |
| 5401 outer_scope, | 5396 outer_scope, |
| 5402 outer_scope->function_level(), | 5397 outer_scope->function_level(), |
| 5403 outer_scope->loop_level() + 1)); | 5398 outer_scope->loop_level() + 1)); |
| 5404 } | 5399 } |
| 5405 | 5400 |
| 5406 | 5401 |
| 5407 void Parser::OpenFunctionBlock(const Function& func) { | 5402 void Parser::OpenFunctionBlock(const Function& func) { |
| 5408 LocalScope* outer_scope; | 5403 LocalScope* outer_scope; |
| 5409 if (current_block_ == NULL) { | 5404 if (current_block_ == NULL) { |
| 5410 if (!func.IsLocalFunction()) { | 5405 if (!func.IsLocalFunction()) { |
| 5411 // We are compiling a non-nested function. | 5406 // We are compiling a non-nested function. |
| 5412 outer_scope = new(isolate()) LocalScope(NULL, 0, 0); | 5407 outer_scope = new(I) LocalScope(NULL, 0, 0); |
| 5413 } else { | 5408 } else { |
| 5414 // We are compiling the function of an invoked closure. | 5409 // We are compiling the function of an invoked closure. |
| 5415 // Restore the outer scope containing all captured variables. | 5410 // Restore the outer scope containing all captured variables. |
| 5416 const ContextScope& context_scope = | 5411 const ContextScope& context_scope = |
| 5417 ContextScope::Handle(isolate(), func.context_scope()); | 5412 ContextScope::Handle(I, func.context_scope()); |
| 5418 ASSERT(!context_scope.IsNull()); | 5413 ASSERT(!context_scope.IsNull()); |
| 5419 outer_scope = new(isolate()) LocalScope( | 5414 outer_scope = new(I) LocalScope( |
| 5420 LocalScope::RestoreOuterScope(context_scope), 0, 0); | 5415 LocalScope::RestoreOuterScope(context_scope), 0, 0); |
| 5421 } | 5416 } |
| 5422 } else { | 5417 } else { |
| 5423 // We are parsing a nested function while compiling the enclosing function. | 5418 // We are parsing a nested function while compiling the enclosing function. |
| 5424 outer_scope = | 5419 outer_scope = |
| 5425 new(isolate()) LocalScope(current_block_->scope, | 5420 new(I) LocalScope(current_block_->scope, |
| 5426 current_block_->scope->function_level() + 1, | 5421 current_block_->scope->function_level() + 1, |
| 5427 0); | 5422 0); |
| 5428 } | 5423 } |
| 5429 ChainNewBlock(outer_scope); | 5424 ChainNewBlock(outer_scope); |
| 5430 } | 5425 } |
| 5431 | 5426 |
| 5432 | 5427 |
| 5433 SequenceNode* Parser::CloseBlock() { | 5428 SequenceNode* Parser::CloseBlock() { |
| 5434 SequenceNode* statements = current_block_->statements; | 5429 SequenceNode* statements = current_block_->statements; |
| 5435 if (current_block_->scope != NULL) { | 5430 if (current_block_->scope != NULL) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5497 // Populate local scope with the formal parameters. | 5492 // Populate local scope with the formal parameters. |
| 5498 void Parser::AddFormalParamsToScope(const ParamList* params, | 5493 void Parser::AddFormalParamsToScope(const ParamList* params, |
| 5499 LocalScope* scope) { | 5494 LocalScope* scope) { |
| 5500 ASSERT((params != NULL) && (params->parameters != NULL)); | 5495 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 5501 ASSERT(scope != NULL); | 5496 ASSERT(scope != NULL); |
| 5502 const int num_parameters = params->parameters->length(); | 5497 const int num_parameters = params->parameters->length(); |
| 5503 for (int i = 0; i < num_parameters; i++) { | 5498 for (int i = 0; i < num_parameters; i++) { |
| 5504 ParamDesc& param_desc = (*params->parameters)[i]; | 5499 ParamDesc& param_desc = (*params->parameters)[i]; |
| 5505 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); | 5500 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); |
| 5506 const String* name = param_desc.name; | 5501 const String* name = param_desc.name; |
| 5507 LocalVariable* parameter = new(isolate()) LocalVariable( | 5502 LocalVariable* parameter = new(I) LocalVariable( |
| 5508 param_desc.name_pos, *name, *param_desc.type); | 5503 param_desc.name_pos, *name, *param_desc.type); |
| 5509 if (!scope->InsertParameterAt(i, parameter)) { | 5504 if (!scope->InsertParameterAt(i, parameter)) { |
| 5510 ErrorMsg(param_desc.name_pos, | 5505 ErrorMsg(param_desc.name_pos, |
| 5511 "name '%s' already exists in scope", | 5506 "name '%s' already exists in scope", |
| 5512 param_desc.name->ToCString()); | 5507 param_desc.name->ToCString()); |
| 5513 } | 5508 } |
| 5514 param_desc.var = parameter; | 5509 param_desc.var = parameter; |
| 5515 if (param_desc.is_final) { | 5510 if (param_desc.is_final) { |
| 5516 parameter->set_is_final(); | 5511 parameter->set_is_final(); |
| 5517 } | 5512 } |
| 5518 if (param_desc.is_field_initializer) { | 5513 if (param_desc.is_field_initializer) { |
| 5519 parameter->set_invisible(true); | 5514 parameter->set_invisible(true); |
| 5520 } | 5515 } |
| 5521 } | 5516 } |
| 5522 } | 5517 } |
| 5523 | 5518 |
| 5524 | 5519 |
| 5525 // Builds ReturnNode/NativeBodyNode for a native function. | 5520 // Builds ReturnNode/NativeBodyNode for a native function. |
| 5526 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 5521 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
| 5527 const Function& func) { | 5522 const Function& func) { |
| 5528 ASSERT(func.is_native()); | 5523 ASSERT(func.is_native()); |
| 5529 TRACE_PARSER("ParseNativeFunctionBlock"); | 5524 TRACE_PARSER("ParseNativeFunctionBlock"); |
| 5530 const Class& cls = Class::Handle(isolate(), func.Owner()); | 5525 const Class& cls = Class::Handle(I, func.Owner()); |
| 5531 const Library& library = Library::Handle(isolate(), cls.library()); | 5526 const Library& library = Library::Handle(I, cls.library()); |
| 5532 ASSERT(func.NumParameters() == params->parameters->length()); | 5527 ASSERT(func.NumParameters() == params->parameters->length()); |
| 5533 | 5528 |
| 5534 // Parse the function name out. | 5529 // Parse the function name out. |
| 5535 const intptr_t native_pos = TokenPos(); | 5530 const intptr_t native_pos = TokenPos(); |
| 5536 const String& native_name = ParseNativeDeclaration(); | 5531 const String& native_name = ParseNativeDeclaration(); |
| 5537 | 5532 |
| 5538 // Now resolve the native function to the corresponding native entrypoint. | 5533 // Now resolve the native function to the corresponding native entrypoint. |
| 5539 const int num_params = NativeArguments::ParameterCountForResolution(func); | 5534 const int num_params = NativeArguments::ParameterCountForResolution(func); |
| 5540 bool auto_setup_scope = true; | 5535 bool auto_setup_scope = true; |
| 5541 NativeFunction native_function = NativeEntry::ResolveNative( | 5536 NativeFunction native_function = NativeEntry::ResolveNative( |
| 5542 library, native_name, num_params, &auto_setup_scope); | 5537 library, native_name, num_params, &auto_setup_scope); |
| 5543 if (native_function == NULL) { | 5538 if (native_function == NULL) { |
| 5544 ErrorMsg(native_pos, | 5539 ErrorMsg(native_pos, |
| 5545 "native function '%s' (%" Pd " arguments) cannot be found", | 5540 "native function '%s' (%" Pd " arguments) cannot be found", |
| 5546 native_name.ToCString(), func.NumParameters()); | 5541 native_name.ToCString(), func.NumParameters()); |
| 5547 } | 5542 } |
| 5548 func.SetIsNativeAutoSetupScope(auto_setup_scope); | 5543 func.SetIsNativeAutoSetupScope(auto_setup_scope); |
| 5549 | 5544 |
| 5550 // Now add the NativeBodyNode and return statement. | 5545 // Now add the NativeBodyNode and return statement. |
| 5551 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); | 5546 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); |
| 5552 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); | 5547 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); |
| 5553 current_block_->statements->Add(new(isolate()) ReturnNode( | 5548 current_block_->statements->Add(new(I) ReturnNode( |
| 5554 TokenPos(), new(isolate()) NativeBodyNode( | 5549 TokenPos(), new(I) NativeBodyNode( |
| 5555 TokenPos(), | 5550 TokenPos(), |
| 5556 Function::ZoneHandle(I, func.raw()), | 5551 Function::ZoneHandle(I, func.raw()), |
| 5557 native_name, | 5552 native_name, |
| 5558 native_function, | 5553 native_function, |
| 5559 current_block_->scope, | 5554 current_block_->scope, |
| 5560 is_bootstrap_native))); | 5555 is_bootstrap_native))); |
| 5561 } | 5556 } |
| 5562 | 5557 |
| 5563 | 5558 |
| 5564 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 5559 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5596 | 5591 |
| 5597 | 5592 |
| 5598 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 5593 AstNode* Parser::LoadReceiver(intptr_t token_pos) { |
| 5599 // A nested function may access 'this', referring to the receiver of the | 5594 // A nested function may access 'this', referring to the receiver of the |
| 5600 // outermost enclosing function. | 5595 // outermost enclosing function. |
| 5601 const bool kTestOnly = false; | 5596 const bool kTestOnly = false; |
| 5602 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 5597 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 5603 if (receiver == NULL) { | 5598 if (receiver == NULL) { |
| 5604 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); | 5599 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); |
| 5605 } | 5600 } |
| 5606 return new(isolate()) LoadLocalNode(TokenPos(), receiver); | 5601 return new(I) LoadLocalNode(TokenPos(), receiver); |
| 5607 } | 5602 } |
| 5608 | 5603 |
| 5609 | 5604 |
| 5610 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) { | 5605 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) { |
| 5611 // A nested function may access ':type_arguments' to use as instantiator, | 5606 // A nested function may access ':type_arguments' to use as instantiator, |
| 5612 // referring to the implicit first parameter of the outermost enclosing | 5607 // referring to the implicit first parameter of the outermost enclosing |
| 5613 // factory function. | 5608 // factory function. |
| 5614 const bool kTestOnly = false; | 5609 const bool kTestOnly = false; |
| 5615 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope, | 5610 LocalVariable* param = LookupTypeArgumentsParameter(current_block_->scope, |
| 5616 kTestOnly); | 5611 kTestOnly); |
| 5617 ASSERT(param != NULL); | 5612 ASSERT(param != NULL); |
| 5618 return new(isolate()) LoadLocalNode(TokenPos(), param); | 5613 return new(I) LoadLocalNode(TokenPos(), param); |
| 5619 } | 5614 } |
| 5620 | 5615 |
| 5621 | 5616 |
| 5622 AstNode* Parser::CallGetter(intptr_t token_pos, | 5617 AstNode* Parser::CallGetter(intptr_t token_pos, |
| 5623 AstNode* object, | 5618 AstNode* object, |
| 5624 const String& name) { | 5619 const String& name) { |
| 5625 return new(isolate()) InstanceGetterNode(token_pos, object, name); | 5620 return new(I) InstanceGetterNode(token_pos, object, name); |
| 5626 } | 5621 } |
| 5627 | 5622 |
| 5628 | 5623 |
| 5629 // Returns ast nodes of the variable initialization. | 5624 // Returns ast nodes of the variable initialization. |
| 5630 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 5625 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 5631 bool is_final, | 5626 bool is_final, |
| 5632 bool is_const) { | 5627 bool is_const) { |
| 5633 TRACE_PARSER("ParseVariableDeclaration"); | 5628 TRACE_PARSER("ParseVariableDeclaration"); |
| 5634 ASSERT(IsIdentifier()); | 5629 ASSERT(IsIdentifier()); |
| 5635 const intptr_t ident_pos = TokenPos(); | 5630 const intptr_t ident_pos = TokenPos(); |
| 5636 const String& ident = *CurrentLiteral(); | 5631 const String& ident = *CurrentLiteral(); |
| 5637 LocalVariable* variable = new(isolate()) LocalVariable( | 5632 LocalVariable* variable = new(I) LocalVariable( |
| 5638 ident_pos, ident, type); | 5633 ident_pos, ident, type); |
| 5639 ConsumeToken(); // Variable identifier. | 5634 ConsumeToken(); // Variable identifier. |
| 5640 AstNode* initialization = NULL; | 5635 AstNode* initialization = NULL; |
| 5641 if (CurrentToken() == Token::kASSIGN) { | 5636 if (CurrentToken() == Token::kASSIGN) { |
| 5642 // Variable initialization. | 5637 // Variable initialization. |
| 5643 const intptr_t assign_pos = TokenPos(); | 5638 const intptr_t assign_pos = TokenPos(); |
| 5644 ConsumeToken(); | 5639 ConsumeToken(); |
| 5645 AstNode* expr = ParseExpr(is_const, kConsumeCascades); | 5640 AstNode* expr = ParseExpr(is_const, kConsumeCascades); |
| 5646 initialization = new(isolate()) StoreLocalNode( | 5641 initialization = new(I) StoreLocalNode( |
| 5647 assign_pos, variable, expr); | 5642 assign_pos, variable, expr); |
| 5648 if (is_const) { | 5643 if (is_const) { |
| 5649 ASSERT(expr->IsLiteralNode()); | 5644 ASSERT(expr->IsLiteralNode()); |
| 5650 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 5645 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 5651 } | 5646 } |
| 5652 } else if (is_final || is_const) { | 5647 } else if (is_final || is_const) { |
| 5653 ErrorMsg(ident_pos, | 5648 ErrorMsg(ident_pos, |
| 5654 "missing initialization of 'final' or 'const' variable"); | 5649 "missing initialization of 'final' or 'const' variable"); |
| 5655 } else { | 5650 } else { |
| 5656 // Initialize variable with null. | 5651 // Initialize variable with null. |
| 5657 AstNode* null_expr = new(isolate()) LiteralNode( | 5652 AstNode* null_expr = new(I) LiteralNode( |
| 5658 ident_pos, Instance::ZoneHandle(I)); | 5653 ident_pos, Instance::ZoneHandle(I)); |
| 5659 initialization = new(isolate()) StoreLocalNode( | 5654 initialization = new(I) StoreLocalNode( |
| 5660 ident_pos, variable, null_expr); | 5655 ident_pos, variable, null_expr); |
| 5661 } | 5656 } |
| 5662 | 5657 |
| 5663 ASSERT(current_block_ != NULL); | 5658 ASSERT(current_block_ != NULL); |
| 5664 const intptr_t previous_pos = | 5659 const intptr_t previous_pos = |
| 5665 current_block_->scope->PreviousReferencePos(ident); | 5660 current_block_->scope->PreviousReferencePos(ident); |
| 5666 if (previous_pos >= 0) { | 5661 if (previous_pos >= 0) { |
| 5667 ASSERT(!script_.IsNull()); | 5662 ASSERT(!script_.IsNull()); |
| 5668 if (previous_pos > ident_pos) { | 5663 if (previous_pos > ident_pos) { |
| 5669 ErrorMsg(ident_pos, | 5664 ErrorMsg(ident_pos, |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5769 NULL); | 5764 NULL); |
| 5770 sequence->Add(ParseVariableDeclaration(type, is_final, is_const)); | 5765 sequence->Add(ParseVariableDeclaration(type, is_final, is_const)); |
| 5771 initializers = sequence; | 5766 initializers = sequence; |
| 5772 } | 5767 } |
| 5773 return initializers; | 5768 return initializers; |
| 5774 } | 5769 } |
| 5775 | 5770 |
| 5776 | 5771 |
| 5777 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 5772 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 5778 TRACE_PARSER("ParseFunctionStatement"); | 5773 TRACE_PARSER("ParseFunctionStatement"); |
| 5779 AbstractType& result_type = AbstractType::Handle(isolate()); | 5774 AbstractType& result_type = AbstractType::Handle(I); |
| 5780 const String* variable_name = NULL; | 5775 const String* variable_name = NULL; |
| 5781 const String* function_name = NULL; | 5776 const String* function_name = NULL; |
| 5782 | 5777 |
| 5783 result_type = Type::DynamicType(); | 5778 result_type = Type::DynamicType(); |
| 5784 | 5779 |
| 5785 const intptr_t function_pos = TokenPos(); | 5780 const intptr_t function_pos = TokenPos(); |
| 5786 if (is_literal) { | 5781 if (is_literal) { |
| 5787 ASSERT(CurrentToken() == Token::kLPAREN); | 5782 ASSERT(CurrentToken() == Token::kLPAREN); |
| 5788 function_name = &Symbols::AnonymousClosure(); | 5783 function_name = &Symbols::AnonymousClosure(); |
| 5789 } else { | 5784 } else { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5843 // passed as a function argument, or returned as a function result. | 5838 // passed as a function argument, or returned as a function result. |
| 5844 | 5839 |
| 5845 LocalVariable* function_variable = NULL; | 5840 LocalVariable* function_variable = NULL; |
| 5846 Type& function_type = Type::ZoneHandle(I); | 5841 Type& function_type = Type::ZoneHandle(I); |
| 5847 if (variable_name != NULL) { | 5842 if (variable_name != NULL) { |
| 5848 // Since the function type depends on the signature of the closure function, | 5843 // Since the function type depends on the signature of the closure function, |
| 5849 // it cannot be determined before the formal parameter list of the closure | 5844 // it cannot be determined before the formal parameter list of the closure |
| 5850 // function is parsed. Therefore, we set the function type to a new | 5845 // function is parsed. Therefore, we set the function type to a new |
| 5851 // parameterized type to be patched after the actual type is known. | 5846 // parameterized type to be patched after the actual type is known. |
| 5852 // We temporarily use the class of the Function interface. | 5847 // We temporarily use the class of the Function interface. |
| 5853 const Class& unknown_signature_class = Class::Handle(isolate(), | 5848 const Class& unknown_signature_class = Class::Handle(I, |
| 5854 Type::Handle(isolate(), Type::Function()).type_class()); | 5849 Type::Handle(I, Type::Function()).type_class()); |
| 5855 function_type = Type::New(unknown_signature_class, | 5850 function_type = Type::New(unknown_signature_class, |
| 5856 TypeArguments::Handle(isolate()), function_pos); | 5851 TypeArguments::Handle(I), function_pos); |
| 5857 function_type.SetIsFinalized(); // No finalization needed. | 5852 function_type.SetIsFinalized(); // No finalization needed. |
| 5858 | 5853 |
| 5859 // Add the function variable to the scope before parsing the function in | 5854 // Add the function variable to the scope before parsing the function in |
| 5860 // order to allow self reference from inside the function. | 5855 // order to allow self reference from inside the function. |
| 5861 function_variable = new(isolate()) LocalVariable(function_pos, | 5856 function_variable = new(I) LocalVariable(function_pos, |
| 5862 *variable_name, | 5857 *variable_name, |
| 5863 function_type); | 5858 function_type); |
| 5864 function_variable->set_is_final(); | 5859 function_variable->set_is_final(); |
| 5865 ASSERT(current_block_ != NULL); | 5860 ASSERT(current_block_ != NULL); |
| 5866 ASSERT(current_block_->scope != NULL); | 5861 ASSERT(current_block_->scope != NULL); |
| 5867 if (!current_block_->scope->AddVariable(function_variable)) { | 5862 if (!current_block_->scope->AddVariable(function_variable)) { |
| 5868 LocalVariable* existing_var = | 5863 LocalVariable* existing_var = |
| 5869 current_block_->scope->LookupVariable(function_variable->name(), | 5864 current_block_->scope->LookupVariable(function_variable->name(), |
| 5870 true); | 5865 true); |
| 5871 ASSERT(existing_var != NULL); | 5866 ASSERT(existing_var != NULL); |
| 5872 if (existing_var->owner() == current_block_->scope) { | 5867 if (existing_var->owner() == current_block_->scope) { |
| 5873 ErrorMsg(function_pos, "identifier '%s' already defined", | 5868 ErrorMsg(function_pos, "identifier '%s' already defined", |
| 5874 function_variable->name().ToCString()); | 5869 function_variable->name().ToCString()); |
| 5875 } else { | 5870 } else { |
| 5876 ErrorMsg(function_pos, | 5871 ErrorMsg(function_pos, |
| 5877 "'%s' from outer scope has already been used, cannot redefine", | 5872 "'%s' from outer scope has already been used, cannot redefine", |
| 5878 function_variable->name().ToCString()); | 5873 function_variable->name().ToCString()); |
| 5879 } | 5874 } |
| 5880 } | 5875 } |
| 5881 } | 5876 } |
| 5882 | 5877 |
| 5883 // Parse the local function. | 5878 // Parse the local function. |
| 5884 Array& default_parameter_values = Array::Handle(isolate()); | 5879 Array& default_parameter_values = Array::Handle(I); |
| 5885 SequenceNode* statements = Parser::ParseFunc(function, | 5880 SequenceNode* statements = Parser::ParseFunc(function, |
| 5886 &default_parameter_values); | 5881 &default_parameter_values); |
| 5887 | 5882 |
| 5888 // Now that the local function has formal parameters, lookup the signature | 5883 // Now that the local function has formal parameters, lookup the signature |
| 5889 // class in the current library (but not in its imports) and only create a new | 5884 // class in the current library (but not in its imports) and only create a new |
| 5890 // canonical signature class if it does not exist yet. | 5885 // canonical signature class if it does not exist yet. |
| 5891 const String& signature = String::Handle(isolate(), function.Signature()); | 5886 const String& signature = String::Handle(I, function.Signature()); |
| 5892 Class& signature_class = Class::ZoneHandle(I); | 5887 Class& signature_class = Class::ZoneHandle(I); |
| 5893 if (!is_new_closure) { | 5888 if (!is_new_closure) { |
| 5894 signature_class = function.signature_class(); | 5889 signature_class = function.signature_class(); |
| 5895 } | 5890 } |
| 5896 if (signature_class.IsNull()) { | 5891 if (signature_class.IsNull()) { |
| 5897 signature_class = library_.LookupLocalClass(signature); | 5892 signature_class = library_.LookupLocalClass(signature); |
| 5898 } | 5893 } |
| 5899 if (signature_class.IsNull()) { | 5894 if (signature_class.IsNull()) { |
| 5900 // If we don't have a signature class yet, this must be a closure we | 5895 // If we don't have a signature class yet, this must be a closure we |
| 5901 // have not parsed before. | 5896 // have not parsed before. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5917 ASSERT(current_class().is_finalized()); | 5912 ASSERT(current_class().is_finalized()); |
| 5918 | 5913 |
| 5919 // Make sure that the instantiator is captured. | 5914 // Make sure that the instantiator is captured. |
| 5920 if ((signature_class.NumTypeParameters() > 0) && | 5915 if ((signature_class.NumTypeParameters() > 0) && |
| 5921 (current_block_->scope->function_level() > 0)) { | 5916 (current_block_->scope->function_level() > 0)) { |
| 5922 CaptureInstantiator(); | 5917 CaptureInstantiator(); |
| 5923 } | 5918 } |
| 5924 | 5919 |
| 5925 // Since the signature type is cached by the signature class, it may have | 5920 // Since the signature type is cached by the signature class, it may have |
| 5926 // been finalized already. | 5921 // been finalized already. |
| 5927 Type& signature_type = Type::Handle(isolate(), | 5922 Type& signature_type = Type::Handle(I, |
| 5928 signature_class.SignatureType()); | 5923 signature_class.SignatureType()); |
| 5929 TypeArguments& signature_type_arguments = TypeArguments::Handle(isolate(), | 5924 TypeArguments& signature_type_arguments = TypeArguments::Handle(I, |
| 5930 signature_type.arguments()); | 5925 signature_type.arguments()); |
| 5931 | 5926 |
| 5932 if (!signature_type.IsFinalized()) { | 5927 if (!signature_type.IsFinalized()) { |
| 5933 signature_type ^= ClassFinalizer::FinalizeType( | 5928 signature_type ^= ClassFinalizer::FinalizeType( |
| 5934 signature_class, signature_type, ClassFinalizer::kCanonicalize); | 5929 signature_class, signature_type, ClassFinalizer::kCanonicalize); |
| 5935 | 5930 |
| 5936 // The call to ClassFinalizer::FinalizeType may have | 5931 // The call to ClassFinalizer::FinalizeType may have |
| 5937 // extended the vector of type arguments. | 5932 // extended the vector of type arguments. |
| 5938 signature_type_arguments = signature_type.arguments(); | 5933 signature_type_arguments = signature_type.arguments(); |
| 5939 ASSERT(signature_type_arguments.IsNull() || | 5934 ASSERT(signature_type_arguments.IsNull() || |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5975 // captured. The captured variables will be recorded along with their | 5970 // captured. The captured variables will be recorded along with their |
| 5976 // allocation information in a Scope object stored in the function object. | 5971 // allocation information in a Scope object stored in the function object. |
| 5977 // This Scope object is then provided to the compiler when compiling the local | 5972 // This Scope object is then provided to the compiler when compiling the local |
| 5978 // function. It would be too early to record the captured variables here, | 5973 // function. It would be too early to record the captured variables here, |
| 5979 // since further closure functions may capture more variables. | 5974 // since further closure functions may capture more variables. |
| 5980 // This Scope object is constructed after all variables have been allocated. | 5975 // This Scope object is constructed after all variables have been allocated. |
| 5981 // The local scope of the parsed function can be pruned, since contained | 5976 // The local scope of the parsed function can be pruned, since contained |
| 5982 // variables are not relevant for the compilation of the enclosing function. | 5977 // variables are not relevant for the compilation of the enclosing function. |
| 5983 // This pruning is done by omitting to hook the local scope in its parent | 5978 // This pruning is done by omitting to hook the local scope in its parent |
| 5984 // scope in the constructor of LocalScope. | 5979 // scope in the constructor of LocalScope. |
| 5985 AstNode* closure = new(isolate()) ClosureNode( | 5980 AstNode* closure = new(I) ClosureNode( |
| 5986 function_pos, function, NULL, statements->scope()); | 5981 function_pos, function, NULL, statements->scope()); |
| 5987 | 5982 |
| 5988 if (function_variable == NULL) { | 5983 if (function_variable == NULL) { |
| 5989 ASSERT(is_literal); | 5984 ASSERT(is_literal); |
| 5990 return closure; | 5985 return closure; |
| 5991 } else { | 5986 } else { |
| 5992 AstNode* initialization = new(isolate()) StoreLocalNode( | 5987 AstNode* initialization = new(I) StoreLocalNode( |
| 5993 function_pos, function_variable, closure); | 5988 function_pos, function_variable, closure); |
| 5994 return initialization; | 5989 return initialization; |
| 5995 } | 5990 } |
| 5996 } | 5991 } |
| 5997 | 5992 |
| 5998 | 5993 |
| 5999 // Returns true if the current and next tokens can be parsed as type | 5994 // Returns true if the current and next tokens can be parsed as type |
| 6000 // parameters. Current token position is not saved and restored. | 5995 // parameters. Current token position is not saved and restored. |
| 6001 bool Parser::TryParseTypeParameters() { | 5996 bool Parser::TryParseTypeParameters() { |
| 6002 if (CurrentToken() == Token::kLT) { | 5997 if (CurrentToken() == Token::kLT) { |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6368 ExpectToken(Token::kLPAREN); | 6363 ExpectToken(Token::kLPAREN); |
| 6369 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6364 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6370 ExpectToken(Token::kRPAREN); | 6365 ExpectToken(Token::kRPAREN); |
| 6371 const bool parsing_loop_body = false; | 6366 const bool parsing_loop_body = false; |
| 6372 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); | 6367 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 6373 SequenceNode* false_branch = NULL; | 6368 SequenceNode* false_branch = NULL; |
| 6374 if (CurrentToken() == Token::kELSE) { | 6369 if (CurrentToken() == Token::kELSE) { |
| 6375 ConsumeToken(); | 6370 ConsumeToken(); |
| 6376 false_branch = ParseNestedStatement(parsing_loop_body, NULL); | 6371 false_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 6377 } | 6372 } |
| 6378 AstNode* if_node = new(isolate()) IfNode( | 6373 AstNode* if_node = new(I) IfNode( |
| 6379 if_pos, cond_expr, true_branch, false_branch); | 6374 if_pos, cond_expr, true_branch, false_branch); |
| 6380 if (label != NULL) { | 6375 if (label != NULL) { |
| 6381 current_block_->statements->Add(if_node); | 6376 current_block_->statements->Add(if_node); |
| 6382 SequenceNode* sequence = CloseBlock(); | 6377 SequenceNode* sequence = CloseBlock(); |
| 6383 sequence->set_label(label); | 6378 sequence->set_label(label); |
| 6384 if_node = sequence; | 6379 if_node = sequence; |
| 6385 } | 6380 } |
| 6386 return if_node; | 6381 return if_node; |
| 6387 } | 6382 } |
| 6388 | 6383 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6436 // Check that the type class does not override the == operator. | 6431 // Check that the type class does not override the == operator. |
| 6437 // Check this only in the first loop iteration since all values | 6432 // Check this only in the first loop iteration since all values |
| 6438 // are of the same type, which we check above. | 6433 // are of the same type, which we check above. |
| 6439 if (ImplementsEqualOperator(val)) { | 6434 if (ImplementsEqualOperator(val)) { |
| 6440 ErrorMsg(val_pos, | 6435 ErrorMsg(val_pos, |
| 6441 "type class of case expression must not implement operator =="); | 6436 "type class of case expression must not implement operator =="); |
| 6442 } | 6437 } |
| 6443 } | 6438 } |
| 6444 } | 6439 } |
| 6445 if (first_value.IsInteger()) { | 6440 if (first_value.IsInteger()) { |
| 6446 return Type::Handle(isolate(), Type::IntType()).type_class(); | 6441 return Type::Handle(I, Type::IntType()).type_class(); |
| 6447 } else if (first_value.IsString()) { | 6442 } else if (first_value.IsString()) { |
| 6448 return Type::Handle(isolate(), Type::StringType()).type_class(); | 6443 return Type::Handle(I, Type::StringType()).type_class(); |
| 6449 } | 6444 } |
| 6450 return first_value.clazz(); | 6445 return first_value.clazz(); |
| 6451 } | 6446 } |
| 6452 | 6447 |
| 6453 | 6448 |
| 6454 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 6449 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 6455 GrowableArray<LiteralNode*>* case_expr_values, | 6450 GrowableArray<LiteralNode*>* case_expr_values, |
| 6456 SourceLabel* case_label) { | 6451 SourceLabel* case_label) { |
| 6457 TRACE_PARSER("ParseCaseClause"); | 6452 TRACE_PARSER("ParseCaseClause"); |
| 6458 bool default_seen = false; | 6453 bool default_seen = false; |
| 6459 const intptr_t case_pos = TokenPos(); | 6454 const intptr_t case_pos = TokenPos(); |
| 6460 // The case expressions node sequence does not own the enclosing scope. | 6455 // The case expressions node sequence does not own the enclosing scope. |
| 6461 SequenceNode* case_expressions = new(isolate()) SequenceNode(case_pos, NULL); | 6456 SequenceNode* case_expressions = new(I) SequenceNode(case_pos, NULL); |
| 6462 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 6457 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 6463 if (CurrentToken() == Token::kCASE) { | 6458 if (CurrentToken() == Token::kCASE) { |
| 6464 if (default_seen) { | 6459 if (default_seen) { |
| 6465 ErrorMsg("default clause must be last case"); | 6460 ErrorMsg("default clause must be last case"); |
| 6466 } | 6461 } |
| 6467 ConsumeToken(); // Keyword case. | 6462 ConsumeToken(); // Keyword case. |
| 6468 const intptr_t expr_pos = TokenPos(); | 6463 const intptr_t expr_pos = TokenPos(); |
| 6469 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); | 6464 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
| 6470 ASSERT(expr->IsLiteralNode()); | 6465 ASSERT(expr->IsLiteralNode()); |
| 6471 case_expr_values->Add(expr->AsLiteralNode()); | 6466 case_expr_values->Add(expr->AsLiteralNode()); |
| 6472 | 6467 |
| 6473 AstNode* switch_expr_load = new(isolate()) LoadLocalNode( | 6468 AstNode* switch_expr_load = new(I) LoadLocalNode( |
| 6474 case_pos, switch_expr_value); | 6469 case_pos, switch_expr_value); |
| 6475 AstNode* case_comparison = new(isolate()) ComparisonNode( | 6470 AstNode* case_comparison = new(I) ComparisonNode( |
| 6476 expr_pos, Token::kEQ, expr, switch_expr_load); | 6471 expr_pos, Token::kEQ, expr, switch_expr_load); |
| 6477 case_expressions->Add(case_comparison); | 6472 case_expressions->Add(case_comparison); |
| 6478 } else { | 6473 } else { |
| 6479 if (default_seen) { | 6474 if (default_seen) { |
| 6480 ErrorMsg("only one default clause is allowed"); | 6475 ErrorMsg("only one default clause is allowed"); |
| 6481 } | 6476 } |
| 6482 ConsumeToken(); // Keyword default. | 6477 ConsumeToken(); // Keyword default. |
| 6483 default_seen = true; | 6478 default_seen = true; |
| 6484 // The default case always succeeds. | 6479 // The default case always succeeds. |
| 6485 } | 6480 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 6499 next_token = CurrentToken(); | 6494 next_token = CurrentToken(); |
| 6500 } | 6495 } |
| 6501 if (next_token == Token::kRBRACE) { | 6496 if (next_token == Token::kRBRACE) { |
| 6502 // End of switch statement. | 6497 // End of switch statement. |
| 6503 break; | 6498 break; |
| 6504 } | 6499 } |
| 6505 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 6500 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
| 6506 // End of this case clause. If there is a possible fall-through to | 6501 // End of this case clause. If there is a possible fall-through to |
| 6507 // the next case clause, throw an implicit FallThroughError. | 6502 // the next case clause, throw an implicit FallThroughError. |
| 6508 if (!abrupt_completing_seen) { | 6503 if (!abrupt_completing_seen) { |
| 6509 ArgumentListNode* arguments = new(isolate()) ArgumentListNode( | 6504 ArgumentListNode* arguments = new(I) ArgumentListNode(TokenPos()); |
| 6510 TokenPos()); | 6505 arguments->Add(new(I) LiteralNode( |
| 6511 arguments->Add(new(isolate()) LiteralNode( | |
| 6512 TokenPos(), Integer::ZoneHandle(I, Integer::New(TokenPos())))); | 6506 TokenPos(), Integer::ZoneHandle(I, Integer::New(TokenPos())))); |
| 6513 current_block_->statements->Add( | 6507 current_block_->statements->Add( |
| 6514 MakeStaticCall(Symbols::FallThroughError(), | 6508 MakeStaticCall(Symbols::FallThroughError(), |
| 6515 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 6509 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 6516 arguments)); | 6510 arguments)); |
| 6517 } | 6511 } |
| 6518 break; | 6512 break; |
| 6519 } | 6513 } |
| 6520 // The next statement still belongs to this case. | 6514 // The next statement still belongs to this case. |
| 6521 AstNode* statement = ParseStatement(); | 6515 AstNode* statement = ParseStatement(); |
| 6522 if (statement != NULL) { | 6516 if (statement != NULL) { |
| 6523 current_block_->statements->Add(statement); | 6517 current_block_->statements->Add(statement); |
| 6524 abrupt_completing_seen |= IsAbruptCompleting(statement); | 6518 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 6525 } | 6519 } |
| 6526 } | 6520 } |
| 6527 SequenceNode* statements = CloseBlock(); | 6521 SequenceNode* statements = CloseBlock(); |
| 6528 return new(isolate()) CaseNode(case_pos, case_label, | 6522 return new(I) CaseNode(case_pos, case_label, |
| 6529 case_expressions, default_seen, switch_expr_value, statements); | 6523 case_expressions, default_seen, switch_expr_value, statements); |
| 6530 } | 6524 } |
| 6531 | 6525 |
| 6532 | 6526 |
| 6533 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 6527 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
| 6534 TRACE_PARSER("ParseSwitchStatement"); | 6528 TRACE_PARSER("ParseSwitchStatement"); |
| 6535 ASSERT(CurrentToken() == Token::kSWITCH); | 6529 ASSERT(CurrentToken() == Token::kSWITCH); |
| 6536 const intptr_t switch_pos = TokenPos(); | 6530 const intptr_t switch_pos = TokenPos(); |
| 6537 SourceLabel* label = | 6531 SourceLabel* label = |
| 6538 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 6532 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
| 6539 ConsumeToken(); | 6533 ConsumeToken(); |
| 6540 ExpectToken(Token::kLPAREN); | 6534 ExpectToken(Token::kLPAREN); |
| 6541 const intptr_t expr_pos = TokenPos(); | 6535 const intptr_t expr_pos = TokenPos(); |
| 6542 AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6536 AstNode* switch_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6543 ExpectToken(Token::kRPAREN); | 6537 ExpectToken(Token::kRPAREN); |
| 6544 ExpectToken(Token::kLBRACE); | 6538 ExpectToken(Token::kLBRACE); |
| 6545 OpenBlock(); | 6539 OpenBlock(); |
| 6546 current_block_->scope->AddLabel(label); | 6540 current_block_->scope->AddLabel(label); |
| 6547 | 6541 |
| 6548 // Store switch expression in temporary local variable. The type of the | 6542 // Store switch expression in temporary local variable. The type of the |
| 6549 // variable is set to dynamic. It will later be patched to match the | 6543 // variable is set to dynamic. It will later be patched to match the |
| 6550 // type of the case clause expressions. Therefore, we have to allocate | 6544 // type of the case clause expressions. Therefore, we have to allocate |
| 6551 // a new type representing dynamic and can't reuse the canonical | 6545 // a new type representing dynamic and can't reuse the canonical |
| 6552 // type object for dynamic. | 6546 // type object for dynamic. |
| 6553 const Type& temp_var_type = Type::ZoneHandle(I, | 6547 const Type& temp_var_type = Type::ZoneHandle(I, |
| 6554 Type::New(Class::Handle(isolate(), Object::dynamic_class()), | 6548 Type::New(Class::Handle(I, Object::dynamic_class()), |
| 6555 TypeArguments::Handle(isolate()), | 6549 TypeArguments::Handle(I), |
| 6556 expr_pos)); | 6550 expr_pos)); |
| 6557 temp_var_type.SetIsFinalized(); | 6551 temp_var_type.SetIsFinalized(); |
| 6558 LocalVariable* temp_variable = new(isolate()) LocalVariable( | 6552 LocalVariable* temp_variable = new(I) LocalVariable( |
| 6559 expr_pos, Symbols::SwitchExpr(), temp_var_type); | 6553 expr_pos, Symbols::SwitchExpr(), temp_var_type); |
| 6560 current_block_->scope->AddVariable(temp_variable); | 6554 current_block_->scope->AddVariable(temp_variable); |
| 6561 AstNode* save_switch_expr = new(isolate()) StoreLocalNode( | 6555 AstNode* save_switch_expr = new(I) StoreLocalNode( |
| 6562 expr_pos, temp_variable, switch_expr); | 6556 expr_pos, temp_variable, switch_expr); |
| 6563 current_block_->statements->Add(save_switch_expr); | 6557 current_block_->statements->Add(save_switch_expr); |
| 6564 | 6558 |
| 6565 // Parse case clauses | 6559 // Parse case clauses |
| 6566 bool default_seen = false; | 6560 bool default_seen = false; |
| 6567 GrowableArray<LiteralNode*> case_expr_values; | 6561 GrowableArray<LiteralNode*> case_expr_values; |
| 6568 while (true) { | 6562 while (true) { |
| 6569 // Check for statement label | 6563 // Check for statement label |
| 6570 SourceLabel* case_label = NULL; | 6564 SourceLabel* case_label = NULL; |
| 6571 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 6565 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 6572 // Case statements start with a label. | 6566 // Case statements start with a label. |
| 6573 String* label_name = CurrentLiteral(); | 6567 String* label_name = CurrentLiteral(); |
| 6574 const intptr_t label_pos = TokenPos(); | 6568 const intptr_t label_pos = TokenPos(); |
| 6575 ConsumeToken(); // Consume label identifier. | 6569 ConsumeToken(); // Consume label identifier. |
| 6576 ConsumeToken(); // Consume colon. | 6570 ConsumeToken(); // Consume colon. |
| 6577 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 6571 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
| 6578 if (case_label == NULL) { | 6572 if (case_label == NULL) { |
| 6579 // Label does not exist yet. Add it to scope of switch statement. | 6573 // Label does not exist yet. Add it to scope of switch statement. |
| 6580 case_label = new(isolate()) SourceLabel( | 6574 case_label = new(I) SourceLabel( |
| 6581 label_pos, *label_name, SourceLabel::kCase); | 6575 label_pos, *label_name, SourceLabel::kCase); |
| 6582 current_block_->scope->AddLabel(case_label); | 6576 current_block_->scope->AddLabel(case_label); |
| 6583 } else if (case_label->kind() == SourceLabel::kForward) { | 6577 } else if (case_label->kind() == SourceLabel::kForward) { |
| 6584 // We have seen a 'continue' with this label name. Resolve | 6578 // We have seen a 'continue' with this label name. Resolve |
| 6585 // the forward reference. | 6579 // the forward reference. |
| 6586 case_label->ResolveForwardReference(); | 6580 case_label->ResolveForwardReference(); |
| 6587 } else { | 6581 } else { |
| 6588 ErrorMsg(label_pos, "label '%s' already exists in scope", | 6582 ErrorMsg(label_pos, "label '%s' already exists in scope", |
| 6589 label_name->ToCString()); | 6583 label_name->ToCString()); |
| 6590 } | 6584 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 6606 } else { | 6600 } else { |
| 6607 break; | 6601 break; |
| 6608 } | 6602 } |
| 6609 } | 6603 } |
| 6610 | 6604 |
| 6611 // Check that all expressions in case clauses are of the same class, | 6605 // Check that all expressions in case clauses are of the same class, |
| 6612 // or implement int, double or String. Patch the type of the temporary | 6606 // or implement int, double or String. Patch the type of the temporary |
| 6613 // variable holding the switch expression to match the type of the | 6607 // variable holding the switch expression to match the type of the |
| 6614 // case clause constants. | 6608 // case clause constants. |
| 6615 temp_var_type.set_type_class( | 6609 temp_var_type.set_type_class( |
| 6616 Class::Handle(isolate(), CheckCaseExpressions(case_expr_values))); | 6610 Class::Handle(I, CheckCaseExpressions(case_expr_values))); |
| 6617 | 6611 |
| 6618 // Check for unresolved label references. | 6612 // Check for unresolved label references. |
| 6619 SourceLabel* unresolved_label = | 6613 SourceLabel* unresolved_label = |
| 6620 current_block_->scope->CheckUnresolvedLabels(); | 6614 current_block_->scope->CheckUnresolvedLabels(); |
| 6621 if (unresolved_label != NULL) { | 6615 if (unresolved_label != NULL) { |
| 6622 ErrorMsg("unresolved reference to label '%s'", | 6616 ErrorMsg("unresolved reference to label '%s'", |
| 6623 unresolved_label->name().ToCString()); | 6617 unresolved_label->name().ToCString()); |
| 6624 } | 6618 } |
| 6625 | 6619 |
| 6626 SequenceNode* switch_body = CloseBlock(); | 6620 SequenceNode* switch_body = CloseBlock(); |
| 6627 ExpectToken(Token::kRBRACE); | 6621 ExpectToken(Token::kRBRACE); |
| 6628 return new(isolate()) SwitchNode(switch_pos, label, switch_body); | 6622 return new(I) SwitchNode(switch_pos, label, switch_body); |
| 6629 } | 6623 } |
| 6630 | 6624 |
| 6631 | 6625 |
| 6632 AstNode* Parser::ParseWhileStatement(String* label_name) { | 6626 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 6633 TRACE_PARSER("ParseWhileStatement"); | 6627 TRACE_PARSER("ParseWhileStatement"); |
| 6634 const intptr_t while_pos = TokenPos(); | 6628 const intptr_t while_pos = TokenPos(); |
| 6635 SourceLabel* label = | 6629 SourceLabel* label = |
| 6636 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 6630 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 6637 ConsumeToken(); | 6631 ConsumeToken(); |
| 6638 ExpectToken(Token::kLPAREN); | 6632 ExpectToken(Token::kLPAREN); |
| 6639 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6633 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6640 ExpectToken(Token::kRPAREN); | 6634 ExpectToken(Token::kRPAREN); |
| 6641 const bool parsing_loop_body = true; | 6635 const bool parsing_loop_body = true; |
| 6642 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 6636 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 6643 return new(isolate()) WhileNode(while_pos, label, cond_expr, while_body); | 6637 return new(I) WhileNode(while_pos, label, cond_expr, while_body); |
| 6644 } | 6638 } |
| 6645 | 6639 |
| 6646 | 6640 |
| 6647 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 6641 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 6648 TRACE_PARSER("ParseDoWhileStatement"); | 6642 TRACE_PARSER("ParseDoWhileStatement"); |
| 6649 const intptr_t do_pos = TokenPos(); | 6643 const intptr_t do_pos = TokenPos(); |
| 6650 SourceLabel* label = | 6644 SourceLabel* label = |
| 6651 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 6645 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 6652 ConsumeToken(); | 6646 ConsumeToken(); |
| 6653 const bool parsing_loop_body = true; | 6647 const bool parsing_loop_body = true; |
| 6654 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 6648 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 6655 ExpectToken(Token::kWHILE); | 6649 ExpectToken(Token::kWHILE); |
| 6656 ExpectToken(Token::kLPAREN); | 6650 ExpectToken(Token::kLPAREN); |
| 6657 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6651 AstNode* cond_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6658 ExpectToken(Token::kRPAREN); | 6652 ExpectToken(Token::kRPAREN); |
| 6659 ExpectSemicolon(); | 6653 ExpectSemicolon(); |
| 6660 return new(isolate()) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 6654 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 6661 } | 6655 } |
| 6662 | 6656 |
| 6663 | 6657 |
| 6664 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 6658 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 6665 SourceLabel* label) { | 6659 SourceLabel* label) { |
| 6666 TRACE_PARSER("ParseForInStatement"); | 6660 TRACE_PARSER("ParseForInStatement"); |
| 6667 bool is_final = (CurrentToken() == Token::kFINAL); | 6661 bool is_final = (CurrentToken() == Token::kFINAL); |
| 6668 if (CurrentToken() == Token::kCONST) { | 6662 if (CurrentToken() == Token::kCONST) { |
| 6669 ErrorMsg("Loop variable cannot be 'const'"); | 6663 ErrorMsg("Loop variable cannot be 'const'"); |
| 6670 } | 6664 } |
| 6671 const String* loop_var_name = NULL; | 6665 const String* loop_var_name = NULL; |
| 6672 LocalVariable* loop_var = NULL; | 6666 LocalVariable* loop_var = NULL; |
| 6673 intptr_t loop_var_pos = 0; | 6667 intptr_t loop_var_pos = 0; |
| 6674 if (LookaheadToken(1) == Token::kIN) { | 6668 if (LookaheadToken(1) == Token::kIN) { |
| 6675 loop_var_pos = TokenPos(); | 6669 loop_var_pos = TokenPos(); |
| 6676 loop_var_name = ExpectIdentifier("variable name expected"); | 6670 loop_var_name = ExpectIdentifier("variable name expected"); |
| 6677 } else { | 6671 } else { |
| 6678 // The case without a type is handled above, so require a type here. | 6672 // The case without a type is handled above, so require a type here. |
| 6679 const AbstractType& type = | 6673 const AbstractType& type = |
| 6680 AbstractType::ZoneHandle(I, ParseConstFinalVarOrType( | 6674 AbstractType::ZoneHandle(I, ParseConstFinalVarOrType( |
| 6681 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : | 6675 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : |
| 6682 ClassFinalizer::kIgnore)); | 6676 ClassFinalizer::kIgnore)); |
| 6683 loop_var_pos = TokenPos(); | 6677 loop_var_pos = TokenPos(); |
| 6684 loop_var_name = ExpectIdentifier("variable name expected"); | 6678 loop_var_name = ExpectIdentifier("variable name expected"); |
| 6685 loop_var = new(isolate()) LocalVariable(loop_var_pos, *loop_var_name, type); | 6679 loop_var = new(I) LocalVariable(loop_var_pos, *loop_var_name, type); |
| 6686 if (is_final) { | 6680 if (is_final) { |
| 6687 loop_var->set_is_final(); | 6681 loop_var->set_is_final(); |
| 6688 } | 6682 } |
| 6689 } | 6683 } |
| 6690 ExpectToken(Token::kIN); | 6684 ExpectToken(Token::kIN); |
| 6691 const intptr_t collection_pos = TokenPos(); | 6685 const intptr_t collection_pos = TokenPos(); |
| 6692 AstNode* collection_expr = ParseExpr(kAllowConst, kConsumeCascades); | 6686 AstNode* collection_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 6693 ExpectToken(Token::kRPAREN); | 6687 ExpectToken(Token::kRPAREN); |
| 6694 | 6688 |
| 6695 OpenBlock(); // Implicit block around while loop. | 6689 OpenBlock(); // Implicit block around while loop. |
| 6696 | 6690 |
| 6697 // Generate implicit iterator variable and add to scope. | 6691 // Generate implicit iterator variable and add to scope. |
| 6698 // We could set the type of the implicit iterator variable to Iterator<T> | 6692 // We could set the type of the implicit iterator variable to Iterator<T> |
| 6699 // where T is the type of the for loop variable. However, the type error | 6693 // where T is the type of the for loop variable. However, the type error |
| 6700 // would refer to the compiler generated iterator and could confuse the user. | 6694 // would refer to the compiler generated iterator and could confuse the user. |
| 6701 // It is better to leave the iterator untyped and postpone the type error | 6695 // It is better to leave the iterator untyped and postpone the type error |
| 6702 // until the loop variable is assigned to. | 6696 // until the loop variable is assigned to. |
| 6703 const AbstractType& iterator_type = Type::ZoneHandle(I, Type::DynamicType()); | 6697 const AbstractType& iterator_type = Type::ZoneHandle(I, Type::DynamicType()); |
| 6704 LocalVariable* iterator_var = new(isolate()) LocalVariable( | 6698 LocalVariable* iterator_var = new(I) LocalVariable( |
| 6705 collection_pos, Symbols::ForInIter(), iterator_type); | 6699 collection_pos, Symbols::ForInIter(), iterator_type); |
| 6706 current_block_->scope->AddVariable(iterator_var); | 6700 current_block_->scope->AddVariable(iterator_var); |
| 6707 | 6701 |
| 6708 // Generate initialization of iterator variable. | 6702 // Generate initialization of iterator variable. |
| 6709 ArgumentListNode* no_args = new(isolate()) ArgumentListNode(collection_pos); | 6703 ArgumentListNode* no_args = new(I) ArgumentListNode(collection_pos); |
| 6710 AstNode* get_iterator = new(isolate()) InstanceGetterNode( | 6704 AstNode* get_iterator = new(I) InstanceGetterNode( |
| 6711 collection_pos, collection_expr, Symbols::GetIterator()); | 6705 collection_pos, collection_expr, Symbols::GetIterator()); |
| 6712 AstNode* iterator_init = | 6706 AstNode* iterator_init = |
| 6713 new(isolate()) StoreLocalNode(collection_pos, iterator_var, get_iterator); | 6707 new(I) StoreLocalNode(collection_pos, iterator_var, get_iterator); |
| 6714 current_block_->statements->Add(iterator_init); | 6708 current_block_->statements->Add(iterator_init); |
| 6715 | 6709 |
| 6716 // Generate while loop condition. | 6710 // Generate while loop condition. |
| 6717 AstNode* iterator_moveNext = new(isolate()) InstanceCallNode( | 6711 AstNode* iterator_moveNext = new(I) InstanceCallNode( |
| 6718 collection_pos, | 6712 collection_pos, |
| 6719 new(isolate()) LoadLocalNode(collection_pos, iterator_var), | 6713 new(I) LoadLocalNode(collection_pos, iterator_var), |
| 6720 Symbols::MoveNext(), | 6714 Symbols::MoveNext(), |
| 6721 no_args); | 6715 no_args); |
| 6722 | 6716 |
| 6723 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 6717 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
| 6724 // here, but that does not work well because we have to insert an implicit | 6718 // here, but that does not work well because we have to insert an implicit |
| 6725 // variable assignment and potentially a variable declaration in the | 6719 // variable assignment and potentially a variable declaration in the |
| 6726 // loop body. | 6720 // loop body. |
| 6727 OpenLoopBlock(); | 6721 OpenLoopBlock(); |
| 6728 current_block_->scope->AddLabel(label); | 6722 current_block_->scope->AddLabel(label); |
| 6729 | 6723 |
| 6730 AstNode* iterator_current = new(isolate()) InstanceGetterNode( | 6724 AstNode* iterator_current = new(I) InstanceGetterNode( |
| 6731 collection_pos, | 6725 collection_pos, |
| 6732 new(isolate()) LoadLocalNode(collection_pos, iterator_var), | 6726 new(I) LoadLocalNode(collection_pos, iterator_var), |
| 6733 Symbols::Current()); | 6727 Symbols::Current()); |
| 6734 | 6728 |
| 6735 // Generate assignment of next iterator value to loop variable. | 6729 // Generate assignment of next iterator value to loop variable. |
| 6736 AstNode* loop_var_assignment = NULL; | 6730 AstNode* loop_var_assignment = NULL; |
| 6737 if (loop_var != NULL) { | 6731 if (loop_var != NULL) { |
| 6738 // The for loop declares a new variable. Add it to the loop body scope. | 6732 // The for loop declares a new variable. Add it to the loop body scope. |
| 6739 current_block_->scope->AddVariable(loop_var); | 6733 current_block_->scope->AddVariable(loop_var); |
| 6740 loop_var_assignment = | 6734 loop_var_assignment = |
| 6741 new(isolate()) StoreLocalNode(loop_var_pos, loop_var, iterator_current); | 6735 new(I) StoreLocalNode(loop_var_pos, loop_var, iterator_current); |
| 6742 } else { | 6736 } else { |
| 6743 AstNode* loop_var_primary = | 6737 AstNode* loop_var_primary = |
| 6744 ResolveIdent(loop_var_pos, *loop_var_name, false); | 6738 ResolveIdent(loop_var_pos, *loop_var_name, false); |
| 6745 ASSERT(!loop_var_primary->IsPrimaryNode()); | 6739 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 6746 loop_var_assignment = CreateAssignmentNode( | 6740 loop_var_assignment = CreateAssignmentNode( |
| 6747 loop_var_primary, iterator_current, loop_var_name, loop_var_pos); | 6741 loop_var_primary, iterator_current, loop_var_name, loop_var_pos); |
| 6748 ASSERT(loop_var_assignment != NULL); | 6742 ASSERT(loop_var_assignment != NULL); |
| 6749 } | 6743 } |
| 6750 current_block_->statements->Add(loop_var_assignment); | 6744 current_block_->statements->Add(loop_var_assignment); |
| 6751 | 6745 |
| 6752 // Now parse the for-in loop statement or block. | 6746 // Now parse the for-in loop statement or block. |
| 6753 if (CurrentToken() == Token::kLBRACE) { | 6747 if (CurrentToken() == Token::kLBRACE) { |
| 6754 ConsumeToken(); | 6748 ConsumeToken(); |
| 6755 ParseStatementSequence(); | 6749 ParseStatementSequence(); |
| 6756 ExpectToken(Token::kRBRACE); | 6750 ExpectToken(Token::kRBRACE); |
| 6757 } else { | 6751 } else { |
| 6758 AstNode* statement = ParseStatement(); | 6752 AstNode* statement = ParseStatement(); |
| 6759 if (statement != NULL) { | 6753 if (statement != NULL) { |
| 6760 current_block_->statements->Add(statement); | 6754 current_block_->statements->Add(statement); |
| 6761 } | 6755 } |
| 6762 } | 6756 } |
| 6763 | 6757 |
| 6764 SequenceNode* for_loop_statement = CloseBlock(); | 6758 SequenceNode* for_loop_statement = CloseBlock(); |
| 6765 | 6759 |
| 6766 AstNode* while_statement = new(isolate()) WhileNode( | 6760 AstNode* while_statement = new(I) WhileNode( |
| 6767 forin_pos, label, iterator_moveNext, for_loop_statement); | 6761 forin_pos, label, iterator_moveNext, for_loop_statement); |
| 6768 current_block_->statements->Add(while_statement); | 6762 current_block_->statements->Add(while_statement); |
| 6769 | 6763 |
| 6770 return CloseBlock(); // Implicit block around while loop. | 6764 return CloseBlock(); // Implicit block around while loop. |
| 6771 } | 6765 } |
| 6772 | 6766 |
| 6773 | 6767 |
| 6774 AstNode* Parser::ParseForStatement(String* label_name) { | 6768 AstNode* Parser::ParseForStatement(String* label_name) { |
| 6775 TRACE_PARSER("ParseForStatement"); | 6769 TRACE_PARSER("ParseForStatement"); |
| 6776 const intptr_t for_pos = TokenPos(); | 6770 const intptr_t for_pos = TokenPos(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6808 const bool parsing_loop_body = true; | 6802 const bool parsing_loop_body = true; |
| 6809 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 6803 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
| 6810 | 6804 |
| 6811 // Check whether any of the variables in the initializer part of | 6805 // Check whether any of the variables in the initializer part of |
| 6812 // the for statement are captured by a closure. If so, we insert a | 6806 // the for statement are captured by a closure. If so, we insert a |
| 6813 // node that creates a new Context for the loop variable before | 6807 // node that creates a new Context for the loop variable before |
| 6814 // the increment expression is evaluated. | 6808 // the increment expression is evaluated. |
| 6815 for (int i = 0; i < init_scope->num_variables(); i++) { | 6809 for (int i = 0; i < init_scope->num_variables(); i++) { |
| 6816 if (init_scope->VariableAt(i)->is_captured() && | 6810 if (init_scope->VariableAt(i)->is_captured() && |
| 6817 (init_scope->VariableAt(i)->owner() == init_scope)) { | 6811 (init_scope->VariableAt(i)->owner() == init_scope)) { |
| 6818 SequenceNode* incr_sequence = new(isolate()) SequenceNode(incr_pos, NULL); | 6812 SequenceNode* incr_sequence = new(I) SequenceNode(incr_pos, NULL); |
| 6819 incr_sequence->Add(new(isolate()) CloneContextNode(for_pos)); | 6813 incr_sequence->Add(new(I) CloneContextNode(for_pos)); |
| 6820 if (increment != NULL) { | 6814 if (increment != NULL) { |
| 6821 incr_sequence->Add(increment); | 6815 incr_sequence->Add(increment); |
| 6822 } | 6816 } |
| 6823 increment = incr_sequence; | 6817 increment = incr_sequence; |
| 6824 break; | 6818 break; |
| 6825 } | 6819 } |
| 6826 } | 6820 } |
| 6827 AstNode* for_node = | 6821 AstNode* for_node = new(I) ForNode( |
| 6828 new(isolate()) ForNode(for_pos, | 6822 for_pos, |
| 6829 label, | 6823 label, |
| 6830 NodeAsSequenceNode(init_pos, initializer, NULL), | 6824 NodeAsSequenceNode(init_pos, initializer, NULL), |
| 6831 condition, | 6825 condition, |
| 6832 NodeAsSequenceNode(incr_pos, increment, NULL), | 6826 NodeAsSequenceNode(incr_pos, increment, NULL), |
| 6833 body); | 6827 body); |
| 6834 current_block_->statements->Add(for_node); | 6828 current_block_->statements->Add(for_node); |
| 6835 return CloseBlock(); | 6829 return CloseBlock(); |
| 6836 } | 6830 } |
| 6837 | 6831 |
| 6838 | 6832 |
| 6839 // Calling VM-internal helpers, uses implementation core library. | 6833 // Calling VM-internal helpers, uses implementation core library. |
| 6840 AstNode* Parser::MakeStaticCall(const String& cls_name, | 6834 AstNode* Parser::MakeStaticCall(const String& cls_name, |
| 6841 const String& func_name, | 6835 const String& func_name, |
| 6842 ArgumentListNode* arguments) { | 6836 ArgumentListNode* arguments) { |
| 6843 const Class& cls = Class::Handle(isolate(), | 6837 const Class& cls = Class::Handle(I, Library::LookupCoreClass(cls_name)); |
| 6844 Library::LookupCoreClass(cls_name)); | |
| 6845 ASSERT(!cls.IsNull()); | 6838 ASSERT(!cls.IsNull()); |
| 6846 const Function& func = Function::ZoneHandle(I, | 6839 const Function& func = Function::ZoneHandle(I, |
| 6847 Resolver::ResolveStatic(cls, | 6840 Resolver::ResolveStatic(cls, |
| 6848 func_name, | 6841 func_name, |
| 6849 arguments->length(), | 6842 arguments->length(), |
| 6850 arguments->names())); | 6843 arguments->names())); |
| 6851 ASSERT(!func.IsNull()); | 6844 ASSERT(!func.IsNull()); |
| 6852 return new(isolate()) StaticCallNode(arguments->token_pos(), func, arguments); | 6845 return new(I) StaticCallNode(arguments->token_pos(), func, arguments); |
| 6853 } | 6846 } |
| 6854 | 6847 |
| 6855 | 6848 |
| 6856 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { | 6849 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { |
| 6857 ArgumentListNode* arguments = new(isolate()) ArgumentListNode(begin); | 6850 ArgumentListNode* arguments = new(I) ArgumentListNode(begin); |
| 6858 arguments->Add(new(isolate()) LiteralNode(begin, | 6851 arguments->Add(new(I) LiteralNode(begin, |
| 6859 Integer::ZoneHandle(I, Integer::New(begin)))); | 6852 Integer::ZoneHandle(I, Integer::New(begin)))); |
| 6860 arguments->Add(new(isolate()) LiteralNode(end, | 6853 arguments->Add(new(I) LiteralNode(end, |
| 6861 Integer::ZoneHandle(I, Integer::New(end)))); | 6854 Integer::ZoneHandle(I, Integer::New(end)))); |
| 6862 return MakeStaticCall(Symbols::AssertionError(), | 6855 return MakeStaticCall(Symbols::AssertionError(), |
| 6863 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 6856 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 6864 arguments); | 6857 arguments); |
| 6865 } | 6858 } |
| 6866 | 6859 |
| 6867 | 6860 |
| 6868 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { | 6861 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { |
| 6869 if (condition->IsClosureNode() || | 6862 if (condition->IsClosureNode() || |
| 6870 (condition->IsStoreLocalNode() && | 6863 (condition->IsStoreLocalNode() && |
| 6871 condition->AsStoreLocalNode()->value()->IsClosureNode())) { | 6864 condition->AsStoreLocalNode()->value()->IsClosureNode())) { |
| 6872 // Function literal in assert implies a call. | 6865 // Function literal in assert implies a call. |
| 6873 const intptr_t pos = condition->token_pos(); | 6866 const intptr_t pos = condition->token_pos(); |
| 6874 condition = BuildClosureCall(pos, | 6867 condition = BuildClosureCall(pos, |
| 6875 condition, | 6868 condition, |
| 6876 new(isolate()) ArgumentListNode(pos)); | 6869 new(I) ArgumentListNode(pos)); |
| 6877 } else if (condition->IsConditionalExprNode()) { | 6870 } else if (condition->IsConditionalExprNode()) { |
| 6878 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); | 6871 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); |
| 6879 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); | 6872 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); |
| 6880 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 6873 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
| 6881 } | 6874 } |
| 6882 return condition; | 6875 return condition; |
| 6883 } | 6876 } |
| 6884 | 6877 |
| 6885 | 6878 |
| 6886 AstNode* Parser::ParseAssertStatement() { | 6879 AstNode* Parser::ParseAssertStatement() { |
| 6887 TRACE_PARSER("ParseAssertStatement"); | 6880 TRACE_PARSER("ParseAssertStatement"); |
| 6888 ConsumeToken(); // Consume assert keyword. | 6881 ConsumeToken(); // Consume assert keyword. |
| 6889 ExpectToken(Token::kLPAREN); | 6882 ExpectToken(Token::kLPAREN); |
| 6890 const intptr_t condition_pos = TokenPos(); | 6883 const intptr_t condition_pos = TokenPos(); |
| 6891 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { | 6884 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { |
| 6892 SkipExpr(); | 6885 SkipExpr(); |
| 6893 ExpectToken(Token::kRPAREN); | 6886 ExpectToken(Token::kRPAREN); |
| 6894 return NULL; | 6887 return NULL; |
| 6895 } | 6888 } |
| 6896 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades); | 6889 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades); |
| 6897 const intptr_t condition_end = TokenPos(); | 6890 const intptr_t condition_end = TokenPos(); |
| 6898 ExpectToken(Token::kRPAREN); | 6891 ExpectToken(Token::kRPAREN); |
| 6899 condition = InsertClosureCallNodes(condition); | 6892 condition = InsertClosureCallNodes(condition); |
| 6900 condition = new(isolate()) UnaryOpNode(condition_pos, Token::kNOT, condition); | 6893 condition = new(I) UnaryOpNode(condition_pos, Token::kNOT, condition); |
| 6901 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 6894 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
| 6902 return new(isolate()) IfNode( | 6895 return new(I) IfNode( |
| 6903 condition_pos, | 6896 condition_pos, |
| 6904 condition, | 6897 condition, |
| 6905 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 6898 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
| 6906 NULL); | 6899 NULL); |
| 6907 } | 6900 } |
| 6908 | 6901 |
| 6909 | 6902 |
| 6910 struct CatchParamDesc { | 6903 struct CatchParamDesc { |
| 6911 CatchParamDesc() | 6904 CatchParamDesc() |
| 6912 : token_pos(0), type(NULL), name(NULL), var(NULL) { } | 6905 : token_pos(0), type(NULL), name(NULL), var(NULL) { } |
| 6913 intptr_t token_pos; | 6906 intptr_t token_pos; |
| 6914 const AbstractType* type; | 6907 const AbstractType* type; |
| 6915 const String* name; | 6908 const String* name; |
| 6916 LocalVariable* var; | 6909 LocalVariable* var; |
| 6917 }; | 6910 }; |
| 6918 | 6911 |
| 6919 | 6912 |
| 6920 // Populate local scope of the catch block with the catch parameters. | 6913 // Populate local scope of the catch block with the catch parameters. |
| 6921 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 6914 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
| 6922 CatchParamDesc* stack_trace_param, | 6915 CatchParamDesc* stack_trace_param, |
| 6923 LocalScope* scope) { | 6916 LocalScope* scope) { |
| 6924 if (exception_param->name != NULL) { | 6917 if (exception_param->name != NULL) { |
| 6925 LocalVariable* var = new(isolate()) LocalVariable( | 6918 LocalVariable* var = new(I) LocalVariable( |
| 6926 exception_param->token_pos, | 6919 exception_param->token_pos, |
| 6927 *exception_param->name, | 6920 *exception_param->name, |
| 6928 *exception_param->type); | 6921 *exception_param->type); |
| 6929 var->set_is_final(); | 6922 var->set_is_final(); |
| 6930 bool added_to_scope = scope->AddVariable(var); | 6923 bool added_to_scope = scope->AddVariable(var); |
| 6931 ASSERT(added_to_scope); | 6924 ASSERT(added_to_scope); |
| 6932 exception_param->var = var; | 6925 exception_param->var = var; |
| 6933 } | 6926 } |
| 6934 if (stack_trace_param->name != NULL) { | 6927 if (stack_trace_param->name != NULL) { |
| 6935 LocalVariable* var = new(isolate()) LocalVariable( | 6928 LocalVariable* var = new(I) LocalVariable( |
| 6936 stack_trace_param->token_pos, | 6929 stack_trace_param->token_pos, |
| 6937 *stack_trace_param->name, | 6930 *stack_trace_param->name, |
| 6938 *stack_trace_param->type); | 6931 *stack_trace_param->type); |
| 6939 var->set_is_final(); | 6932 var->set_is_final(); |
| 6940 bool added_to_scope = scope->AddVariable(var); | 6933 bool added_to_scope = scope->AddVariable(var); |
| 6941 if (!added_to_scope) { | 6934 if (!added_to_scope) { |
| 6942 ErrorMsg(stack_trace_param->token_pos, | 6935 ErrorMsg(stack_trace_param->token_pos, |
| 6943 "name '%s' already exists in scope", | 6936 "name '%s' already exists in scope", |
| 6944 stack_trace_param->name->ToCString()); | 6937 stack_trace_param->name->ToCString()); |
| 6945 } | 6938 } |
| 6946 stack_trace_param->var = var; | 6939 stack_trace_param->var = var; |
| 6947 } | 6940 } |
| 6948 } | 6941 } |
| 6949 | 6942 |
| 6950 | 6943 |
| 6951 SequenceNode* Parser::ParseFinallyBlock() { | 6944 SequenceNode* Parser::ParseFinallyBlock() { |
| 6952 TRACE_PARSER("ParseFinallyBlock"); | 6945 TRACE_PARSER("ParseFinallyBlock"); |
| 6953 OpenBlock(); | 6946 OpenBlock(); |
| 6954 ExpectToken(Token::kLBRACE); | 6947 ExpectToken(Token::kLBRACE); |
| 6955 ParseStatementSequence(); | 6948 ParseStatementSequence(); |
| 6956 ExpectToken(Token::kRBRACE); | 6949 ExpectToken(Token::kRBRACE); |
| 6957 SequenceNode* finally_block = CloseBlock(); | 6950 SequenceNode* finally_block = CloseBlock(); |
| 6958 return finally_block; | 6951 return finally_block; |
| 6959 } | 6952 } |
| 6960 | 6953 |
| 6961 | 6954 |
| 6962 void Parser::PushTryBlock(Block* try_block) { | 6955 void Parser::PushTryBlock(Block* try_block) { |
| 6963 intptr_t try_index = AllocateTryIndex(); | 6956 intptr_t try_index = AllocateTryIndex(); |
| 6964 TryBlocks* block = new(isolate()) TryBlocks( | 6957 TryBlocks* block = new(I) TryBlocks( |
| 6965 try_block, try_blocks_list_, try_index); | 6958 try_block, try_blocks_list_, try_index); |
| 6966 try_blocks_list_ = block; | 6959 try_blocks_list_ = block; |
| 6967 } | 6960 } |
| 6968 | 6961 |
| 6969 | 6962 |
| 6970 Parser::TryBlocks* Parser::PopTryBlock() { | 6963 Parser::TryBlocks* Parser::PopTryBlock() { |
| 6971 TryBlocks* innermost_try_block = try_blocks_list_; | 6964 TryBlocks* innermost_try_block = try_blocks_list_; |
| 6972 try_blocks_list_ = try_blocks_list_->outer_try_block(); | 6965 try_blocks_list_ = try_blocks_list_->outer_try_block(); |
| 6973 return innermost_try_block; | 6966 return innermost_try_block; |
| 6974 } | 6967 } |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7070 // variables (as needed). | 7063 // variables (as needed). |
| 7071 // 2) Nested block with source code from catch clause block. | 7064 // 2) Nested block with source code from catch clause block. |
| 7072 OpenBlock(); | 7065 OpenBlock(); |
| 7073 AddCatchParamsToScope(&exception_param, &stack_trace_param, | 7066 AddCatchParamsToScope(&exception_param, &stack_trace_param, |
| 7074 current_block_->scope); | 7067 current_block_->scope); |
| 7075 | 7068 |
| 7076 if (exception_param.var != NULL) { | 7069 if (exception_param.var != NULL) { |
| 7077 // Generate code to load the exception object (:exception_var) into | 7070 // Generate code to load the exception object (:exception_var) into |
| 7078 // the exception variable specified in this block. | 7071 // the exception variable specified in this block. |
| 7079 ASSERT(exception_var != NULL); | 7072 ASSERT(exception_var != NULL); |
| 7080 current_block_->statements->Add(new(isolate()) StoreLocalNode( | 7073 current_block_->statements->Add(new(I) StoreLocalNode( |
| 7081 catch_pos, exception_param.var, new(isolate()) LoadLocalNode( | 7074 catch_pos, exception_param.var, new(I) LoadLocalNode( |
| 7082 catch_pos, exception_var))); | 7075 catch_pos, exception_var))); |
| 7083 } | 7076 } |
| 7084 if (stack_trace_param.var != NULL) { | 7077 if (stack_trace_param.var != NULL) { |
| 7085 // A stack trace variable is specified in this block, so generate code | 7078 // A stack trace variable is specified in this block, so generate code |
| 7086 // to load the stack trace object (:stack_trace_var) into the stack | 7079 // to load the stack trace object (:stack_trace_var) into the stack |
| 7087 // trace variable specified in this block. | 7080 // trace variable specified in this block. |
| 7088 *needs_stack_trace = true; | 7081 *needs_stack_trace = true; |
| 7089 ArgumentListNode* no_args = new(isolate()) ArgumentListNode(catch_pos); | 7082 ArgumentListNode* no_args = new(I) ArgumentListNode(catch_pos); |
| 7090 ASSERT(stack_trace_var != NULL); | 7083 ASSERT(stack_trace_var != NULL); |
| 7091 current_block_->statements->Add(new(isolate()) StoreLocalNode( | 7084 current_block_->statements->Add(new(I) StoreLocalNode( |
| 7092 catch_pos, stack_trace_param.var, new(isolate()) LoadLocalNode( | 7085 catch_pos, stack_trace_param.var, new(I) LoadLocalNode( |
| 7093 catch_pos, stack_trace_var))); | 7086 catch_pos, stack_trace_var))); |
| 7094 current_block_->statements->Add(new(isolate()) InstanceCallNode( | 7087 current_block_->statements->Add(new(I) InstanceCallNode( |
| 7095 catch_pos, | 7088 catch_pos, |
| 7096 new(isolate()) LoadLocalNode(catch_pos, stack_trace_param.var), | 7089 new(I) LoadLocalNode(catch_pos, stack_trace_param.var), |
| 7097 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 7090 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
| 7098 no_args)); | 7091 no_args)); |
| 7099 } | 7092 } |
| 7100 | 7093 |
| 7101 // Add nested block with user-defined code. This blocks allows | 7094 // Add nested block with user-defined code. This blocks allows |
| 7102 // declarations in the body to shadow the catch parameters. | 7095 // declarations in the body to shadow the catch parameters. |
| 7103 CheckToken(Token::kLBRACE); | 7096 CheckToken(Token::kLBRACE); |
| 7104 current_block_->statements->Add(ParseNestedStatement(false, NULL)); | 7097 current_block_->statements->Add(ParseNestedStatement(false, NULL)); |
| 7105 catch_blocks.Add(CloseBlock()); | 7098 catch_blocks.Add(CloseBlock()); |
| 7106 | 7099 |
| 7107 const bool is_bad_type = | 7100 const bool is_bad_type = |
| 7108 exception_param.type->IsMalformed() || | 7101 exception_param.type->IsMalformed() || |
| 7109 exception_param.type->IsMalbounded(); | 7102 exception_param.type->IsMalbounded(); |
| 7110 if (exception_param.type->IsDynamicType() || is_bad_type) { | 7103 if (exception_param.type->IsDynamicType() || is_bad_type) { |
| 7111 // There is no exception type or else it is malformed or malbounded. | 7104 // There is no exception type or else it is malformed or malbounded. |
| 7112 // In the first case, unconditionally execute the catch body. In the | 7105 // In the first case, unconditionally execute the catch body. In the |
| 7113 // second case, unconditionally throw. | 7106 // second case, unconditionally throw. |
| 7114 generic_catch_seen = true; | 7107 generic_catch_seen = true; |
| 7115 type_tests.Add(new(isolate()) LiteralNode(catch_pos, Bool::True())); | 7108 type_tests.Add(new(I) LiteralNode(catch_pos, Bool::True())); |
| 7116 if (is_bad_type) { | 7109 if (is_bad_type) { |
| 7117 // Replace the body with one that throws. | 7110 // Replace the body with one that throws. |
| 7118 SequenceNode* block = new(isolate()) SequenceNode(catch_pos, NULL); | 7111 SequenceNode* block = new(I) SequenceNode(catch_pos, NULL); |
| 7119 block->Add(ThrowTypeError(catch_pos, *exception_param.type)); | 7112 block->Add(ThrowTypeError(catch_pos, *exception_param.type)); |
| 7120 catch_blocks.Last() = block; | 7113 catch_blocks.Last() = block; |
| 7121 } | 7114 } |
| 7122 // This catch clause will handle all exceptions. We can safely forget | 7115 // This catch clause will handle all exceptions. We can safely forget |
| 7123 // all previous catch clause types. | 7116 // all previous catch clause types. |
| 7124 handler_types.SetLength(0); | 7117 handler_types.SetLength(0); |
| 7125 handler_types.Add(*exception_param.type); | 7118 handler_types.Add(*exception_param.type); |
| 7126 } else { | 7119 } else { |
| 7127 // Has a type specification that is not malformed or malbounded. Now | 7120 // Has a type specification that is not malformed or malbounded. Now |
| 7128 // form an 'if type check' to guard the catch handler code. | 7121 // form an 'if type check' to guard the catch handler code. |
| 7129 if (!exception_param.type->IsInstantiated() && | 7122 if (!exception_param.type->IsInstantiated() && |
| 7130 (current_block_->scope->function_level() > 0)) { | 7123 (current_block_->scope->function_level() > 0)) { |
| 7131 // Make sure that the instantiator is captured. | 7124 // Make sure that the instantiator is captured. |
| 7132 CaptureInstantiator(); | 7125 CaptureInstantiator(); |
| 7133 } | 7126 } |
| 7134 TypeNode* exception_type = new(isolate()) TypeNode( | 7127 TypeNode* exception_type = new(I) TypeNode( |
| 7135 catch_pos, *exception_param.type); | 7128 catch_pos, *exception_param.type); |
| 7136 AstNode* exception_value = new(isolate()) LoadLocalNode( | 7129 AstNode* exception_value = new(I) LoadLocalNode( |
| 7137 catch_pos, exception_var); | 7130 catch_pos, exception_var); |
| 7138 if (!exception_type->type().IsInstantiated()) { | 7131 if (!exception_type->type().IsInstantiated()) { |
| 7139 EnsureExpressionTemp(); | 7132 EnsureExpressionTemp(); |
| 7140 } | 7133 } |
| 7141 type_tests.Add(new(isolate()) ComparisonNode( | 7134 type_tests.Add(new(I) ComparisonNode( |
| 7142 catch_pos, Token::kIS, exception_value, exception_type)); | 7135 catch_pos, Token::kIS, exception_value, exception_type)); |
| 7143 | 7136 |
| 7144 // Do not add uninstantiated types (e.g. type parameter T or generic | 7137 // Do not add uninstantiated types (e.g. type parameter T or generic |
| 7145 // type List<T>), since the debugger won't be able to instantiate it | 7138 // type List<T>), since the debugger won't be able to instantiate it |
| 7146 // when walking the stack. | 7139 // when walking the stack. |
| 7147 // | 7140 // |
| 7148 // This means that the debugger is not able to determine whether an | 7141 // This means that the debugger is not able to determine whether an |
| 7149 // exception is caught if the catch clause uses generic types. It | 7142 // exception is caught if the catch clause uses generic types. It |
| 7150 // will report the exception as uncaught when in fact it might be | 7143 // will report the exception as uncaught when in fact it might be |
| 7151 // caught and handled when we unwind the stack. | 7144 // caught and handled when we unwind the stack. |
| 7152 if (!generic_catch_seen && exception_param.type->IsInstantiated()) { | 7145 if (!generic_catch_seen && exception_param.type->IsInstantiated()) { |
| 7153 handler_types.Add(*exception_param.type); | 7146 handler_types.Add(*exception_param.type); |
| 7154 } | 7147 } |
| 7155 } | 7148 } |
| 7156 | 7149 |
| 7157 ASSERT(type_tests.length() == catch_blocks.length()); | 7150 ASSERT(type_tests.length() == catch_blocks.length()); |
| 7158 } | 7151 } |
| 7159 | 7152 |
| 7160 // Build the if/then/else nest from the inside out. Keep the AST simple | 7153 // Build the if/then/else nest from the inside out. Keep the AST simple |
| 7161 // for the case of a single generic catch clause. The initial value of | 7154 // for the case of a single generic catch clause. The initial value of |
| 7162 // current is the last (innermost) else block if there were any catch | 7155 // current is the last (innermost) else block if there were any catch |
| 7163 // clauses. | 7156 // clauses. |
| 7164 SequenceNode* current = NULL; | 7157 SequenceNode* current = NULL; |
| 7165 if (!generic_catch_seen) { | 7158 if (!generic_catch_seen) { |
| 7166 // There isn't a generic catch clause so create a clause body that | 7159 // There isn't a generic catch clause so create a clause body that |
| 7167 // rethrows the exception. This includes the case that there were no | 7160 // rethrows the exception. This includes the case that there were no |
| 7168 // catch clauses. | 7161 // catch clauses. |
| 7169 current = new(isolate()) SequenceNode(handler_pos, NULL); | 7162 current = new(I) SequenceNode(handler_pos, NULL); |
| 7170 current->Add(new(isolate()) ThrowNode( | 7163 current->Add(new(I) ThrowNode( |
| 7171 handler_pos, | 7164 handler_pos, |
| 7172 new(isolate()) LoadLocalNode(handler_pos, exception_var), | 7165 new(I) LoadLocalNode(handler_pos, exception_var), |
| 7173 new(isolate()) LoadLocalNode(handler_pos, stack_trace_var))); | 7166 new(I) LoadLocalNode(handler_pos, stack_trace_var))); |
| 7174 } else if (type_tests.Last()->IsLiteralNode()) { | 7167 } else if (type_tests.Last()->IsLiteralNode()) { |
| 7175 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == | 7168 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == |
| 7176 Bool::True().raw()); | 7169 Bool::True().raw()); |
| 7177 // The last body is entered unconditionally. Start building the | 7170 // The last body is entered unconditionally. Start building the |
| 7178 // if/then/else nest with that body as the innermost else block. | 7171 // if/then/else nest with that body as the innermost else block. |
| 7179 // Note that it is nested inside an extra block which we opened | 7172 // Note that it is nested inside an extra block which we opened |
| 7180 // before we knew the body was entered unconditionally. | 7173 // before we knew the body was entered unconditionally. |
| 7181 type_tests.RemoveLast(); | 7174 type_tests.RemoveLast(); |
| 7182 current_block_->statements->Add(catch_blocks.RemoveLast()); | 7175 current_block_->statements->Add(catch_blocks.RemoveLast()); |
| 7183 current = CloseBlock(); | 7176 current = CloseBlock(); |
| 7184 } | 7177 } |
| 7185 // If the last body was entered conditionally and there is no need to add | 7178 // If the last body was entered conditionally and there is no need to add |
| 7186 // a rethrow, use an empty else body (current = NULL above). | 7179 // a rethrow, use an empty else body (current = NULL above). |
| 7187 | 7180 |
| 7188 while (!type_tests.is_empty()) { | 7181 while (!type_tests.is_empty()) { |
| 7189 AstNode* type_test = type_tests.RemoveLast(); | 7182 AstNode* type_test = type_tests.RemoveLast(); |
| 7190 SequenceNode* catch_block = catch_blocks.RemoveLast(); | 7183 SequenceNode* catch_block = catch_blocks.RemoveLast(); |
| 7191 current_block_->statements->Add(new(isolate()) IfNode( | 7184 current_block_->statements->Add(new(I) IfNode( |
| 7192 type_test->token_pos(), type_test, catch_block, current)); | 7185 type_test->token_pos(), type_test, catch_block, current)); |
| 7193 current = CloseBlock(); | 7186 current = CloseBlock(); |
| 7194 } | 7187 } |
| 7195 return current; | 7188 return current; |
| 7196 } | 7189 } |
| 7197 | 7190 |
| 7198 | 7191 |
| 7199 AstNode* Parser::ParseTryStatement(String* label_name) { | 7192 AstNode* Parser::ParseTryStatement(String* label_name) { |
| 7200 TRACE_PARSER("ParseTryStatement"); | 7193 TRACE_PARSER("ParseTryStatement"); |
| 7201 | 7194 |
| 7202 // We create three variables for exceptions here: | 7195 // We create three variables for exceptions here: |
| 7203 // ':saved_try_context_var' - Used to save the context before the start of | 7196 // ':saved_try_context_var' - Used to save the context before the start of |
| 7204 // the try block. The context register is | 7197 // the try block. The context register is |
| 7205 // restored from this variable before | 7198 // restored from this variable before |
| 7206 // processing the catch block handler. | 7199 // processing the catch block handler. |
| 7207 // ':exception_var' - Used to save the current exception object that was | 7200 // ':exception_var' - Used to save the current exception object that was |
| 7208 // thrown. | 7201 // thrown. |
| 7209 // ':stack_trace_var' - Used to save the current stack trace object which | 7202 // ':stack_trace_var' - Used to save the current stack trace object which |
| 7210 // the stack trace was copied into when an exception | 7203 // the stack trace was copied into when an exception |
| 7211 // was thrown. | 7204 // was thrown. |
| 7212 // :exception_var and :stack_trace_var get set with the exception object | 7205 // :exception_var and :stack_trace_var get set with the exception object |
| 7213 // and the stack trace object when an exception is thrown. These three | 7206 // and the stack trace object when an exception is thrown. These three |
| 7214 // implicit variables can never be captured. | 7207 // implicit variables can never be captured. |
| 7215 LocalVariable* context_var = | 7208 LocalVariable* context_var = |
| 7216 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 7209 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 7217 if (context_var == NULL) { | 7210 if (context_var == NULL) { |
| 7218 context_var = new(isolate()) LocalVariable( | 7211 context_var = new(I) LocalVariable( |
| 7219 TokenPos(), | 7212 TokenPos(), |
| 7220 Symbols::SavedTryContextVar(), | 7213 Symbols::SavedTryContextVar(), |
| 7221 Type::ZoneHandle(I, Type::DynamicType())); | 7214 Type::ZoneHandle(I, Type::DynamicType())); |
| 7222 current_block_->scope->AddVariable(context_var); | 7215 current_block_->scope->AddVariable(context_var); |
| 7223 } | 7216 } |
| 7224 LocalVariable* exception_var = | 7217 LocalVariable* exception_var = |
| 7225 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); | 7218 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 7226 if (exception_var == NULL) { | 7219 if (exception_var == NULL) { |
| 7227 exception_var = new(isolate()) LocalVariable( | 7220 exception_var = new(I) LocalVariable( |
| 7228 TokenPos(), | 7221 TokenPos(), |
| 7229 Symbols::ExceptionVar(), | 7222 Symbols::ExceptionVar(), |
| 7230 Type::ZoneHandle(I, Type::DynamicType())); | 7223 Type::ZoneHandle(I, Type::DynamicType())); |
| 7231 current_block_->scope->AddVariable(exception_var); | 7224 current_block_->scope->AddVariable(exception_var); |
| 7232 } | 7225 } |
| 7233 LocalVariable* stack_trace_var = | 7226 LocalVariable* stack_trace_var = |
| 7234 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); | 7227 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 7235 if (stack_trace_var == NULL) { | 7228 if (stack_trace_var == NULL) { |
| 7236 stack_trace_var = new(isolate()) LocalVariable( | 7229 stack_trace_var = new(I) LocalVariable( |
| 7237 TokenPos(), | 7230 TokenPos(), |
| 7238 Symbols::StackTraceVar(), | 7231 Symbols::StackTraceVar(), |
| 7239 Type::ZoneHandle(I, Type::DynamicType())); | 7232 Type::ZoneHandle(I, Type::DynamicType())); |
| 7240 current_block_->scope->AddVariable(stack_trace_var); | 7233 current_block_->scope->AddVariable(stack_trace_var); |
| 7241 } | 7234 } |
| 7242 | 7235 |
| 7243 const intptr_t try_pos = TokenPos(); | 7236 const intptr_t try_pos = TokenPos(); |
| 7244 ConsumeToken(); // Consume the 'try'. | 7237 ConsumeToken(); // Consume the 'try'. |
| 7245 | 7238 |
| 7246 SourceLabel* try_label = NULL; | 7239 SourceLabel* try_label = NULL; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 7260 | 7253 |
| 7261 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && | 7254 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && |
| 7262 (CurrentToken() != Token::kFINALLY)) { | 7255 (CurrentToken() != Token::kFINALLY)) { |
| 7263 ErrorMsg("catch or finally clause expected"); | 7256 ErrorMsg("catch or finally clause expected"); |
| 7264 } | 7257 } |
| 7265 | 7258 |
| 7266 // Now parse the 'catch' blocks if any. | 7259 // Now parse the 'catch' blocks if any. |
| 7267 try_blocks_list_->enter_catch(); | 7260 try_blocks_list_->enter_catch(); |
| 7268 const intptr_t handler_pos = TokenPos(); | 7261 const intptr_t handler_pos = TokenPos(); |
| 7269 const GrowableObjectArray& handler_types = | 7262 const GrowableObjectArray& handler_types = |
| 7270 GrowableObjectArray::Handle(isolate(), GrowableObjectArray::New()); | 7263 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 7271 bool needs_stack_trace = false; | 7264 bool needs_stack_trace = false; |
| 7272 SequenceNode* catch_handler_list = | 7265 SequenceNode* catch_handler_list = |
| 7273 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, | 7266 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, |
| 7274 handler_types, &needs_stack_trace); | 7267 handler_types, &needs_stack_trace); |
| 7275 | 7268 |
| 7276 TryBlocks* inner_try_block = PopTryBlock(); | 7269 TryBlocks* inner_try_block = PopTryBlock(); |
| 7277 const intptr_t try_index = inner_try_block->try_index(); | 7270 const intptr_t try_index = inner_try_block->try_index(); |
| 7278 TryBlocks* outer_try_block = try_blocks_list_; | 7271 TryBlocks* outer_try_block = try_blocks_list_; |
| 7279 const intptr_t outer_try_index = (outer_try_block != NULL) | 7272 const intptr_t outer_try_index = (outer_try_block != NULL) |
| 7280 ? outer_try_block->try_index() | 7273 ? outer_try_block->try_index() |
| 7281 : CatchClauseNode::kInvalidTryIndex; | 7274 : CatchClauseNode::kInvalidTryIndex; |
| 7282 | 7275 |
| 7283 // Finally parse the 'finally' block. | 7276 // Finally parse the 'finally' block. |
| 7284 SequenceNode* finally_block = NULL; | 7277 SequenceNode* finally_block = NULL; |
| 7285 if (CurrentToken() == Token::kFINALLY) { | 7278 if (CurrentToken() == Token::kFINALLY) { |
| 7286 ConsumeToken(); // Consume the 'finally'. | 7279 ConsumeToken(); // Consume the 'finally'. |
| 7287 const intptr_t finally_pos = TokenPos(); | 7280 const intptr_t finally_pos = TokenPos(); |
| 7288 // Add the finally block to the exit points recorded so far. | 7281 // Add the finally block to the exit points recorded so far. |
| 7289 intptr_t node_index = 0; | 7282 intptr_t node_index = 0; |
| 7290 AstNode* node_to_inline = | 7283 AstNode* node_to_inline = |
| 7291 inner_try_block->GetNodeToInlineFinally(node_index); | 7284 inner_try_block->GetNodeToInlineFinally(node_index); |
| 7292 while (node_to_inline != NULL) { | 7285 while (node_to_inline != NULL) { |
| 7293 finally_block = ParseFinallyBlock(); | 7286 finally_block = ParseFinallyBlock(); |
| 7294 InlinedFinallyNode* node = new(isolate()) InlinedFinallyNode(finally_pos, | 7287 InlinedFinallyNode* node = new(I) InlinedFinallyNode(finally_pos, |
| 7295 finally_block, | 7288 finally_block, |
| 7296 context_var, | 7289 context_var, |
| 7297 outer_try_index); | 7290 outer_try_index); |
| 7298 AddFinallyBlockToNode(node_to_inline, node); | 7291 AddFinallyBlockToNode(node_to_inline, node); |
| 7299 node_index += 1; | 7292 node_index += 1; |
| 7300 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); | 7293 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); |
| 7301 tokens_iterator_.SetCurrentPosition(finally_pos); | 7294 tokens_iterator_.SetCurrentPosition(finally_pos); |
| 7302 } | 7295 } |
| 7303 finally_block = ParseFinallyBlock(); | 7296 finally_block = ParseFinallyBlock(); |
| 7304 } | 7297 } |
| 7305 | 7298 |
| 7306 CatchClauseNode* catch_clause = new(isolate()) CatchClauseNode( | 7299 CatchClauseNode* catch_clause = new(I) CatchClauseNode( |
| 7307 handler_pos, | 7300 handler_pos, |
| 7308 catch_handler_list, | 7301 catch_handler_list, |
| 7309 Array::ZoneHandle(I, Array::MakeArray(handler_types)), | 7302 Array::ZoneHandle(I, Array::MakeArray(handler_types)), |
| 7310 context_var, | 7303 context_var, |
| 7311 exception_var, | 7304 exception_var, |
| 7312 stack_trace_var, | 7305 stack_trace_var, |
| 7313 (finally_block != NULL) ? | 7306 (finally_block != NULL) ? |
| 7314 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, | 7307 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, |
| 7315 needs_stack_trace); | 7308 needs_stack_trace); |
| 7316 | 7309 |
| 7317 // Now create the try/catch ast node and return it. If there is a label | 7310 // Now create the try/catch ast node and return it. If there is a label |
| 7318 // on the try/catch, close the block that's embedding the try statement | 7311 // on the try/catch, close the block that's embedding the try statement |
| 7319 // and attach the label to it. | 7312 // and attach the label to it. |
| 7320 AstNode* try_catch_node = new(isolate()) TryCatchNode( | 7313 AstNode* try_catch_node = new(I) TryCatchNode( |
| 7321 try_pos, try_block, context_var, catch_clause, finally_block, try_index); | 7314 try_pos, try_block, context_var, catch_clause, finally_block, try_index); |
| 7322 | 7315 |
| 7323 if (try_label != NULL) { | 7316 if (try_label != NULL) { |
| 7324 current_block_->statements->Add(try_catch_node); | 7317 current_block_->statements->Add(try_catch_node); |
| 7325 SequenceNode* sequence = CloseBlock(); | 7318 SequenceNode* sequence = CloseBlock(); |
| 7326 sequence->set_label(try_label); | 7319 sequence->set_label(try_label); |
| 7327 try_catch_node = sequence; | 7320 try_catch_node = sequence; |
| 7328 } | 7321 } |
| 7329 return try_catch_node; | 7322 return try_catch_node; |
| 7330 } | 7323 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 7352 } | 7345 } |
| 7353 target = current_block_->scope->LookupLabel(target_name); | 7346 target = current_block_->scope->LookupLabel(target_name); |
| 7354 if (target == NULL && jump_kind == Token::kCONTINUE) { | 7347 if (target == NULL && jump_kind == Token::kCONTINUE) { |
| 7355 // Either a reference to a non-existent label, or a forward reference | 7348 // Either a reference to a non-existent label, or a forward reference |
| 7356 // to a case label that we haven't seen yet. If we are inside a switch | 7349 // to a case label that we haven't seen yet. If we are inside a switch |
| 7357 // statement, create a "forward reference" label in the scope of | 7350 // statement, create a "forward reference" label in the scope of |
| 7358 // the switch statement. | 7351 // the switch statement. |
| 7359 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); | 7352 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); |
| 7360 if (switch_scope != NULL) { | 7353 if (switch_scope != NULL) { |
| 7361 // We found a switch scope. Enter a forward reference to the label. | 7354 // We found a switch scope. Enter a forward reference to the label. |
| 7362 target = new(isolate()) SourceLabel( | 7355 target = new(I) SourceLabel( |
| 7363 TokenPos(), target_name, SourceLabel::kForward); | 7356 TokenPos(), target_name, SourceLabel::kForward); |
| 7364 switch_scope->AddLabel(target); | 7357 switch_scope->AddLabel(target); |
| 7365 } | 7358 } |
| 7366 } | 7359 } |
| 7367 if (target == NULL) { | 7360 if (target == NULL) { |
| 7368 ErrorMsg(jump_pos, "label '%s' not found", target_name.ToCString()); | 7361 ErrorMsg(jump_pos, "label '%s' not found", target_name.ToCString()); |
| 7369 } | 7362 } |
| 7370 } else { | 7363 } else { |
| 7371 target = current_block_->scope->LookupInnermostLabel(jump_kind); | 7364 target = current_block_->scope->LookupInnermostLabel(jump_kind); |
| 7372 if (target == NULL) { | 7365 if (target == NULL) { |
| 7373 ErrorMsg(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); | 7366 ErrorMsg(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); |
| 7374 } | 7367 } |
| 7375 } | 7368 } |
| 7376 ASSERT(target != NULL); | 7369 ASSERT(target != NULL); |
| 7377 if (jump_kind == Token::kCONTINUE) { | 7370 if (jump_kind == Token::kCONTINUE) { |
| 7378 if (target->kind() == SourceLabel::kSwitch) { | 7371 if (target->kind() == SourceLabel::kSwitch) { |
| 7379 ErrorMsg(jump_pos, "'continue' jump to switch statement is illegal"); | 7372 ErrorMsg(jump_pos, "'continue' jump to switch statement is illegal"); |
| 7380 } else if (target->kind() == SourceLabel::kStatement) { | 7373 } else if (target->kind() == SourceLabel::kStatement) { |
| 7381 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 7374 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", |
| 7382 target->name().ToCString()); | 7375 target->name().ToCString()); |
| 7383 } | 7376 } |
| 7384 } | 7377 } |
| 7385 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { | 7378 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { |
| 7386 ErrorMsg(jump_pos, "'break' to case clause label is illegal"); | 7379 ErrorMsg(jump_pos, "'break' to case clause label is illegal"); |
| 7387 } | 7380 } |
| 7388 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 7381 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 7389 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 7382 ErrorMsg(jump_pos, "'%s' target must be in same function context", |
| 7390 Token::Str(jump_kind)); | 7383 Token::Str(jump_kind)); |
| 7391 } | 7384 } |
| 7392 return new(isolate()) JumpNode(jump_pos, jump_kind, target); | 7385 return new(I) JumpNode(jump_pos, jump_kind, target); |
| 7393 } | 7386 } |
| 7394 | 7387 |
| 7395 | 7388 |
| 7396 AstNode* Parser::ParseStatement() { | 7389 AstNode* Parser::ParseStatement() { |
| 7397 TRACE_PARSER("ParseStatement"); | 7390 TRACE_PARSER("ParseStatement"); |
| 7398 AstNode* statement = NULL; | 7391 AstNode* statement = NULL; |
| 7399 intptr_t label_pos = 0; | 7392 intptr_t label_pos = 0; |
| 7400 String* label_name = NULL; | 7393 String* label_name = NULL; |
| 7401 if (IsIdentifier()) { | 7394 if (IsIdentifier()) { |
| 7402 if (LookaheadToken(1) == Token::kCOLON) { | 7395 if (LookaheadToken(1) == Token::kCOLON) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 7423 statement = ParseTryStatement(label_name); | 7416 statement = ParseTryStatement(label_name); |
| 7424 } else if (token == Token::kRETURN) { | 7417 } else if (token == Token::kRETURN) { |
| 7425 const intptr_t return_pos = TokenPos(); | 7418 const intptr_t return_pos = TokenPos(); |
| 7426 ConsumeToken(); | 7419 ConsumeToken(); |
| 7427 if (CurrentToken() != Token::kSEMICOLON) { | 7420 if (CurrentToken() != Token::kSEMICOLON) { |
| 7428 if (current_function().IsConstructor() && | 7421 if (current_function().IsConstructor() && |
| 7429 (current_block_->scope->function_level() == 0)) { | 7422 (current_block_->scope->function_level() == 0)) { |
| 7430 ErrorMsg(return_pos, "return of a value not allowed in constructors"); | 7423 ErrorMsg(return_pos, "return of a value not allowed in constructors"); |
| 7431 } | 7424 } |
| 7432 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 7425 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 7433 statement = new(isolate()) ReturnNode(statement_pos, expr); | 7426 statement = new(I) ReturnNode(statement_pos, expr); |
| 7434 } else { | 7427 } else { |
| 7435 statement = new(isolate()) ReturnNode(statement_pos); | 7428 statement = new(I) ReturnNode(statement_pos); |
| 7436 } | 7429 } |
| 7437 AddNodeForFinallyInlining(statement); | 7430 AddNodeForFinallyInlining(statement); |
| 7438 ExpectSemicolon(); | 7431 ExpectSemicolon(); |
| 7439 } else if (token == Token::kIF) { | 7432 } else if (token == Token::kIF) { |
| 7440 statement = ParseIfStatement(label_name); | 7433 statement = ParseIfStatement(label_name); |
| 7441 } else if (token == Token::kASSERT) { | 7434 } else if (token == Token::kASSERT) { |
| 7442 statement = ParseAssertStatement(); | 7435 statement = ParseAssertStatement(); |
| 7443 ExpectSemicolon(); | 7436 ExpectSemicolon(); |
| 7444 } else if (IsVariableDeclaration()) { | 7437 } else if (IsVariableDeclaration()) { |
| 7445 statement = ParseVariableDeclarationList(); | 7438 statement = ParseVariableDeclarationList(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7482 // The exception and stack trace variables are bound in the block | 7475 // The exception and stack trace variables are bound in the block |
| 7483 // containing the try. | 7476 // containing the try. |
| 7484 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); | 7477 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); |
| 7485 ASSERT(scope != NULL); | 7478 ASSERT(scope != NULL); |
| 7486 LocalVariable* excp_var = | 7479 LocalVariable* excp_var = |
| 7487 scope->LocalLookupVariable(Symbols::ExceptionVar()); | 7480 scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 7488 ASSERT(excp_var != NULL); | 7481 ASSERT(excp_var != NULL); |
| 7489 LocalVariable* trace_var = | 7482 LocalVariable* trace_var = |
| 7490 scope->LocalLookupVariable(Symbols::StackTraceVar()); | 7483 scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 7491 ASSERT(trace_var != NULL); | 7484 ASSERT(trace_var != NULL); |
| 7492 statement = new(isolate()) ThrowNode( | 7485 statement = new(I) ThrowNode( |
| 7493 statement_pos, | 7486 statement_pos, |
| 7494 new(isolate()) LoadLocalNode(statement_pos, excp_var), | 7487 new(I) LoadLocalNode(statement_pos, excp_var), |
| 7495 new(isolate()) LoadLocalNode(statement_pos, trace_var)); | 7488 new(I) LoadLocalNode(statement_pos, trace_var)); |
| 7496 } else { | 7489 } else { |
| 7497 statement = ParseExpr(kAllowConst, kConsumeCascades); | 7490 statement = ParseExpr(kAllowConst, kConsumeCascades); |
| 7498 ExpectSemicolon(); | 7491 ExpectSemicolon(); |
| 7499 } | 7492 } |
| 7500 return statement; | 7493 return statement; |
| 7501 } | 7494 } |
| 7502 | 7495 |
| 7503 | 7496 |
| 7504 void Parser::ErrorMsg(intptr_t token_pos, const char* format, ...) const { | 7497 void Parser::ErrorMsg(intptr_t token_pos, const char* format, ...) const { |
| 7505 va_list args; | 7498 va_list args; |
| 7506 va_start(args, format); | 7499 va_start(args, format); |
| 7507 const Error& error = Error::Handle(isolate(), LanguageError::NewFormattedV( | 7500 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( |
| 7508 Error::Handle(isolate()), script_, token_pos, | 7501 Error::Handle(I), script_, token_pos, |
| 7509 LanguageError::kError, Heap::kNew, format, args)); | 7502 LanguageError::kError, Heap::kNew, format, args)); |
| 7510 va_end(args); | 7503 va_end(args); |
| 7511 isolate()->long_jump_base()->Jump(1, error); | 7504 I->long_jump_base()->Jump(1, error); |
| 7512 UNREACHABLE(); | 7505 UNREACHABLE(); |
| 7513 } | 7506 } |
| 7514 | 7507 |
| 7515 | 7508 |
| 7516 void Parser::ErrorMsg(const char* format, ...) { | 7509 void Parser::ErrorMsg(const char* format, ...) { |
| 7517 va_list args; | 7510 va_list args; |
| 7518 va_start(args, format); | 7511 va_start(args, format); |
| 7519 const Error& error = Error::Handle(isolate(), LanguageError::NewFormattedV( | 7512 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( |
| 7520 Error::Handle(isolate()), script_, TokenPos(), | 7513 Error::Handle(I), script_, TokenPos(), |
| 7521 LanguageError::kError, Heap::kNew, format, args)); | 7514 LanguageError::kError, Heap::kNew, format, args)); |
| 7522 va_end(args); | 7515 va_end(args); |
| 7523 isolate()->long_jump_base()->Jump(1, error); | 7516 I->long_jump_base()->Jump(1, error); |
| 7524 UNREACHABLE(); | 7517 UNREACHABLE(); |
| 7525 } | 7518 } |
| 7526 | 7519 |
| 7527 | 7520 |
| 7528 void Parser::ErrorMsg(const Error& error) { | 7521 void Parser::ErrorMsg(const Error& error) { |
| 7529 Isolate::Current()->long_jump_base()->Jump(1, error); | 7522 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 7530 UNREACHABLE(); | 7523 UNREACHABLE(); |
| 7531 } | 7524 } |
| 7532 | 7525 |
| 7533 | 7526 |
| 7534 void Parser::AppendErrorMsg( | 7527 void Parser::AppendErrorMsg( |
| 7535 const Error& prev_error, intptr_t token_pos, const char* format, ...) { | 7528 const Error& prev_error, intptr_t token_pos, const char* format, ...) { |
| 7536 va_list args; | 7529 va_list args; |
| 7537 va_start(args, format); | 7530 va_start(args, format); |
| 7538 const Error& error = Error::Handle(isolate(), LanguageError::NewFormattedV( | 7531 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( |
| 7539 prev_error, script_, token_pos, | 7532 prev_error, script_, token_pos, |
| 7540 LanguageError::kError, Heap::kNew, | 7533 LanguageError::kError, Heap::kNew, |
| 7541 format, args)); | 7534 format, args)); |
| 7542 va_end(args); | 7535 va_end(args); |
| 7543 isolate()->long_jump_base()->Jump(1, error); | 7536 I->long_jump_base()->Jump(1, error); |
| 7544 UNREACHABLE(); | 7537 UNREACHABLE(); |
| 7545 } | 7538 } |
| 7546 | 7539 |
| 7547 | 7540 |
| 7548 void Parser::Warning(intptr_t token_pos, const char* format, ...) { | 7541 void Parser::Warning(intptr_t token_pos, const char* format, ...) { |
| 7549 if (FLAG_silent_warnings) return; | 7542 if (FLAG_silent_warnings) return; |
| 7550 va_list args; | 7543 va_list args; |
| 7551 va_start(args, format); | 7544 va_start(args, format); |
| 7552 const Error& error = Error::Handle(isolate(), LanguageError::NewFormattedV( | 7545 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( |
| 7553 Error::Handle(isolate()), script_, token_pos, | 7546 Error::Handle(I), script_, token_pos, |
| 7554 LanguageError::kWarning, Heap::kNew, | 7547 LanguageError::kWarning, Heap::kNew, |
| 7555 format, args)); | 7548 format, args)); |
| 7556 va_end(args); | 7549 va_end(args); |
| 7557 if (FLAG_warning_as_error) { | 7550 if (FLAG_warning_as_error) { |
| 7558 isolate()->long_jump_base()->Jump(1, error); | 7551 I->long_jump_base()->Jump(1, error); |
| 7559 UNREACHABLE(); | 7552 UNREACHABLE(); |
| 7560 } else { | 7553 } else { |
| 7561 OS::Print("%s", error.ToErrorCString()); | 7554 OS::Print("%s", error.ToErrorCString()); |
| 7562 va_start(args, format); | 7555 va_start(args, format); |
| 7563 Exceptions::TraceJSWarningV(script_, token_pos, format, args); | 7556 Exceptions::TraceJSWarningV(script_, token_pos, format, args); |
| 7564 va_end(args); | 7557 va_end(args); |
| 7565 } | 7558 } |
| 7566 } | 7559 } |
| 7567 | 7560 |
| 7568 | 7561 |
| 7569 void Parser::Warning(const char* format, ...) { | 7562 void Parser::Warning(const char* format, ...) { |
| 7570 if (FLAG_silent_warnings) return; | 7563 if (FLAG_silent_warnings) return; |
| 7571 va_list args; | 7564 va_list args; |
| 7572 va_start(args, format); | 7565 va_start(args, format); |
| 7573 const Error& error = Error::Handle(isolate(), LanguageError::NewFormattedV( | 7566 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( |
| 7574 Error::Handle(isolate()), script_, TokenPos(), | 7567 Error::Handle(I), script_, TokenPos(), |
| 7575 LanguageError::kWarning, Heap::kNew, | 7568 LanguageError::kWarning, Heap::kNew, |
| 7576 format, args)); | 7569 format, args)); |
| 7577 va_end(args); | 7570 va_end(args); |
| 7578 if (FLAG_warning_as_error) { | 7571 if (FLAG_warning_as_error) { |
| 7579 isolate()->long_jump_base()->Jump(1, error); | 7572 I->long_jump_base()->Jump(1, error); |
| 7580 UNREACHABLE(); | 7573 UNREACHABLE(); |
| 7581 } else { | 7574 } else { |
| 7582 OS::Print("%s", error.ToErrorCString()); | 7575 OS::Print("%s", error.ToErrorCString()); |
| 7583 va_start(args, format); | 7576 va_start(args, format); |
| 7584 Exceptions::TraceJSWarningV(script_, TokenPos(), format, args); | 7577 Exceptions::TraceJSWarningV(script_, TokenPos(), format, args); |
| 7585 va_end(args); | 7578 va_end(args); |
| 7586 } | 7579 } |
| 7587 } | 7580 } |
| 7588 | 7581 |
| 7589 | 7582 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7675 if (node != NULL) { | 7668 if (node != NULL) { |
| 7676 sequence->Add(node); | 7669 sequence->Add(node); |
| 7677 } | 7670 } |
| 7678 return sequence; | 7671 return sequence; |
| 7679 } | 7672 } |
| 7680 return node->AsSequenceNode(); | 7673 return node->AsSequenceNode(); |
| 7681 } | 7674 } |
| 7682 | 7675 |
| 7683 | 7676 |
| 7684 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { | 7677 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { |
| 7685 ArgumentListNode* arguments = new(isolate()) ArgumentListNode(type_pos); | 7678 ArgumentListNode* arguments = new(I) ArgumentListNode(type_pos); |
| 7686 // Location argument. | 7679 // Location argument. |
| 7687 arguments->Add(new(isolate()) LiteralNode( | 7680 arguments->Add(new(I) LiteralNode( |
| 7688 type_pos, Integer::ZoneHandle(I, Integer::New(type_pos)))); | 7681 type_pos, Integer::ZoneHandle(I, Integer::New(type_pos)))); |
| 7689 // Src value argument. | 7682 // Src value argument. |
| 7690 arguments->Add(new(isolate()) LiteralNode(type_pos, Instance::ZoneHandle(I))); | 7683 arguments->Add(new(I) LiteralNode(type_pos, Instance::ZoneHandle(I))); |
| 7691 // Dst type name argument. | 7684 // Dst type name argument. |
| 7692 arguments->Add(new(isolate()) LiteralNode(type_pos, Symbols::Malformed())); | 7685 arguments->Add(new(I) LiteralNode(type_pos, Symbols::Malformed())); |
| 7693 // Dst name argument. | 7686 // Dst name argument. |
| 7694 arguments->Add(new(isolate()) LiteralNode(type_pos, Symbols::Empty())); | 7687 arguments->Add(new(I) LiteralNode(type_pos, Symbols::Empty())); |
| 7695 // Malformed type error or malbounded type error. | 7688 // Malformed type error or malbounded type error. |
| 7696 const Error& error = Error::Handle(isolate(), type.error()); | 7689 const Error& error = Error::Handle(I, type.error()); |
| 7697 ASSERT(!error.IsNull()); | 7690 ASSERT(!error.IsNull()); |
| 7698 arguments->Add(new(isolate()) LiteralNode(type_pos, String::ZoneHandle(I, | 7691 arguments->Add(new(I) LiteralNode(type_pos, String::ZoneHandle(I, |
| 7699 Symbols::New(error.ToErrorCString())))); | 7692 Symbols::New(error.ToErrorCString())))); |
| 7700 return MakeStaticCall(Symbols::TypeError(), | 7693 return MakeStaticCall(Symbols::TypeError(), |
| 7701 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 7694 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 7702 arguments); | 7695 arguments); |
| 7703 } | 7696 } |
| 7704 | 7697 |
| 7705 | 7698 |
| 7706 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 7699 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, |
| 7707 const Class& cls, | 7700 const Class& cls, |
| 7708 const String& function_name, | 7701 const String& function_name, |
| 7709 ArgumentListNode* function_arguments, | 7702 ArgumentListNode* function_arguments, |
| 7710 InvocationMirror::Call im_call, | 7703 InvocationMirror::Call im_call, |
| 7711 InvocationMirror::Type im_type, | 7704 InvocationMirror::Type im_type, |
| 7712 const Function* func) { | 7705 const Function* func) { |
| 7713 ArgumentListNode* arguments = new(isolate()) ArgumentListNode(call_pos); | 7706 ArgumentListNode* arguments = new(I) ArgumentListNode(call_pos); |
| 7714 // Object receiver. | 7707 // Object receiver. |
| 7715 // If the function is external and dynamic, pass the actual receiver, | 7708 // If the function is external and dynamic, pass the actual receiver, |
| 7716 // otherwise, pass a class literal of the unresolved method's owner. | 7709 // otherwise, pass a class literal of the unresolved method's owner. |
| 7717 if ((func != NULL) && !func->IsNull() && | 7710 if ((func != NULL) && !func->IsNull() && |
| 7718 func->is_external() && !func->is_static()) { | 7711 func->is_external() && !func->is_static()) { |
| 7719 arguments->Add(LoadReceiver(func->token_pos())); | 7712 arguments->Add(LoadReceiver(func->token_pos())); |
| 7720 } else { | 7713 } else { |
| 7721 Type& type = Type::ZoneHandle(I, | 7714 Type& type = Type::ZoneHandle(I, |
| 7722 Type::New(cls, TypeArguments::Handle(isolate()), call_pos, Heap::kOld)); | 7715 Type::New(cls, TypeArguments::Handle(I), call_pos, Heap::kOld)); |
| 7723 type ^= ClassFinalizer::FinalizeType( | 7716 type ^= ClassFinalizer::FinalizeType( |
| 7724 current_class(), type, ClassFinalizer::kCanonicalize); | 7717 current_class(), type, ClassFinalizer::kCanonicalize); |
| 7725 arguments->Add(new(isolate()) LiteralNode(call_pos, type)); | 7718 arguments->Add(new(I) LiteralNode(call_pos, type)); |
| 7726 } | 7719 } |
| 7727 // String memberName. | 7720 // String memberName. |
| 7728 arguments->Add(new(isolate()) LiteralNode( | 7721 arguments->Add(new(I) LiteralNode( |
| 7729 call_pos, String::ZoneHandle(I, Symbols::New(function_name)))); | 7722 call_pos, String::ZoneHandle(I, Symbols::New(function_name)))); |
| 7730 // Smi invocation_type. | 7723 // Smi invocation_type. |
| 7731 if (cls.IsTopLevel()) { | 7724 if (cls.IsTopLevel()) { |
| 7732 ASSERT(im_call == InvocationMirror::kStatic || | 7725 ASSERT(im_call == InvocationMirror::kStatic || |
| 7733 im_call == InvocationMirror::kTopLevel); | 7726 im_call == InvocationMirror::kTopLevel); |
| 7734 im_call = InvocationMirror::kTopLevel; | 7727 im_call = InvocationMirror::kTopLevel; |
| 7735 } | 7728 } |
| 7736 arguments->Add(new(isolate()) LiteralNode(call_pos, Smi::ZoneHandle(I, | 7729 arguments->Add(new(I) LiteralNode(call_pos, Smi::ZoneHandle(I, |
| 7737 Smi::New(InvocationMirror::EncodeType(im_call, im_type))))); | 7730 Smi::New(InvocationMirror::EncodeType(im_call, im_type))))); |
| 7738 // List arguments. | 7731 // List arguments. |
| 7739 if (function_arguments == NULL) { | 7732 if (function_arguments == NULL) { |
| 7740 arguments->Add(new(isolate()) LiteralNode(call_pos, Array::ZoneHandle(I))); | 7733 arguments->Add(new(I) LiteralNode(call_pos, Array::ZoneHandle(I))); |
| 7741 } else { | 7734 } else { |
| 7742 ArrayNode* array = new(isolate()) ArrayNode( | 7735 ArrayNode* array = new(I) ArrayNode( |
| 7743 call_pos, | 7736 call_pos, |
| 7744 Type::ZoneHandle(I, Type::ArrayType()), | 7737 Type::ZoneHandle(I, Type::ArrayType()), |
| 7745 function_arguments->nodes()); | 7738 function_arguments->nodes()); |
| 7746 arguments->Add(array); | 7739 arguments->Add(array); |
| 7747 } | 7740 } |
| 7748 // List argumentNames. | 7741 // List argumentNames. |
| 7749 if (function_arguments == NULL) { | 7742 if (function_arguments == NULL) { |
| 7750 arguments->Add(new(isolate()) LiteralNode(call_pos, Array::ZoneHandle(I))); | 7743 arguments->Add(new(I) LiteralNode(call_pos, Array::ZoneHandle(I))); |
| 7751 } else { | 7744 } else { |
| 7752 arguments->Add(new(isolate()) LiteralNode( | 7745 arguments->Add(new(I) LiteralNode(call_pos, function_arguments->names())); |
| 7753 call_pos, function_arguments->names())); | |
| 7754 } | 7746 } |
| 7755 | 7747 |
| 7756 // List existingArgumentNames. | 7748 // List existingArgumentNames. |
| 7757 // Check if there exists a function with the same name unless caller | 7749 // Check if there exists a function with the same name unless caller |
| 7758 // has done the lookup already. If there is a function with the same | 7750 // has done the lookup already. If there is a function with the same |
| 7759 // name but incompatible parameters, inform the NoSuchMethodError what the | 7751 // name but incompatible parameters, inform the NoSuchMethodError what the |
| 7760 // expected parameters are. | 7752 // expected parameters are. |
| 7761 Function& function = Function::Handle(isolate()); | 7753 Function& function = Function::Handle(I); |
| 7762 if (func != NULL) { | 7754 if (func != NULL) { |
| 7763 function = func->raw(); | 7755 function = func->raw(); |
| 7764 } else { | 7756 } else { |
| 7765 function = cls.LookupStaticFunction(function_name); | 7757 function = cls.LookupStaticFunction(function_name); |
| 7766 } | 7758 } |
| 7767 Array& array = Array::ZoneHandle(I); | 7759 Array& array = Array::ZoneHandle(I); |
| 7768 // An unpatched external function is treated as an unresolved function. | 7760 // An unpatched external function is treated as an unresolved function. |
| 7769 if (!function.IsNull() && !function.is_external()) { | 7761 if (!function.IsNull() && !function.is_external()) { |
| 7770 // The constructor for NoSuchMethodError takes a list of existing | 7762 // The constructor for NoSuchMethodError takes a list of existing |
| 7771 // parameter names to produce a descriptive error message explaining | 7763 // parameter names to produce a descriptive error message explaining |
| 7772 // the parameter mismatch. The problem is that the array of names | 7764 // the parameter mismatch. The problem is that the array of names |
| 7773 // does not describe which parameters are optional positional or | 7765 // does not describe which parameters are optional positional or |
| 7774 // named, which can lead to confusing error messages. | 7766 // named, which can lead to confusing error messages. |
| 7775 // Since the NoSuchMethodError class only uses the list to produce | 7767 // Since the NoSuchMethodError class only uses the list to produce |
| 7776 // a string describing the expected parameters, we construct a more | 7768 // a string describing the expected parameters, we construct a more |
| 7777 // descriptive string here and pass it as the only element of the | 7769 // descriptive string here and pass it as the only element of the |
| 7778 // "existingArgumentNames" array of the NoSuchMethodError constructor. | 7770 // "existingArgumentNames" array of the NoSuchMethodError constructor. |
| 7779 // TODO(13471): Separate the implementations of NoSuchMethodError | 7771 // TODO(13471): Separate the implementations of NoSuchMethodError |
| 7780 // between dart2js and VM. Update the constructor to accept a string | 7772 // between dart2js and VM. Update the constructor to accept a string |
| 7781 // describing the formal parameters of an incompatible call target. | 7773 // describing the formal parameters of an incompatible call target. |
| 7782 array = Array::New(1, Heap::kOld); | 7774 array = Array::New(1, Heap::kOld); |
| 7783 array.SetAt(0, String::Handle(isolate(), | 7775 array.SetAt(0, String::Handle(I, function.UserVisibleFormalParameters())); |
| 7784 function.UserVisibleFormalParameters())); | |
| 7785 } | 7776 } |
| 7786 arguments->Add(new(isolate()) LiteralNode(call_pos, array)); | 7777 arguments->Add(new(I) LiteralNode(call_pos, array)); |
| 7787 | 7778 |
| 7788 return MakeStaticCall(Symbols::NoSuchMethodError(), | 7779 return MakeStaticCall(Symbols::NoSuchMethodError(), |
| 7789 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 7780 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 7790 arguments); | 7781 arguments); |
| 7791 } | 7782 } |
| 7792 | 7783 |
| 7793 | 7784 |
| 7794 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 7785 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
| 7795 TRACE_PARSER("ParseBinaryExpr"); | 7786 TRACE_PARSER("ParseBinaryExpr"); |
| 7796 ASSERT(min_preced >= Token::Precedence(Token::kOR)); | 7787 ASSERT(min_preced >= Token::Precedence(Token::kOR)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 7815 op_kind = Token::kISNOT; | 7806 op_kind = Token::kISNOT; |
| 7816 } | 7807 } |
| 7817 const intptr_t type_pos = TokenPos(); | 7808 const intptr_t type_pos = TokenPos(); |
| 7818 const AbstractType& type = AbstractType::ZoneHandle(I, | 7809 const AbstractType& type = AbstractType::ZoneHandle(I, |
| 7819 ParseType(ClassFinalizer::kCanonicalize)); | 7810 ParseType(ClassFinalizer::kCanonicalize)); |
| 7820 if (!type.IsInstantiated() && | 7811 if (!type.IsInstantiated() && |
| 7821 (current_block_->scope->function_level() > 0)) { | 7812 (current_block_->scope->function_level() > 0)) { |
| 7822 // Make sure that the instantiator is captured. | 7813 // Make sure that the instantiator is captured. |
| 7823 CaptureInstantiator(); | 7814 CaptureInstantiator(); |
| 7824 } | 7815 } |
| 7825 right_operand = new(isolate()) TypeNode(type_pos, type); | 7816 right_operand = new(I) TypeNode(type_pos, type); |
| 7826 // In production mode, the type may be malformed. | 7817 // In production mode, the type may be malformed. |
| 7827 // In checked mode, the type may be malformed or malbounded. | 7818 // In checked mode, the type may be malformed or malbounded. |
| 7828 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || | 7819 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || |
| 7829 (op_kind == Token::kAS)) && | 7820 (op_kind == Token::kAS)) && |
| 7830 type.IsMalformedOrMalbounded()) { | 7821 type.IsMalformedOrMalbounded()) { |
| 7831 // Note that a type error is thrown in a type test or in | 7822 // Note that a type error is thrown in a type test or in |
| 7832 // a type cast even if the tested value is null. | 7823 // a type cast even if the tested value is null. |
| 7833 // We need to evaluate the left operand for potential | 7824 // We need to evaluate the left operand for potential |
| 7834 // side effects. | 7825 // side effects. |
| 7835 LetNode* let = new(isolate()) LetNode(left_operand->token_pos()); | 7826 LetNode* let = new(I) LetNode(left_operand->token_pos()); |
| 7836 let->AddNode(left_operand); | 7827 let->AddNode(left_operand); |
| 7837 let->AddNode(ThrowTypeError(type_pos, type)); | 7828 let->AddNode(ThrowTypeError(type_pos, type)); |
| 7838 left_operand = let; | 7829 left_operand = let; |
| 7839 break; // Type checks and casts can't be chained. | 7830 break; // Type checks and casts can't be chained. |
| 7840 } | 7831 } |
| 7841 } | 7832 } |
| 7842 if (Token::IsRelationalOperator(op_kind) | 7833 if (Token::IsRelationalOperator(op_kind) |
| 7843 || Token::IsTypeTestOperator(op_kind) | 7834 || Token::IsTypeTestOperator(op_kind) |
| 7844 || Token::IsTypeCastOperator(op_kind) | 7835 || Token::IsTypeCastOperator(op_kind) |
| 7845 || Token::IsEqualityOperator(op_kind)) { | 7836 || Token::IsEqualityOperator(op_kind)) { |
| 7846 if (Token::IsTypeTestOperator(op_kind) || | 7837 if (Token::IsTypeTestOperator(op_kind) || |
| 7847 Token::IsTypeCastOperator(op_kind)) { | 7838 Token::IsTypeCastOperator(op_kind)) { |
| 7848 if (!right_operand->AsTypeNode()->type().IsInstantiated()) { | 7839 if (!right_operand->AsTypeNode()->type().IsInstantiated()) { |
| 7849 EnsureExpressionTemp(); | 7840 EnsureExpressionTemp(); |
| 7850 } | 7841 } |
| 7851 } | 7842 } |
| 7852 left_operand = new(isolate()) ComparisonNode( | 7843 left_operand = new(I) ComparisonNode( |
| 7853 op_pos, op_kind, left_operand, right_operand); | 7844 op_pos, op_kind, left_operand, right_operand); |
| 7854 break; // Equality and relational operators cannot be chained. | 7845 break; // Equality and relational operators cannot be chained. |
| 7855 } else { | 7846 } else { |
| 7856 left_operand = OptimizeBinaryOpNode( | 7847 left_operand = OptimizeBinaryOpNode( |
| 7857 op_pos, op_kind, left_operand, right_operand); | 7848 op_pos, op_kind, left_operand, right_operand); |
| 7858 } | 7849 } |
| 7859 } | 7850 } |
| 7860 current_preced--; | 7851 current_preced--; |
| 7861 } | 7852 } |
| 7862 return left_operand; | 7853 return left_operand; |
| 7863 } | 7854 } |
| 7864 | 7855 |
| 7865 | 7856 |
| 7866 AstNode* Parser::ParseExprList() { | 7857 AstNode* Parser::ParseExprList() { |
| 7867 TRACE_PARSER("ParseExprList"); | 7858 TRACE_PARSER("ParseExprList"); |
| 7868 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); | 7859 AstNode* expressions = ParseExpr(kAllowConst, kConsumeCascades); |
| 7869 if (CurrentToken() == Token::kCOMMA) { | 7860 if (CurrentToken() == Token::kCOMMA) { |
| 7870 // Collect comma-separated expressions in a non scope owning sequence node. | 7861 // Collect comma-separated expressions in a non scope owning sequence node. |
| 7871 SequenceNode* list = new(isolate()) SequenceNode(TokenPos(), NULL); | 7862 SequenceNode* list = new(I) SequenceNode(TokenPos(), NULL); |
| 7872 list->Add(expressions); | 7863 list->Add(expressions); |
| 7873 while (CurrentToken() == Token::kCOMMA) { | 7864 while (CurrentToken() == Token::kCOMMA) { |
| 7874 ConsumeToken(); | 7865 ConsumeToken(); |
| 7875 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 7866 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 7876 list->Add(expr); | 7867 list->Add(expr); |
| 7877 } | 7868 } |
| 7878 expressions = list; | 7869 expressions = list; |
| 7879 } | 7870 } |
| 7880 return expressions; | 7871 return expressions; |
| 7881 } | 7872 } |
| 7882 | 7873 |
| 7883 | 7874 |
| 7884 void Parser::EnsureExpressionTemp() { | 7875 void Parser::EnsureExpressionTemp() { |
| 7885 // Temporary used later by the flow_graph_builder. | 7876 // Temporary used later by the flow_graph_builder. |
| 7886 parsed_function()->EnsureExpressionTemp(); | 7877 parsed_function()->EnsureExpressionTemp(); |
| 7887 } | 7878 } |
| 7888 | 7879 |
| 7889 | 7880 |
| 7890 void Parser::EnsureSavedCurrentContext() { | 7881 void Parser::EnsureSavedCurrentContext() { |
| 7891 // Used later by the flow_graph_builder to save current context. | 7882 // Used later by the flow_graph_builder to save current context. |
| 7892 if (!parsed_function()->has_saved_current_context_var()) { | 7883 if (!parsed_function()->has_saved_current_context_var()) { |
| 7893 LocalVariable* temp = new(isolate()) LocalVariable( | 7884 LocalVariable* temp = new(I) LocalVariable( |
| 7894 current_function().token_pos(), | 7885 current_function().token_pos(), |
| 7895 Symbols::SavedCurrentContextVar(), | 7886 Symbols::SavedCurrentContextVar(), |
| 7896 Type::ZoneHandle(I, Type::DynamicType())); | 7887 Type::ZoneHandle(I, Type::DynamicType())); |
| 7897 ASSERT(temp != NULL); | 7888 ASSERT(temp != NULL); |
| 7898 parsed_function()->set_saved_current_context_var(temp); | 7889 parsed_function()->set_saved_current_context_var(temp); |
| 7899 } | 7890 } |
| 7900 } | 7891 } |
| 7901 | 7892 |
| 7902 | 7893 |
| 7903 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 7894 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
| 7904 const char* s) { | 7895 const char* s) { |
| 7905 char name[64]; | 7896 char name[64]; |
| 7906 OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos); | 7897 OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos); |
| 7907 LocalVariable* temp = new(isolate()) LocalVariable( | 7898 LocalVariable* temp = new(I) LocalVariable( |
| 7908 token_pos, | 7899 token_pos, |
| 7909 String::ZoneHandle(I, Symbols::New(name)), | 7900 String::ZoneHandle(I, Symbols::New(name)), |
| 7910 Type::ZoneHandle(I, Type::DynamicType())); | 7901 Type::ZoneHandle(I, Type::DynamicType())); |
| 7911 temp->set_is_final(); | 7902 temp->set_is_final(); |
| 7912 current_block_->scope->AddVariable(temp); | 7903 current_block_->scope->AddVariable(temp); |
| 7913 return temp; | 7904 return temp; |
| 7914 } | 7905 } |
| 7915 | 7906 |
| 7916 | 7907 |
| 7917 // TODO(srdjan): Implement other optimizations. | 7908 // TODO(srdjan): Implement other optimizations. |
| 7918 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, | 7909 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, |
| 7919 Token::Kind binary_op, | 7910 Token::Kind binary_op, |
| 7920 AstNode* lhs, | 7911 AstNode* lhs, |
| 7921 AstNode* rhs) { | 7912 AstNode* rhs) { |
| 7922 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 7913 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
| 7923 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 7914 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
| 7924 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 7915 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
| 7925 if (lhs_literal->literal().IsDouble() && | 7916 if (lhs_literal->literal().IsDouble() && |
| 7926 rhs_literal->literal().IsDouble()) { | 7917 rhs_literal->literal().IsDouble()) { |
| 7927 double left_double = Double::Cast(lhs_literal->literal()).value(); | 7918 double left_double = Double::Cast(lhs_literal->literal()).value(); |
| 7928 double right_double = Double::Cast(rhs_literal->literal()).value(); | 7919 double right_double = Double::Cast(rhs_literal->literal()).value(); |
| 7929 if (binary_op == Token::kDIV) { | 7920 if (binary_op == Token::kDIV) { |
| 7930 const Double& dbl_obj = Double::ZoneHandle(I, | 7921 const Double& dbl_obj = Double::ZoneHandle(I, |
| 7931 Double::NewCanonical((left_double / right_double))); | 7922 Double::NewCanonical((left_double / right_double))); |
| 7932 return new(isolate()) LiteralNode(op_pos, dbl_obj); | 7923 return new(I) LiteralNode(op_pos, dbl_obj); |
| 7933 } | 7924 } |
| 7934 } | 7925 } |
| 7935 } | 7926 } |
| 7936 if ((binary_op == Token::kAND) || (binary_op == Token::kOR)) { | 7927 if ((binary_op == Token::kAND) || (binary_op == Token::kOR)) { |
| 7937 EnsureExpressionTemp(); | 7928 EnsureExpressionTemp(); |
| 7938 } | 7929 } |
| 7939 if (binary_op == Token::kBIT_AND) { | 7930 if (binary_op == Token::kBIT_AND) { |
| 7940 // Normalize so that rhs is a literal if any is. | 7931 // Normalize so that rhs is a literal if any is. |
| 7941 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { | 7932 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { |
| 7942 // Swap. | 7933 // Swap. |
| 7943 LiteralNode* temp = rhs_literal; | 7934 LiteralNode* temp = rhs_literal; |
| 7944 rhs_literal = lhs_literal; | 7935 rhs_literal = lhs_literal; |
| 7945 lhs_literal = temp; | 7936 lhs_literal = temp; |
| 7946 } | 7937 } |
| 7947 if ((rhs_literal != NULL) && | 7938 if ((rhs_literal != NULL) && |
| 7948 (rhs_literal->literal().IsSmi() || rhs_literal->literal().IsMint())) { | 7939 (rhs_literal->literal().IsSmi() || rhs_literal->literal().IsMint())) { |
| 7949 const int64_t val = Integer::Cast(rhs_literal->literal()).AsInt64Value(); | 7940 const int64_t val = Integer::Cast(rhs_literal->literal()).AsInt64Value(); |
| 7950 if ((0 <= val) && (Utils::IsUint(32, val))) { | 7941 if ((0 <= val) && (Utils::IsUint(32, val))) { |
| 7951 if (lhs->IsBinaryOpNode() && | 7942 if (lhs->IsBinaryOpNode() && |
| 7952 (lhs->AsBinaryOpNode()->kind() == Token::kSHL)) { | 7943 (lhs->AsBinaryOpNode()->kind() == Token::kSHL)) { |
| 7953 // Merge SHL and BIT_AND into one "SHL with mask" node. | 7944 // Merge SHL and BIT_AND into one "SHL with mask" node. |
| 7954 BinaryOpNode* old = lhs->AsBinaryOpNode(); | 7945 BinaryOpNode* old = lhs->AsBinaryOpNode(); |
| 7955 BinaryOpWithMask32Node* binop = new(isolate()) BinaryOpWithMask32Node( | 7946 BinaryOpWithMask32Node* binop = new(I) BinaryOpWithMask32Node( |
| 7956 old->token_pos(), old->kind(), old->left(), old->right(), val); | 7947 old->token_pos(), old->kind(), old->left(), old->right(), val); |
| 7957 return binop; | 7948 return binop; |
| 7958 } | 7949 } |
| 7959 } | 7950 } |
| 7960 } | 7951 } |
| 7961 } | 7952 } |
| 7962 return new(isolate()) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 7953 return new(I) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
| 7963 } | 7954 } |
| 7964 | 7955 |
| 7965 | 7956 |
| 7966 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, | 7957 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, |
| 7967 Token::Kind assignment_op, | 7958 Token::Kind assignment_op, |
| 7968 AstNode* lhs, | 7959 AstNode* lhs, |
| 7969 AstNode* rhs) { | 7960 AstNode* rhs) { |
| 7970 TRACE_PARSER("ExpandAssignableOp"); | 7961 TRACE_PARSER("ExpandAssignableOp"); |
| 7971 switch (assignment_op) { | 7962 switch (assignment_op) { |
| 7972 case Token::kASSIGN: | 7963 case Token::kASSIGN: |
| 7973 return rhs; | 7964 return rhs; |
| 7974 case Token::kASSIGN_ADD: | 7965 case Token::kASSIGN_ADD: |
| 7975 return new(isolate()) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 7966 return new(I) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
| 7976 case Token::kASSIGN_SUB: | 7967 case Token::kASSIGN_SUB: |
| 7977 return new(isolate()) BinaryOpNode(op_pos, Token::kSUB, lhs, rhs); | 7968 return new(I) BinaryOpNode(op_pos, Token::kSUB, lhs, rhs); |
| 7978 case Token::kASSIGN_MUL: | 7969 case Token::kASSIGN_MUL: |
| 7979 return new(isolate()) BinaryOpNode(op_pos, Token::kMUL, lhs, rhs); | 7970 return new(I) BinaryOpNode(op_pos, Token::kMUL, lhs, rhs); |
| 7980 case Token::kASSIGN_TRUNCDIV: | 7971 case Token::kASSIGN_TRUNCDIV: |
| 7981 return new(isolate()) BinaryOpNode(op_pos, Token::kTRUNCDIV, lhs, rhs); | 7972 return new(I) BinaryOpNode(op_pos, Token::kTRUNCDIV, lhs, rhs); |
| 7982 case Token::kASSIGN_DIV: | 7973 case Token::kASSIGN_DIV: |
| 7983 return new(isolate()) BinaryOpNode(op_pos, Token::kDIV, lhs, rhs); | 7974 return new(I) BinaryOpNode(op_pos, Token::kDIV, lhs, rhs); |
| 7984 case Token::kASSIGN_MOD: | 7975 case Token::kASSIGN_MOD: |
| 7985 return new(isolate()) BinaryOpNode(op_pos, Token::kMOD, lhs, rhs); | 7976 return new(I) BinaryOpNode(op_pos, Token::kMOD, lhs, rhs); |
| 7986 case Token::kASSIGN_SHR: | 7977 case Token::kASSIGN_SHR: |
| 7987 return new(isolate()) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); | 7978 return new(I) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); |
| 7988 case Token::kASSIGN_SHL: | 7979 case Token::kASSIGN_SHL: |
| 7989 return new(isolate()) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); | 7980 return new(I) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); |
| 7990 case Token::kASSIGN_OR: | 7981 case Token::kASSIGN_OR: |
| 7991 return new(isolate()) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); | 7982 return new(I) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); |
| 7992 case Token::kASSIGN_AND: | 7983 case Token::kASSIGN_AND: |
| 7993 return new(isolate()) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); | 7984 return new(I) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); |
| 7994 case Token::kASSIGN_XOR: | 7985 case Token::kASSIGN_XOR: |
| 7995 return new(isolate()) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); | 7986 return new(I) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); |
| 7996 default: | 7987 default: |
| 7997 ErrorMsg(op_pos, "internal error: ExpandAssignableOp '%s' unimplemented", | 7988 ErrorMsg(op_pos, "internal error: ExpandAssignableOp '%s' unimplemented", |
| 7998 Token::Name(assignment_op)); | 7989 Token::Name(assignment_op)); |
| 7999 UNIMPLEMENTED(); | 7990 UNIMPLEMENTED(); |
| 8000 return NULL; | 7991 return NULL; |
| 8001 } | 7992 } |
| 8002 } | 7993 } |
| 8003 | 7994 |
| 8004 | 7995 |
| 8005 // Evaluates the value of the compile time constant expression | 7996 // Evaluates the value of the compile time constant expression |
| 8006 // and returns a literal node for the value. | 7997 // and returns a literal node for the value. |
| 8007 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { | 7998 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { |
| 8008 if (expr->IsLiteralNode()) { | 7999 if (expr->IsLiteralNode()) { |
| 8009 return expr; | 8000 return expr; |
| 8010 } | 8001 } |
| 8011 if (expr->EvalConstExpr() == NULL) { | 8002 if (expr->EvalConstExpr() == NULL) { |
| 8012 ErrorMsg(expr_pos, "expression is not a valid compile-time constant"); | 8003 ErrorMsg(expr_pos, "expression is not a valid compile-time constant"); |
| 8013 } | 8004 } |
| 8014 return new(isolate()) LiteralNode( | 8005 return new(I) LiteralNode( |
| 8015 expr_pos, EvaluateConstExpr(expr_pos, expr)); | 8006 expr_pos, EvaluateConstExpr(expr_pos, expr)); |
| 8016 } | 8007 } |
| 8017 | 8008 |
| 8018 | 8009 |
| 8019 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 8010 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
| 8020 AstNode* node = *expr; | 8011 AstNode* node = *expr; |
| 8021 intptr_t token_pos = node->token_pos(); | 8012 intptr_t token_pos = node->token_pos(); |
| 8022 LetNode* result = new(isolate()) LetNode(token_pos); | 8013 LetNode* result = new(I) LetNode(token_pos); |
| 8023 if (node->IsLoadIndexedNode()) { | 8014 if (node->IsLoadIndexedNode()) { |
| 8024 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 8015 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
| 8025 AstNode* array = load_indexed->array(); | 8016 AstNode* array = load_indexed->array(); |
| 8026 AstNode* index = load_indexed->index_expr(); | 8017 AstNode* index = load_indexed->index_expr(); |
| 8027 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 8018 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
| 8028 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 8019 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
| 8029 array = new(isolate()) LoadLocalNode(token_pos, t0); | 8020 array = new(I) LoadLocalNode(token_pos, t0); |
| 8030 } | 8021 } |
| 8031 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { | 8022 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { |
| 8032 LocalVariable* t1 = result->AddInitializer( | 8023 LocalVariable* t1 = result->AddInitializer( |
| 8033 load_indexed->index_expr()); | 8024 load_indexed->index_expr()); |
| 8034 index = new(isolate()) LoadLocalNode(token_pos, t1); | 8025 index = new(I) LoadLocalNode(token_pos, t1); |
| 8035 } | 8026 } |
| 8036 *expr = new(isolate()) LoadIndexedNode(token_pos, | 8027 *expr = new(I) LoadIndexedNode(token_pos, |
| 8037 array, | 8028 array, |
| 8038 index, | 8029 index, |
| 8039 load_indexed->super_class()); | 8030 load_indexed->super_class()); |
| 8040 return result; | 8031 return result; |
| 8041 } | 8032 } |
| 8042 if (node->IsInstanceGetterNode()) { | 8033 if (node->IsInstanceGetterNode()) { |
| 8043 InstanceGetterNode* getter = node->AsInstanceGetterNode(); | 8034 InstanceGetterNode* getter = node->AsInstanceGetterNode(); |
| 8044 AstNode* receiver = getter->receiver(); | 8035 AstNode* receiver = getter->receiver(); |
| 8045 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { | 8036 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { |
| 8046 LocalVariable* t0 = result->AddInitializer(getter->receiver()); | 8037 LocalVariable* t0 = result->AddInitializer(getter->receiver()); |
| 8047 receiver = new(isolate()) LoadLocalNode(token_pos, t0); | 8038 receiver = new(I) LoadLocalNode(token_pos, t0); |
| 8048 } | 8039 } |
| 8049 *expr = new(isolate()) InstanceGetterNode(token_pos, | 8040 *expr = new(I) InstanceGetterNode( |
| 8050 receiver, | 8041 token_pos, receiver, getter->field_name()); |
| 8051 getter->field_name()); | |
| 8052 return result; | 8042 return result; |
| 8053 } | 8043 } |
| 8054 return result; | 8044 return result; |
| 8055 } | 8045 } |
| 8056 | 8046 |
| 8057 | 8047 |
| 8058 // Check whether the syntax of expression expr is a grammatically legal | 8048 // Check whether the syntax of expression expr is a grammatically legal |
| 8059 // assignable expression. This check is used to detect situations where | 8049 // assignable expression. This check is used to detect situations where |
| 8060 // the expression itself is assignable, but the source is grammatically | 8050 // the expression itself is assignable, but the source is grammatically |
| 8061 // wrong. The AST representation of an expression cannot distinguish | 8051 // wrong. The AST representation of an expression cannot distinguish |
| (...skipping 20 matching lines...) Expand all Loading... |
| 8082 const String* left_ident, | 8072 const String* left_ident, |
| 8083 intptr_t left_pos) { | 8073 intptr_t left_pos) { |
| 8084 AstNode* result = original->MakeAssignmentNode(rhs); | 8074 AstNode* result = original->MakeAssignmentNode(rhs); |
| 8085 if (result == NULL) { | 8075 if (result == NULL) { |
| 8086 String& name = String::ZoneHandle(I); | 8076 String& name = String::ZoneHandle(I); |
| 8087 const Class* target_cls = ¤t_class(); | 8077 const Class* target_cls = ¤t_class(); |
| 8088 if (original->IsTypeNode()) { | 8078 if (original->IsTypeNode()) { |
| 8089 name = Symbols::New(original->AsTypeNode()->TypeName()); | 8079 name = Symbols::New(original->AsTypeNode()->TypeName()); |
| 8090 } else if (original->IsLoadStaticFieldNode()) { | 8080 } else if (original->IsLoadStaticFieldNode()) { |
| 8091 name = original->AsLoadStaticFieldNode()->field().name(); | 8081 name = original->AsLoadStaticFieldNode()->field().name(); |
| 8092 target_cls = &Class::Handle(isolate(), | 8082 target_cls = &Class::Handle(I, |
| 8093 original->AsLoadStaticFieldNode()->field().owner()); | 8083 original->AsLoadStaticFieldNode()->field().owner()); |
| 8094 } else if ((left_ident != NULL) && | 8084 } else if ((left_ident != NULL) && |
| 8095 (original->IsLiteralNode() || | 8085 (original->IsLiteralNode() || |
| 8096 original->IsLoadLocalNode())) { | 8086 original->IsLoadLocalNode())) { |
| 8097 name = left_ident->raw(); | 8087 name = left_ident->raw(); |
| 8098 } | 8088 } |
| 8099 if (name.IsNull()) { | 8089 if (name.IsNull()) { |
| 8100 ErrorMsg(left_pos, "expression is not assignable"); | 8090 ErrorMsg(left_pos, "expression is not assignable"); |
| 8101 } | 8091 } |
| 8102 result = ThrowNoSuchMethodError( | 8092 result = ThrowNoSuchMethodError( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8115 result->IsStoreLocalNode()) { | 8105 result->IsStoreLocalNode()) { |
| 8116 // Ensure that the expression temp is allocated for nodes that may need it. | 8106 // Ensure that the expression temp is allocated for nodes that may need it. |
| 8117 EnsureExpressionTemp(); | 8107 EnsureExpressionTemp(); |
| 8118 } | 8108 } |
| 8119 return result; | 8109 return result; |
| 8120 } | 8110 } |
| 8121 | 8111 |
| 8122 | 8112 |
| 8123 AstNode* Parser::ParseCascades(AstNode* expr) { | 8113 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 8124 intptr_t cascade_pos = TokenPos(); | 8114 intptr_t cascade_pos = TokenPos(); |
| 8125 LetNode* cascade = new(isolate()) LetNode(cascade_pos); | 8115 LetNode* cascade = new(I) LetNode(cascade_pos); |
| 8126 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 8116 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| 8127 while (CurrentToken() == Token::kCASCADE) { | 8117 while (CurrentToken() == Token::kCASCADE) { |
| 8128 cascade_pos = TokenPos(); | 8118 cascade_pos = TokenPos(); |
| 8129 LoadLocalNode* load_cascade_receiver = | 8119 LoadLocalNode* load_cascade_receiver = |
| 8130 new(isolate()) LoadLocalNode(cascade_pos, cascade_receiver_var); | 8120 new(I) LoadLocalNode(cascade_pos, cascade_receiver_var); |
| 8131 if (Token::IsIdentifier(LookaheadToken(1))) { | 8121 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 8132 // Replace .. with . for ParseSelectors(). | 8122 // Replace .. with . for ParseSelectors(). |
| 8133 token_kind_ = Token::kPERIOD; | 8123 token_kind_ = Token::kPERIOD; |
| 8134 } else if (LookaheadToken(1) == Token::kLBRACK) { | 8124 } else if (LookaheadToken(1) == Token::kLBRACK) { |
| 8135 ConsumeToken(); | 8125 ConsumeToken(); |
| 8136 } else { | 8126 } else { |
| 8137 ErrorMsg("identifier or [ expected after .."); | 8127 ErrorMsg("identifier or [ expected after .."); |
| 8138 } | 8128 } |
| 8139 String* expr_ident = | 8129 String* expr_ident = |
| 8140 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8130 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 8165 AstNode* assign_expr = | 8155 AstNode* assign_expr = |
| 8166 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); | 8156 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); |
| 8167 ASSERT(assign_expr != NULL); | 8157 ASSERT(assign_expr != NULL); |
| 8168 expr = assign_expr; | 8158 expr = assign_expr; |
| 8169 } | 8159 } |
| 8170 } | 8160 } |
| 8171 cascade->AddNode(expr); | 8161 cascade->AddNode(expr); |
| 8172 } | 8162 } |
| 8173 // The result is an expression with the (side effects of the) cascade | 8163 // The result is an expression with the (side effects of the) cascade |
| 8174 // sequence followed by the (value of the) receiver temp variable load. | 8164 // sequence followed by the (value of the) receiver temp variable load. |
| 8175 cascade->AddNode(new(isolate()) LoadLocalNode( | 8165 cascade->AddNode(new(I) LoadLocalNode(cascade_pos, cascade_receiver_var)); |
| 8176 cascade_pos, cascade_receiver_var)); | |
| 8177 return cascade; | 8166 return cascade; |
| 8178 } | 8167 } |
| 8179 | 8168 |
| 8180 | 8169 |
| 8181 // Convert loading of a static const field into a literal node. | 8170 // Convert loading of a static const field into a literal node. |
| 8182 static AstNode* LiteralIfStaticConst(Isolate* iso, AstNode* expr) { | 8171 static AstNode* LiteralIfStaticConst(Isolate* iso, AstNode* expr) { |
| 8183 if (expr->IsLoadStaticFieldNode()) { | 8172 if (expr->IsLoadStaticFieldNode()) { |
| 8184 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 8173 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
| 8185 if (field.is_const()) { | 8174 if (field.is_const()) { |
| 8186 ASSERT(field.value() != Object::sentinel().raw()); | 8175 ASSERT(field.value() != Object::sentinel().raw()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8199 String* expr_ident = | 8188 String* expr_ident = |
| 8200 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8189 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8201 const intptr_t expr_pos = TokenPos(); | 8190 const intptr_t expr_pos = TokenPos(); |
| 8202 | 8191 |
| 8203 if (CurrentToken() == Token::kTHROW) { | 8192 if (CurrentToken() == Token::kTHROW) { |
| 8204 ConsumeToken(); | 8193 ConsumeToken(); |
| 8205 if (CurrentToken() == Token::kSEMICOLON) { | 8194 if (CurrentToken() == Token::kSEMICOLON) { |
| 8206 ErrorMsg("expression expected after throw"); | 8195 ErrorMsg("expression expected after throw"); |
| 8207 } | 8196 } |
| 8208 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 8197 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 8209 return new(isolate()) ThrowNode(expr_pos, expr, NULL); | 8198 return new(I) ThrowNode(expr_pos, expr, NULL); |
| 8210 } | 8199 } |
| 8211 AstNode* expr = ParseConditionalExpr(); | 8200 AstNode* expr = ParseConditionalExpr(); |
| 8212 if (!Token::IsAssignmentOperator(CurrentToken())) { | 8201 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 8213 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 8202 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
| 8214 return ParseCascades(expr); | 8203 return ParseCascades(expr); |
| 8215 } | 8204 } |
| 8216 if (require_compiletime_const) { | 8205 if (require_compiletime_const) { |
| 8217 expr = FoldConstExpr(expr_pos, expr); | 8206 expr = FoldConstExpr(expr_pos, expr); |
| 8218 } else { | 8207 } else { |
| 8219 expr = LiteralIfStaticConst(I, expr); | 8208 expr = LiteralIfStaticConst(I, expr); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8266 AstNode* Parser::ParseConditionalExpr() { | 8255 AstNode* Parser::ParseConditionalExpr() { |
| 8267 TRACE_PARSER("ParseConditionalExpr"); | 8256 TRACE_PARSER("ParseConditionalExpr"); |
| 8268 const intptr_t expr_pos = TokenPos(); | 8257 const intptr_t expr_pos = TokenPos(); |
| 8269 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 8258 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); |
| 8270 if (CurrentToken() == Token::kCONDITIONAL) { | 8259 if (CurrentToken() == Token::kCONDITIONAL) { |
| 8271 EnsureExpressionTemp(); | 8260 EnsureExpressionTemp(); |
| 8272 ConsumeToken(); | 8261 ConsumeToken(); |
| 8273 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 8262 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
| 8274 ExpectToken(Token::kCOLON); | 8263 ExpectToken(Token::kCOLON); |
| 8275 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 8264 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
| 8276 expr = new(isolate()) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 8265 expr = new(I) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 8277 } | 8266 } |
| 8278 return expr; | 8267 return expr; |
| 8279 } | 8268 } |
| 8280 | 8269 |
| 8281 | 8270 |
| 8282 AstNode* Parser::ParseUnaryExpr() { | 8271 AstNode* Parser::ParseUnaryExpr() { |
| 8283 TRACE_PARSER("ParseUnaryExpr"); | 8272 TRACE_PARSER("ParseUnaryExpr"); |
| 8284 AstNode* expr = NULL; | 8273 AstNode* expr = NULL; |
| 8285 const intptr_t op_pos = TokenPos(); | 8274 const intptr_t op_pos = TokenPos(); |
| 8286 if (IsPrefixOperator(CurrentToken())) { | 8275 if (IsPrefixOperator(CurrentToken())) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 8302 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8291 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8303 const intptr_t expr_pos = TokenPos(); | 8292 const intptr_t expr_pos = TokenPos(); |
| 8304 expr = ParseUnaryExpr(); | 8293 expr = ParseUnaryExpr(); |
| 8305 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 8294 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 8306 ErrorMsg(expr_pos, "expression is not assignable"); | 8295 ErrorMsg(expr_pos, "expression is not assignable"); |
| 8307 } | 8296 } |
| 8308 // Is prefix. | 8297 // Is prefix. |
| 8309 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 8298 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 8310 Token::Kind binary_op = | 8299 Token::Kind binary_op = |
| 8311 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 8300 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 8312 BinaryOpNode* add = new(isolate()) BinaryOpNode( | 8301 BinaryOpNode* add = new(I) BinaryOpNode( |
| 8313 op_pos, | 8302 op_pos, |
| 8314 binary_op, | 8303 binary_op, |
| 8315 expr, | 8304 expr, |
| 8316 new(isolate()) LiteralNode(op_pos, Smi::ZoneHandle(I, Smi::New(1)))); | 8305 new(I) LiteralNode(op_pos, Smi::ZoneHandle(I, Smi::New(1)))); |
| 8317 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 8306 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); |
| 8318 ASSERT(store != NULL); | 8307 ASSERT(store != NULL); |
| 8319 let_expr->AddNode(store); | 8308 let_expr->AddNode(store); |
| 8320 expr = let_expr; | 8309 expr = let_expr; |
| 8321 } else { | 8310 } else { |
| 8322 expr = ParsePostfixExpr(); | 8311 expr = ParsePostfixExpr(); |
| 8323 } | 8312 } |
| 8324 return expr; | 8313 return expr; |
| 8325 } | 8314 } |
| 8326 | 8315 |
| 8327 | 8316 |
| 8328 ArgumentListNode* Parser::ParseActualParameters( | 8317 ArgumentListNode* Parser::ParseActualParameters( |
| 8329 ArgumentListNode* implicit_arguments, | 8318 ArgumentListNode* implicit_arguments, |
| 8330 bool require_const) { | 8319 bool require_const) { |
| 8331 TRACE_PARSER("ParseActualParameters"); | 8320 TRACE_PARSER("ParseActualParameters"); |
| 8332 ASSERT(CurrentToken() == Token::kLPAREN); | 8321 ASSERT(CurrentToken() == Token::kLPAREN); |
| 8333 const bool saved_mode = SetAllowFunctionLiterals(true); | 8322 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 8334 ArgumentListNode* arguments; | 8323 ArgumentListNode* arguments; |
| 8335 if (implicit_arguments == NULL) { | 8324 if (implicit_arguments == NULL) { |
| 8336 arguments = new(isolate()) ArgumentListNode(TokenPos()); | 8325 arguments = new(I) ArgumentListNode(TokenPos()); |
| 8337 } else { | 8326 } else { |
| 8338 arguments = implicit_arguments; | 8327 arguments = implicit_arguments; |
| 8339 } | 8328 } |
| 8340 const GrowableObjectArray& names = GrowableObjectArray::Handle(isolate(), | 8329 const GrowableObjectArray& names = GrowableObjectArray::Handle(I, |
| 8341 GrowableObjectArray::New(Heap::kOld)); | 8330 GrowableObjectArray::New(Heap::kOld)); |
| 8342 bool named_argument_seen = false; | 8331 bool named_argument_seen = false; |
| 8343 if (LookaheadToken(1) != Token::kRPAREN) { | 8332 if (LookaheadToken(1) != Token::kRPAREN) { |
| 8344 String& arg_name = String::Handle(isolate()); | 8333 String& arg_name = String::Handle(I); |
| 8345 do { | 8334 do { |
| 8346 ASSERT((CurrentToken() == Token::kLPAREN) || | 8335 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 8347 (CurrentToken() == Token::kCOMMA)); | 8336 (CurrentToken() == Token::kCOMMA)); |
| 8348 ConsumeToken(); | 8337 ConsumeToken(); |
| 8349 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 8338 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 8350 named_argument_seen = true; | 8339 named_argument_seen = true; |
| 8351 // The canonicalization of the arguments descriptor array built in | 8340 // The canonicalization of the arguments descriptor array built in |
| 8352 // the code generator requires that the names are symbols, i.e. | 8341 // the code generator requires that the names are symbols, i.e. |
| 8353 // canonicalized strings. | 8342 // canonicalized strings. |
| 8354 ASSERT(CurrentLiteral()->IsSymbol()); | 8343 ASSERT(CurrentLiteral()->IsSymbol()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 8365 ErrorMsg("named argument expected"); | 8354 ErrorMsg("named argument expected"); |
| 8366 } | 8355 } |
| 8367 arguments->Add(ParseExpr(require_const, kConsumeCascades)); | 8356 arguments->Add(ParseExpr(require_const, kConsumeCascades)); |
| 8368 } while (CurrentToken() == Token::kCOMMA); | 8357 } while (CurrentToken() == Token::kCOMMA); |
| 8369 } else { | 8358 } else { |
| 8370 ConsumeToken(); | 8359 ConsumeToken(); |
| 8371 } | 8360 } |
| 8372 ExpectToken(Token::kRPAREN); | 8361 ExpectToken(Token::kRPAREN); |
| 8373 SetAllowFunctionLiterals(saved_mode); | 8362 SetAllowFunctionLiterals(saved_mode); |
| 8374 if (named_argument_seen) { | 8363 if (named_argument_seen) { |
| 8375 arguments->set_names(Array::Handle(isolate(), Array::MakeArray(names))); | 8364 arguments->set_names(Array::Handle(I, Array::MakeArray(names))); |
| 8376 } | 8365 } |
| 8377 return arguments; | 8366 return arguments; |
| 8378 } | 8367 } |
| 8379 | 8368 |
| 8380 | 8369 |
| 8381 AstNode* Parser::ParseStaticCall(const Class& cls, | 8370 AstNode* Parser::ParseStaticCall(const Class& cls, |
| 8382 const String& func_name, | 8371 const String& func_name, |
| 8383 intptr_t ident_pos) { | 8372 intptr_t ident_pos) { |
| 8384 TRACE_PARSER("ParseStaticCall"); | 8373 TRACE_PARSER("ParseStaticCall"); |
| 8385 const intptr_t call_pos = TokenPos(); | 8374 const intptr_t call_pos = TokenPos(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 8401 // No field, check if we have an explicit getter function. | 8390 // No field, check if we have an explicit getter function. |
| 8402 const String& getter_name = | 8391 const String& getter_name = |
| 8403 String::ZoneHandle(I, Field::GetterName(func_name)); | 8392 String::ZoneHandle(I, Field::GetterName(func_name)); |
| 8404 const int kNumArguments = 0; // no arguments. | 8393 const int kNumArguments = 0; // no arguments. |
| 8405 func = Resolver::ResolveStatic(cls, | 8394 func = Resolver::ResolveStatic(cls, |
| 8406 getter_name, | 8395 getter_name, |
| 8407 kNumArguments, | 8396 kNumArguments, |
| 8408 Object::empty_array()); | 8397 Object::empty_array()); |
| 8409 if (!func.IsNull()) { | 8398 if (!func.IsNull()) { |
| 8410 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 8399 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 8411 closure = new(isolate()) StaticGetterNode( | 8400 closure = new(I) StaticGetterNode( |
| 8412 call_pos, | 8401 call_pos, |
| 8413 NULL, | 8402 NULL, |
| 8414 false, | 8403 false, |
| 8415 Class::ZoneHandle(I, cls.raw()), | 8404 Class::ZoneHandle(I, cls.raw()), |
| 8416 func_name); | 8405 func_name); |
| 8417 return BuildClosureCall(call_pos, closure, arguments); | 8406 return BuildClosureCall(call_pos, closure, arguments); |
| 8418 } | 8407 } |
| 8419 } else { | 8408 } else { |
| 8420 closure = GenerateStaticFieldLookup(field, call_pos); | 8409 closure = GenerateStaticFieldLookup(field, call_pos); |
| 8421 return BuildClosureCall(call_pos, closure, arguments); | 8410 return BuildClosureCall(call_pos, closure, arguments); |
| 8422 } | 8411 } |
| 8423 // Could not resolve static method: throw a NoSuchMethodError. | 8412 // Could not resolve static method: throw a NoSuchMethodError. |
| 8424 return ThrowNoSuchMethodError(ident_pos, | 8413 return ThrowNoSuchMethodError(ident_pos, |
| 8425 cls, | 8414 cls, |
| 8426 func_name, | 8415 func_name, |
| 8427 arguments, | 8416 arguments, |
| 8428 InvocationMirror::kStatic, | 8417 InvocationMirror::kStatic, |
| 8429 InvocationMirror::kMethod, | 8418 InvocationMirror::kMethod, |
| 8430 NULL); // No existing function. | 8419 NULL); // No existing function. |
| 8431 } else if (cls.IsTopLevel() && | 8420 } else if (cls.IsTopLevel() && |
| 8432 (cls.library() == Library::CoreLibrary()) && | 8421 (cls.library() == Library::CoreLibrary()) && |
| 8433 (func.name() == Symbols::Identical().raw())) { | 8422 (func.name() == Symbols::Identical().raw())) { |
| 8434 // This is the predefined toplevel function identical(a,b). | 8423 // This is the predefined toplevel function identical(a,b). |
| 8435 // Create a comparison node instead of a static call to the function, unless | 8424 // Create a comparison node instead of a static call to the function, unless |
| 8436 // javascript warnings are desired and identical is not invoked from a patch | 8425 // javascript warnings are desired and identical is not invoked from a patch |
| 8437 // source. | 8426 // source. |
| 8438 if (!FLAG_warn_on_javascript_compatibility || is_patch_source()) { | 8427 if (!FLAG_warn_on_javascript_compatibility || is_patch_source()) { |
| 8439 ASSERT(num_arguments == 2); | 8428 ASSERT(num_arguments == 2); |
| 8440 return new(isolate()) ComparisonNode(ident_pos, | 8429 return new(I) ComparisonNode(ident_pos, |
| 8441 Token::kEQ_STRICT, | 8430 Token::kEQ_STRICT, |
| 8442 arguments->NodeAt(0), | 8431 arguments->NodeAt(0), |
| 8443 arguments->NodeAt(1)); | 8432 arguments->NodeAt(1)); |
| 8444 } | 8433 } |
| 8445 } | 8434 } |
| 8446 return new(isolate()) StaticCallNode(call_pos, func, arguments); | 8435 return new(I) StaticCallNode(call_pos, func, arguments); |
| 8447 } | 8436 } |
| 8448 | 8437 |
| 8449 | 8438 |
| 8450 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { | 8439 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { |
| 8451 TRACE_PARSER("ParseInstanceCall"); | 8440 TRACE_PARSER("ParseInstanceCall"); |
| 8452 const intptr_t call_pos = TokenPos(); | 8441 const intptr_t call_pos = TokenPos(); |
| 8453 CheckToken(Token::kLPAREN); | 8442 CheckToken(Token::kLPAREN); |
| 8454 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 8443 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 8455 return new(isolate()) InstanceCallNode( | 8444 return new(I) InstanceCallNode(call_pos, receiver, func_name, arguments); |
| 8456 call_pos, receiver, func_name, arguments); | |
| 8457 } | 8445 } |
| 8458 | 8446 |
| 8459 | 8447 |
| 8460 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 8448 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
| 8461 TRACE_PARSER("ParseClosureCall"); | 8449 TRACE_PARSER("ParseClosureCall"); |
| 8462 const intptr_t call_pos = TokenPos(); | 8450 const intptr_t call_pos = TokenPos(); |
| 8463 ASSERT(CurrentToken() == Token::kLPAREN); | 8451 ASSERT(CurrentToken() == Token::kLPAREN); |
| 8464 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 8452 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 8465 return BuildClosureCall(call_pos, closure, arguments); | 8453 return BuildClosureCall(call_pos, closure, arguments); |
| 8466 } | 8454 } |
| 8467 | 8455 |
| 8468 | 8456 |
| 8469 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 8457 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
| 8470 intptr_t ident_pos) { | 8458 intptr_t ident_pos) { |
| 8471 // If the static field has an initializer, initialize the field at compile | 8459 // If the static field has an initializer, initialize the field at compile |
| 8472 // time, which is only possible if the field is const. | 8460 // time, which is only possible if the field is const. |
| 8473 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 8461 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
| 8474 if (initializing_getter != NULL) { | 8462 if (initializing_getter != NULL) { |
| 8475 // The field is not yet initialized and could not be initialized at compile | 8463 // The field is not yet initialized and could not be initialized at compile |
| 8476 // time. The getter will initialize the field. | 8464 // time. The getter will initialize the field. |
| 8477 return initializing_getter; | 8465 return initializing_getter; |
| 8478 } | 8466 } |
| 8479 // The field is initialized. | 8467 // The field is initialized. |
| 8480 ASSERT(field.is_static()); | 8468 ASSERT(field.is_static()); |
| 8481 const Class& field_owner = Class::ZoneHandle(I, field.owner()); | 8469 const Class& field_owner = Class::ZoneHandle(I, field.owner()); |
| 8482 const String& field_name = String::ZoneHandle(I, field.name()); | 8470 const String& field_name = String::ZoneHandle(I, field.name()); |
| 8483 const String& getter_name = String::Handle(isolate(), | 8471 const String& getter_name = String::Handle(I, Field::GetterName(field_name)); |
| 8484 Field::GetterName(field_name)); | 8472 const Function& getter = Function::Handle(I, |
| 8485 const Function& getter = Function::Handle(isolate(), | |
| 8486 field_owner.LookupStaticFunction(getter_name)); | 8473 field_owner.LookupStaticFunction(getter_name)); |
| 8487 // Never load field directly if there is a getter (deterministic AST). | 8474 // Never load field directly if there is a getter (deterministic AST). |
| 8488 if (getter.IsNull() || field.is_const()) { | 8475 if (getter.IsNull() || field.is_const()) { |
| 8489 return new(isolate()) LoadStaticFieldNode( | 8476 return new(I) LoadStaticFieldNode( |
| 8490 ident_pos, Field::ZoneHandle(I, field.raw())); | 8477 ident_pos, Field::ZoneHandle(I, field.raw())); |
| 8491 } else { | 8478 } else { |
| 8492 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); | 8479 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 8493 return new(isolate()) StaticGetterNode(ident_pos, | 8480 return new(I) StaticGetterNode(ident_pos, |
| 8494 NULL, // Receiver. | 8481 NULL, // Receiver. |
| 8495 false, // is_super_getter. | 8482 false, // is_super_getter. |
| 8496 field_owner, | 8483 field_owner, |
| 8497 field_name); | 8484 field_name); |
| 8498 } | 8485 } |
| 8499 } | 8486 } |
| 8500 | 8487 |
| 8501 | 8488 |
| 8502 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 8489 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
| 8503 const String& field_name, | 8490 const String& field_name, |
| 8504 intptr_t ident_pos, | 8491 intptr_t ident_pos, |
| 8505 bool consume_cascades) { | 8492 bool consume_cascades) { |
| 8506 TRACE_PARSER("ParseStaticFieldAccess"); | 8493 TRACE_PARSER("ParseStaticFieldAccess"); |
| 8507 AstNode* access = NULL; | 8494 AstNode* access = NULL; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 8529 // a setter call, or else the backend will generate | 8516 // a setter call, or else the backend will generate |
| 8530 // a throw NoSuchMethodError(). | 8517 // a throw NoSuchMethodError(). |
| 8531 access = new(I) StaticGetterNode(ident_pos, | 8518 access = new(I) StaticGetterNode(ident_pos, |
| 8532 NULL, | 8519 NULL, |
| 8533 false, | 8520 false, |
| 8534 Class::ZoneHandle(I, cls.raw()), | 8521 Class::ZoneHandle(I, cls.raw()), |
| 8535 field_name); | 8522 field_name); |
| 8536 } | 8523 } |
| 8537 } else { | 8524 } else { |
| 8538 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 8525 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 8539 access = new(isolate()) StaticGetterNode( | 8526 access = new(I) StaticGetterNode( |
| 8540 ident_pos, NULL, false, Class::ZoneHandle(I, cls.raw()), field_name); | 8527 ident_pos, NULL, false, Class::ZoneHandle(I, cls.raw()), field_name); |
| 8541 } | 8528 } |
| 8542 } else { | 8529 } else { |
| 8543 access = GenerateStaticFieldLookup(field, ident_pos); | 8530 access = GenerateStaticFieldLookup(field, ident_pos); |
| 8544 } | 8531 } |
| 8545 return access; | 8532 return access; |
| 8546 } | 8533 } |
| 8547 | 8534 |
| 8548 | 8535 |
| 8549 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 8536 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
| 8550 if (!node->IsPrimaryNode()) { | 8537 if (!node->IsPrimaryNode()) { |
| 8551 return node; | 8538 return node; |
| 8552 } | 8539 } |
| 8553 PrimaryNode* primary = node->AsPrimaryNode(); | 8540 PrimaryNode* primary = node->AsPrimaryNode(); |
| 8554 if (primary->primary().IsString()) { | 8541 if (primary->primary().IsString()) { |
| 8555 if (primary->IsSuper()) { | 8542 if (primary->IsSuper()) { |
| 8556 return primary; | 8543 return primary; |
| 8557 } | 8544 } |
| 8558 // In a static method, evaluation of an unresolved identifier causes a | 8545 // In a static method, evaluation of an unresolved identifier causes a |
| 8559 // NoSuchMethodError to be thrown. | 8546 // NoSuchMethodError to be thrown. |
| 8560 // In an instance method, we convert this into a getter call | 8547 // In an instance method, we convert this into a getter call |
| 8561 // for a field (which may be defined in a subclass.) | 8548 // for a field (which may be defined in a subclass.) |
| 8562 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 8549 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
| 8563 if (current_function().is_static() || | 8550 if (current_function().is_static() || |
| 8564 current_function().IsInFactoryScope()) { | 8551 current_function().IsInFactoryScope()) { |
| 8565 StaticGetterNode* getter = | 8552 StaticGetterNode* getter = new(I) StaticGetterNode( |
| 8566 new(isolate()) StaticGetterNode( | 8553 primary->token_pos(), |
| 8567 primary->token_pos(), | 8554 NULL, // No receiver. |
| 8568 NULL, // No receiver. | 8555 false, // Not a super getter. |
| 8569 false, // Not a super getter. | 8556 Class::ZoneHandle(I, current_class().raw()), |
| 8570 Class::ZoneHandle(I, current_class().raw()), | 8557 name); |
| 8571 name); | |
| 8572 getter->set_is_deferred(primary->is_deferred_reference()); | 8558 getter->set_is_deferred(primary->is_deferred_reference()); |
| 8573 return getter; | 8559 return getter; |
| 8574 } else { | 8560 } else { |
| 8575 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8561 AstNode* receiver = LoadReceiver(primary->token_pos()); |
| 8576 return CallGetter(node->token_pos(), receiver, name); | 8562 return CallGetter(node->token_pos(), receiver, name); |
| 8577 } | 8563 } |
| 8578 } | 8564 } |
| 8579 return primary; | 8565 return primary; |
| 8580 } | 8566 } |
| 8581 | 8567 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8629 if (current_block_->scope->function_level() > 0) { | 8615 if (current_block_->scope->function_level() > 0) { |
| 8630 // Make sure that the instantiator is captured. | 8616 // Make sure that the instantiator is captured. |
| 8631 CaptureInstantiator(); | 8617 CaptureInstantiator(); |
| 8632 } | 8618 } |
| 8633 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 8619 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); |
| 8634 type_parameter ^= ClassFinalizer::FinalizeType( | 8620 type_parameter ^= ClassFinalizer::FinalizeType( |
| 8635 current_class(), | 8621 current_class(), |
| 8636 TypeParameter::Cast(primary_node->primary()), | 8622 TypeParameter::Cast(primary_node->primary()), |
| 8637 ClassFinalizer::kCanonicalize); | 8623 ClassFinalizer::kCanonicalize); |
| 8638 ASSERT(!type_parameter.IsMalformed()); | 8624 ASSERT(!type_parameter.IsMalformed()); |
| 8639 left = new(isolate()) TypeNode(primary->token_pos(), type_parameter); | 8625 left = new(I) TypeNode(primary->token_pos(), type_parameter); |
| 8640 } else { | 8626 } else { |
| 8641 // Super field access handled in ParseSuperFieldAccess(), | 8627 // Super field access handled in ParseSuperFieldAccess(), |
| 8642 // super calls handled in ParseSuperCall(). | 8628 // super calls handled in ParseSuperCall(). |
| 8643 ASSERT(!primary_node->IsSuper()); | 8629 ASSERT(!primary_node->IsSuper()); |
| 8644 left = LoadFieldIfUnresolved(left); | 8630 left = LoadFieldIfUnresolved(left); |
| 8645 } | 8631 } |
| 8646 } | 8632 } |
| 8647 const intptr_t ident_pos = TokenPos(); | 8633 const intptr_t ident_pos = TokenPos(); |
| 8648 String* ident = ExpectIdentifier("identifier expected"); | 8634 String* ident = ExpectIdentifier("identifier expected"); |
| 8649 if (CurrentToken() == Token::kLPAREN) { | 8635 if (CurrentToken() == Token::kLPAREN) { |
| 8650 // Identifier followed by a opening paren: method call. | 8636 // Identifier followed by a opening paren: method call. |
| 8651 if (left->IsPrimaryNode() && | 8637 if (left->IsPrimaryNode() && |
| 8652 left->AsPrimaryNode()->primary().IsClass()) { | 8638 left->AsPrimaryNode()->primary().IsClass()) { |
| 8653 // Static method call prefixed with class name. | 8639 // Static method call prefixed with class name. |
| 8654 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | 8640 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); |
| 8655 selector = ParseStaticCall(cls, *ident, ident_pos); | 8641 selector = ParseStaticCall(cls, *ident, ident_pos); |
| 8656 } else { | 8642 } else { |
| 8657 selector = ParseInstanceCall(left, *ident); | 8643 selector = ParseInstanceCall(left, *ident); |
| 8658 } | 8644 } |
| 8659 } else { | 8645 } else { |
| 8660 // Field access. | 8646 // Field access. |
| 8661 Class& cls = Class::Handle(isolate()); | 8647 Class& cls = Class::Handle(I); |
| 8662 if (left->IsPrimaryNode()) { | 8648 if (left->IsPrimaryNode()) { |
| 8663 PrimaryNode* primary_node = left->AsPrimaryNode(); | 8649 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 8664 if (primary_node->primary().IsClass()) { | 8650 if (primary_node->primary().IsClass()) { |
| 8665 // If the primary node referred to a class we are loading a | 8651 // If the primary node referred to a class we are loading a |
| 8666 // qualified static field. | 8652 // qualified static field. |
| 8667 cls ^= primary_node->primary().raw(); | 8653 cls ^= primary_node->primary().raw(); |
| 8668 } | 8654 } |
| 8669 } | 8655 } |
| 8670 if (cls.IsNull()) { | 8656 if (cls.IsNull()) { |
| 8671 // Instance field access. | 8657 // Instance field access. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 8689 ExpectToken(Token::kRBRACK); | 8675 ExpectToken(Token::kRBRACK); |
| 8690 AstNode* array = left; | 8676 AstNode* array = left; |
| 8691 if (left->IsPrimaryNode()) { | 8677 if (left->IsPrimaryNode()) { |
| 8692 PrimaryNode* primary_node = left->AsPrimaryNode(); | 8678 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 8693 const intptr_t primary_pos = primary_node->token_pos(); | 8679 const intptr_t primary_pos = primary_node->token_pos(); |
| 8694 if (primary_node->primary().IsFunction()) { | 8680 if (primary_node->primary().IsFunction()) { |
| 8695 array = LoadClosure(primary_node); | 8681 array = LoadClosure(primary_node); |
| 8696 } else if (primary_node->primary().IsClass()) { | 8682 } else if (primary_node->primary().IsClass()) { |
| 8697 const Class& type_class = Class::Cast(primary_node->primary()); | 8683 const Class& type_class = Class::Cast(primary_node->primary()); |
| 8698 AbstractType& type = Type::ZoneHandle(I, | 8684 AbstractType& type = Type::ZoneHandle(I, |
| 8699 Type::New(type_class, TypeArguments::Handle(isolate()), | 8685 Type::New(type_class, TypeArguments::Handle(I), |
| 8700 primary_pos, Heap::kOld)); | 8686 primary_pos, Heap::kOld)); |
| 8701 type ^= ClassFinalizer::FinalizeType( | 8687 type ^= ClassFinalizer::FinalizeType( |
| 8702 current_class(), type, ClassFinalizer::kCanonicalize); | 8688 current_class(), type, ClassFinalizer::kCanonicalize); |
| 8703 // Type may be malbounded, but not malformed. | 8689 // Type may be malbounded, but not malformed. |
| 8704 ASSERT(!type.IsMalformed()); | 8690 ASSERT(!type.IsMalformed()); |
| 8705 array = new(isolate()) TypeNode(primary_pos, type); | 8691 array = new(I) TypeNode(primary_pos, type); |
| 8706 } else if (primary_node->primary().IsTypeParameter()) { | 8692 } else if (primary_node->primary().IsTypeParameter()) { |
| 8707 if (current_function().is_static()) { | 8693 if (current_function().is_static()) { |
| 8708 const String& name = String::ZoneHandle(I, | 8694 const String& name = String::ZoneHandle(I, |
| 8709 TypeParameter::Cast(primary_node->primary()).name()); | 8695 TypeParameter::Cast(primary_node->primary()).name()); |
| 8710 ErrorMsg(primary_pos, | 8696 ErrorMsg(primary_pos, |
| 8711 "cannot access type parameter '%s' from static function", | 8697 "cannot access type parameter '%s' from static function", |
| 8712 name.ToCString()); | 8698 name.ToCString()); |
| 8713 } | 8699 } |
| 8714 if (current_block_->scope->function_level() > 0) { | 8700 if (current_block_->scope->function_level() > 0) { |
| 8715 // Make sure that the instantiator is captured. | 8701 // Make sure that the instantiator is captured. |
| 8716 CaptureInstantiator(); | 8702 CaptureInstantiator(); |
| 8717 } | 8703 } |
| 8718 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 8704 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); |
| 8719 type_parameter ^= ClassFinalizer::FinalizeType( | 8705 type_parameter ^= ClassFinalizer::FinalizeType( |
| 8720 current_class(), | 8706 current_class(), |
| 8721 TypeParameter::Cast(primary_node->primary()), | 8707 TypeParameter::Cast(primary_node->primary()), |
| 8722 ClassFinalizer::kCanonicalize); | 8708 ClassFinalizer::kCanonicalize); |
| 8723 ASSERT(!type_parameter.IsMalformed()); | 8709 ASSERT(!type_parameter.IsMalformed()); |
| 8724 array = new(isolate()) TypeNode(primary_pos, type_parameter); | 8710 array = new(I) TypeNode(primary_pos, type_parameter); |
| 8725 } else { | 8711 } else { |
| 8726 UNREACHABLE(); // Internal parser error. | 8712 UNREACHABLE(); // Internal parser error. |
| 8727 } | 8713 } |
| 8728 } | 8714 } |
| 8729 selector = new(isolate()) LoadIndexedNode( | 8715 selector = new(I) LoadIndexedNode( |
| 8730 bracket_pos, array, index, Class::ZoneHandle(I)); | 8716 bracket_pos, array, index, Class::ZoneHandle(I)); |
| 8731 } else if (CurrentToken() == Token::kLPAREN) { | 8717 } else if (CurrentToken() == Token::kLPAREN) { |
| 8732 if (left->IsPrimaryNode()) { | 8718 if (left->IsPrimaryNode()) { |
| 8733 PrimaryNode* primary_node = left->AsPrimaryNode(); | 8719 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 8734 const intptr_t primary_pos = primary_node->token_pos(); | 8720 const intptr_t primary_pos = primary_node->token_pos(); |
| 8735 if (primary_node->primary().IsFunction()) { | 8721 if (primary_node->primary().IsFunction()) { |
| 8736 const Function& func = Function::Cast(primary_node->primary()); | 8722 const Function& func = Function::Cast(primary_node->primary()); |
| 8737 const String& func_name = String::ZoneHandle(I, func.name()); | 8723 const String& func_name = String::ZoneHandle(I, func.name()); |
| 8738 if (func.is_static()) { | 8724 if (func.is_static()) { |
| 8739 // Parse static function call. | 8725 // Parse static function call. |
| 8740 Class& cls = Class::Handle(isolate(), func.Owner()); | 8726 Class& cls = Class::Handle(I, func.Owner()); |
| 8741 selector = ParseStaticCall(cls, func_name, primary_pos); | 8727 selector = ParseStaticCall(cls, func_name, primary_pos); |
| 8742 } else { | 8728 } else { |
| 8743 // Dynamic function call on implicit "this" parameter. | 8729 // Dynamic function call on implicit "this" parameter. |
| 8744 if (current_function().is_static()) { | 8730 if (current_function().is_static()) { |
| 8745 ErrorMsg(primary_pos, | 8731 ErrorMsg(primary_pos, |
| 8746 "cannot access instance method '%s' " | 8732 "cannot access instance method '%s' " |
| 8747 "from static function", | 8733 "from static function", |
| 8748 func_name.ToCString()); | 8734 func_name.ToCString()); |
| 8749 } | 8735 } |
| 8750 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); | 8736 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 8776 ErrorMsg(primary_pos, | 8762 ErrorMsg(primary_pos, |
| 8777 "cannot access type parameter '%s' from static function", | 8763 "cannot access type parameter '%s' from static function", |
| 8778 name.ToCString()); | 8764 name.ToCString()); |
| 8779 } else { | 8765 } else { |
| 8780 // Treat as call to unresolved (instance) method. | 8766 // Treat as call to unresolved (instance) method. |
| 8781 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); | 8767 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); |
| 8782 } | 8768 } |
| 8783 } else if (primary_node->primary().IsClass()) { | 8769 } else if (primary_node->primary().IsClass()) { |
| 8784 const Class& type_class = Class::Cast(primary_node->primary()); | 8770 const Class& type_class = Class::Cast(primary_node->primary()); |
| 8785 AbstractType& type = Type::ZoneHandle(I, Type::New( | 8771 AbstractType& type = Type::ZoneHandle(I, Type::New( |
| 8786 type_class, TypeArguments::Handle(isolate()), primary_pos)); | 8772 type_class, TypeArguments::Handle(I), primary_pos)); |
| 8787 type ^= ClassFinalizer::FinalizeType( | 8773 type ^= ClassFinalizer::FinalizeType( |
| 8788 current_class(), type, ClassFinalizer::kCanonicalize); | 8774 current_class(), type, ClassFinalizer::kCanonicalize); |
| 8789 // Type may be malbounded, but not malformed. | 8775 // Type may be malbounded, but not malformed. |
| 8790 ASSERT(!type.IsMalformed()); | 8776 ASSERT(!type.IsMalformed()); |
| 8791 selector = new(isolate()) TypeNode(primary_pos, type); | 8777 selector = new(I) TypeNode(primary_pos, type); |
| 8792 } else { | 8778 } else { |
| 8793 UNREACHABLE(); // Internal parser error. | 8779 UNREACHABLE(); // Internal parser error. |
| 8794 } | 8780 } |
| 8795 } else { | 8781 } else { |
| 8796 // Left is not a primary node; this must be a closure call. | 8782 // Left is not a primary node; this must be a closure call. |
| 8797 AstNode* closure = left; | 8783 AstNode* closure = left; |
| 8798 selector = ParseClosureCall(closure); | 8784 selector = ParseClosureCall(closure); |
| 8799 } | 8785 } |
| 8800 } else { | 8786 } else { |
| 8801 // No (more) selectors to parse. | 8787 // No (more) selectors to parse. |
| 8802 left = LoadFieldIfUnresolved(left); | 8788 left = LoadFieldIfUnresolved(left); |
| 8803 if (left->IsPrimaryNode()) { | 8789 if (left->IsPrimaryNode()) { |
| 8804 PrimaryNode* primary_node = left->AsPrimaryNode(); | 8790 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 8805 const intptr_t primary_pos = primary->token_pos(); | 8791 const intptr_t primary_pos = primary->token_pos(); |
| 8806 if (primary_node->primary().IsFunction()) { | 8792 if (primary_node->primary().IsFunction()) { |
| 8807 // Treat as implicit closure. | 8793 // Treat as implicit closure. |
| 8808 left = LoadClosure(primary_node); | 8794 left = LoadClosure(primary_node); |
| 8809 } else if (primary_node->primary().IsClass()) { | 8795 } else if (primary_node->primary().IsClass()) { |
| 8810 const Class& type_class = Class::Cast(primary_node->primary()); | 8796 const Class& type_class = Class::Cast(primary_node->primary()); |
| 8811 AbstractType& type = Type::ZoneHandle(I, Type::New( | 8797 AbstractType& type = Type::ZoneHandle(I, Type::New( |
| 8812 type_class, TypeArguments::Handle(isolate()), primary_pos)); | 8798 type_class, TypeArguments::Handle(I), primary_pos)); |
| 8813 type = ClassFinalizer::FinalizeType( | 8799 type = ClassFinalizer::FinalizeType( |
| 8814 current_class(), type, ClassFinalizer::kCanonicalize); | 8800 current_class(), type, ClassFinalizer::kCanonicalize); |
| 8815 // Type may be malbounded, but not malformed. | 8801 // Type may be malbounded, but not malformed. |
| 8816 ASSERT(!type.IsMalformed()); | 8802 ASSERT(!type.IsMalformed()); |
| 8817 left = new(isolate()) TypeNode(primary_pos, type); | 8803 left = new(I) TypeNode(primary_pos, type); |
| 8818 } else if (primary_node->primary().IsTypeParameter()) { | 8804 } else if (primary_node->primary().IsTypeParameter()) { |
| 8819 if (current_function().is_static()) { | 8805 if (current_function().is_static()) { |
| 8820 const String& name = String::ZoneHandle(I, | 8806 const String& name = String::ZoneHandle(I, |
| 8821 TypeParameter::Cast(primary_node->primary()).name()); | 8807 TypeParameter::Cast(primary_node->primary()).name()); |
| 8822 ErrorMsg(primary_pos, | 8808 ErrorMsg(primary_pos, |
| 8823 "cannot access type parameter '%s' from static function", | 8809 "cannot access type parameter '%s' from static function", |
| 8824 name.ToCString()); | 8810 name.ToCString()); |
| 8825 } | 8811 } |
| 8826 if (current_block_->scope->function_level() > 0) { | 8812 if (current_block_->scope->function_level() > 0) { |
| 8827 // Make sure that the instantiator is captured. | 8813 // Make sure that the instantiator is captured. |
| 8828 CaptureInstantiator(); | 8814 CaptureInstantiator(); |
| 8829 } | 8815 } |
| 8830 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 8816 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); |
| 8831 type_parameter ^= ClassFinalizer::FinalizeType( | 8817 type_parameter ^= ClassFinalizer::FinalizeType( |
| 8832 current_class(), | 8818 current_class(), |
| 8833 TypeParameter::Cast(primary_node->primary()), | 8819 TypeParameter::Cast(primary_node->primary()), |
| 8834 ClassFinalizer::kCanonicalize); | 8820 ClassFinalizer::kCanonicalize); |
| 8835 ASSERT(!type_parameter.IsMalformed()); | 8821 ASSERT(!type_parameter.IsMalformed()); |
| 8836 left = new(isolate()) TypeNode(primary_pos, type_parameter); | 8822 left = new(I) TypeNode(primary_pos, type_parameter); |
| 8837 } else if (primary_node->IsSuper()) { | 8823 } else if (primary_node->IsSuper()) { |
| 8838 // Return "super" to handle unary super operator calls, | 8824 // Return "super" to handle unary super operator calls, |
| 8839 // or to report illegal use of "super" otherwise. | 8825 // or to report illegal use of "super" otherwise. |
| 8840 left = primary_node; | 8826 left = primary_node; |
| 8841 } else { | 8827 } else { |
| 8842 UNREACHABLE(); // Internal parser error. | 8828 UNREACHABLE(); // Internal parser error. |
| 8843 } | 8829 } |
| 8844 } | 8830 } |
| 8845 // Done parsing selectors. | 8831 // Done parsing selectors. |
| 8846 return left; | 8832 return left; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 8863 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 8849 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 8864 ErrorMsg(expr_pos, "expression is not assignable"); | 8850 ErrorMsg(expr_pos, "expression is not assignable"); |
| 8865 } | 8851 } |
| 8866 Token::Kind incr_op = CurrentToken(); | 8852 Token::Kind incr_op = CurrentToken(); |
| 8867 ConsumeToken(); | 8853 ConsumeToken(); |
| 8868 // Not prefix. | 8854 // Not prefix. |
| 8869 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 8855 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 8870 LocalVariable* temp = let_expr->AddInitializer(expr); | 8856 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 8871 Token::Kind binary_op = | 8857 Token::Kind binary_op = |
| 8872 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 8858 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 8873 BinaryOpNode* add = new(isolate()) BinaryOpNode( | 8859 BinaryOpNode* add = new(I) BinaryOpNode( |
| 8874 expr_pos, | 8860 expr_pos, |
| 8875 binary_op, | 8861 binary_op, |
| 8876 new(isolate()) LoadLocalNode(expr_pos, temp), | 8862 new(I) LoadLocalNode(expr_pos, temp), |
| 8877 new(isolate()) LiteralNode(expr_pos, Smi::ZoneHandle(I, Smi::New(1)))); | 8863 new(I) LiteralNode(expr_pos, Smi::ZoneHandle(I, Smi::New(1)))); |
| 8878 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 8864 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); |
| 8879 ASSERT(store != NULL); | 8865 ASSERT(store != NULL); |
| 8880 // The result is a pair of the (side effects of the) store followed by | 8866 // The result is a pair of the (side effects of the) store followed by |
| 8881 // the (value of the) initial value temp variable load. | 8867 // the (value of the) initial value temp variable load. |
| 8882 let_expr->AddNode(store); | 8868 let_expr->AddNode(store); |
| 8883 let_expr->AddNode(new(isolate()) LoadLocalNode(expr_pos, temp)); | 8869 let_expr->AddNode(new(I) LoadLocalNode(expr_pos, temp)); |
| 8884 return let_expr; | 8870 return let_expr; |
| 8885 } | 8871 } |
| 8886 return expr; | 8872 return expr; |
| 8887 } | 8873 } |
| 8888 | 8874 |
| 8889 | 8875 |
| 8890 // Resolve the given type and its type arguments from the given scope class | 8876 // Resolve the given type and its type arguments from the given scope class |
| 8891 // according to the given type finalization mode. | 8877 // according to the given type finalization mode. |
| 8892 // If the given scope class is null, use the current library, but do not try to | 8878 // If the given scope class is null, use the current library, but do not try to |
| 8893 // resolve type parameters. | 8879 // resolve type parameters. |
| 8894 // Not all involved type classes may get resolved yet, but at least the type | 8880 // Not all involved type classes may get resolved yet, but at least the type |
| 8895 // parameters of the given class will get resolved, thereby relieving the class | 8881 // parameters of the given class will get resolved, thereby relieving the class |
| 8896 // finalizer from resolving type parameters out of context. | 8882 // finalizer from resolving type parameters out of context. |
| 8897 void Parser::ResolveTypeFromClass(const Class& scope_class, | 8883 void Parser::ResolveTypeFromClass(const Class& scope_class, |
| 8898 ClassFinalizer::FinalizationKind finalization, | 8884 ClassFinalizer::FinalizationKind finalization, |
| 8899 AbstractType* type) { | 8885 AbstractType* type) { |
| 8900 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); | 8886 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); |
| 8901 ASSERT(type != NULL); | 8887 ASSERT(type != NULL); |
| 8902 if (type->IsResolved()) { | 8888 if (type->IsResolved()) { |
| 8903 return; | 8889 return; |
| 8904 } | 8890 } |
| 8905 // Resolve class. | 8891 // Resolve class. |
| 8906 if (!type->HasResolvedTypeClass()) { | 8892 if (!type->HasResolvedTypeClass()) { |
| 8907 const UnresolvedClass& unresolved_class = | 8893 const UnresolvedClass& unresolved_class = |
| 8908 UnresolvedClass::Handle(isolate(), type->unresolved_class()); | 8894 UnresolvedClass::Handle(I, type->unresolved_class()); |
| 8909 const String& unresolved_class_name = | 8895 const String& unresolved_class_name = |
| 8910 String::Handle(isolate(), unresolved_class.ident()); | 8896 String::Handle(I, unresolved_class.ident()); |
| 8911 Class& resolved_type_class = Class::Handle(isolate()); | 8897 Class& resolved_type_class = Class::Handle(I); |
| 8912 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 8898 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 8913 if (!scope_class.IsNull()) { | 8899 if (!scope_class.IsNull()) { |
| 8914 // First check if the type is a type parameter of the given scope class. | 8900 // First check if the type is a type parameter of the given scope class. |
| 8915 const TypeParameter& type_parameter = TypeParameter::Handle( | 8901 const TypeParameter& type_parameter = TypeParameter::Handle(I, |
| 8916 isolate(), | |
| 8917 scope_class.LookupTypeParameter(unresolved_class_name)); | 8902 scope_class.LookupTypeParameter(unresolved_class_name)); |
| 8918 if (!type_parameter.IsNull()) { | 8903 if (!type_parameter.IsNull()) { |
| 8919 // A type parameter is considered to be a malformed type when | 8904 // A type parameter is considered to be a malformed type when |
| 8920 // referenced by a static member. | 8905 // referenced by a static member. |
| 8921 if (ParsingStaticMember()) { | 8906 if (ParsingStaticMember()) { |
| 8922 ASSERT(scope_class.raw() == current_class().raw()); | 8907 ASSERT(scope_class.raw() == current_class().raw()); |
| 8923 *type = ClassFinalizer::NewFinalizedMalformedType( | 8908 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 8924 Error::Handle(isolate()), // No previous error. | 8909 Error::Handle(I), // No previous error. |
| 8925 script_, | 8910 script_, |
| 8926 type->token_pos(), | 8911 type->token_pos(), |
| 8927 "type parameter '%s' cannot be referenced " | 8912 "type parameter '%s' cannot be referenced " |
| 8928 "from static member", | 8913 "from static member", |
| 8929 String::Handle(isolate(), type_parameter.name()).ToCString()); | 8914 String::Handle(I, type_parameter.name()).ToCString()); |
| 8930 return; | 8915 return; |
| 8931 } | 8916 } |
| 8932 // A type parameter cannot be parameterized, so make the type | 8917 // A type parameter cannot be parameterized, so make the type |
| 8933 // malformed if type arguments have previously been parsed. | 8918 // malformed if type arguments have previously been parsed. |
| 8934 if (!TypeArguments::Handle(isolate(), type->arguments()).IsNull()) { | 8919 if (!TypeArguments::Handle(I, type->arguments()).IsNull()) { |
| 8935 *type = ClassFinalizer::NewFinalizedMalformedType( | 8920 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 8936 Error::Handle(isolate()), // No previous error. | 8921 Error::Handle(I), // No previous error. |
| 8937 script_, | 8922 script_, |
| 8938 type_parameter.token_pos(), | 8923 type_parameter.token_pos(), |
| 8939 "type parameter '%s' cannot be parameterized", | 8924 "type parameter '%s' cannot be parameterized", |
| 8940 String::Handle(isolate(), type_parameter.name()).ToCString()); | 8925 String::Handle(I, type_parameter.name()).ToCString()); |
| 8941 return; | 8926 return; |
| 8942 } | 8927 } |
| 8943 *type = type_parameter.raw(); | 8928 *type = type_parameter.raw(); |
| 8944 return; | 8929 return; |
| 8945 } | 8930 } |
| 8946 } | 8931 } |
| 8947 // The referenced class may not have been parsed yet. It would be wrong | 8932 // The referenced class may not have been parsed yet. It would be wrong |
| 8948 // to resolve it too early to an imported class of the same name. | 8933 // to resolve it too early to an imported class of the same name. |
| 8949 if (finalization > ClassFinalizer::kResolveTypeParameters) { | 8934 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
| 8950 // Resolve classname in the scope of the current library. | 8935 // Resolve classname in the scope of the current library. |
| 8951 resolved_type_class = ResolveClassInCurrentLibraryScope( | 8936 resolved_type_class = ResolveClassInCurrentLibraryScope( |
| 8952 unresolved_class_name); | 8937 unresolved_class_name); |
| 8953 } | 8938 } |
| 8954 } else { | 8939 } else { |
| 8955 LibraryPrefix& lib_prefix = | 8940 LibraryPrefix& lib_prefix = |
| 8956 LibraryPrefix::Handle(isolate(), unresolved_class.library_prefix()); | 8941 LibraryPrefix::Handle(I, unresolved_class.library_prefix()); |
| 8957 // Resolve class name in the scope of the library prefix. | 8942 // Resolve class name in the scope of the library prefix. |
| 8958 resolved_type_class = | 8943 resolved_type_class = |
| 8959 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); | 8944 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); |
| 8960 } | 8945 } |
| 8961 // At this point, we can only have a parameterized_type. | 8946 // At this point, we can only have a parameterized_type. |
| 8962 const Type& parameterized_type = Type::Cast(*type); | 8947 const Type& parameterized_type = Type::Cast(*type); |
| 8963 if (!resolved_type_class.IsNull()) { | 8948 if (!resolved_type_class.IsNull()) { |
| 8964 // Replace unresolved class with resolved type class. | 8949 // Replace unresolved class with resolved type class. |
| 8965 parameterized_type.set_type_class(resolved_type_class); | 8950 parameterized_type.set_type_class(resolved_type_class); |
| 8966 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 8951 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
| 8967 ClassFinalizer::FinalizeMalformedType( | 8952 ClassFinalizer::FinalizeMalformedType( |
| 8968 Error::Handle(isolate()), // No previous error. | 8953 Error::Handle(I), // No previous error. |
| 8969 script_, | 8954 script_, |
| 8970 parameterized_type, | 8955 parameterized_type, |
| 8971 "type '%s' is not loaded", | 8956 "type '%s' is not loaded", |
| 8972 String::Handle(isolate(), | 8957 String::Handle(I, parameterized_type.UserVisibleName()).ToCString()); |
| 8973 parameterized_type.UserVisibleName()).ToCString()); | |
| 8974 return; | 8958 return; |
| 8975 } | 8959 } |
| 8976 } | 8960 } |
| 8977 // Resolve type arguments, if any. | 8961 // Resolve type arguments, if any. |
| 8978 const TypeArguments& arguments = TypeArguments::Handle(isolate(), | 8962 const TypeArguments& arguments = TypeArguments::Handle(I, type->arguments()); |
| 8979 type->arguments()); | 8963 TypeArguments::Handle(I, type->arguments()); |
| 8980 TypeArguments::Handle(isolate(), type->arguments()); | |
| 8981 if (!arguments.IsNull()) { | 8964 if (!arguments.IsNull()) { |
| 8982 const intptr_t num_arguments = arguments.Length(); | 8965 const intptr_t num_arguments = arguments.Length(); |
| 8983 for (intptr_t i = 0; i < num_arguments; i++) { | 8966 for (intptr_t i = 0; i < num_arguments; i++) { |
| 8984 AbstractType& type_argument = AbstractType::Handle(isolate(), | 8967 AbstractType& type_argument = AbstractType::Handle(I, |
| 8985 arguments.TypeAt(i)); | 8968 arguments.TypeAt(i)); |
| 8986 ResolveTypeFromClass(scope_class, finalization, &type_argument); | 8969 ResolveTypeFromClass(scope_class, finalization, &type_argument); |
| 8987 arguments.SetTypeAt(i, type_argument); | 8970 arguments.SetTypeAt(i, type_argument); |
| 8988 } | 8971 } |
| 8989 } | 8972 } |
| 8990 } | 8973 } |
| 8991 | 8974 |
| 8992 | 8975 |
| 8993 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 8976 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
| 8994 if (current_block_ == NULL) { | 8977 if (current_block_ == NULL) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9050 } | 9033 } |
| 9051 | 9034 |
| 9052 | 9035 |
| 9053 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 9036 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
| 9054 intptr_t token_pos) { | 9037 intptr_t token_pos) { |
| 9055 if (instance.IsNull()) { | 9038 if (instance.IsNull()) { |
| 9056 return instance.raw(); | 9039 return instance.raw(); |
| 9057 } | 9040 } |
| 9058 const char* error_str = NULL; | 9041 const char* error_str = NULL; |
| 9059 Instance& result = | 9042 Instance& result = |
| 9060 Instance::Handle(isolate(), instance.CheckAndCanonicalize(&error_str)); | 9043 Instance::Handle(I, instance.CheckAndCanonicalize(&error_str)); |
| 9061 if (result.IsNull()) { | 9044 if (result.IsNull()) { |
| 9062 ErrorMsg(token_pos, "Invalid const object %s", error_str); | 9045 ErrorMsg(token_pos, "Invalid const object %s", error_str); |
| 9063 } | 9046 } |
| 9064 return result.raw(); | 9047 return result.raw(); |
| 9065 } | 9048 } |
| 9066 | 9049 |
| 9067 | 9050 |
| 9068 // If the field is already initialized, return no ast (NULL). | 9051 // If the field is already initialized, return no ast (NULL). |
| 9069 // Otherwise, if the field is constant, initialize the field and return no ast. | 9052 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 9070 // If the field is not initialized and not const, return the ast for the getter. | 9053 // If the field is not initialized and not const, return the ast for the getter. |
| 9071 AstNode* Parser::RunStaticFieldInitializer(const Field& field, | 9054 AstNode* Parser::RunStaticFieldInitializer(const Field& field, |
| 9072 intptr_t field_ref_pos) { | 9055 intptr_t field_ref_pos) { |
| 9073 ASSERT(field.is_static()); | 9056 ASSERT(field.is_static()); |
| 9074 const Class& field_owner = Class::ZoneHandle(I, field.owner()); | 9057 const Class& field_owner = Class::ZoneHandle(I, field.owner()); |
| 9075 const String& field_name = String::ZoneHandle(I, field.name()); | 9058 const String& field_name = String::ZoneHandle(I, field.name()); |
| 9076 const String& getter_name = String::Handle(isolate(), | 9059 const String& getter_name = String::Handle(I, Field::GetterName(field_name)); |
| 9077 Field::GetterName(field_name)); | 9060 const Function& getter = Function::Handle(I, |
| 9078 const Function& getter = Function::Handle( | 9061 field_owner.LookupStaticFunction(getter_name)); |
| 9079 isolate(), field_owner.LookupStaticFunction(getter_name)); | 9062 const Instance& value = Instance::Handle(I, field.value()); |
| 9080 const Instance& value = Instance::Handle(isolate(), field.value()); | |
| 9081 if (value.raw() == Object::transition_sentinel().raw()) { | 9063 if (value.raw() == Object::transition_sentinel().raw()) { |
| 9082 if (field.is_const()) { | 9064 if (field.is_const()) { |
| 9083 ErrorMsg("circular dependency while initializing static field '%s'", | 9065 ErrorMsg("circular dependency while initializing static field '%s'", |
| 9084 field_name.ToCString()); | 9066 field_name.ToCString()); |
| 9085 } else { | 9067 } else { |
| 9086 // The implicit static getter will throw the exception if necessary. | 9068 // The implicit static getter will throw the exception if necessary. |
| 9087 return new(isolate()) StaticGetterNode( | 9069 return new(I) StaticGetterNode( |
| 9088 field_ref_pos, NULL, false, field_owner, field_name); | 9070 field_ref_pos, NULL, false, field_owner, field_name); |
| 9089 } | 9071 } |
| 9090 } else if (value.raw() == Object::sentinel().raw()) { | 9072 } else if (value.raw() == Object::sentinel().raw()) { |
| 9091 // This field has not been referenced yet and thus the value has | 9073 // This field has not been referenced yet and thus the value has |
| 9092 // not been evaluated. If the field is const, call the static getter method | 9074 // not been evaluated. If the field is const, call the static getter method |
| 9093 // to evaluate the expression and canonicalize the value. | 9075 // to evaluate the expression and canonicalize the value. |
| 9094 if (field.is_const()) { | 9076 if (field.is_const()) { |
| 9095 field.set_value(Object::transition_sentinel()); | 9077 field.set_value(Object::transition_sentinel()); |
| 9096 const int kNumArguments = 0; // no arguments. | 9078 const int kNumArguments = 0; // no arguments. |
| 9097 const Function& func = Function::Handle(isolate(), | 9079 const Function& func = Function::Handle(I, |
| 9098 Resolver::ResolveStatic(field_owner, | 9080 Resolver::ResolveStatic(field_owner, |
| 9099 getter_name, | 9081 getter_name, |
| 9100 kNumArguments, | 9082 kNumArguments, |
| 9101 Object::empty_array())); | 9083 Object::empty_array())); |
| 9102 ASSERT(!func.IsNull()); | 9084 ASSERT(!func.IsNull()); |
| 9103 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); | 9085 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 9104 Object& const_value = Object::Handle(isolate()); | 9086 Object& const_value = Object::Handle(I); |
| 9105 { | 9087 { |
| 9106 PAUSETIMERSCOPE(isolate(), time_compilation); | 9088 PAUSETIMERSCOPE(I, time_compilation); |
| 9107 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); | 9089 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); |
| 9108 } | 9090 } |
| 9109 if (const_value.IsError()) { | 9091 if (const_value.IsError()) { |
| 9110 const Error& error = Error::Cast(const_value); | 9092 const Error& error = Error::Cast(const_value); |
| 9111 if (error.IsUnhandledException()) { | 9093 if (error.IsUnhandledException()) { |
| 9112 // An exception may not occur in every parse attempt, i.e., the | 9094 // An exception may not occur in every parse attempt, i.e., the |
| 9113 // generated AST is not deterministic. Therefore mark the function as | 9095 // generated AST is not deterministic. Therefore mark the function as |
| 9114 // not optimizable. | 9096 // not optimizable. |
| 9115 current_function().SetIsOptimizable(false); | 9097 current_function().SetIsOptimizable(false); |
| 9116 field.set_value(Object::null_instance()); | 9098 field.set_value(Object::null_instance()); |
| 9117 // It is a compile-time error if evaluation of a compile-time constant | 9099 // It is a compile-time error if evaluation of a compile-time constant |
| 9118 // would raise an exception. | 9100 // would raise an exception. |
| 9119 AppendErrorMsg(error, field_ref_pos, | 9101 AppendErrorMsg(error, field_ref_pos, |
| 9120 "error initializing const field '%s'", | 9102 "error initializing const field '%s'", |
| 9121 String::Handle(isolate(), field.name()).ToCString()); | 9103 String::Handle(I, field.name()).ToCString()); |
| 9122 } else { | 9104 } else { |
| 9123 isolate()->long_jump_base()->Jump(1, error); | 9105 I->long_jump_base()->Jump(1, error); |
| 9124 UNREACHABLE(); | 9106 UNREACHABLE(); |
| 9125 } | 9107 } |
| 9126 } | 9108 } |
| 9127 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 9109 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 9128 Instance& instance = Instance::Handle(isolate()); | 9110 Instance& instance = Instance::Handle(I); |
| 9129 instance ^= const_value.raw(); | 9111 instance ^= const_value.raw(); |
| 9130 instance = TryCanonicalize(instance, field_ref_pos); | 9112 instance = TryCanonicalize(instance, field_ref_pos); |
| 9131 field.set_value(instance); | 9113 field.set_value(instance); |
| 9132 return NULL; // Constant | 9114 return NULL; // Constant |
| 9133 } else { | 9115 } else { |
| 9134 return new(isolate()) StaticGetterNode( | 9116 return new(I) StaticGetterNode( |
| 9135 field_ref_pos, NULL, false, field_owner, field_name); | 9117 field_ref_pos, NULL, false, field_owner, field_name); |
| 9136 } | 9118 } |
| 9137 } | 9119 } |
| 9138 if (getter.IsNull() || | 9120 if (getter.IsNull() || |
| 9139 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { | 9121 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
| 9140 return NULL; | 9122 return NULL; |
| 9141 } | 9123 } |
| 9142 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 9124 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
| 9143 return new(isolate()) StaticGetterNode( | 9125 return new(I) StaticGetterNode( |
| 9144 field_ref_pos, NULL, false, field_owner, field_name); | 9126 field_ref_pos, NULL, false, field_owner, field_name); |
| 9145 } | 9127 } |
| 9146 | 9128 |
| 9147 | 9129 |
| 9148 RawObject* Parser::EvaluateConstConstructorCall( | 9130 RawObject* Parser::EvaluateConstConstructorCall( |
| 9149 const Class& type_class, | 9131 const Class& type_class, |
| 9150 const TypeArguments& type_arguments, | 9132 const TypeArguments& type_arguments, |
| 9151 const Function& constructor, | 9133 const Function& constructor, |
| 9152 ArgumentListNode* arguments) { | 9134 ArgumentListNode* arguments) { |
| 9153 // Factories have one extra argument: the type arguments. | 9135 // Factories have one extra argument: the type arguments. |
| 9154 // Constructors have 2 extra arguments: rcvr and construction phase. | 9136 // Constructors have 2 extra arguments: rcvr and construction phase. |
| 9155 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; | 9137 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; |
| 9156 const int num_arguments = arguments->length() + kNumExtraArgs; | 9138 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 9157 const Array& arg_values = Array::Handle(isolate(), | 9139 const Array& arg_values = Array::Handle(I, Array::New(num_arguments)); |
| 9158 Array::New(num_arguments)); | 9140 Instance& instance = Instance::Handle(I); |
| 9159 Instance& instance = Instance::Handle(isolate()); | |
| 9160 if (!constructor.IsFactory()) { | 9141 if (!constructor.IsFactory()) { |
| 9161 instance = Instance::New(type_class, Heap::kOld); | 9142 instance = Instance::New(type_class, Heap::kOld); |
| 9162 if (!type_arguments.IsNull()) { | 9143 if (!type_arguments.IsNull()) { |
| 9163 if (!type_arguments.IsInstantiated()) { | 9144 if (!type_arguments.IsInstantiated()) { |
| 9164 ErrorMsg("type must be constant in const constructor"); | 9145 ErrorMsg("type must be constant in const constructor"); |
| 9165 } | 9146 } |
| 9166 instance.SetTypeArguments( | 9147 instance.SetTypeArguments( |
| 9167 TypeArguments::Handle(isolate(), type_arguments.Canonicalize())); | 9148 TypeArguments::Handle(I, type_arguments.Canonicalize())); |
| 9168 } | 9149 } |
| 9169 arg_values.SetAt(0, instance); | 9150 arg_values.SetAt(0, instance); |
| 9170 arg_values.SetAt(1, Smi::Handle(isolate(), | 9151 arg_values.SetAt(1, Smi::Handle(I, Smi::New(Function::kCtorPhaseAll))); |
| 9171 Smi::New(Function::kCtorPhaseAll))); | |
| 9172 } else { | 9152 } else { |
| 9173 // Prepend type_arguments to list of arguments to factory. | 9153 // Prepend type_arguments to list of arguments to factory. |
| 9174 ASSERT(type_arguments.IsZoneHandle()); | 9154 ASSERT(type_arguments.IsZoneHandle()); |
| 9175 arg_values.SetAt(0, type_arguments); | 9155 arg_values.SetAt(0, type_arguments); |
| 9176 } | 9156 } |
| 9177 for (int i = 0; i < arguments->length(); i++) { | 9157 for (int i = 0; i < arguments->length(); i++) { |
| 9178 AstNode* arg = arguments->NodeAt(i); | 9158 AstNode* arg = arguments->NodeAt(i); |
| 9179 // Arguments have been evaluated to a literal value already. | 9159 // Arguments have been evaluated to a literal value already. |
| 9180 ASSERT(arg->IsLiteralNode()); | 9160 ASSERT(arg->IsLiteralNode()); |
| 9181 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 9161 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
| 9182 } | 9162 } |
| 9183 const Array& args_descriptor = Array::Handle( | 9163 const Array& args_descriptor = Array::Handle(I, |
| 9184 isolate(), ArgumentsDescriptor::New(num_arguments, arguments->names())); | 9164 ArgumentsDescriptor::New(num_arguments, arguments->names())); |
| 9185 Object& result = Object::Handle(isolate()); | 9165 Object& result = Object::Handle(I); |
| 9186 { | 9166 { |
| 9187 PAUSETIMERSCOPE(isolate(), time_compilation); | 9167 PAUSETIMERSCOPE(I, time_compilation); |
| 9188 result = DartEntry::InvokeFunction( | 9168 result = DartEntry::InvokeFunction( |
| 9189 constructor, arg_values, args_descriptor); | 9169 constructor, arg_values, args_descriptor); |
| 9190 } | 9170 } |
| 9191 if (result.IsError()) { | 9171 if (result.IsError()) { |
| 9192 // An exception may not occur in every parse attempt, i.e., the | 9172 // An exception may not occur in every parse attempt, i.e., the |
| 9193 // generated AST is not deterministic. Therefore mark the function as | 9173 // generated AST is not deterministic. Therefore mark the function as |
| 9194 // not optimizable. | 9174 // not optimizable. |
| 9195 current_function().SetIsOptimizable(false); | 9175 current_function().SetIsOptimizable(false); |
| 9196 if (result.IsUnhandledException()) { | 9176 if (result.IsUnhandledException()) { |
| 9197 return result.raw(); | 9177 return result.raw(); |
| 9198 } else { | 9178 } else { |
| 9199 isolate()->long_jump_base()->Jump(1, Error::Cast(result)); | 9179 I->long_jump_base()->Jump(1, Error::Cast(result)); |
| 9200 UNREACHABLE(); | 9180 UNREACHABLE(); |
| 9201 return Object::null(); | 9181 return Object::null(); |
| 9202 } | 9182 } |
| 9203 } else { | 9183 } else { |
| 9204 if (constructor.IsFactory()) { | 9184 if (constructor.IsFactory()) { |
| 9205 // The factory method returns the allocated object. | 9185 // The factory method returns the allocated object. |
| 9206 instance ^= result.raw(); | 9186 instance ^= result.raw(); |
| 9207 } | 9187 } |
| 9208 return TryCanonicalize(instance, TokenPos()); | 9188 return TryCanonicalize(instance, TokenPos()); |
| 9209 } | 9189 } |
| 9210 } | 9190 } |
| 9211 | 9191 |
| 9212 | 9192 |
| 9213 // Do a lookup for the identifier in the block scope and the class scope | 9193 // Do a lookup for the identifier in the block scope and the class scope |
| 9214 // return true if the identifier is found, false otherwise. | 9194 // return true if the identifier is found, false otherwise. |
| 9215 // If node is non NULL return an AST node corresponding to the identifier. | 9195 // If node is non NULL return an AST node corresponding to the identifier. |
| 9216 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 9196 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
| 9217 const String &ident, | 9197 const String &ident, |
| 9218 AstNode** node) { | 9198 AstNode** node) { |
| 9219 TRACE_PARSER("ResolveIdentInLocalScope"); | 9199 TRACE_PARSER("ResolveIdentInLocalScope"); |
| 9220 // First try to find the identifier in the nested local scopes. | 9200 // First try to find the identifier in the nested local scopes. |
| 9221 LocalVariable* local = LookupLocalScope(ident); | 9201 LocalVariable* local = LookupLocalScope(ident); |
| 9222 if (current_block_ != NULL) { | 9202 if (current_block_ != NULL) { |
| 9223 current_block_->scope->AddReferencedName(ident_pos, ident); | 9203 current_block_->scope->AddReferencedName(ident_pos, ident); |
| 9224 } | 9204 } |
| 9225 if (local != NULL) { | 9205 if (local != NULL) { |
| 9226 if (node != NULL) { | 9206 if (node != NULL) { |
| 9227 *node = new(isolate()) LoadLocalNode(ident_pos, local); | 9207 *node = new(I) LoadLocalNode(ident_pos, local); |
| 9228 } | 9208 } |
| 9229 return true; | 9209 return true; |
| 9230 } | 9210 } |
| 9231 | 9211 |
| 9232 // Try to find the identifier in the class scope of the current class. | 9212 // Try to find the identifier in the class scope of the current class. |
| 9233 // If the current class is the result of a mixin application, we must | 9213 // If the current class is the result of a mixin application, we must |
| 9234 // use the class scope of the class from which the function originates. | 9214 // use the class scope of the class from which the function originates. |
| 9235 Class& cls = Class::Handle(isolate()); | 9215 Class& cls = Class::Handle(I); |
| 9236 if (!current_class().IsMixinApplication()) { | 9216 if (!current_class().IsMixinApplication()) { |
| 9237 cls = current_class().raw(); | 9217 cls = current_class().raw(); |
| 9238 } else { | 9218 } else { |
| 9239 cls = parsed_function()->function().origin(); | 9219 cls = parsed_function()->function().origin(); |
| 9240 } | 9220 } |
| 9241 Function& func = Function::Handle(isolate(), Function::null()); | 9221 Function& func = Function::Handle(I, Function::null()); |
| 9242 Field& field = Field::Handle(isolate(), Field::null()); | 9222 Field& field = Field::Handle(I, Field::null()); |
| 9243 | 9223 |
| 9244 // First check if a field exists. | 9224 // First check if a field exists. |
| 9245 field = cls.LookupField(ident); | 9225 field = cls.LookupField(ident); |
| 9246 if (!field.IsNull()) { | 9226 if (!field.IsNull()) { |
| 9247 if (node != NULL) { | 9227 if (node != NULL) { |
| 9248 if (!field.is_static()) { | 9228 if (!field.is_static()) { |
| 9249 CheckInstanceFieldAccess(ident_pos, ident); | 9229 CheckInstanceFieldAccess(ident_pos, ident); |
| 9250 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 9230 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 9251 } else { | 9231 } else { |
| 9252 *node = GenerateStaticFieldLookup(field, ident_pos); | 9232 *node = GenerateStaticFieldLookup(field, ident_pos); |
| 9253 } | 9233 } |
| 9254 } | 9234 } |
| 9255 return true; | 9235 return true; |
| 9256 } | 9236 } |
| 9257 | 9237 |
| 9258 // Check if an instance/static function exists. | 9238 // Check if an instance/static function exists. |
| 9259 func = cls.LookupFunction(ident); | 9239 func = cls.LookupFunction(ident); |
| 9260 if (!func.IsNull() && | 9240 if (!func.IsNull() && |
| 9261 (func.IsDynamicFunction() || | 9241 (func.IsDynamicFunction() || |
| 9262 func.IsStaticFunction() || | 9242 func.IsStaticFunction() || |
| 9263 func.is_abstract())) { | 9243 func.is_abstract())) { |
| 9264 if (node != NULL) { | 9244 if (node != NULL) { |
| 9265 *node = new(isolate()) PrimaryNode( | 9245 *node = new(I) PrimaryNode( |
| 9266 ident_pos, Function::ZoneHandle(I, func.raw())); | 9246 ident_pos, Function::ZoneHandle(I, func.raw())); |
| 9267 } | 9247 } |
| 9268 return true; | 9248 return true; |
| 9269 } | 9249 } |
| 9270 | 9250 |
| 9271 // Now check if a getter/setter method exists for it in which case | 9251 // Now check if a getter/setter method exists for it in which case |
| 9272 // it is still a field. | 9252 // it is still a field. |
| 9273 func = cls.LookupGetterFunction(ident); | 9253 func = cls.LookupGetterFunction(ident); |
| 9274 if (!func.IsNull()) { | 9254 if (!func.IsNull()) { |
| 9275 if (func.IsDynamicFunction() || func.is_abstract()) { | 9255 if (func.IsDynamicFunction() || func.is_abstract()) { |
| 9276 if (node != NULL) { | 9256 if (node != NULL) { |
| 9277 CheckInstanceFieldAccess(ident_pos, ident); | 9257 CheckInstanceFieldAccess(ident_pos, ident); |
| 9278 ASSERT(AbstractType::Handle(isolate(), | 9258 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 9279 func.result_type()).IsResolved()); | |
| 9280 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 9259 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 9281 } | 9260 } |
| 9282 return true; | 9261 return true; |
| 9283 } else if (func.IsStaticFunction()) { | 9262 } else if (func.IsStaticFunction()) { |
| 9284 if (node != NULL) { | 9263 if (node != NULL) { |
| 9285 ASSERT(AbstractType::Handle(isolate(), | 9264 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 9286 func.result_type()).IsResolved()); | |
| 9287 // The static getter may later be changed into a dynamically | 9265 // The static getter may later be changed into a dynamically |
| 9288 // resolved instance setter if no static setter can | 9266 // resolved instance setter if no static setter can |
| 9289 // be found. | 9267 // be found. |
| 9290 AstNode* receiver = NULL; | 9268 AstNode* receiver = NULL; |
| 9291 const bool kTestOnly = true; | 9269 const bool kTestOnly = true; |
| 9292 if (!current_function().is_static() && | 9270 if (!current_function().is_static() && |
| 9293 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { | 9271 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { |
| 9294 receiver = LoadReceiver(ident_pos); | 9272 receiver = LoadReceiver(ident_pos); |
| 9295 } | 9273 } |
| 9296 *node = new(isolate()) StaticGetterNode(ident_pos, | 9274 *node = new(I) StaticGetterNode(ident_pos, |
| 9297 receiver, | 9275 receiver, |
| 9298 false, | 9276 false, |
| 9299 Class::ZoneHandle(I, cls.raw()), | 9277 Class::ZoneHandle(I, cls.raw()), |
| 9300 ident); | 9278 ident); |
| 9301 } | 9279 } |
| 9302 return true; | 9280 return true; |
| 9303 } | 9281 } |
| 9304 } | 9282 } |
| 9305 func = cls.LookupSetterFunction(ident); | 9283 func = cls.LookupSetterFunction(ident); |
| 9306 if (!func.IsNull()) { | 9284 if (!func.IsNull()) { |
| 9307 if (func.IsDynamicFunction() || func.is_abstract()) { | 9285 if (func.IsDynamicFunction() || func.is_abstract()) { |
| 9308 if (node != NULL) { | 9286 if (node != NULL) { |
| 9309 // We create a getter node even though a getter doesn't exist as | 9287 // We create a getter node even though a getter doesn't exist as |
| 9310 // it could be followed by an assignment which will convert it to | 9288 // it could be followed by an assignment which will convert it to |
| 9311 // a setter node. If there is no assignment we will get an error | 9289 // a setter node. If there is no assignment we will get an error |
| 9312 // when we try to invoke the getter. | 9290 // when we try to invoke the getter. |
| 9313 CheckInstanceFieldAccess(ident_pos, ident); | 9291 CheckInstanceFieldAccess(ident_pos, ident); |
| 9314 ASSERT(AbstractType::Handle(isolate(), | 9292 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 9315 func.result_type()).IsResolved()); | |
| 9316 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 9293 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 9317 } | 9294 } |
| 9318 return true; | 9295 return true; |
| 9319 } else if (func.IsStaticFunction()) { | 9296 } else if (func.IsStaticFunction()) { |
| 9320 if (node != NULL) { | 9297 if (node != NULL) { |
| 9321 // We create a getter node even though a getter doesn't exist as | 9298 // We create a getter node even though a getter doesn't exist as |
| 9322 // it could be followed by an assignment which will convert it to | 9299 // it could be followed by an assignment which will convert it to |
| 9323 // a setter node. If there is no assignment we will get an error | 9300 // a setter node. If there is no assignment we will get an error |
| 9324 // when we try to invoke the getter. | 9301 // when we try to invoke the getter. |
| 9325 *node = new(isolate()) StaticGetterNode( | 9302 *node = new(I) StaticGetterNode( |
| 9326 ident_pos, | 9303 ident_pos, |
| 9327 NULL, | 9304 NULL, |
| 9328 false, | 9305 false, |
| 9329 Class::ZoneHandle(I, cls.raw()), | 9306 Class::ZoneHandle(I, cls.raw()), |
| 9330 ident); | 9307 ident); |
| 9331 } | 9308 } |
| 9332 return true; | 9309 return true; |
| 9333 } | 9310 } |
| 9334 } | 9311 } |
| 9335 | 9312 |
| 9336 // Nothing found in scope of current class. | 9313 // Nothing found in scope of current class. |
| 9337 if (node != NULL) { | 9314 if (node != NULL) { |
| 9338 *node = NULL; | 9315 *node = NULL; |
| 9339 } | 9316 } |
| 9340 return false; // Not an unqualified identifier. | 9317 return false; // Not an unqualified identifier. |
| 9341 } | 9318 } |
| 9342 | 9319 |
| 9343 | 9320 |
| 9344 RawClass* Parser::ResolveClassInCurrentLibraryScope(const String& name) { | 9321 RawClass* Parser::ResolveClassInCurrentLibraryScope(const String& name) { |
| 9345 HANDLESCOPE(isolate()); | 9322 HANDLESCOPE(I); |
| 9346 const Object& obj = Object::Handle(isolate(), library_.ResolveName(name)); | 9323 const Object& obj = Object::Handle(I, library_.ResolveName(name)); |
| 9347 if (obj.IsClass()) { | 9324 if (obj.IsClass()) { |
| 9348 return Class::Cast(obj).raw(); | 9325 return Class::Cast(obj).raw(); |
| 9349 } | 9326 } |
| 9350 return Class::null(); | 9327 return Class::null(); |
| 9351 } | 9328 } |
| 9352 | 9329 |
| 9353 | 9330 |
| 9354 // Resolve an identifier by checking the global scope of the current | 9331 // Resolve an identifier by checking the global scope of the current |
| 9355 // library. If not found in the current library, then look in the scopes | 9332 // library. If not found in the current library, then look in the scopes |
| 9356 // of all libraries that are imported without a library prefix. | 9333 // of all libraries that are imported without a library prefix. |
| 9357 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 9334 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, |
| 9358 const String& ident) { | 9335 const String& ident) { |
| 9359 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 9336 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
| 9360 HANDLESCOPE(isolate()); | 9337 HANDLESCOPE(I); |
| 9361 const Object& obj = Object::Handle(isolate(), library_.ResolveName(ident)); | 9338 const Object& obj = Object::Handle(I, library_.ResolveName(ident)); |
| 9362 if (obj.IsClass()) { | 9339 if (obj.IsClass()) { |
| 9363 const Class& cls = Class::Cast(obj); | 9340 const Class& cls = Class::Cast(obj); |
| 9364 return new(isolate()) PrimaryNode( | 9341 return new(I) PrimaryNode(ident_pos, Class::ZoneHandle(I, cls.raw())); |
| 9365 ident_pos, Class::ZoneHandle(I, cls.raw())); | |
| 9366 } else if (obj.IsField()) { | 9342 } else if (obj.IsField()) { |
| 9367 const Field& field = Field::Cast(obj); | 9343 const Field& field = Field::Cast(obj); |
| 9368 ASSERT(field.is_static()); | 9344 ASSERT(field.is_static()); |
| 9369 return GenerateStaticFieldLookup(field, ident_pos); | 9345 return GenerateStaticFieldLookup(field, ident_pos); |
| 9370 } else if (obj.IsFunction()) { | 9346 } else if (obj.IsFunction()) { |
| 9371 const Function& func = Function::Cast(obj); | 9347 const Function& func = Function::Cast(obj); |
| 9372 ASSERT(func.is_static()); | 9348 ASSERT(func.is_static()); |
| 9373 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 9349 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
| 9374 return new(isolate()) StaticGetterNode(ident_pos, | 9350 return new(I) StaticGetterNode(ident_pos, |
| 9375 /* receiver */ NULL, | 9351 /* receiver */ NULL, |
| 9376 /* is_super_getter */ false, | 9352 /* is_super_getter */ false, |
| 9377 Class::ZoneHandle(I, func.Owner()), | 9353 Class::ZoneHandle(I, func.Owner()), |
| 9378 ident); | 9354 ident); |
| 9379 | 9355 |
| 9380 } else { | 9356 } else { |
| 9381 return new(isolate()) PrimaryNode(ident_pos, | 9357 return new(I) PrimaryNode(ident_pos, Function::ZoneHandle(I, func.raw())); |
| 9382 Function::ZoneHandle(I, func.raw())); | |
| 9383 } | 9358 } |
| 9384 } else { | 9359 } else { |
| 9385 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); | 9360 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); |
| 9386 } | 9361 } |
| 9387 // Lexically unresolved primary identifiers are referenced by their name. | 9362 // Lexically unresolved primary identifiers are referenced by their name. |
| 9388 return new(isolate()) PrimaryNode(ident_pos, ident); | 9363 return new(I) PrimaryNode(ident_pos, ident); |
| 9389 } | 9364 } |
| 9390 | 9365 |
| 9391 | 9366 |
| 9392 RawClass* Parser::ResolveClassInPrefixScope(const LibraryPrefix& prefix, | 9367 RawClass* Parser::ResolveClassInPrefixScope(const LibraryPrefix& prefix, |
| 9393 const String& name) { | 9368 const String& name) { |
| 9394 HANDLESCOPE(isolate()); | 9369 HANDLESCOPE(I); |
| 9395 const Object& obj = Object::Handle(isolate(), prefix.LookupObject(name)); | 9370 const Object& obj = Object::Handle(I, prefix.LookupObject(name)); |
| 9396 if (obj.IsClass()) { | 9371 if (obj.IsClass()) { |
| 9397 return Class::Cast(obj).raw(); | 9372 return Class::Cast(obj).raw(); |
| 9398 } | 9373 } |
| 9399 return Class::null(); | 9374 return Class::null(); |
| 9400 } | 9375 } |
| 9401 | 9376 |
| 9402 | 9377 |
| 9403 // Do a lookup for the identifier in the scope of the specified | 9378 // Do a lookup for the identifier in the scope of the specified |
| 9404 // library prefix. This means trying to resolve it locally in all of the | 9379 // library prefix. This means trying to resolve it locally in all of the |
| 9405 // libraries present in the library prefix. | 9380 // libraries present in the library prefix. |
| 9406 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 9381 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, |
| 9407 const LibraryPrefix& prefix, | 9382 const LibraryPrefix& prefix, |
| 9408 const String& ident) { | 9383 const String& ident) { |
| 9409 TRACE_PARSER("ResolveIdentInPrefixScope"); | 9384 TRACE_PARSER("ResolveIdentInPrefixScope"); |
| 9410 HANDLESCOPE(isolate()); | 9385 HANDLESCOPE(I); |
| 9411 Object& obj = Object::Handle(isolate()); | 9386 Object& obj = Object::Handle(I); |
| 9412 if (prefix.is_loaded()) { | 9387 if (prefix.is_loaded()) { |
| 9413 obj = prefix.LookupObject(ident); | 9388 obj = prefix.LookupObject(ident); |
| 9414 } else { | 9389 } else { |
| 9415 // Remember that this function depends on an import prefix of an | 9390 // Remember that this function depends on an import prefix of an |
| 9416 // unloaded deferred library. Note that parsed_function() can be | 9391 // unloaded deferred library. Note that parsed_function() can be |
| 9417 // NULL when parsing expressions outside the scope of a function. | 9392 // NULL when parsing expressions outside the scope of a function. |
| 9418 if (parsed_function() != NULL) { | 9393 if (parsed_function() != NULL) { |
| 9419 parsed_function()->AddDeferredPrefix(prefix); | 9394 parsed_function()->AddDeferredPrefix(prefix); |
| 9420 } | 9395 } |
| 9421 } | 9396 } |
| 9422 const bool is_deferred = prefix.is_deferred_load(); | 9397 const bool is_deferred = prefix.is_deferred_load(); |
| 9423 if (obj.IsNull()) { | 9398 if (obj.IsNull()) { |
| 9424 // Unresolved prefixed primary identifier. | 9399 // Unresolved prefixed primary identifier. |
| 9425 return NULL; | 9400 return NULL; |
| 9426 } else if (obj.IsClass()) { | 9401 } else if (obj.IsClass()) { |
| 9427 const Class& cls = Class::Cast(obj); | 9402 const Class& cls = Class::Cast(obj); |
| 9428 PrimaryNode* primary = | 9403 PrimaryNode* primary = |
| 9429 new(isolate()) PrimaryNode(ident_pos, Class::ZoneHandle(I, cls.raw())); | 9404 new(I) PrimaryNode(ident_pos, Class::ZoneHandle(I, cls.raw())); |
| 9430 primary->set_is_deferred(is_deferred); | 9405 primary->set_is_deferred(is_deferred); |
| 9431 return primary; | 9406 return primary; |
| 9432 } else if (obj.IsField()) { | 9407 } else if (obj.IsField()) { |
| 9433 const Field& field = Field::Cast(obj); | 9408 const Field& field = Field::Cast(obj); |
| 9434 ASSERT(field.is_static()); | 9409 ASSERT(field.is_static()); |
| 9435 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); | 9410 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); |
| 9436 ASSERT(get_field != NULL); | 9411 ASSERT(get_field != NULL); |
| 9437 ASSERT(get_field->IsLoadStaticFieldNode() || | 9412 ASSERT(get_field->IsLoadStaticFieldNode() || |
| 9438 get_field->IsStaticGetterNode()); | 9413 get_field->IsStaticGetterNode()); |
| 9439 if (get_field->IsLoadStaticFieldNode()) { | 9414 if (get_field->IsLoadStaticFieldNode()) { |
| 9440 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 9415 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
| 9441 } else if (get_field->IsStaticGetterNode()) { | 9416 } else if (get_field->IsStaticGetterNode()) { |
| 9442 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); | 9417 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); |
| 9443 } | 9418 } |
| 9444 return get_field; | 9419 return get_field; |
| 9445 } else if (obj.IsFunction()) { | 9420 } else if (obj.IsFunction()) { |
| 9446 const Function& func = Function::Cast(obj); | 9421 const Function& func = Function::Cast(obj); |
| 9447 ASSERT(func.is_static()); | 9422 ASSERT(func.is_static()); |
| 9448 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 9423 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
| 9449 StaticGetterNode* getter = | 9424 StaticGetterNode* getter = new(I) StaticGetterNode( |
| 9450 new(isolate()) StaticGetterNode(ident_pos, | 9425 ident_pos, |
| 9451 /* receiver */ NULL, | 9426 /* receiver */ NULL, |
| 9452 /* is_super_getter */ false, | 9427 /* is_super_getter */ false, |
| 9453 Class::ZoneHandle(I, func.Owner()), | 9428 Class::ZoneHandle(I, func.Owner()), |
| 9454 ident); | 9429 ident); |
| 9455 getter->set_is_deferred(is_deferred); | 9430 getter->set_is_deferred(is_deferred); |
| 9456 return getter; | 9431 return getter; |
| 9457 } else { | 9432 } else { |
| 9458 PrimaryNode* primary = new(isolate()) PrimaryNode( | 9433 PrimaryNode* primary = new(I) PrimaryNode( |
| 9459 ident_pos, Function::ZoneHandle(I, func.raw())); | 9434 ident_pos, Function::ZoneHandle(I, func.raw())); |
| 9460 primary->set_is_deferred(is_deferred); | 9435 primary->set_is_deferred(is_deferred); |
| 9461 return primary; | 9436 return primary; |
| 9462 } | 9437 } |
| 9463 } | 9438 } |
| 9464 // All possible object types are handled above. | 9439 // All possible object types are handled above. |
| 9465 UNREACHABLE(); | 9440 UNREACHABLE(); |
| 9466 return NULL; | 9441 return NULL; |
| 9467 } | 9442 } |
| 9468 | 9443 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 9486 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I, | 9461 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I, |
| 9487 current_class().LookupTypeParameter(ident)); | 9462 current_class().LookupTypeParameter(ident)); |
| 9488 if (!type_parameter.IsNull()) { | 9463 if (!type_parameter.IsNull()) { |
| 9489 if (current_block_->scope->function_level() > 0) { | 9464 if (current_block_->scope->function_level() > 0) { |
| 9490 // Make sure that the instantiator is captured. | 9465 // Make sure that the instantiator is captured. |
| 9491 CaptureInstantiator(); | 9466 CaptureInstantiator(); |
| 9492 } | 9467 } |
| 9493 type_parameter ^= ClassFinalizer::FinalizeType( | 9468 type_parameter ^= ClassFinalizer::FinalizeType( |
| 9494 current_class(), type_parameter, ClassFinalizer::kCanonicalize); | 9469 current_class(), type_parameter, ClassFinalizer::kCanonicalize); |
| 9495 ASSERT(!type_parameter.IsMalformed()); | 9470 ASSERT(!type_parameter.IsMalformed()); |
| 9496 return new(isolate()) TypeNode(ident_pos, type_parameter); | 9471 return new(I) TypeNode(ident_pos, type_parameter); |
| 9497 } | 9472 } |
| 9498 } | 9473 } |
| 9499 // Not found in the local scope, and the name is not a type parameter. | 9474 // Not found in the local scope, and the name is not a type parameter. |
| 9500 // Try finding the variable in the library scope (current library | 9475 // Try finding the variable in the library scope (current library |
| 9501 // and all libraries imported by it without a library prefix). | 9476 // and all libraries imported by it without a library prefix). |
| 9502 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 9477 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
| 9503 } | 9478 } |
| 9504 if (resolved->IsPrimaryNode()) { | 9479 if (resolved->IsPrimaryNode()) { |
| 9505 PrimaryNode* primary = resolved->AsPrimaryNode(); | 9480 PrimaryNode* primary = resolved->AsPrimaryNode(); |
| 9506 const intptr_t primary_pos = primary->token_pos(); | 9481 const intptr_t primary_pos = primary->token_pos(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 9525 } else if (primary->primary().IsFunction()) { | 9500 } else if (primary->primary().IsFunction()) { |
| 9526 if (allow_closure_names) { | 9501 if (allow_closure_names) { |
| 9527 resolved = LoadClosure(primary); | 9502 resolved = LoadClosure(primary); |
| 9528 } else { | 9503 } else { |
| 9529 ErrorMsg(ident_pos, "illegal reference to method '%s'", | 9504 ErrorMsg(ident_pos, "illegal reference to method '%s'", |
| 9530 ident.ToCString()); | 9505 ident.ToCString()); |
| 9531 } | 9506 } |
| 9532 } else if (primary->primary().IsClass()) { | 9507 } else if (primary->primary().IsClass()) { |
| 9533 const Class& type_class = Class::Cast(primary->primary()); | 9508 const Class& type_class = Class::Cast(primary->primary()); |
| 9534 AbstractType& type = Type::ZoneHandle(I, | 9509 AbstractType& type = Type::ZoneHandle(I, |
| 9535 Type::New(type_class, TypeArguments::Handle(isolate()), primary_pos)); | 9510 Type::New(type_class, TypeArguments::Handle(I), primary_pos)); |
| 9536 type ^= ClassFinalizer::FinalizeType( | 9511 type ^= ClassFinalizer::FinalizeType( |
| 9537 current_class(), type, ClassFinalizer::kCanonicalize); | 9512 current_class(), type, ClassFinalizer::kCanonicalize); |
| 9538 // Type may be malbounded, but not malformed. | 9513 // Type may be malbounded, but not malformed. |
| 9539 ASSERT(!type.IsMalformed()); | 9514 ASSERT(!type.IsMalformed()); |
| 9540 resolved = new(isolate()) TypeNode(primary_pos, type); | 9515 resolved = new(I) TypeNode(primary_pos, type); |
| 9541 } | 9516 } |
| 9542 } | 9517 } |
| 9543 return resolved; | 9518 return resolved; |
| 9544 } | 9519 } |
| 9545 | 9520 |
| 9546 | 9521 |
| 9547 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 9522 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
| 9548 // finalize it according to the given type finalization mode. | 9523 // finalize it according to the given type finalization mode. |
| 9549 RawAbstractType* Parser::ParseType( | 9524 RawAbstractType* Parser::ParseType( |
| 9550 ClassFinalizer::FinalizationKind finalization, | 9525 ClassFinalizer::FinalizationKind finalization, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9561 SkipQualIdent(); | 9536 SkipQualIdent(); |
| 9562 } else { | 9537 } else { |
| 9563 ParseQualIdent(&type_name); | 9538 ParseQualIdent(&type_name); |
| 9564 // An identifier cannot be resolved in a local scope when top level parsing. | 9539 // An identifier cannot be resolved in a local scope when top level parsing. |
| 9565 if (!is_top_level_ && | 9540 if (!is_top_level_ && |
| 9566 (type_name.lib_prefix == NULL) && | 9541 (type_name.lib_prefix == NULL) && |
| 9567 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { | 9542 ResolveIdentInLocalScope(type_name.ident_pos, *type_name.ident, NULL)) { |
| 9568 // The type is malformed. Skip over its type arguments. | 9543 // The type is malformed. Skip over its type arguments. |
| 9569 ParseTypeArguments(ClassFinalizer::kIgnore); | 9544 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 9570 return ClassFinalizer::NewFinalizedMalformedType( | 9545 return ClassFinalizer::NewFinalizedMalformedType( |
| 9571 Error::Handle(isolate()), // No previous error. | 9546 Error::Handle(I), // No previous error. |
| 9572 script_, | 9547 script_, |
| 9573 type_name.ident_pos, | 9548 type_name.ident_pos, |
| 9574 "using '%s' in this context is invalid", | 9549 "using '%s' in this context is invalid", |
| 9575 type_name.ident->ToCString()); | 9550 type_name.ident->ToCString()); |
| 9576 } | 9551 } |
| 9577 if ((type_name.lib_prefix != NULL) && | 9552 if ((type_name.lib_prefix != NULL) && |
| 9578 type_name.lib_prefix->is_deferred_load() && | 9553 type_name.lib_prefix->is_deferred_load() && |
| 9579 !allow_deferred_type) { | 9554 !allow_deferred_type) { |
| 9580 ParseTypeArguments(ClassFinalizer::kIgnore); | 9555 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 9581 return ClassFinalizer::NewFinalizedMalformedType( | 9556 return ClassFinalizer::NewFinalizedMalformedType( |
| 9582 Error::Handle(isolate()), // No previous error. | 9557 Error::Handle(I), // No previous error. |
| 9583 script_, | 9558 script_, |
| 9584 type_name.ident_pos, | 9559 type_name.ident_pos, |
| 9585 "using deferred type '%s.%s' is invalid", | 9560 "using deferred type '%s.%s' is invalid", |
| 9586 String::Handle(isolate(), type_name.lib_prefix->name()).ToCString(), | 9561 String::Handle(I, type_name.lib_prefix->name()).ToCString(), |
| 9587 type_name.ident->ToCString()); | 9562 type_name.ident->ToCString()); |
| 9588 } | 9563 } |
| 9589 } | 9564 } |
| 9590 Object& type_class = Object::Handle(isolate()); | 9565 Object& type_class = Object::Handle(I); |
| 9591 // Leave type_class as null if type finalization mode is kIgnore. | 9566 // Leave type_class as null if type finalization mode is kIgnore. |
| 9592 if (finalization != ClassFinalizer::kIgnore) { | 9567 if (finalization != ClassFinalizer::kIgnore) { |
| 9593 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(isolate()); | 9568 LibraryPrefix& lib_prefix = LibraryPrefix::Handle(I); |
| 9594 if (type_name.lib_prefix != NULL) { | 9569 if (type_name.lib_prefix != NULL) { |
| 9595 lib_prefix = type_name.lib_prefix->raw(); | 9570 lib_prefix = type_name.lib_prefix->raw(); |
| 9596 } | 9571 } |
| 9597 type_class = UnresolvedClass::New(lib_prefix, | 9572 type_class = UnresolvedClass::New(lib_prefix, |
| 9598 *type_name.ident, | 9573 *type_name.ident, |
| 9599 type_name.ident_pos); | 9574 type_name.ident_pos); |
| 9600 } | 9575 } |
| 9601 TypeArguments& type_arguments = TypeArguments::Handle( | 9576 TypeArguments& type_arguments = TypeArguments::Handle( |
| 9602 isolate(), ParseTypeArguments(finalization)); | 9577 I, ParseTypeArguments(finalization)); |
| 9603 if (finalization == ClassFinalizer::kIgnore) { | 9578 if (finalization == ClassFinalizer::kIgnore) { |
| 9604 return Type::DynamicType(); | 9579 return Type::DynamicType(); |
| 9605 } | 9580 } |
| 9606 AbstractType& type = AbstractType::Handle( | 9581 AbstractType& type = AbstractType::Handle( |
| 9607 isolate(), Type::New(type_class, type_arguments, type_name.ident_pos)); | 9582 I, Type::New(type_class, type_arguments, type_name.ident_pos)); |
| 9608 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 9583 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
| 9609 ResolveTypeFromClass(current_class(), finalization, &type); | 9584 ResolveTypeFromClass(current_class(), finalization, &type); |
| 9610 if (finalization >= ClassFinalizer::kCanonicalize) { | 9585 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 9611 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 9586 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
| 9612 } | 9587 } |
| 9613 } | 9588 } |
| 9614 return type.raw(); | 9589 return type.raw(); |
| 9615 } | 9590 } |
| 9616 | 9591 |
| 9617 | 9592 |
| 9618 void Parser::CheckConstructorCallTypeArguments( | 9593 void Parser::CheckConstructorCallTypeArguments( |
| 9619 intptr_t pos, const Function& constructor, | 9594 intptr_t pos, const Function& constructor, |
| 9620 const TypeArguments& type_arguments) { | 9595 const TypeArguments& type_arguments) { |
| 9621 if (!type_arguments.IsNull()) { | 9596 if (!type_arguments.IsNull()) { |
| 9622 const Class& constructor_class = Class::Handle(isolate(), | 9597 const Class& constructor_class = Class::Handle(I, constructor.Owner()); |
| 9623 constructor.Owner()); | |
| 9624 ASSERT(!constructor_class.IsNull()); | 9598 ASSERT(!constructor_class.IsNull()); |
| 9625 ASSERT(constructor_class.is_finalized()); | 9599 ASSERT(constructor_class.is_finalized()); |
| 9626 ASSERT(type_arguments.IsCanonical()); | 9600 ASSERT(type_arguments.IsCanonical()); |
| 9627 // Do not report the expected vs. actual number of type arguments, because | 9601 // Do not report the expected vs. actual number of type arguments, because |
| 9628 // the type argument vector is flattened and raw types are allowed. | 9602 // the type argument vector is flattened and raw types are allowed. |
| 9629 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 9603 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
| 9630 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); | 9604 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); |
| 9631 } | 9605 } |
| 9632 } | 9606 } |
| 9633 } | 9607 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9670 if (FLAG_error_on_bad_type) { | 9644 if (FLAG_error_on_bad_type) { |
| 9671 ErrorMsg(type_pos, | 9645 ErrorMsg(type_pos, |
| 9672 "a list literal takes one type argument specifying " | 9646 "a list literal takes one type argument specifying " |
| 9673 "the element type"); | 9647 "the element type"); |
| 9674 } | 9648 } |
| 9675 // Ignore type arguments. | 9649 // Ignore type arguments. |
| 9676 list_type_arguments = TypeArguments::null(); | 9650 list_type_arguments = TypeArguments::null(); |
| 9677 } | 9651 } |
| 9678 } | 9652 } |
| 9679 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); | 9653 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
| 9680 const Class& array_class = Class::Handle(isolate(), | 9654 const Class& array_class = Class::Handle(I, I->object_store()->array_class()); |
| 9681 isolate()->object_store()->array_class()); | |
| 9682 Type& type = Type::ZoneHandle(I, | 9655 Type& type = Type::ZoneHandle(I, |
| 9683 Type::New(array_class, list_type_arguments, type_pos)); | 9656 Type::New(array_class, list_type_arguments, type_pos)); |
| 9684 type ^= ClassFinalizer::FinalizeType( | 9657 type ^= ClassFinalizer::FinalizeType( |
| 9685 current_class(), type, ClassFinalizer::kCanonicalize); | 9658 current_class(), type, ClassFinalizer::kCanonicalize); |
| 9686 GrowableArray<AstNode*> element_list; | 9659 GrowableArray<AstNode*> element_list; |
| 9687 // Parse the list elements. Note: there may be an optional extra | 9660 // Parse the list elements. Note: there may be an optional extra |
| 9688 // comma after the last element. | 9661 // comma after the last element. |
| 9689 if (!is_empty_literal) { | 9662 if (!is_empty_literal) { |
| 9690 const bool saved_mode = SetAllowFunctionLiterals(true); | 9663 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 9691 while (CurrentToken() != Token::kRBRACK) { | 9664 while (CurrentToken() != Token::kRBRACK) { |
| 9692 const intptr_t element_pos = TokenPos(); | 9665 const intptr_t element_pos = TokenPos(); |
| 9693 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 9666 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
| 9694 if (FLAG_enable_type_checks && | 9667 if (FLAG_enable_type_checks && |
| 9695 !is_const && | 9668 !is_const && |
| 9696 !element_type.IsDynamicType()) { | 9669 !element_type.IsDynamicType()) { |
| 9697 element = new(isolate()) AssignableNode(element_pos, | 9670 element = new(I) AssignableNode(element_pos, |
| 9698 element, | 9671 element, |
| 9699 element_type, | 9672 element_type, |
| 9700 Symbols::ListLiteralElement()); | 9673 Symbols::ListLiteralElement()); |
| 9701 } | 9674 } |
| 9702 element_list.Add(element); | 9675 element_list.Add(element); |
| 9703 if (CurrentToken() == Token::kCOMMA) { | 9676 if (CurrentToken() == Token::kCOMMA) { |
| 9704 ConsumeToken(); | 9677 ConsumeToken(); |
| 9705 } else if (CurrentToken() != Token::kRBRACK) { | 9678 } else if (CurrentToken() != Token::kRBRACK) { |
| 9706 ErrorMsg("comma or ']' expected"); | 9679 ErrorMsg("comma or ']' expected"); |
| 9707 } | 9680 } |
| 9708 } | 9681 } |
| 9709 ExpectToken(Token::kRBRACK); | 9682 ExpectToken(Token::kRBRACK); |
| 9710 SetAllowFunctionLiterals(saved_mode); | 9683 SetAllowFunctionLiterals(saved_mode); |
| 9711 } | 9684 } |
| 9712 | 9685 |
| 9713 if (is_const) { | 9686 if (is_const) { |
| 9714 // Allocate and initialize the const list at compile time. | 9687 // Allocate and initialize the const list at compile time. |
| 9715 Array& const_list = | 9688 Array& const_list = |
| 9716 Array::ZoneHandle(I, Array::New(element_list.length(), Heap::kOld)); | 9689 Array::ZoneHandle(I, Array::New(element_list.length(), Heap::kOld)); |
| 9717 const_list.SetTypeArguments( | 9690 const_list.SetTypeArguments( |
| 9718 TypeArguments::Handle(isolate(), list_type_arguments.Canonicalize())); | 9691 TypeArguments::Handle(I, list_type_arguments.Canonicalize())); |
| 9719 Error& malformed_error = Error::Handle(isolate()); | 9692 Error& malformed_error = Error::Handle(I); |
| 9720 for (int i = 0; i < element_list.length(); i++) { | 9693 for (int i = 0; i < element_list.length(); i++) { |
| 9721 AstNode* elem = element_list[i]; | 9694 AstNode* elem = element_list[i]; |
| 9722 // Arguments have been evaluated to a literal value already. | 9695 // Arguments have been evaluated to a literal value already. |
| 9723 ASSERT(elem->IsLiteralNode()); | 9696 ASSERT(elem->IsLiteralNode()); |
| 9724 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9697 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 9725 if (FLAG_enable_type_checks && | 9698 if (FLAG_enable_type_checks && |
| 9726 !element_type.IsDynamicType() && | 9699 !element_type.IsDynamicType() && |
| 9727 (!elem->AsLiteralNode()->literal().IsNull() && | 9700 (!elem->AsLiteralNode()->literal().IsNull() && |
| 9728 !elem->AsLiteralNode()->literal().IsInstanceOf( | 9701 !elem->AsLiteralNode()->literal().IsInstanceOf( |
| 9729 element_type, | 9702 element_type, |
| 9730 TypeArguments::Handle(isolate()), | 9703 TypeArguments::Handle(I), |
| 9731 &malformed_error))) { | 9704 &malformed_error))) { |
| 9732 // If the failure is due to a malformed type error, display it instead. | 9705 // If the failure is due to a malformed type error, display it instead. |
| 9733 if (!malformed_error.IsNull()) { | 9706 if (!malformed_error.IsNull()) { |
| 9734 ErrorMsg(malformed_error); | 9707 ErrorMsg(malformed_error); |
| 9735 } else { | 9708 } else { |
| 9736 ErrorMsg(elem->AsLiteralNode()->token_pos(), | 9709 ErrorMsg(elem->AsLiteralNode()->token_pos(), |
| 9737 "list literal element at index %d must be " | 9710 "list literal element at index %d must be " |
| 9738 "a constant of type '%s'", | 9711 "a constant of type '%s'", |
| 9739 i, | 9712 i, |
| 9740 String::Handle(isolate(), | 9713 String::Handle(I, |
| 9741 element_type.UserVisibleName()).ToCString()); | 9714 element_type.UserVisibleName()).ToCString()); |
| 9742 } | 9715 } |
| 9743 } | 9716 } |
| 9744 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 9717 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 9745 } | 9718 } |
| 9746 const_list ^= TryCanonicalize(const_list, literal_pos); | 9719 const_list ^= TryCanonicalize(const_list, literal_pos); |
| 9747 const_list.MakeImmutable(); | 9720 const_list.MakeImmutable(); |
| 9748 return new(isolate()) LiteralNode(literal_pos, const_list); | 9721 return new(I) LiteralNode(literal_pos, const_list); |
| 9749 } else { | 9722 } else { |
| 9750 // Factory call at runtime. | 9723 // Factory call at runtime. |
| 9751 const Class& factory_class = | 9724 const Class& factory_class = |
| 9752 Class::Handle(isolate(), Library::LookupCoreClass(Symbols::List())); | 9725 Class::Handle(I, Library::LookupCoreClass(Symbols::List())); |
| 9753 ASSERT(!factory_class.IsNull()); | 9726 ASSERT(!factory_class.IsNull()); |
| 9754 const Function& factory_method = Function::ZoneHandle(I, | 9727 const Function& factory_method = Function::ZoneHandle(I, |
| 9755 factory_class.LookupFactory( | 9728 factory_class.LookupFactory( |
| 9756 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 9729 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
| 9757 ASSERT(!factory_method.IsNull()); | 9730 ASSERT(!factory_method.IsNull()); |
| 9758 if (!list_type_arguments.IsNull() && | 9731 if (!list_type_arguments.IsNull() && |
| 9759 !list_type_arguments.IsInstantiated() && | 9732 !list_type_arguments.IsInstantiated() && |
| 9760 (current_block_->scope->function_level() > 0)) { | 9733 (current_block_->scope->function_level() > 0)) { |
| 9761 // Make sure that the instantiator is captured. | 9734 // Make sure that the instantiator is captured. |
| 9762 CaptureInstantiator(); | 9735 CaptureInstantiator(); |
| 9763 } | 9736 } |
| 9764 TypeArguments& factory_type_args = | 9737 TypeArguments& factory_type_args = |
| 9765 TypeArguments::ZoneHandle(I, list_type_arguments.raw()); | 9738 TypeArguments::ZoneHandle(I, list_type_arguments.raw()); |
| 9766 // If the factory class extends other parameterized classes, adjust the | 9739 // If the factory class extends other parameterized classes, adjust the |
| 9767 // type argument vector. | 9740 // type argument vector. |
| 9768 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { | 9741 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { |
| 9769 ASSERT(factory_type_args.Length() == 1); | 9742 ASSERT(factory_type_args.Length() == 1); |
| 9770 Type& factory_type = Type::Handle(isolate(), Type::New( | 9743 Type& factory_type = Type::Handle(I, Type::New( |
| 9771 factory_class, factory_type_args, type_pos, Heap::kNew)); | 9744 factory_class, factory_type_args, type_pos, Heap::kNew)); |
| 9772 factory_type ^= ClassFinalizer::FinalizeType( | 9745 factory_type ^= ClassFinalizer::FinalizeType( |
| 9773 current_class(), factory_type, ClassFinalizer::kFinalize); | 9746 current_class(), factory_type, ClassFinalizer::kFinalize); |
| 9774 factory_type_args = factory_type.arguments(); | 9747 factory_type_args = factory_type.arguments(); |
| 9775 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 9748 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
| 9776 } | 9749 } |
| 9777 factory_type_args = factory_type_args.Canonicalize(); | 9750 factory_type_args = factory_type_args.Canonicalize(); |
| 9778 ArgumentListNode* factory_param = new(isolate()) ArgumentListNode( | 9751 ArgumentListNode* factory_param = new(I) ArgumentListNode( |
| 9779 literal_pos); | 9752 literal_pos); |
| 9780 if (element_list.length() == 0) { | 9753 if (element_list.length() == 0) { |
| 9781 // TODO(srdjan): Use Object::empty_array once issue 9871 has been fixed. | 9754 // TODO(srdjan): Use Object::empty_array once issue 9871 has been fixed. |
| 9782 Array& empty_array = Array::ZoneHandle(I, Object::empty_array().raw()); | 9755 Array& empty_array = Array::ZoneHandle(I, Object::empty_array().raw()); |
| 9783 LiteralNode* empty_array_literal = | 9756 LiteralNode* empty_array_literal = |
| 9784 new(isolate()) LiteralNode(TokenPos(), empty_array); | 9757 new(I) LiteralNode(TokenPos(), empty_array); |
| 9785 factory_param->Add(empty_array_literal); | 9758 factory_param->Add(empty_array_literal); |
| 9786 } else { | 9759 } else { |
| 9787 ArrayNode* list = new(isolate()) ArrayNode( | 9760 ArrayNode* list = new(I) ArrayNode(TokenPos(), type, element_list); |
| 9788 TokenPos(), type, element_list); | |
| 9789 factory_param->Add(list); | 9761 factory_param->Add(list); |
| 9790 } | 9762 } |
| 9791 return CreateConstructorCallNode(literal_pos, | 9763 return CreateConstructorCallNode(literal_pos, |
| 9792 factory_type_args, | 9764 factory_type_args, |
| 9793 factory_method, | 9765 factory_method, |
| 9794 factory_param); | 9766 factory_param); |
| 9795 } | 9767 } |
| 9796 } | 9768 } |
| 9797 | 9769 |
| 9798 | 9770 |
| 9799 ConstructorCallNode* Parser::CreateConstructorCallNode( | 9771 ConstructorCallNode* Parser::CreateConstructorCallNode( |
| 9800 intptr_t token_pos, | 9772 intptr_t token_pos, |
| 9801 const TypeArguments& type_arguments, | 9773 const TypeArguments& type_arguments, |
| 9802 const Function& constructor, | 9774 const Function& constructor, |
| 9803 ArgumentListNode* arguments) { | 9775 ArgumentListNode* arguments) { |
| 9804 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 9776 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
| 9805 EnsureExpressionTemp(); | 9777 EnsureExpressionTemp(); |
| 9806 } | 9778 } |
| 9807 return new(isolate()) ConstructorCallNode( | 9779 return new(I) ConstructorCallNode( |
| 9808 token_pos, type_arguments, constructor, arguments); | 9780 token_pos, type_arguments, constructor, arguments); |
| 9809 } | 9781 } |
| 9810 | 9782 |
| 9811 | 9783 |
| 9812 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, | 9784 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, |
| 9813 bool is_const, | 9785 bool is_const, |
| 9814 AstNode* key, | 9786 AstNode* key, |
| 9815 AstNode* value) { | 9787 AstNode* value) { |
| 9816 if (is_const) { | 9788 if (is_const) { |
| 9817 ASSERT(key->IsLiteralNode()); | 9789 ASSERT(key->IsLiteralNode()); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9883 GrowableArray<AstNode*> kv_pairs_list; | 9855 GrowableArray<AstNode*> kv_pairs_list; |
| 9884 // Parse the map entries. Note: there may be an optional extra | 9856 // Parse the map entries. Note: there may be an optional extra |
| 9885 // comma after the last entry. | 9857 // comma after the last entry. |
| 9886 while (CurrentToken() != Token::kRBRACE) { | 9858 while (CurrentToken() != Token::kRBRACE) { |
| 9887 const bool saved_mode = SetAllowFunctionLiterals(true); | 9859 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 9888 const intptr_t key_pos = TokenPos(); | 9860 const intptr_t key_pos = TokenPos(); |
| 9889 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 9861 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
| 9890 if (FLAG_enable_type_checks && | 9862 if (FLAG_enable_type_checks && |
| 9891 !is_const && | 9863 !is_const && |
| 9892 !key_type.IsDynamicType()) { | 9864 !key_type.IsDynamicType()) { |
| 9893 key = new(isolate()) AssignableNode( | 9865 key = new(I) AssignableNode( |
| 9894 key_pos, key, key_type, Symbols::ListLiteralElement()); | 9866 key_pos, key, key_type, Symbols::ListLiteralElement()); |
| 9895 } | 9867 } |
| 9896 if (is_const) { | 9868 if (is_const) { |
| 9897 ASSERT(key->IsLiteralNode()); | 9869 ASSERT(key->IsLiteralNode()); |
| 9898 const Instance& key_value = key->AsLiteralNode()->literal(); | 9870 const Instance& key_value = key->AsLiteralNode()->literal(); |
| 9899 if (key_value.IsDouble()) { | 9871 if (key_value.IsDouble()) { |
| 9900 ErrorMsg(key_pos, "key value must not be of type double"); | 9872 ErrorMsg(key_pos, "key value must not be of type double"); |
| 9901 } | 9873 } |
| 9902 if (!key_value.IsInteger() && | 9874 if (!key_value.IsInteger() && |
| 9903 !key_value.IsString() && | 9875 !key_value.IsString() && |
| 9904 ImplementsEqualOperator(key_value)) { | 9876 ImplementsEqualOperator(key_value)) { |
| 9905 ErrorMsg(key_pos, "key value must not implement operator =="); | 9877 ErrorMsg(key_pos, "key value must not implement operator =="); |
| 9906 } | 9878 } |
| 9907 } | 9879 } |
| 9908 ExpectToken(Token::kCOLON); | 9880 ExpectToken(Token::kCOLON); |
| 9909 const intptr_t value_pos = TokenPos(); | 9881 const intptr_t value_pos = TokenPos(); |
| 9910 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 9882 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
| 9911 SetAllowFunctionLiterals(saved_mode); | 9883 SetAllowFunctionLiterals(saved_mode); |
| 9912 if (FLAG_enable_type_checks && | 9884 if (FLAG_enable_type_checks && |
| 9913 !is_const && | 9885 !is_const && |
| 9914 !value_type.IsDynamicType()) { | 9886 !value_type.IsDynamicType()) { |
| 9915 value = new(isolate()) AssignableNode( | 9887 value = new(I) AssignableNode( |
| 9916 value_pos, value, value_type, Symbols::ListLiteralElement()); | 9888 value_pos, value, value_type, Symbols::ListLiteralElement()); |
| 9917 } | 9889 } |
| 9918 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 9890 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
| 9919 | 9891 |
| 9920 if (CurrentToken() == Token::kCOMMA) { | 9892 if (CurrentToken() == Token::kCOMMA) { |
| 9921 ConsumeToken(); | 9893 ConsumeToken(); |
| 9922 } else if (CurrentToken() != Token::kRBRACE) { | 9894 } else if (CurrentToken() != Token::kRBRACE) { |
| 9923 ErrorMsg("comma or '}' expected"); | 9895 ErrorMsg("comma or '}' expected"); |
| 9924 } | 9896 } |
| 9925 } | 9897 } |
| 9926 ASSERT(kv_pairs_list.length() % 2 == 0); | 9898 ASSERT(kv_pairs_list.length() % 2 == 0); |
| 9927 ExpectToken(Token::kRBRACE); | 9899 ExpectToken(Token::kRBRACE); |
| 9928 | 9900 |
| 9929 if (is_const) { | 9901 if (is_const) { |
| 9930 // Create the key-value pair array, canonicalize it and then create | 9902 // Create the key-value pair array, canonicalize it and then create |
| 9931 // the immutable map object with it. This all happens at compile time. | 9903 // the immutable map object with it. This all happens at compile time. |
| 9932 // The resulting immutable map object is returned as a literal. | 9904 // The resulting immutable map object is returned as a literal. |
| 9933 | 9905 |
| 9934 // First, create the canonicalized key-value pair array. | 9906 // First, create the canonicalized key-value pair array. |
| 9935 Array& key_value_array = | 9907 Array& key_value_array = |
| 9936 Array::ZoneHandle(I, Array::New(kv_pairs_list.length(), Heap::kOld)); | 9908 Array::ZoneHandle(I, Array::New(kv_pairs_list.length(), Heap::kOld)); |
| 9937 AbstractType& arg_type = Type::Handle(isolate()); | 9909 AbstractType& arg_type = Type::Handle(I); |
| 9938 Error& malformed_error = Error::Handle(isolate()); | 9910 Error& malformed_error = Error::Handle(I); |
| 9939 for (int i = 0; i < kv_pairs_list.length(); i++) { | 9911 for (int i = 0; i < kv_pairs_list.length(); i++) { |
| 9940 AstNode* arg = kv_pairs_list[i]; | 9912 AstNode* arg = kv_pairs_list[i]; |
| 9941 // Arguments have been evaluated to a literal value already. | 9913 // Arguments have been evaluated to a literal value already. |
| 9942 ASSERT(arg->IsLiteralNode()); | 9914 ASSERT(arg->IsLiteralNode()); |
| 9943 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9915 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 9944 if (FLAG_enable_type_checks) { | 9916 if (FLAG_enable_type_checks) { |
| 9945 if ((i % 2) == 0) { | 9917 if ((i % 2) == 0) { |
| 9946 // Check key type. | 9918 // Check key type. |
| 9947 arg_type = key_type.raw(); | 9919 arg_type = key_type.raw(); |
| 9948 } else { | 9920 } else { |
| 9949 // Check value type. | 9921 // Check value type. |
| 9950 arg_type = value_type.raw(); | 9922 arg_type = value_type.raw(); |
| 9951 } | 9923 } |
| 9952 if (!arg_type.IsDynamicType() && | 9924 if (!arg_type.IsDynamicType() && |
| 9953 (!arg->AsLiteralNode()->literal().IsNull() && | 9925 (!arg->AsLiteralNode()->literal().IsNull() && |
| 9954 !arg->AsLiteralNode()->literal().IsInstanceOf( | 9926 !arg->AsLiteralNode()->literal().IsInstanceOf( |
| 9955 arg_type, | 9927 arg_type, |
| 9956 Object::null_type_arguments(), | 9928 Object::null_type_arguments(), |
| 9957 &malformed_error))) { | 9929 &malformed_error))) { |
| 9958 // If the failure is due to a malformed type error, display it. | 9930 // If the failure is due to a malformed type error, display it. |
| 9959 if (!malformed_error.IsNull()) { | 9931 if (!malformed_error.IsNull()) { |
| 9960 ErrorMsg(malformed_error); | 9932 ErrorMsg(malformed_error); |
| 9961 } else { | 9933 } else { |
| 9962 ErrorMsg(arg->AsLiteralNode()->token_pos(), | 9934 ErrorMsg(arg->AsLiteralNode()->token_pos(), |
| 9963 "map literal %s at index %d must be " | 9935 "map literal %s at index %d must be " |
| 9964 "a constant of type '%s'", | 9936 "a constant of type '%s'", |
| 9965 ((i % 2) == 0) ? "key" : "value", | 9937 ((i % 2) == 0) ? "key" : "value", |
| 9966 i >> 1, | 9938 i >> 1, |
| 9967 String::Handle(isolate(), | 9939 String::Handle(I, |
| 9968 arg_type.UserVisibleName()).ToCString()); | 9940 arg_type.UserVisibleName()).ToCString()); |
| 9969 } | 9941 } |
| 9970 } | 9942 } |
| 9971 } | 9943 } |
| 9972 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 9944 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 9973 } | 9945 } |
| 9974 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); | 9946 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); |
| 9975 key_value_array.MakeImmutable(); | 9947 key_value_array.MakeImmutable(); |
| 9976 | 9948 |
| 9977 // Construct the map object. | 9949 // Construct the map object. |
| 9978 const Class& immutable_map_class = Class::Handle(isolate(), | 9950 const Class& immutable_map_class = Class::Handle(I, |
| 9979 Library::LookupCoreClass(Symbols::ImmutableMap())); | 9951 Library::LookupCoreClass(Symbols::ImmutableMap())); |
| 9980 ASSERT(!immutable_map_class.IsNull()); | 9952 ASSERT(!immutable_map_class.IsNull()); |
| 9981 // If the immutable map class extends other parameterized classes, we need | 9953 // If the immutable map class extends other parameterized classes, we need |
| 9982 // to adjust the type argument vector. This is currently not the case. | 9954 // to adjust the type argument vector. This is currently not the case. |
| 9983 ASSERT(immutable_map_class.NumTypeArguments() == 2); | 9955 ASSERT(immutable_map_class.NumTypeArguments() == 2); |
| 9984 ArgumentListNode* constr_args = new(isolate()) ArgumentListNode(TokenPos()); | 9956 ArgumentListNode* constr_args = new(I) ArgumentListNode(TokenPos()); |
| 9985 constr_args->Add(new(isolate()) LiteralNode(literal_pos, key_value_array)); | 9957 constr_args->Add(new(I) LiteralNode(literal_pos, key_value_array)); |
| 9986 const Function& map_constr = | 9958 const Function& map_constr = |
| 9987 Function::ZoneHandle(I, immutable_map_class.LookupConstructor( | 9959 Function::ZoneHandle(I, immutable_map_class.LookupConstructor( |
| 9988 Library::PrivateCoreLibName(Symbols::ImmutableMapConstructor()))); | 9960 Library::PrivateCoreLibName(Symbols::ImmutableMapConstructor()))); |
| 9989 ASSERT(!map_constr.IsNull()); | 9961 ASSERT(!map_constr.IsNull()); |
| 9990 const Object& constructor_result = Object::Handle(isolate(), | 9962 const Object& constructor_result = Object::Handle(I, |
| 9991 EvaluateConstConstructorCall(immutable_map_class, | 9963 EvaluateConstConstructorCall(immutable_map_class, |
| 9992 map_type_arguments, | 9964 map_type_arguments, |
| 9993 map_constr, | 9965 map_constr, |
| 9994 constr_args)); | 9966 constr_args)); |
| 9995 if (constructor_result.IsUnhandledException()) { | 9967 if (constructor_result.IsUnhandledException()) { |
| 9996 AppendErrorMsg(Error::Cast(constructor_result), | 9968 AppendErrorMsg(Error::Cast(constructor_result), |
| 9997 literal_pos, | 9969 literal_pos, |
| 9998 "error executing const Map constructor"); | 9970 "error executing const Map constructor"); |
| 9999 } else { | 9971 } else { |
| 10000 const Instance& const_instance = Instance::Cast(constructor_result); | 9972 const Instance& const_instance = Instance::Cast(constructor_result); |
| 10001 return new(isolate()) LiteralNode( | 9973 return new(I) LiteralNode( |
| 10002 literal_pos, Instance::ZoneHandle(I, const_instance.raw())); | 9974 literal_pos, Instance::ZoneHandle(I, const_instance.raw())); |
| 10003 } | 9975 } |
| 10004 } else { | 9976 } else { |
| 10005 // Factory call at runtime. | 9977 // Factory call at runtime. |
| 10006 const Class& factory_class = | 9978 const Class& factory_class = |
| 10007 Class::Handle(isolate(), Library::LookupCoreClass(Symbols::Map())); | 9979 Class::Handle(I, Library::LookupCoreClass(Symbols::Map())); |
| 10008 ASSERT(!factory_class.IsNull()); | 9980 ASSERT(!factory_class.IsNull()); |
| 10009 const Function& factory_method = Function::ZoneHandle(I, | 9981 const Function& factory_method = Function::ZoneHandle(I, |
| 10010 factory_class.LookupFactory( | 9982 factory_class.LookupFactory( |
| 10011 Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); | 9983 Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); |
| 10012 ASSERT(!factory_method.IsNull()); | 9984 ASSERT(!factory_method.IsNull()); |
| 10013 if (!map_type_arguments.IsNull() && | 9985 if (!map_type_arguments.IsNull() && |
| 10014 !map_type_arguments.IsInstantiated() && | 9986 !map_type_arguments.IsInstantiated() && |
| 10015 (current_block_->scope->function_level() > 0)) { | 9987 (current_block_->scope->function_level() > 0)) { |
| 10016 // Make sure that the instantiator is captured. | 9988 // Make sure that the instantiator is captured. |
| 10017 CaptureInstantiator(); | 9989 CaptureInstantiator(); |
| 10018 } | 9990 } |
| 10019 TypeArguments& factory_type_args = | 9991 TypeArguments& factory_type_args = |
| 10020 TypeArguments::ZoneHandle(I, map_type_arguments.raw()); | 9992 TypeArguments::ZoneHandle(I, map_type_arguments.raw()); |
| 10021 // If the factory class extends other parameterized classes, adjust the | 9993 // If the factory class extends other parameterized classes, adjust the |
| 10022 // type argument vector. | 9994 // type argument vector. |
| 10023 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) { | 9995 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) { |
| 10024 ASSERT(factory_type_args.Length() == 2); | 9996 ASSERT(factory_type_args.Length() == 2); |
| 10025 Type& factory_type = Type::Handle(isolate(), Type::New( | 9997 Type& factory_type = Type::Handle(I, Type::New( |
| 10026 factory_class, factory_type_args, type_pos, Heap::kNew)); | 9998 factory_class, factory_type_args, type_pos, Heap::kNew)); |
| 10027 factory_type ^= ClassFinalizer::FinalizeType( | 9999 factory_type ^= ClassFinalizer::FinalizeType( |
| 10028 current_class(), factory_type, ClassFinalizer::kFinalize); | 10000 current_class(), factory_type, ClassFinalizer::kFinalize); |
| 10029 factory_type_args = factory_type.arguments(); | 10001 factory_type_args = factory_type.arguments(); |
| 10030 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 10002 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
| 10031 } | 10003 } |
| 10032 factory_type_args = factory_type_args.Canonicalize(); | 10004 factory_type_args = factory_type_args.Canonicalize(); |
| 10033 ArgumentListNode* factory_param = | 10005 ArgumentListNode* factory_param = new(I) ArgumentListNode(literal_pos); |
| 10034 new(isolate()) ArgumentListNode(literal_pos); | |
| 10035 // The kv_pair array is temporary and of element type dynamic. It is passed | 10006 // The kv_pair array is temporary and of element type dynamic. It is passed |
| 10036 // to the factory to initialize a properly typed map. | 10007 // to the factory to initialize a properly typed map. |
| 10037 ArrayNode* kv_pairs = new(isolate()) ArrayNode( | 10008 ArrayNode* kv_pairs = new(I) ArrayNode( |
| 10038 TokenPos(), | 10009 TokenPos(), |
| 10039 Type::ZoneHandle(I, Type::ArrayType()), | 10010 Type::ZoneHandle(I, Type::ArrayType()), |
| 10040 kv_pairs_list); | 10011 kv_pairs_list); |
| 10041 factory_param->Add(kv_pairs); | 10012 factory_param->Add(kv_pairs); |
| 10042 return CreateConstructorCallNode(literal_pos, | 10013 return CreateConstructorCallNode(literal_pos, |
| 10043 factory_type_args, | 10014 factory_type_args, |
| 10044 factory_method, | 10015 factory_method, |
| 10045 factory_param); | 10016 factory_param); |
| 10046 } | 10017 } |
| 10047 UNREACHABLE(); | 10018 UNREACHABLE(); |
| 10048 return NULL; | 10019 return NULL; |
| 10049 } | 10020 } |
| 10050 | 10021 |
| 10051 | 10022 |
| 10052 AstNode* Parser::ParseCompoundLiteral() { | 10023 AstNode* Parser::ParseCompoundLiteral() { |
| 10053 TRACE_PARSER("ParseCompoundLiteral"); | 10024 TRACE_PARSER("ParseCompoundLiteral"); |
| 10054 bool is_const = false; | 10025 bool is_const = false; |
| 10055 if (CurrentToken() == Token::kCONST) { | 10026 if (CurrentToken() == Token::kCONST) { |
| 10056 is_const = true; | 10027 is_const = true; |
| 10057 ConsumeToken(); | 10028 ConsumeToken(); |
| 10058 } | 10029 } |
| 10059 const intptr_t type_pos = TokenPos(); | 10030 const intptr_t type_pos = TokenPos(); |
| 10060 TypeArguments& type_arguments = TypeArguments::Handle(isolate(), | 10031 TypeArguments& type_arguments = TypeArguments::Handle(I, |
| 10061 ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 10032 ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
| 10062 // Malformed type arguments are mapped to dynamic, so we will not encounter | 10033 // Malformed type arguments are mapped to dynamic, so we will not encounter |
| 10063 // them here. | 10034 // them here. |
| 10064 // Map and List interfaces do not declare bounds on their type parameters, so | 10035 // Map and List interfaces do not declare bounds on their type parameters, so |
| 10065 // we will not see malbounded type arguments here. | 10036 // we will not see malbounded type arguments here. |
| 10066 AstNode* primary = NULL; | 10037 AstNode* primary = NULL; |
| 10067 if ((CurrentToken() == Token::kLBRACK) || | 10038 if ((CurrentToken() == Token::kLBRACK) || |
| 10068 (CurrentToken() == Token::kINDEX)) { | 10039 (CurrentToken() == Token::kINDEX)) { |
| 10069 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 10040 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 10070 } else if (CurrentToken() == Token::kLBRACE) { | 10041 } else if (CurrentToken() == Token::kLBRACE) { |
| 10071 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 10042 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 10072 } else { | 10043 } else { |
| 10073 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); | 10044 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); |
| 10074 } | 10045 } |
| 10075 return primary; | 10046 return primary; |
| 10076 } | 10047 } |
| 10077 | 10048 |
| 10078 | 10049 |
| 10079 AstNode* Parser::ParseSymbolLiteral() { | 10050 AstNode* Parser::ParseSymbolLiteral() { |
| 10080 ASSERT(CurrentToken() == Token::kHASH); | 10051 ASSERT(CurrentToken() == Token::kHASH); |
| 10081 ConsumeToken(); | 10052 ConsumeToken(); |
| 10082 intptr_t symbol_pos = TokenPos(); | 10053 intptr_t symbol_pos = TokenPos(); |
| 10083 String& symbol = String::Handle(isolate()); | 10054 String& symbol = String::Handle(I); |
| 10084 if (IsIdentifier()) { | 10055 if (IsIdentifier()) { |
| 10085 symbol = CurrentLiteral()->raw(); | 10056 symbol = CurrentLiteral()->raw(); |
| 10086 ConsumeToken(); | 10057 ConsumeToken(); |
| 10087 while (CurrentToken() == Token::kPERIOD) { | 10058 while (CurrentToken() == Token::kPERIOD) { |
| 10088 symbol = String::Concat(symbol, Symbols::Dot()); | 10059 symbol = String::Concat(symbol, Symbols::Dot()); |
| 10089 ConsumeToken(); | 10060 ConsumeToken(); |
| 10090 symbol = String::Concat(symbol, | 10061 symbol = String::Concat(symbol, |
| 10091 *ExpectIdentifier("identifier expected")); | 10062 *ExpectIdentifier("identifier expected")); |
| 10092 } | 10063 } |
| 10093 } else if (Token::CanBeOverloaded(CurrentToken())) { | 10064 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 10094 symbol = String::New(Token::Str(CurrentToken())); | 10065 symbol = String::New(Token::Str(CurrentToken())); |
| 10095 ConsumeToken(); | 10066 ConsumeToken(); |
| 10096 } else { | 10067 } else { |
| 10097 ErrorMsg("illegal symbol literal"); | 10068 ErrorMsg("illegal symbol literal"); |
| 10098 } | 10069 } |
| 10099 // Lookup class Symbol from internal library and call the | 10070 // Lookup class Symbol from internal library and call the |
| 10100 // constructor to create a symbol instance. | 10071 // constructor to create a symbol instance. |
| 10101 const Library& lib = Library::Handle(isolate(), Library::InternalLibrary()); | 10072 const Library& lib = Library::Handle(I, Library::InternalLibrary()); |
| 10102 const Class& symbol_class = Class::Handle(isolate(), | 10073 const Class& symbol_class = Class::Handle(I, |
| 10103 lib.LookupClass(Symbols::Symbol())); | 10074 lib.LookupClass(Symbols::Symbol())); |
| 10104 ASSERT(!symbol_class.IsNull()); | 10075 ASSERT(!symbol_class.IsNull()); |
| 10105 ArgumentListNode* constr_args = new(isolate()) ArgumentListNode(symbol_pos); | 10076 ArgumentListNode* constr_args = new(I) ArgumentListNode(symbol_pos); |
| 10106 constr_args->Add(new(isolate()) LiteralNode( | 10077 constr_args->Add(new(I) LiteralNode( |
| 10107 symbol_pos, String::ZoneHandle(I, Symbols::New(symbol)))); | 10078 symbol_pos, String::ZoneHandle(I, Symbols::New(symbol)))); |
| 10108 const Function& constr = Function::ZoneHandle(I, | 10079 const Function& constr = Function::ZoneHandle(I, |
| 10109 symbol_class.LookupConstructor(Symbols::SymbolCtor())); | 10080 symbol_class.LookupConstructor(Symbols::SymbolCtor())); |
| 10110 ASSERT(!constr.IsNull()); | 10081 ASSERT(!constr.IsNull()); |
| 10111 const Object& result = Object::Handle(isolate(), | 10082 const Object& result = Object::Handle(I, |
| 10112 EvaluateConstConstructorCall(symbol_class, | 10083 EvaluateConstConstructorCall(symbol_class, |
| 10113 TypeArguments::Handle(isolate()), | 10084 TypeArguments::Handle(I), |
| 10114 constr, | 10085 constr, |
| 10115 constr_args)); | 10086 constr_args)); |
| 10116 if (result.IsUnhandledException()) { | 10087 if (result.IsUnhandledException()) { |
| 10117 AppendErrorMsg(Error::Cast(result), | 10088 AppendErrorMsg(Error::Cast(result), |
| 10118 symbol_pos, | 10089 symbol_pos, |
| 10119 "error executing const Symbol constructor"); | 10090 "error executing const Symbol constructor"); |
| 10120 } | 10091 } |
| 10121 const Instance& instance = Instance::Cast(result); | 10092 const Instance& instance = Instance::Cast(result); |
| 10122 return new(isolate()) LiteralNode(symbol_pos, | 10093 return new(I) LiteralNode(symbol_pos, |
| 10123 Instance::ZoneHandle(I, instance.raw())); | 10094 Instance::ZoneHandle(I, instance.raw())); |
| 10124 } | 10095 } |
| 10125 | 10096 |
| 10126 | 10097 |
| 10127 static String& BuildConstructorName(const String& type_class_name, | 10098 static String& BuildConstructorName(const String& type_class_name, |
| 10128 const String* named_constructor) { | 10099 const String* named_constructor) { |
| 10129 // By convention, the static function implementing a named constructor 'C' | 10100 // By convention, the static function implementing a named constructor 'C' |
| 10130 // for class 'A' is labeled 'A.C', and the static function implementing the | 10101 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 10131 // unnamed constructor for class 'A' is labeled 'A.'. | 10102 // unnamed constructor for class 'A' is labeled 'A.'. |
| 10132 // This convention prevents users from explicitly calling constructors. | 10103 // This convention prevents users from explicitly calling constructors. |
| 10133 String& constructor_name = | 10104 String& constructor_name = |
| 10134 String::Handle(String::Concat(type_class_name, Symbols::Dot())); | 10105 String::Handle(String::Concat(type_class_name, Symbols::Dot())); |
| 10135 if (named_constructor != NULL) { | 10106 if (named_constructor != NULL) { |
| 10136 constructor_name = String::Concat(constructor_name, *named_constructor); | 10107 constructor_name = String::Concat(constructor_name, *named_constructor); |
| 10137 } | 10108 } |
| 10138 return constructor_name; | 10109 return constructor_name; |
| 10139 } | 10110 } |
| 10140 | 10111 |
| 10141 | 10112 |
| 10142 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 10113 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
| 10143 TRACE_PARSER("ParseNewOperator"); | 10114 TRACE_PARSER("ParseNewOperator"); |
| 10144 const intptr_t new_pos = TokenPos(); | 10115 const intptr_t new_pos = TokenPos(); |
| 10145 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 10116 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
| 10146 bool is_const = (op_kind == Token::kCONST); | 10117 bool is_const = (op_kind == Token::kCONST); |
| 10147 if (!IsIdentifier()) { | 10118 if (!IsIdentifier()) { |
| 10148 ErrorMsg("type name expected"); | 10119 ErrorMsg("type name expected"); |
| 10149 } | 10120 } |
| 10150 intptr_t type_pos = TokenPos(); | 10121 intptr_t type_pos = TokenPos(); |
| 10151 // Can't allocate const objects of a deferred type. | 10122 // Can't allocate const objects of a deferred type. |
| 10152 const bool allow_deferred_type = !is_const; | 10123 const bool allow_deferred_type = !is_const; |
| 10153 AbstractType& type = AbstractType::Handle(isolate(), | 10124 AbstractType& type = AbstractType::Handle(I, |
| 10154 ParseType(ClassFinalizer::kCanonicalizeWellFormed, allow_deferred_type)); | 10125 ParseType(ClassFinalizer::kCanonicalizeWellFormed, allow_deferred_type)); |
| 10155 // In case the type is malformed, throw a dynamic type error after finishing | 10126 // In case the type is malformed, throw a dynamic type error after finishing |
| 10156 // parsing the instance creation expression. | 10127 // parsing the instance creation expression. |
| 10157 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 10128 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
| 10158 // Replace the type with a malformed type. | 10129 // Replace the type with a malformed type. |
| 10159 type = ClassFinalizer::NewFinalizedMalformedType( | 10130 type = ClassFinalizer::NewFinalizedMalformedType( |
| 10160 Error::Handle(isolate()), // No previous error. | 10131 Error::Handle(I), // No previous error. |
| 10161 script_, | 10132 script_, |
| 10162 type_pos, | 10133 type_pos, |
| 10163 "%s'%s' cannot be instantiated", | 10134 "%s'%s' cannot be instantiated", |
| 10164 type.IsTypeParameter() ? "type parameter " : "", | 10135 type.IsTypeParameter() ? "type parameter " : "", |
| 10165 type.IsTypeParameter() ? | 10136 type.IsTypeParameter() ? |
| 10166 String::Handle(isolate(), type.UserVisibleName()).ToCString() : | 10137 String::Handle(I, type.UserVisibleName()).ToCString() : |
| 10167 "dynamic"); | 10138 "dynamic"); |
| 10168 } | 10139 } |
| 10169 | 10140 |
| 10170 // The grammar allows for an optional ('.' identifier)? after the type, which | 10141 // The grammar allows for an optional ('.' identifier)? after the type, which |
| 10171 // is a named constructor. Note that ParseType() above will not consume it as | 10142 // is a named constructor. Note that ParseType() above will not consume it as |
| 10172 // part of a misinterpreted qualified identifier, because only a valid library | 10143 // part of a misinterpreted qualified identifier, because only a valid library |
| 10173 // prefix is accepted as qualifier. | 10144 // prefix is accepted as qualifier. |
| 10174 String* named_constructor = NULL; | 10145 String* named_constructor = NULL; |
| 10175 if (CurrentToken() == Token::kPERIOD) { | 10146 if (CurrentToken() == Token::kPERIOD) { |
| 10176 ConsumeToken(); | 10147 ConsumeToken(); |
| 10177 named_constructor = ExpectIdentifier("name of constructor expected"); | 10148 named_constructor = ExpectIdentifier("name of constructor expected"); |
| 10178 } | 10149 } |
| 10179 | 10150 |
| 10180 // Parse constructor parameters. | 10151 // Parse constructor parameters. |
| 10181 CheckToken(Token::kLPAREN); | 10152 CheckToken(Token::kLPAREN); |
| 10182 intptr_t call_pos = TokenPos(); | 10153 intptr_t call_pos = TokenPos(); |
| 10183 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 10154 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
| 10184 | 10155 |
| 10185 // Parsing is complete, so we can return a throw in case of a malformed or | 10156 // Parsing is complete, so we can return a throw in case of a malformed or |
| 10186 // malbounded type or report a compile-time error if the constructor is const. | 10157 // malbounded type or report a compile-time error if the constructor is const. |
| 10187 if (type.IsMalformedOrMalbounded()) { | 10158 if (type.IsMalformedOrMalbounded()) { |
| 10188 if (is_const) { | 10159 if (is_const) { |
| 10189 const Error& error = Error::Handle(isolate(), type.error()); | 10160 const Error& error = Error::Handle(I, type.error()); |
| 10190 ErrorMsg(error); | 10161 ErrorMsg(error); |
| 10191 } | 10162 } |
| 10192 return ThrowTypeError(type_pos, type); | 10163 return ThrowTypeError(type_pos, type); |
| 10193 } | 10164 } |
| 10194 | 10165 |
| 10195 // Resolve the type and optional identifier to a constructor or factory. | 10166 // Resolve the type and optional identifier to a constructor or factory. |
| 10196 Class& type_class = Class::Handle(isolate(), type.type_class()); | 10167 Class& type_class = Class::Handle(I, type.type_class()); |
| 10197 String& type_class_name = String::Handle(isolate(), type_class.Name()); | 10168 String& type_class_name = String::Handle(I, type_class.Name()); |
| 10198 TypeArguments& type_arguments = | 10169 TypeArguments& type_arguments = |
| 10199 TypeArguments::ZoneHandle(I, type.arguments()); | 10170 TypeArguments::ZoneHandle(I, type.arguments()); |
| 10200 | 10171 |
| 10201 // A constructor has an implicit 'this' parameter (instance to construct) | 10172 // A constructor has an implicit 'this' parameter (instance to construct) |
| 10202 // and a factory has an implicit 'this' parameter (type_arguments). | 10173 // and a factory has an implicit 'this' parameter (type_arguments). |
| 10203 // A constructor has a second implicit 'phase' parameter. | 10174 // A constructor has a second implicit 'phase' parameter. |
| 10204 intptr_t arguments_length = arguments->length() + 2; | 10175 intptr_t arguments_length = arguments->length() + 2; |
| 10205 | 10176 |
| 10206 // An additional type check of the result of a redirecting factory may be | 10177 // An additional type check of the result of a redirecting factory may be |
| 10207 // required. | 10178 // required. |
| 10208 AbstractType& type_bound = AbstractType::ZoneHandle(I); | 10179 AbstractType& type_bound = AbstractType::ZoneHandle(I); |
| 10209 | 10180 |
| 10210 // Make sure that an appropriate constructor exists. | 10181 // Make sure that an appropriate constructor exists. |
| 10211 String& constructor_name = | 10182 String& constructor_name = |
| 10212 BuildConstructorName(type_class_name, named_constructor); | 10183 BuildConstructorName(type_class_name, named_constructor); |
| 10213 Function& constructor = Function::ZoneHandle(I, | 10184 Function& constructor = Function::ZoneHandle(I, |
| 10214 type_class.LookupConstructor(constructor_name)); | 10185 type_class.LookupConstructor(constructor_name)); |
| 10215 if (constructor.IsNull()) { | 10186 if (constructor.IsNull()) { |
| 10216 constructor = type_class.LookupFactory(constructor_name); | 10187 constructor = type_class.LookupFactory(constructor_name); |
| 10217 if (constructor.IsNull()) { | 10188 if (constructor.IsNull()) { |
| 10218 const String& external_constructor_name = | 10189 const String& external_constructor_name = |
| 10219 (named_constructor ? constructor_name : type_class_name); | 10190 (named_constructor ? constructor_name : type_class_name); |
| 10220 // Replace the type with a malformed type and compile a throw or report a | 10191 // Replace the type with a malformed type and compile a throw or report a |
| 10221 // compile-time error if the constructor is const. | 10192 // compile-time error if the constructor is const. |
| 10222 if (is_const) { | 10193 if (is_const) { |
| 10223 type = ClassFinalizer::NewFinalizedMalformedType( | 10194 type = ClassFinalizer::NewFinalizedMalformedType( |
| 10224 Error::Handle(isolate()), // No previous error. | 10195 Error::Handle(I), // No previous error. |
| 10225 script_, | 10196 script_, |
| 10226 call_pos, | 10197 call_pos, |
| 10227 "class '%s' has no constructor or factory named '%s'", | 10198 "class '%s' has no constructor or factory named '%s'", |
| 10228 String::Handle(isolate(), type_class.Name()).ToCString(), | 10199 String::Handle(I, type_class.Name()).ToCString(), |
| 10229 external_constructor_name.ToCString()); | 10200 external_constructor_name.ToCString()); |
| 10230 ErrorMsg(Error::Handle(isolate(), type.error())); | 10201 ErrorMsg(Error::Handle(I, type.error())); |
| 10231 } | 10202 } |
| 10232 return ThrowNoSuchMethodError(call_pos, | 10203 return ThrowNoSuchMethodError(call_pos, |
| 10233 type_class, | 10204 type_class, |
| 10234 external_constructor_name, | 10205 external_constructor_name, |
| 10235 arguments, | 10206 arguments, |
| 10236 InvocationMirror::kConstructor, | 10207 InvocationMirror::kConstructor, |
| 10237 InvocationMirror::kMethod, | 10208 InvocationMirror::kMethod, |
| 10238 NULL); // No existing function. | 10209 NULL); // No existing function. |
| 10239 } else if (constructor.IsRedirectingFactory()) { | 10210 } else if (constructor.IsRedirectingFactory()) { |
| 10240 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); | 10211 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); |
| 10241 Type& redirect_type = Type::Handle(isolate(), | 10212 Type& redirect_type = Type::Handle(I, constructor.RedirectionType()); |
| 10242 constructor.RedirectionType()); | |
| 10243 if (!redirect_type.IsMalformedOrMalbounded() && | 10213 if (!redirect_type.IsMalformedOrMalbounded() && |
| 10244 !redirect_type.IsInstantiated()) { | 10214 !redirect_type.IsInstantiated()) { |
| 10245 // The type arguments of the redirection type are instantiated from the | 10215 // The type arguments of the redirection type are instantiated from the |
| 10246 // type arguments of the parsed type of the 'new' or 'const' expression. | 10216 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 10247 Error& error = Error::Handle(isolate()); | 10217 Error& error = Error::Handle(I); |
| 10248 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); | 10218 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); |
| 10249 if (!error.IsNull()) { | 10219 if (!error.IsNull()) { |
| 10250 redirect_type = ClassFinalizer::NewFinalizedMalformedType( | 10220 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
| 10251 error, | 10221 error, |
| 10252 script_, | 10222 script_, |
| 10253 call_pos, | 10223 call_pos, |
| 10254 "redirecting factory type '%s' cannot be instantiated", | 10224 "redirecting factory type '%s' cannot be instantiated", |
| 10255 String::Handle(isolate(), | 10225 String::Handle(I, redirect_type.UserVisibleName()).ToCString()); |
| 10256 redirect_type.UserVisibleName()).ToCString()); | |
| 10257 } | 10226 } |
| 10258 } | 10227 } |
| 10259 if (redirect_type.IsMalformedOrMalbounded()) { | 10228 if (redirect_type.IsMalformedOrMalbounded()) { |
| 10260 if (is_const) { | 10229 if (is_const) { |
| 10261 ErrorMsg(Error::Handle(isolate(), redirect_type.error())); | 10230 ErrorMsg(Error::Handle(I, redirect_type.error())); |
| 10262 } | 10231 } |
| 10263 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 10232 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
| 10264 } | 10233 } |
| 10265 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { | 10234 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { |
| 10266 // Additional type checking of the result is necessary. | 10235 // Additional type checking of the result is necessary. |
| 10267 type_bound = type.raw(); | 10236 type_bound = type.raw(); |
| 10268 } | 10237 } |
| 10269 type = redirect_type.raw(); | 10238 type = redirect_type.raw(); |
| 10270 type_class = type.type_class(); | 10239 type_class = type.type_class(); |
| 10271 type_class_name = type_class.Name(); | 10240 type_class_name = type_class.Name(); |
| 10272 type_arguments = type.arguments(); | 10241 type_arguments = type.arguments(); |
| 10273 constructor = constructor.RedirectionTarget(); | 10242 constructor = constructor.RedirectionTarget(); |
| 10274 constructor_name = constructor.name(); | 10243 constructor_name = constructor.name(); |
| 10275 ASSERT(!constructor.IsNull()); | 10244 ASSERT(!constructor.IsNull()); |
| 10276 } | 10245 } |
| 10277 if (constructor.IsFactory()) { | 10246 if (constructor.IsFactory()) { |
| 10278 // A factory does not have the implicit 'phase' parameter. | 10247 // A factory does not have the implicit 'phase' parameter. |
| 10279 arguments_length -= 1; | 10248 arguments_length -= 1; |
| 10280 } | 10249 } |
| 10281 } | 10250 } |
| 10282 | 10251 |
| 10283 // It is ok to call a factory method of an abstract class, but it is | 10252 // It is ok to call a factory method of an abstract class, but it is |
| 10284 // a dynamic error to instantiate an abstract class. | 10253 // a dynamic error to instantiate an abstract class. |
| 10285 ASSERT(!constructor.IsNull()); | 10254 ASSERT(!constructor.IsNull()); |
| 10286 if (type_class.is_abstract() && !constructor.IsFactory()) { | 10255 if (type_class.is_abstract() && !constructor.IsFactory()) { |
| 10287 // Evaluate arguments before throwing. | 10256 // Evaluate arguments before throwing. |
| 10288 LetNode* result = new(isolate()) LetNode(call_pos); | 10257 LetNode* result = new(I) LetNode(call_pos); |
| 10289 for (intptr_t i = 0; i < arguments->length(); ++i) { | 10258 for (intptr_t i = 0; i < arguments->length(); ++i) { |
| 10290 result->AddNode(arguments->NodeAt(i)); | 10259 result->AddNode(arguments->NodeAt(i)); |
| 10291 } | 10260 } |
| 10292 ArgumentListNode* error_arguments = | 10261 ArgumentListNode* error_arguments = new(I) ArgumentListNode(type_pos); |
| 10293 new(isolate()) ArgumentListNode(type_pos); | 10262 error_arguments->Add(new(I) LiteralNode( |
| 10294 error_arguments->Add(new(isolate()) LiteralNode( | |
| 10295 TokenPos(), Integer::ZoneHandle(I, Integer::New(type_pos)))); | 10263 TokenPos(), Integer::ZoneHandle(I, Integer::New(type_pos)))); |
| 10296 error_arguments->Add(new(isolate()) LiteralNode( | 10264 error_arguments->Add(new(I) LiteralNode( |
| 10297 TokenPos(), String::ZoneHandle(I, type_class_name.raw()))); | 10265 TokenPos(), String::ZoneHandle(I, type_class_name.raw()))); |
| 10298 result->AddNode( | 10266 result->AddNode( |
| 10299 MakeStaticCall(Symbols::AbstractClassInstantiationError(), | 10267 MakeStaticCall(Symbols::AbstractClassInstantiationError(), |
| 10300 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 10268 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 10301 error_arguments)); | 10269 error_arguments)); |
| 10302 return result; | 10270 return result; |
| 10303 } | 10271 } |
| 10304 String& error_message = String::Handle(isolate()); | 10272 String& error_message = String::Handle(I); |
| 10305 if (!constructor.AreValidArguments(arguments_length, | 10273 if (!constructor.AreValidArguments(arguments_length, |
| 10306 arguments->names(), | 10274 arguments->names(), |
| 10307 &error_message)) { | 10275 &error_message)) { |
| 10308 const String& external_constructor_name = | 10276 const String& external_constructor_name = |
| 10309 (named_constructor ? constructor_name : type_class_name); | 10277 (named_constructor ? constructor_name : type_class_name); |
| 10310 if (is_const) { | 10278 if (is_const) { |
| 10311 ErrorMsg(call_pos, | 10279 ErrorMsg(call_pos, |
| 10312 "invalid arguments passed to constructor '%s' " | 10280 "invalid arguments passed to constructor '%s' " |
| 10313 "for class '%s': %s", | 10281 "for class '%s': %s", |
| 10314 external_constructor_name.ToCString(), | 10282 external_constructor_name.ToCString(), |
| 10315 String::Handle(isolate(), type_class.Name()).ToCString(), | 10283 String::Handle(I, type_class.Name()).ToCString(), |
| 10316 error_message.ToCString()); | 10284 error_message.ToCString()); |
| 10317 } | 10285 } |
| 10318 return ThrowNoSuchMethodError(call_pos, | 10286 return ThrowNoSuchMethodError(call_pos, |
| 10319 type_class, | 10287 type_class, |
| 10320 external_constructor_name, | 10288 external_constructor_name, |
| 10321 arguments, | 10289 arguments, |
| 10322 InvocationMirror::kConstructor, | 10290 InvocationMirror::kConstructor, |
| 10323 InvocationMirror::kMethod, | 10291 InvocationMirror::kMethod, |
| 10324 &constructor); | 10292 &constructor); |
| 10325 } | 10293 } |
| 10326 | 10294 |
| 10327 // Return a throw in case of a malformed or malbounded type or report a | 10295 // Return a throw in case of a malformed or malbounded type or report a |
| 10328 // compile-time error if the constructor is const. | 10296 // compile-time error if the constructor is const. |
| 10329 if (type.IsMalformedOrMalbounded()) { | 10297 if (type.IsMalformedOrMalbounded()) { |
| 10330 if (is_const) { | 10298 if (is_const) { |
| 10331 ErrorMsg(Error::Handle(isolate(), type.error())); | 10299 ErrorMsg(Error::Handle(I, type.error())); |
| 10332 } | 10300 } |
| 10333 return ThrowTypeError(type_pos, type); | 10301 return ThrowTypeError(type_pos, type); |
| 10334 } | 10302 } |
| 10335 type_arguments ^= type_arguments.Canonicalize(); | 10303 type_arguments ^= type_arguments.Canonicalize(); |
| 10336 // Make the constructor call. | 10304 // Make the constructor call. |
| 10337 AstNode* new_object = NULL; | 10305 AstNode* new_object = NULL; |
| 10338 if (is_const) { | 10306 if (is_const) { |
| 10339 if (!constructor.is_const()) { | 10307 if (!constructor.is_const()) { |
| 10340 const String& external_constructor_name = | 10308 const String& external_constructor_name = |
| 10341 (named_constructor ? constructor_name : type_class_name); | 10309 (named_constructor ? constructor_name : type_class_name); |
| 10342 ErrorMsg("non-const constructor '%s' cannot be used in " | 10310 ErrorMsg("non-const constructor '%s' cannot be used in " |
| 10343 "const object creation", | 10311 "const object creation", |
| 10344 external_constructor_name.ToCString()); | 10312 external_constructor_name.ToCString()); |
| 10345 } | 10313 } |
| 10346 const Object& constructor_result = Object::Handle(isolate(), | 10314 const Object& constructor_result = Object::Handle(I, |
| 10347 EvaluateConstConstructorCall(type_class, | 10315 EvaluateConstConstructorCall(type_class, |
| 10348 type_arguments, | 10316 type_arguments, |
| 10349 constructor, | 10317 constructor, |
| 10350 arguments)); | 10318 arguments)); |
| 10351 if (constructor_result.IsUnhandledException()) { | 10319 if (constructor_result.IsUnhandledException()) { |
| 10352 // It's a compile-time error if invocation of a const constructor | 10320 // It's a compile-time error if invocation of a const constructor |
| 10353 // call fails. | 10321 // call fails. |
| 10354 AppendErrorMsg(Error::Cast(constructor_result), | 10322 AppendErrorMsg(Error::Cast(constructor_result), |
| 10355 new_pos, | 10323 new_pos, |
| 10356 "error while evaluating const constructor"); | 10324 "error while evaluating const constructor"); |
| 10357 } else { | 10325 } else { |
| 10358 // Const constructors can return null in the case where a const native | 10326 // Const constructors can return null in the case where a const native |
| 10359 // factory returns a null value. Thus we cannot use a Instance::Cast here. | 10327 // factory returns a null value. Thus we cannot use a Instance::Cast here. |
| 10360 Instance& const_instance = Instance::Handle(isolate()); | 10328 Instance& const_instance = Instance::Handle(I); |
| 10361 const_instance ^= constructor_result.raw(); | 10329 const_instance ^= constructor_result.raw(); |
| 10362 new_object = new(isolate()) LiteralNode( | 10330 new_object = new(I) LiteralNode( |
| 10363 new_pos, Instance::ZoneHandle(I, const_instance.raw())); | 10331 new_pos, Instance::ZoneHandle(I, const_instance.raw())); |
| 10364 if (!type_bound.IsNull()) { | 10332 if (!type_bound.IsNull()) { |
| 10365 ASSERT(!type_bound.IsMalformed()); | 10333 ASSERT(!type_bound.IsMalformed()); |
| 10366 Error& malformed_error = Error::Handle(isolate()); | 10334 Error& malformed_error = Error::Handle(I); |
| 10367 ASSERT(!is_top_level_); // We cannot check unresolved types. | 10335 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 10368 if (!const_instance.IsInstanceOf(type_bound, | 10336 if (!const_instance.IsInstanceOf(type_bound, |
| 10369 TypeArguments::Handle(isolate()), | 10337 TypeArguments::Handle(I), |
| 10370 &malformed_error)) { | 10338 &malformed_error)) { |
| 10371 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 10339 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
| 10372 malformed_error, | 10340 malformed_error, |
| 10373 script_, | 10341 script_, |
| 10374 new_pos, | 10342 new_pos, |
| 10375 "const factory result is not an instance of '%s'", | 10343 "const factory result is not an instance of '%s'", |
| 10376 String::Handle(isolate(), | 10344 String::Handle(I, type_bound.UserVisibleName()).ToCString()); |
| 10377 type_bound.UserVisibleName()).ToCString()); | |
| 10378 new_object = ThrowTypeError(new_pos, type_bound); | 10345 new_object = ThrowTypeError(new_pos, type_bound); |
| 10379 } | 10346 } |
| 10380 type_bound = AbstractType::null(); | 10347 type_bound = AbstractType::null(); |
| 10381 } | 10348 } |
| 10382 } | 10349 } |
| 10383 } else { | 10350 } else { |
| 10384 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 10351 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 10385 if (!type_arguments.IsNull() && | 10352 if (!type_arguments.IsNull() && |
| 10386 !type_arguments.IsInstantiated() && | 10353 !type_arguments.IsInstantiated() && |
| 10387 (current_block_->scope->function_level() > 0)) { | 10354 (current_block_->scope->function_level() > 0)) { |
| 10388 // Make sure that the instantiator is captured. | 10355 // Make sure that the instantiator is captured. |
| 10389 CaptureInstantiator(); | 10356 CaptureInstantiator(); |
| 10390 } | 10357 } |
| 10391 // If the type argument vector is not instantiated, we verify in checked | 10358 // If the type argument vector is not instantiated, we verify in checked |
| 10392 // mode at runtime that it is within its declared bounds. | 10359 // mode at runtime that it is within its declared bounds. |
| 10393 new_object = CreateConstructorCallNode( | 10360 new_object = CreateConstructorCallNode( |
| 10394 new_pos, type_arguments, constructor, arguments); | 10361 new_pos, type_arguments, constructor, arguments); |
| 10395 } | 10362 } |
| 10396 if (!type_bound.IsNull()) { | 10363 if (!type_bound.IsNull()) { |
| 10397 new_object = new(isolate()) AssignableNode( | 10364 new_object = new(I) AssignableNode( |
| 10398 new_pos, new_object, type_bound, Symbols::FactoryResult()); | 10365 new_pos, new_object, type_bound, Symbols::FactoryResult()); |
| 10399 } | 10366 } |
| 10400 return new_object; | 10367 return new_object; |
| 10401 } | 10368 } |
| 10402 | 10369 |
| 10403 | 10370 |
| 10404 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { | 10371 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { |
| 10405 const Class& cls = Class::Handle( | 10372 const Class& cls = Class::Handle( |
| 10406 isolate(), Library::LookupCoreClass(Symbols::StringBase())); | 10373 I, Library::LookupCoreClass(Symbols::StringBase())); |
| 10407 ASSERT(!cls.IsNull()); | 10374 ASSERT(!cls.IsNull()); |
| 10408 const Function& func = Function::Handle(isolate(), cls.LookupStaticFunction( | 10375 const Function& func = Function::Handle(I, cls.LookupStaticFunction( |
| 10409 Library::PrivateCoreLibName(Symbols::Interpolate()))); | 10376 Library::PrivateCoreLibName(Symbols::Interpolate()))); |
| 10410 ASSERT(!func.IsNull()); | 10377 ASSERT(!func.IsNull()); |
| 10411 | 10378 |
| 10412 // Build the array of literal values to interpolate. | 10379 // Build the array of literal values to interpolate. |
| 10413 const Array& value_arr = Array::Handle(isolate(), | 10380 const Array& value_arr = Array::Handle(I, Array::New(values.length())); |
| 10414 Array::New(values.length())); | |
| 10415 for (int i = 0; i < values.length(); i++) { | 10381 for (int i = 0; i < values.length(); i++) { |
| 10416 ASSERT(values[i]->IsLiteralNode()); | 10382 ASSERT(values[i]->IsLiteralNode()); |
| 10417 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); | 10383 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); |
| 10418 } | 10384 } |
| 10419 | 10385 |
| 10420 // Build argument array to pass to the interpolation function. | 10386 // Build argument array to pass to the interpolation function. |
| 10421 const Array& interpolate_arg = Array::Handle(isolate(), Array::New(1)); | 10387 const Array& interpolate_arg = Array::Handle(I, Array::New(1)); |
| 10422 interpolate_arg.SetAt(0, value_arr); | 10388 interpolate_arg.SetAt(0, value_arr); |
| 10423 | 10389 |
| 10424 // Call interpolation function. | 10390 // Call interpolation function. |
| 10425 Object& result = Object::Handle(isolate()); | 10391 Object& result = Object::Handle(I); |
| 10426 { | 10392 { |
| 10427 PAUSETIMERSCOPE(isolate(), time_compilation); | 10393 PAUSETIMERSCOPE(I, time_compilation); |
| 10428 result = DartEntry::InvokeFunction(func, interpolate_arg); | 10394 result = DartEntry::InvokeFunction(func, interpolate_arg); |
| 10429 } | 10395 } |
| 10430 if (result.IsUnhandledException()) { | 10396 if (result.IsUnhandledException()) { |
| 10431 ErrorMsg("%s", Error::Cast(result).ToErrorCString()); | 10397 ErrorMsg("%s", Error::Cast(result).ToErrorCString()); |
| 10432 } | 10398 } |
| 10433 String& concatenated = String::ZoneHandle(I); | 10399 String& concatenated = String::ZoneHandle(I); |
| 10434 concatenated ^= result.raw(); | 10400 concatenated ^= result.raw(); |
| 10435 concatenated = Symbols::New(concatenated); | 10401 concatenated = Symbols::New(concatenated); |
| 10436 return concatenated; | 10402 return concatenated; |
| 10437 } | 10403 } |
| 10438 | 10404 |
| 10439 | 10405 |
| 10440 // A string literal consists of the concatenation of the next n tokens | 10406 // A string literal consists of the concatenation of the next n tokens |
| 10441 // that satisfy the EBNF grammar: | 10407 // that satisfy the EBNF grammar: |
| 10442 // literal = kSTRING {{ interpol } kSTRING } | 10408 // literal = kSTRING {{ interpol } kSTRING } |
| 10443 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 10409 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 10444 // In other words, the scanner breaks down interpolated strings so that | 10410 // In other words, the scanner breaks down interpolated strings so that |
| 10445 // a string literal always begins and ends with a kSTRING token. | 10411 // a string literal always begins and ends with a kSTRING token. |
| 10446 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 10412 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
| 10447 TRACE_PARSER("ParseStringLiteral"); | 10413 TRACE_PARSER("ParseStringLiteral"); |
| 10448 AstNode* primary = NULL; | 10414 AstNode* primary = NULL; |
| 10449 const intptr_t literal_start = TokenPos(); | 10415 const intptr_t literal_start = TokenPos(); |
| 10450 ASSERT(CurrentToken() == Token::kSTRING); | 10416 ASSERT(CurrentToken() == Token::kSTRING); |
| 10451 Token::Kind l1_token = LookaheadToken(1); | 10417 Token::Kind l1_token = LookaheadToken(1); |
| 10452 if ((l1_token != Token::kSTRING) && | 10418 if ((l1_token != Token::kSTRING) && |
| 10453 (l1_token != Token::kINTERPOL_VAR) && | 10419 (l1_token != Token::kINTERPOL_VAR) && |
| 10454 (l1_token != Token::kINTERPOL_START)) { | 10420 (l1_token != Token::kINTERPOL_START)) { |
| 10455 // Common case: no interpolation. | 10421 // Common case: no interpolation. |
| 10456 primary = new(isolate()) LiteralNode(literal_start, *CurrentLiteral()); | 10422 primary = new(I) LiteralNode(literal_start, *CurrentLiteral()); |
| 10457 ConsumeToken(); | 10423 ConsumeToken(); |
| 10458 return primary; | 10424 return primary; |
| 10459 } | 10425 } |
| 10460 // String interpolation needed. | 10426 // String interpolation needed. |
| 10461 bool is_compiletime_const = true; | 10427 bool is_compiletime_const = true; |
| 10462 bool has_interpolation = false; | 10428 bool has_interpolation = false; |
| 10463 GrowableArray<AstNode*> values_list; | 10429 GrowableArray<AstNode*> values_list; |
| 10464 while (CurrentToken() == Token::kSTRING) { | 10430 while (CurrentToken() == Token::kSTRING) { |
| 10465 if (CurrentLiteral()->Length() > 0) { | 10431 if (CurrentLiteral()->Length() > 0) { |
| 10466 // Only add non-empty string sections to the values list | 10432 // Only add non-empty string sections to the values list |
| 10467 // that will be concatenated. | 10433 // that will be concatenated. |
| 10468 values_list.Add(new(isolate()) LiteralNode(TokenPos(), | 10434 values_list.Add(new(I) LiteralNode(TokenPos(), *CurrentLiteral())); |
| 10469 *CurrentLiteral())); | |
| 10470 } | 10435 } |
| 10471 ConsumeToken(); | 10436 ConsumeToken(); |
| 10472 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 10437 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 10473 (CurrentToken() == Token::kINTERPOL_START)) { | 10438 (CurrentToken() == Token::kINTERPOL_START)) { |
| 10474 if (!allow_interpolation) { | 10439 if (!allow_interpolation) { |
| 10475 ErrorMsg("string interpolation not allowed in this context"); | 10440 ErrorMsg("string interpolation not allowed in this context"); |
| 10476 } | 10441 } |
| 10477 has_interpolation = true; | 10442 has_interpolation = true; |
| 10478 AstNode* expr = NULL; | 10443 AstNode* expr = NULL; |
| 10479 const intptr_t expr_pos = TokenPos(); | 10444 const intptr_t expr_pos = TokenPos(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 10493 // a constant or not. Only strings, numbers, booleans and null values | 10458 // a constant or not. Only strings, numbers, booleans and null values |
| 10494 // are allowed in compile time const interpolations. | 10459 // are allowed in compile time const interpolations. |
| 10495 if (is_compiletime_const) { | 10460 if (is_compiletime_const) { |
| 10496 const Object* const_expr = expr->EvalConstExpr(); | 10461 const Object* const_expr = expr->EvalConstExpr(); |
| 10497 if ((const_expr != NULL) && | 10462 if ((const_expr != NULL) && |
| 10498 (const_expr->IsNumber() || | 10463 (const_expr->IsNumber() || |
| 10499 const_expr->IsString() || | 10464 const_expr->IsString() || |
| 10500 const_expr->IsBool() || | 10465 const_expr->IsBool() || |
| 10501 const_expr->IsNull())) { | 10466 const_expr->IsNull())) { |
| 10502 // Change expr into a literal. | 10467 // Change expr into a literal. |
| 10503 expr = new(isolate()) LiteralNode(expr_pos, | 10468 expr = new(I) LiteralNode(expr_pos, |
| 10504 EvaluateConstExpr(expr_pos, expr)); | 10469 EvaluateConstExpr(expr_pos, expr)); |
| 10505 } else { | 10470 } else { |
| 10506 is_compiletime_const = false; | 10471 is_compiletime_const = false; |
| 10507 } | 10472 } |
| 10508 } | 10473 } |
| 10509 values_list.Add(expr); | 10474 values_list.Add(expr); |
| 10510 } | 10475 } |
| 10511 } | 10476 } |
| 10512 if (is_compiletime_const) { | 10477 if (is_compiletime_const) { |
| 10513 if (has_interpolation) { | 10478 if (has_interpolation) { |
| 10514 primary = new(isolate()) LiteralNode( | 10479 primary = new(I) LiteralNode(literal_start, Interpolate(values_list)); |
| 10515 literal_start, Interpolate(values_list)); | |
| 10516 } else { | 10480 } else { |
| 10517 const Array& strings = Array::Handle(isolate(), | 10481 const Array& strings = Array::Handle(I, Array::New(values_list.length())); |
| 10518 Array::New(values_list.length())); | |
| 10519 for (int i = 0; i < values_list.length(); i++) { | 10482 for (int i = 0; i < values_list.length(); i++) { |
| 10520 const Instance& part = values_list[i]->AsLiteralNode()->literal(); | 10483 const Instance& part = values_list[i]->AsLiteralNode()->literal(); |
| 10521 ASSERT(part.IsString()); | 10484 ASSERT(part.IsString()); |
| 10522 strings.SetAt(i, String::Cast(part)); | 10485 strings.SetAt(i, String::Cast(part)); |
| 10523 } | 10486 } |
| 10524 String& lit = String::ZoneHandle(I, | 10487 String& lit = String::ZoneHandle(I, |
| 10525 String::ConcatAll(strings, Heap::kOld)); | 10488 String::ConcatAll(strings, Heap::kOld)); |
| 10526 lit = Symbols::New(lit); | 10489 lit = Symbols::New(lit); |
| 10527 primary = new(isolate()) LiteralNode(literal_start, lit); | 10490 primary = new(I) LiteralNode(literal_start, lit); |
| 10528 } | 10491 } |
| 10529 } else { | 10492 } else { |
| 10530 ArrayNode* values = new(isolate()) ArrayNode( | 10493 ArrayNode* values = new(I) ArrayNode( |
| 10531 TokenPos(), | 10494 TokenPos(), |
| 10532 Type::ZoneHandle(I, Type::ArrayType()), | 10495 Type::ZoneHandle(I, Type::ArrayType()), |
| 10533 values_list); | 10496 values_list); |
| 10534 primary = new(isolate()) StringInterpolateNode(TokenPos(), values); | 10497 primary = new(I) StringInterpolateNode(TokenPos(), values); |
| 10535 } | 10498 } |
| 10536 return primary; | 10499 return primary; |
| 10537 } | 10500 } |
| 10538 | 10501 |
| 10539 | 10502 |
| 10540 AstNode* Parser::ParsePrimary() { | 10503 AstNode* Parser::ParsePrimary() { |
| 10541 TRACE_PARSER("ParsePrimary"); | 10504 TRACE_PARSER("ParsePrimary"); |
| 10542 ASSERT(!is_top_level_); | 10505 ASSERT(!is_top_level_); |
| 10543 AstNode* primary = NULL; | 10506 AstNode* primary = NULL; |
| 10544 const Token::Kind token = CurrentToken(); | 10507 const Token::Kind token = CurrentToken(); |
| 10545 if (IsFunctionLiteral()) { | 10508 if (IsFunctionLiteral()) { |
| 10546 // The name of a literal function is visible from inside the function, but | 10509 // The name of a literal function is visible from inside the function, but |
| 10547 // must not collide with names in the scope declaring the literal. | 10510 // must not collide with names in the scope declaring the literal. |
| 10548 OpenBlock(); | 10511 OpenBlock(); |
| 10549 primary = ParseFunctionStatement(true); | 10512 primary = ParseFunctionStatement(true); |
| 10550 CloseBlock(); | 10513 CloseBlock(); |
| 10551 } else if (IsIdentifier()) { | 10514 } else if (IsIdentifier()) { |
| 10552 QualIdent qual_ident; | 10515 QualIdent qual_ident; |
| 10553 intptr_t qual_ident_pos = TokenPos(); | 10516 intptr_t qual_ident_pos = TokenPos(); |
| 10554 ParseQualIdent(&qual_ident); | 10517 ParseQualIdent(&qual_ident); |
| 10555 if (qual_ident.lib_prefix == NULL) { | 10518 if (qual_ident.lib_prefix == NULL) { |
| 10556 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, | 10519 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 10557 *qual_ident.ident, | 10520 *qual_ident.ident, |
| 10558 &primary)) { | 10521 &primary)) { |
| 10559 // Check whether the identifier is a type parameter. | 10522 // Check whether the identifier is a type parameter. |
| 10560 if (!current_class().IsNull()) { | 10523 if (!current_class().IsNull()) { |
| 10561 TypeParameter& type_param = TypeParameter::ZoneHandle(I, | 10524 TypeParameter& type_param = TypeParameter::ZoneHandle(I, |
| 10562 current_class().LookupTypeParameter(*(qual_ident.ident))); | 10525 current_class().LookupTypeParameter(*(qual_ident.ident))); |
| 10563 if (!type_param.IsNull()) { | 10526 if (!type_param.IsNull()) { |
| 10564 return new(isolate()) PrimaryNode(qual_ident.ident_pos, type_param); | 10527 return new(I) PrimaryNode(qual_ident.ident_pos, type_param); |
| 10565 } | 10528 } |
| 10566 } | 10529 } |
| 10567 // This is a non-local unqualified identifier so resolve the | 10530 // This is a non-local unqualified identifier so resolve the |
| 10568 // identifier locally in the main app library and all libraries | 10531 // identifier locally in the main app library and all libraries |
| 10569 // imported by it. | 10532 // imported by it. |
| 10570 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos, | 10533 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos, |
| 10571 *qual_ident.ident); | 10534 *qual_ident.ident); |
| 10572 } | 10535 } |
| 10573 } else { | 10536 } else { |
| 10574 // This is a qualified identifier with a library prefix so resolve | 10537 // This is a qualified identifier with a library prefix so resolve |
| 10575 // the identifier locally in that library (we do not include the | 10538 // the identifier locally in that library (we do not include the |
| 10576 // libraries imported by that library). | 10539 // libraries imported by that library). |
| 10577 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos, | 10540 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos, |
| 10578 *qual_ident.lib_prefix, | 10541 *qual_ident.lib_prefix, |
| 10579 *qual_ident.ident); | 10542 *qual_ident.ident); |
| 10580 // If the identifier could not be resolved, throw a NoSuchMethodError. | 10543 // If the identifier could not be resolved, throw a NoSuchMethodError. |
| 10581 // Note: unlike in the case of an unqualified identifier, do not | 10544 // Note: unlike in the case of an unqualified identifier, do not |
| 10582 // interpret the unresolved identifier as an instance method or | 10545 // interpret the unresolved identifier as an instance method or |
| 10583 // instance getter call when compiling an instance method. | 10546 // instance getter call when compiling an instance method. |
| 10584 if (primary == NULL) { | 10547 if (primary == NULL) { |
| 10585 if (qual_ident.lib_prefix->is_deferred_load() && | 10548 if (qual_ident.lib_prefix->is_deferred_load() && |
| 10586 qual_ident.ident->Equals(Symbols::LoadLibrary())) { | 10549 qual_ident.ident->Equals(Symbols::LoadLibrary())) { |
| 10587 // Hack Alert: recognize special 'loadLibrary' call on the | 10550 // Hack Alert: recognize special 'loadLibrary' call on the |
| 10588 // prefix object. The prefix is the primary. Rewind parser and | 10551 // prefix object. The prefix is the primary. Rewind parser and |
| 10589 // let ParseSelectors() handle the loadLibrary call. | 10552 // let ParseSelectors() handle the loadLibrary call. |
| 10590 SetPosition(qual_ident_pos); | 10553 SetPosition(qual_ident_pos); |
| 10591 ConsumeToken(); // Prefix name. | 10554 ConsumeToken(); // Prefix name. |
| 10592 primary = new(isolate()) LiteralNode( | 10555 primary = new(I) LiteralNode(qual_ident_pos, *qual_ident.lib_prefix); |
| 10593 qual_ident_pos, *qual_ident.lib_prefix); | |
| 10594 } else { | 10556 } else { |
| 10595 // TODO(hausner): Ideally we should generate the NoSuchMethodError | 10557 // TODO(hausner): Ideally we should generate the NoSuchMethodError |
| 10596 // later, when we know more about how the unresolved name is used. | 10558 // later, when we know more about how the unresolved name is used. |
| 10597 // For example, we don't know yet whether the unresolved name | 10559 // For example, we don't know yet whether the unresolved name |
| 10598 // refers to a getter or a setter. However, it is more awkward | 10560 // refers to a getter or a setter. However, it is more awkward |
| 10599 // to distinuish four NoSuchMethodError cases all over the place | 10561 // to distinuish four NoSuchMethodError cases all over the place |
| 10600 // in the parser. The four cases are: prefixed vs non-prefixed | 10562 // in the parser. The four cases are: prefixed vs non-prefixed |
| 10601 // name, static vs dynamic context in which the unresolved name | 10563 // name, static vs dynamic context in which the unresolved name |
| 10602 // is used. We cheat a little here by looking at the next token | 10564 // is used. We cheat a little here by looking at the next token |
| 10603 // to determine whether we have an unresolved method call or | 10565 // to determine whether we have an unresolved method call or |
| (...skipping 15 matching lines...) Expand all Loading... |
| 10619 NULL); // No existing function. | 10581 NULL); // No existing function. |
| 10620 } | 10582 } |
| 10621 } | 10583 } |
| 10622 } | 10584 } |
| 10623 ASSERT(primary != NULL); | 10585 ASSERT(primary != NULL); |
| 10624 } else if (token == Token::kTHIS) { | 10586 } else if (token == Token::kTHIS) { |
| 10625 LocalVariable* local = LookupLocalScope(Symbols::This()); | 10587 LocalVariable* local = LookupLocalScope(Symbols::This()); |
| 10626 if (local == NULL) { | 10588 if (local == NULL) { |
| 10627 ErrorMsg("receiver 'this' is not in scope"); | 10589 ErrorMsg("receiver 'this' is not in scope"); |
| 10628 } | 10590 } |
| 10629 primary = new(isolate()) LoadLocalNode(TokenPos(), local); | 10591 primary = new(I) LoadLocalNode(TokenPos(), local); |
| 10630 ConsumeToken(); | 10592 ConsumeToken(); |
| 10631 } else if (token == Token::kINTEGER) { | 10593 } else if (token == Token::kINTEGER) { |
| 10632 const Integer& literal = Integer::ZoneHandle(I, CurrentIntegerLiteral()); | 10594 const Integer& literal = Integer::ZoneHandle(I, CurrentIntegerLiteral()); |
| 10633 primary = new(isolate()) LiteralNode(TokenPos(), literal); | 10595 primary = new(I) LiteralNode(TokenPos(), literal); |
| 10634 ConsumeToken(); | 10596 ConsumeToken(); |
| 10635 } else if (token == Token::kTRUE) { | 10597 } else if (token == Token::kTRUE) { |
| 10636 primary = new(isolate()) LiteralNode(TokenPos(), Bool::True()); | 10598 primary = new(I) LiteralNode(TokenPos(), Bool::True()); |
| 10637 ConsumeToken(); | 10599 ConsumeToken(); |
| 10638 } else if (token == Token::kFALSE) { | 10600 } else if (token == Token::kFALSE) { |
| 10639 primary = new(isolate()) LiteralNode(TokenPos(), Bool::False()); | 10601 primary = new(I) LiteralNode(TokenPos(), Bool::False()); |
| 10640 ConsumeToken(); | 10602 ConsumeToken(); |
| 10641 } else if (token == Token::kNULL) { | 10603 } else if (token == Token::kNULL) { |
| 10642 primary = new(isolate()) LiteralNode(TokenPos(), Instance::ZoneHandle(I)); | 10604 primary = new(I) LiteralNode(TokenPos(), Instance::ZoneHandle(I)); |
| 10643 ConsumeToken(); | 10605 ConsumeToken(); |
| 10644 } else if (token == Token::kLPAREN) { | 10606 } else if (token == Token::kLPAREN) { |
| 10645 ConsumeToken(); | 10607 ConsumeToken(); |
| 10646 const bool saved_mode = SetAllowFunctionLiterals(true); | 10608 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 10647 primary = ParseExpr(kAllowConst, kConsumeCascades); | 10609 primary = ParseExpr(kAllowConst, kConsumeCascades); |
| 10648 SetAllowFunctionLiterals(saved_mode); | 10610 SetAllowFunctionLiterals(saved_mode); |
| 10649 ExpectToken(Token::kRPAREN); | 10611 ExpectToken(Token::kRPAREN); |
| 10650 } else if (token == Token::kDOUBLE) { | 10612 } else if (token == Token::kDOUBLE) { |
| 10651 Double& double_value = Double::ZoneHandle(I, CurrentDoubleLiteral()); | 10613 Double& double_value = Double::ZoneHandle(I, CurrentDoubleLiteral()); |
| 10652 if (double_value.IsNull()) { | 10614 if (double_value.IsNull()) { |
| 10653 ErrorMsg("invalid double literal"); | 10615 ErrorMsg("invalid double literal"); |
| 10654 } | 10616 } |
| 10655 primary = new(isolate()) LiteralNode(TokenPos(), double_value); | 10617 primary = new(I) LiteralNode(TokenPos(), double_value); |
| 10656 ConsumeToken(); | 10618 ConsumeToken(); |
| 10657 } else if (token == Token::kSTRING) { | 10619 } else if (token == Token::kSTRING) { |
| 10658 primary = ParseStringLiteral(true); | 10620 primary = ParseStringLiteral(true); |
| 10659 } else if (token == Token::kNEW) { | 10621 } else if (token == Token::kNEW) { |
| 10660 ConsumeToken(); | 10622 ConsumeToken(); |
| 10661 primary = ParseNewOperator(Token::kNEW); | 10623 primary = ParseNewOperator(Token::kNEW); |
| 10662 } else if (token == Token::kCONST) { | 10624 } else if (token == Token::kCONST) { |
| 10663 if ((LookaheadToken(1) == Token::kLT) || | 10625 if ((LookaheadToken(1) == Token::kLT) || |
| 10664 (LookaheadToken(1) == Token::kLBRACK) || | 10626 (LookaheadToken(1) == Token::kLBRACK) || |
| 10665 (LookaheadToken(1) == Token::kINDEX) || | 10627 (LookaheadToken(1) == Token::kINDEX) || |
| 10666 (LookaheadToken(1) == Token::kLBRACE)) { | 10628 (LookaheadToken(1) == Token::kLBRACE)) { |
| 10667 primary = ParseCompoundLiteral(); | 10629 primary = ParseCompoundLiteral(); |
| 10668 } else { | 10630 } else { |
| 10669 ConsumeToken(); | 10631 ConsumeToken(); |
| 10670 primary = ParseNewOperator(Token::kCONST); | 10632 primary = ParseNewOperator(Token::kCONST); |
| 10671 } | 10633 } |
| 10672 } else if (token == Token::kLT || | 10634 } else if (token == Token::kLT || |
| 10673 token == Token::kLBRACK || | 10635 token == Token::kLBRACK || |
| 10674 token == Token::kINDEX || | 10636 token == Token::kINDEX || |
| 10675 token == Token::kLBRACE) { | 10637 token == Token::kLBRACE) { |
| 10676 primary = ParseCompoundLiteral(); | 10638 primary = ParseCompoundLiteral(); |
| 10677 } else if (token == Token::kHASH) { | 10639 } else if (token == Token::kHASH) { |
| 10678 primary = ParseSymbolLiteral(); | 10640 primary = ParseSymbolLiteral(); |
| 10679 } else if (token == Token::kSUPER) { | 10641 } else if (token == Token::kSUPER) { |
| 10680 if (current_function().is_static()) { | 10642 if (current_function().is_static()) { |
| 10681 ErrorMsg("cannot access superclass from static method"); | 10643 ErrorMsg("cannot access superclass from static method"); |
| 10682 } | 10644 } |
| 10683 if (current_class().SuperClass() == Class::null()) { | 10645 if (current_class().SuperClass() == Class::null()) { |
| 10684 ErrorMsg("class '%s' does not have a superclass", | 10646 ErrorMsg("class '%s' does not have a superclass", |
| 10685 String::Handle(isolate(), current_class().Name()).ToCString()); | 10647 String::Handle(I, current_class().Name()).ToCString()); |
| 10686 } | 10648 } |
| 10687 if (current_class().IsMixinApplication()) { | 10649 if (current_class().IsMixinApplication()) { |
| 10688 const Type& mixin_type = Type::Handle(isolate(), current_class().mixin()); | 10650 const Type& mixin_type = Type::Handle(I, current_class().mixin()); |
| 10689 if (mixin_type.type_class() == current_function().origin()) { | 10651 if (mixin_type.type_class() == current_function().origin()) { |
| 10690 ErrorMsg("method of mixin class '%s' may not refer to 'super'", | 10652 ErrorMsg("method of mixin class '%s' may not refer to 'super'", |
| 10691 String::Handle(isolate(), Class::Handle(isolate(), | 10653 String::Handle(I, Class::Handle(I, |
| 10692 current_function().origin()).Name()).ToCString()); | 10654 current_function().origin()).Name()).ToCString()); |
| 10693 } | 10655 } |
| 10694 } | 10656 } |
| 10695 const intptr_t super_pos = TokenPos(); | 10657 const intptr_t super_pos = TokenPos(); |
| 10696 ConsumeToken(); | 10658 ConsumeToken(); |
| 10697 if (CurrentToken() == Token::kPERIOD) { | 10659 if (CurrentToken() == Token::kPERIOD) { |
| 10698 ConsumeToken(); | 10660 ConsumeToken(); |
| 10699 const intptr_t ident_pos = TokenPos(); | 10661 const intptr_t ident_pos = TokenPos(); |
| 10700 const String& ident = *ExpectIdentifier("identifier expected"); | 10662 const String& ident = *ExpectIdentifier("identifier expected"); |
| 10701 if (CurrentToken() == Token::kLPAREN) { | 10663 if (CurrentToken() == Token::kLPAREN) { |
| 10702 primary = ParseSuperCall(ident); | 10664 primary = ParseSuperCall(ident); |
| 10703 } else { | 10665 } else { |
| 10704 primary = ParseSuperFieldAccess(ident, ident_pos); | 10666 primary = ParseSuperFieldAccess(ident, ident_pos); |
| 10705 } | 10667 } |
| 10706 } else if ((CurrentToken() == Token::kLBRACK) || | 10668 } else if ((CurrentToken() == Token::kLBRACK) || |
| 10707 Token::CanBeOverloaded(CurrentToken()) || | 10669 Token::CanBeOverloaded(CurrentToken()) || |
| 10708 (CurrentToken() == Token::kNE)) { | 10670 (CurrentToken() == Token::kNE)) { |
| 10709 primary = ParseSuperOperator(); | 10671 primary = ParseSuperOperator(); |
| 10710 } else { | 10672 } else { |
| 10711 primary = new(isolate()) PrimaryNode(super_pos, Symbols::Super()); | 10673 primary = new(I) PrimaryNode(super_pos, Symbols::Super()); |
| 10712 } | 10674 } |
| 10713 } else { | 10675 } else { |
| 10714 UnexpectedToken(); | 10676 UnexpectedToken(); |
| 10715 } | 10677 } |
| 10716 return primary; | 10678 return primary; |
| 10717 } | 10679 } |
| 10718 | 10680 |
| 10719 | 10681 |
| 10720 // Evaluate expression in expr and return the value. The expression must | 10682 // Evaluate expression in expr and return the value. The expression must |
| 10721 // be a compile time constant. | 10683 // be a compile time constant. |
| 10722 const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) { | 10684 const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) { |
| 10723 if (expr->IsLiteralNode()) { | 10685 if (expr->IsLiteralNode()) { |
| 10724 return expr->AsLiteralNode()->literal(); | 10686 return expr->AsLiteralNode()->literal(); |
| 10725 } else if (expr->IsLoadLocalNode() && | 10687 } else if (expr->IsLoadLocalNode() && |
| 10726 expr->AsLoadLocalNode()->local().IsConst()) { | 10688 expr->AsLoadLocalNode()->local().IsConst()) { |
| 10727 return *expr->AsLoadLocalNode()->local().ConstValue(); | 10689 return *expr->AsLoadLocalNode()->local().ConstValue(); |
| 10728 } else if (expr->IsLoadStaticFieldNode()) { | 10690 } else if (expr->IsLoadStaticFieldNode()) { |
| 10729 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 10691 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
| 10730 // We already checked that this field is const and has been | 10692 // We already checked that this field is const and has been |
| 10731 // initialized. | 10693 // initialized. |
| 10732 ASSERT(field.is_const()); | 10694 ASSERT(field.is_const()); |
| 10733 ASSERT(field.value() != Object::sentinel().raw()); | 10695 ASSERT(field.value() != Object::sentinel().raw()); |
| 10734 ASSERT(field.value() != Object::transition_sentinel().raw()); | 10696 ASSERT(field.value() != Object::transition_sentinel().raw()); |
| 10735 return Instance::ZoneHandle(I, field.value()); | 10697 return Instance::ZoneHandle(I, field.value()); |
| 10736 } else { | 10698 } else { |
| 10737 ASSERT(expr->EvalConstExpr() != NULL); | 10699 ASSERT(expr->EvalConstExpr() != NULL); |
| 10738 ReturnNode* ret = new(isolate()) ReturnNode(expr->token_pos(), expr); | 10700 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); |
| 10739 // Compile time constant expressions cannot reference anything from a | 10701 // Compile time constant expressions cannot reference anything from a |
| 10740 // local scope. | 10702 // local scope. |
| 10741 LocalScope* empty_scope = new(isolate()) LocalScope(NULL, 0, 0); | 10703 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); |
| 10742 SequenceNode* seq = new(isolate()) SequenceNode(expr->token_pos(), | 10704 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), |
| 10743 empty_scope); | 10705 empty_scope); |
| 10744 seq->Add(ret); | 10706 seq->Add(ret); |
| 10745 | 10707 |
| 10746 Object& result = Object::Handle(isolate(), Compiler::ExecuteOnce(seq)); | 10708 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); |
| 10747 if (result.IsError()) { | 10709 if (result.IsError()) { |
| 10748 AppendErrorMsg(Error::Cast(result), | 10710 AppendErrorMsg(Error::Cast(result), |
| 10749 expr_pos, | 10711 expr_pos, |
| 10750 "error evaluating constant expression"); | 10712 "error evaluating constant expression"); |
| 10751 } | 10713 } |
| 10752 ASSERT(result.IsInstance()); | 10714 ASSERT(result.IsInstance()); |
| 10753 Instance& value = Instance::ZoneHandle(I); | 10715 Instance& value = Instance::ZoneHandle(I); |
| 10754 value ^= result.raw(); | 10716 value ^= result.raw(); |
| 10755 value = TryCanonicalize(value, TokenPos()); | 10717 value = TryCanonicalize(value, TokenPos()); |
| 10756 return value; | 10718 return value; |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11084 void Parser::SkipQualIdent() { | 11046 void Parser::SkipQualIdent() { |
| 11085 ASSERT(IsIdentifier()); | 11047 ASSERT(IsIdentifier()); |
| 11086 ConsumeToken(); | 11048 ConsumeToken(); |
| 11087 if (CurrentToken() == Token::kPERIOD) { | 11049 if (CurrentToken() == Token::kPERIOD) { |
| 11088 ConsumeToken(); // Consume the kPERIOD token. | 11050 ConsumeToken(); // Consume the kPERIOD token. |
| 11089 ExpectIdentifier("identifier expected after '.'"); | 11051 ExpectIdentifier("identifier expected after '.'"); |
| 11090 } | 11052 } |
| 11091 } | 11053 } |
| 11092 | 11054 |
| 11093 } // namespace dart | 11055 } // namespace dart |
| OLD | NEW |