| 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 int TraceParser::indent_ = 0; | 70 int TraceParser::indent_ = 0; |
| 71 | 71 |
| 72 #define TRACE_PARSER(s) \ | 72 #define TRACE_PARSER(s) \ |
| 73 TraceParser __p__(this->token_index_, this->script_, s) | 73 TraceParser __p__(this->token_index_, this->script_, s) |
| 74 | 74 |
| 75 #else // not DEBUG | 75 #else // not DEBUG |
| 76 #define TRACE_PARSER(s) | 76 #define TRACE_PARSER(s) |
| 77 #endif // DEBUG | 77 #endif // DEBUG |
| 78 | 78 |
| 79 | 79 |
| 80 template<typename T> | 80 static RawTypeArguments* NewTypeArguments(const GrowableObjectArray& objs) { |
| 81 static RawArray* NewArray(const GrowableArray<T*>& objs) { | |
| 82 Array& a = Array::Handle(Array::New(objs.length(), Heap::kOld)); | |
| 83 for (int i = 0; i < objs.length(); i++) { | |
| 84 a.SetAt(i, *objs[i]); | |
| 85 } | |
| 86 return a.raw(); | |
| 87 } | |
| 88 | |
| 89 | |
| 90 static RawTypeArguments* NewTypeArguments( | |
| 91 const GrowableArray<AbstractType*>& objs) { | |
| 92 const TypeArguments& a = | 81 const TypeArguments& a = |
| 93 TypeArguments::Handle(TypeArguments::New(objs.length())); | 82 TypeArguments::Handle(TypeArguments::New(objs.Length())); |
| 94 for (int i = 0; i < objs.length(); i++) { | 83 AbstractType& type = AbstractType::Handle(); |
| 95 a.SetTypeAt(i, *objs[i]); | 84 for (int i = 0; i < objs.Length(); i++) { |
| 85 type ^= objs.At(i); |
| 86 a.SetTypeAt(i, type); |
| 96 } | 87 } |
| 97 // Cannot canonicalize TypeArgument yet as its types may not have been | 88 // Cannot canonicalize TypeArgument yet as its types may not have been |
| 98 // finalized yet. | 89 // finalized yet. |
| 99 return a.raw(); | 90 return a.raw(); |
| 100 } | 91 } |
| 101 | 92 |
| 102 | 93 |
| 103 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, | 94 static ThrowNode* CreateEvalConstConstructorThrow(intptr_t token_pos, |
| 104 const Object& obj) { | 95 const Object& obj) { |
| 105 UnhandledException& excp = UnhandledException::Handle(); | 96 UnhandledException& excp = UnhandledException::Handle(); |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 class ClassDesc : public ValueObject { | 404 class ClassDesc : public ValueObject { |
| 414 public: | 405 public: |
| 415 ClassDesc(const Class& cls, | 406 ClassDesc(const Class& cls, |
| 416 const String& cls_name, | 407 const String& cls_name, |
| 417 bool is_interface, | 408 bool is_interface, |
| 418 intptr_t token_pos) | 409 intptr_t token_pos) |
| 419 : clazz_(cls), | 410 : clazz_(cls), |
| 420 class_name_(cls_name), | 411 class_name_(cls_name), |
| 421 is_interface_(is_interface), | 412 is_interface_(is_interface), |
| 422 token_pos_(token_pos), | 413 token_pos_(token_pos), |
| 423 functions_(4), | 414 functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 424 fields_(4) { | 415 fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) { |
| 425 } | 416 } |
| 426 | 417 |
| 427 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { | 418 bool FunctionNameExists(const String& name, RawFunction::Kind kind) const { |
| 428 // First check if a function or field of same name exists. | 419 // First check if a function or field of same name exists. |
| 429 if (NameExists<Function>(functions_, name) || | 420 if (NameExists<Function>(functions_, name) || |
| 430 NameExists<Field>(fields_, name)) { | 421 NameExists<Field>(fields_, name)) { |
| 431 return true; | 422 return true; |
| 432 } | 423 } |
| 433 String& accessor_name = String::Handle(); | 424 String& accessor_name = String::Handle(); |
| 434 if (kind != RawFunction::kSetterFunction) { | 425 if (kind != RawFunction::kSetterFunction) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 457 // Now check if a getter/setter function of same name exists. | 448 // Now check if a getter/setter function of same name exists. |
| 458 String& getter_name = String::Handle(Field::GetterName(name)); | 449 String& getter_name = String::Handle(Field::GetterName(name)); |
| 459 String& setter_name = String::Handle(Field::SetterName(name)); | 450 String& setter_name = String::Handle(Field::SetterName(name)); |
| 460 if (NameExists<Function>(functions_, getter_name) || | 451 if (NameExists<Function>(functions_, getter_name) || |
| 461 NameExists<Function>(functions_, setter_name)) { | 452 NameExists<Function>(functions_, setter_name)) { |
| 462 return true; | 453 return true; |
| 463 } | 454 } |
| 464 return false; | 455 return false; |
| 465 } | 456 } |
| 466 | 457 |
| 467 void AddFunction(Function* function) { | 458 void AddFunction(const Function& function) { |
| 468 ASSERT(!NameExists<Function>(functions_, String::Handle(function->name()))); | 459 ASSERT(!NameExists<Function>(functions_, String::Handle(function.name()))); |
| 469 functions_.Add(function); | 460 functions_.Add(function); |
| 470 } | 461 } |
| 471 | 462 |
| 472 const GrowableArray<Function*>& functions() const { | 463 const GrowableObjectArray& functions() const { |
| 473 return functions_; | 464 return functions_; |
| 474 } | 465 } |
| 475 | 466 |
| 476 void AddField(Field* field) { | 467 void AddField(const Field& field) { |
| 477 ASSERT(!NameExists<Field>(fields_, String::Handle(field->name()))); | 468 ASSERT(!NameExists<Field>(fields_, String::Handle(field.name()))); |
| 478 fields_.Add(field); | 469 fields_.Add(field); |
| 479 } | 470 } |
| 480 | 471 |
| 481 const GrowableArray<Field*>& fields() const { | 472 const GrowableObjectArray& fields() const { |
| 482 return fields_; | 473 return fields_; |
| 483 } | 474 } |
| 484 | 475 |
| 485 RawClass* clazz() const { | 476 RawClass* clazz() const { |
| 486 return clazz_.raw(); | 477 return clazz_.raw(); |
| 487 } | 478 } |
| 488 | 479 |
| 489 const String& class_name() const { | 480 const String& class_name() const { |
| 490 return class_name_; | 481 return class_name_; |
| 491 } | 482 } |
| 492 | 483 |
| 493 bool is_interface() const { | 484 bool is_interface() const { |
| 494 return is_interface_; | 485 return is_interface_; |
| 495 } | 486 } |
| 496 | 487 |
| 497 bool has_constructor() const { | 488 bool has_constructor() const { |
| 498 for (int i = 0; i < functions_.length(); i++) { | 489 Function& func = Function::Handle(); |
| 499 if (functions_[i]->kind() == RawFunction::kConstructor) { | 490 for (int i = 0; i < functions_.Length(); i++) { |
| 491 func ^= functions_.At(i); |
| 492 if (func.kind() == RawFunction::kConstructor) { |
| 500 return true; | 493 return true; |
| 501 } | 494 } |
| 502 } | 495 } |
| 503 return false; | 496 return false; |
| 504 } | 497 } |
| 505 | 498 |
| 506 intptr_t token_pos() const { | 499 intptr_t token_pos() const { |
| 507 return token_pos_; | 500 return token_pos_; |
| 508 } | 501 } |
| 509 | 502 |
| 510 void AddMember(const MemberDesc& member) { | 503 void AddMember(const MemberDesc& member) { |
| 511 members_.Add(member); | 504 members_.Add(member); |
| 512 } | 505 } |
| 513 | 506 |
| 514 const GrowableArray<MemberDesc>& members() const { | 507 const GrowableArray<MemberDesc>& members() const { |
| 515 return members_; | 508 return members_; |
| 516 } | 509 } |
| 517 | 510 |
| 518 MemberDesc* LookupMember(const String& name) const { | 511 MemberDesc* LookupMember(const String& name) const { |
| 519 for (int i = 0; i < members_.length(); i++) { | 512 for (int i = 0; i < members_.length(); i++) { |
| 520 if (name.Equals(*members_[i].name)) { | 513 if (name.Equals(*members_[i].name)) { |
| 521 return &members_[i]; | 514 return &members_[i]; |
| 522 } | 515 } |
| 523 } | 516 } |
| 524 return NULL; | 517 return NULL; |
| 525 } | 518 } |
| 526 | 519 |
| 527 private: | 520 private: |
| 528 template<typename T> | 521 template<typename T> |
| 529 bool NameExists(const GrowableArray<T*>& list, const String& name) const { | 522 bool NameExists(const GrowableObjectArray& list, const String& name) const { |
| 530 String& test_name = String::Handle(); | 523 String& test_name = String::Handle(); |
| 531 for (int i = 0; i < list.length(); i++) { | 524 T& obj = T::Handle(); |
| 532 test_name = list[i]->name(); | 525 for (int i = 0; i < list.Length(); i++) { |
| 526 obj ^= list.At(i); |
| 527 test_name = obj.name(); |
| 533 if (name.Equals(test_name)) { | 528 if (name.Equals(test_name)) { |
| 534 return true; | 529 return true; |
| 535 } | 530 } |
| 536 } | 531 } |
| 537 return false; | 532 return false; |
| 538 } | 533 } |
| 539 | 534 |
| 540 const Class& clazz_; | 535 const Class& clazz_; |
| 541 const String& class_name_; | 536 const String& class_name_; |
| 542 const bool is_interface_; | 537 const bool is_interface_; |
| 543 intptr_t token_pos_; // Token index of "class" keyword. | 538 intptr_t token_pos_; // Token index of "class" keyword. |
| 544 GrowableArray<Function*> functions_; | 539 GrowableObjectArray& functions_; |
| 545 GrowableArray<Field*> fields_; | 540 GrowableObjectArray& fields_; |
| 546 GrowableArray<MemberDesc> members_; | 541 GrowableArray<MemberDesc> members_; |
| 547 }; | 542 }; |
| 548 | 543 |
| 549 | 544 |
| 550 struct TopLevel { | 545 struct TopLevel { |
| 551 TopLevel() : fields(4), functions(4) { } | 546 TopLevel() : |
| 547 fields(GrowableObjectArray::Handle(GrowableObjectArray::New())), |
| 548 functions(GrowableObjectArray::Handle(GrowableObjectArray::New())) { } |
| 552 | 549 |
| 553 GrowableArray<Field*> fields; | 550 GrowableObjectArray& fields; |
| 554 GrowableArray<Function*> functions; | 551 GrowableObjectArray& functions; |
| 555 }; | 552 }; |
| 556 | 553 |
| 557 | 554 |
| 558 static bool HasReturnNode(SequenceNode* seq) { | 555 static bool HasReturnNode(SequenceNode* seq) { |
| 559 if (seq->length() == 0) { | 556 if (seq->length() == 0) { |
| 560 return false; | 557 return false; |
| 561 } else if ((seq->length()) == 1 && | 558 } else if ((seq->length()) == 1 && |
| 562 (seq->NodeAt(seq->length() - 1)->IsSequenceNode())) { | 559 (seq->NodeAt(seq->length() - 1)->IsSequenceNode())) { |
| 563 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); | 560 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); |
| 564 } else { | 561 } else { |
| (...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2147 function_kind = RawFunction::kConstructor; | 2144 function_kind = RawFunction::kConstructor; |
| 2148 } else if (method->has_abstract) { | 2145 } else if (method->has_abstract) { |
| 2149 function_kind = RawFunction::kAbstract; | 2146 function_kind = RawFunction::kAbstract; |
| 2150 } else if (method->IsGetter()) { | 2147 } else if (method->IsGetter()) { |
| 2151 function_kind = RawFunction::kGetterFunction; | 2148 function_kind = RawFunction::kGetterFunction; |
| 2152 } else if (method->IsSetter()) { | 2149 } else if (method->IsSetter()) { |
| 2153 function_kind = RawFunction::kSetterFunction; | 2150 function_kind = RawFunction::kSetterFunction; |
| 2154 } else { | 2151 } else { |
| 2155 function_kind = RawFunction::kFunction; | 2152 function_kind = RawFunction::kFunction; |
| 2156 } | 2153 } |
| 2157 Function& func = Function::ZoneHandle( | 2154 Function& func = Function::Handle( |
| 2158 Function::New(*method->name, | 2155 Function::New(*method->name, |
| 2159 function_kind, | 2156 function_kind, |
| 2160 method->has_static, | 2157 method->has_static, |
| 2161 method->has_const, | 2158 method->has_const, |
| 2162 method_pos)); | 2159 method_pos)); |
| 2163 func.set_result_type(*method->type); | 2160 func.set_result_type(*method->type); |
| 2164 func.set_end_token_index(method_end_pos); | 2161 func.set_end_token_index(method_end_pos); |
| 2165 | 2162 |
| 2166 // No need to resolve parameter types yet, or add parameters to local scope. | 2163 // No need to resolve parameter types yet, or add parameters to local scope. |
| 2167 ASSERT(is_top_level_); | 2164 ASSERT(is_top_level_); |
| 2168 AddFormalParamsToFunction(&method->params, func); | 2165 AddFormalParamsToFunction(&method->params, func); |
| 2169 members->AddFunction(&func); | 2166 members->AddFunction(func); |
| 2170 } | 2167 } |
| 2171 | 2168 |
| 2172 | 2169 |
| 2173 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 2170 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
| 2174 TRACE_PARSER("ParseFieldDefinition"); | 2171 TRACE_PARSER("ParseFieldDefinition"); |
| 2175 // The parser has read the first field name and is now at the token | 2172 // The parser has read the first field name and is now at the token |
| 2176 // after the field name. | 2173 // after the field name. |
| 2177 ASSERT(CurrentToken() == Token::kSEMICOLON || | 2174 ASSERT(CurrentToken() == Token::kSEMICOLON || |
| 2178 CurrentToken() == Token::kCOMMA || | 2175 CurrentToken() == Token::kCOMMA || |
| 2179 CurrentToken() == Token::kASSIGN); | 2176 CurrentToken() == Token::kASSIGN); |
| 2180 ASSERT(field->type != NULL); | 2177 ASSERT(field->type != NULL); |
| 2181 ASSERT(field->name_pos > 0); | 2178 ASSERT(field->name_pos > 0); |
| 2182 ASSERT(current_member_ == field); | 2179 ASSERT(current_member_ == field); |
| 2183 | 2180 |
| 2184 if (field->has_const) { | 2181 if (field->has_const) { |
| 2185 ErrorMsg("keyword 'const' not allowed in field declaration"); | 2182 ErrorMsg("keyword 'const' not allowed in field declaration"); |
| 2186 } | 2183 } |
| 2187 if (field->has_abstract) { | 2184 if (field->has_abstract) { |
| 2188 ErrorMsg("keyword 'abstract' not allowed in field declaration"); | 2185 ErrorMsg("keyword 'abstract' not allowed in field declaration"); |
| 2189 } | 2186 } |
| 2190 if (field->has_factory) { | 2187 if (field->has_factory) { |
| 2191 ErrorMsg("keyword 'factory' not allowed in field declaration"); | 2188 ErrorMsg("keyword 'factory' not allowed in field declaration"); |
| 2192 } | 2189 } |
| 2193 if (members->FieldNameExists(*field->name)) { | 2190 if (members->FieldNameExists(*field->name)) { |
| 2194 ErrorMsg(field->name_pos, | 2191 ErrorMsg(field->name_pos, |
| 2195 "'%s' field/method already defined\n", field->name->ToCString()); | 2192 "'%s' field/method already defined\n", field->name->ToCString()); |
| 2196 } | 2193 } |
| 2194 Function& getter = Function::Handle(); |
| 2195 Function& setter = Function::Handle(); |
| 2196 Field& class_field = Field::Handle(); |
| 2197 while (true) { | 2197 while (true) { |
| 2198 bool has_initializer = CurrentToken() == Token::kASSIGN; | 2198 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 2199 if (has_initializer) { | 2199 if (has_initializer) { |
| 2200 ConsumeToken(); | 2200 ConsumeToken(); |
| 2201 // For static final fields, the initialization expression | 2201 // For static final fields, the initialization expression |
| 2202 // will be parsed through the kConstImplicitGetter method | 2202 // will be parsed through the kConstImplicitGetter method |
| 2203 // invocation/compilation. | 2203 // invocation/compilation. |
| 2204 // For instance fields, the expression is parsed when a constructor | 2204 // For instance fields, the expression is parsed when a constructor |
| 2205 // is compiled. | 2205 // is compiled. |
| 2206 SkipExpr(); | 2206 SkipExpr(); |
| 2207 } else { | 2207 } else { |
| 2208 if (field->has_static && field->has_final) { | 2208 if (field->has_static && field->has_final) { |
| 2209 ErrorMsg(field->name_pos, | 2209 ErrorMsg(field->name_pos, |
| 2210 "static final field '%s' must have an initializer expression", | 2210 "static final field '%s' must have an initializer expression", |
| 2211 field->name->ToCString()); | 2211 field->name->ToCString()); |
| 2212 } | 2212 } |
| 2213 } | 2213 } |
| 2214 | 2214 |
| 2215 // Create the field object. | 2215 // Create the field object. |
| 2216 Field& class_field = Field::ZoneHandle( | 2216 class_field = Field::New(*field->name, |
| 2217 Field::New(*field->name, | 2217 field->has_static, |
| 2218 field->has_static, | 2218 field->has_final, |
| 2219 field->has_final, | 2219 field->name_pos); |
| 2220 field->name_pos)); | |
| 2221 class_field.set_type(*field->type); | 2220 class_field.set_type(*field->type); |
| 2222 class_field.set_has_initializer(has_initializer); | 2221 class_field.set_has_initializer(has_initializer); |
| 2223 members->AddField(&class_field); | 2222 members->AddField(class_field); |
| 2224 | 2223 |
| 2225 // For static final fields, set value to "uninitialized" and | 2224 // For static final fields, set value to "uninitialized" and |
| 2226 // create a kConstImplicitGetter getter method. | 2225 // create a kConstImplicitGetter getter method. |
| 2227 if (field->has_static && has_initializer) { | 2226 if (field->has_static && has_initializer) { |
| 2228 class_field.set_value(Instance::Handle(Object::sentinel())); | 2227 class_field.set_value(Instance::Handle(Object::sentinel())); |
| 2229 String& getter_name = | 2228 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
| 2230 String::ZoneHandle(Field::GetterSymbol(*field->name)); | 2229 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter, |
| 2231 Function& getter = Function::ZoneHandle( | 2230 field->has_static, field->has_final, |
| 2232 Function::New(getter_name, RawFunction::kConstImplicitGetter, | 2231 field->name_pos); |
| 2233 field->has_static, field->has_final, | |
| 2234 field->name_pos)); | |
| 2235 getter.set_result_type(*field->type); | 2232 getter.set_result_type(*field->type); |
| 2236 members->AddFunction(&getter); | 2233 members->AddFunction(getter); |
| 2237 } | 2234 } |
| 2238 | 2235 |
| 2239 // For instance fields, we create implicit getter and setter methods. | 2236 // For instance fields, we create implicit getter and setter methods. |
| 2240 if (!field->has_static) { | 2237 if (!field->has_static) { |
| 2241 String& getter_name = | 2238 String& getter_name = String::Handle(Field::GetterSymbol(*field->name)); |
| 2242 String::ZoneHandle(Field::GetterSymbol(*field->name)); | 2239 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
| 2243 Function& getter = Function::ZoneHandle( | 2240 field->has_static, field->has_final, |
| 2244 Function::New(getter_name, RawFunction::kImplicitGetter, | 2241 field->name_pos); |
| 2245 field->has_static, field->has_final, | |
| 2246 field->name_pos)); | |
| 2247 ParamList params; | 2242 ParamList params; |
| 2248 params.AddReceiver(token_index_); | 2243 params.AddReceiver(token_index_); |
| 2249 getter.set_result_type(*field->type); | 2244 getter.set_result_type(*field->type); |
| 2250 AddFormalParamsToFunction(¶ms, getter); | 2245 AddFormalParamsToFunction(¶ms, getter); |
| 2251 members->AddFunction(&getter); | 2246 members->AddFunction(getter); |
| 2252 if (!field->has_final) { | 2247 if (!field->has_final) { |
| 2253 // Build a setter accessor for non-const fields. | 2248 // Build a setter accessor for non-const fields. |
| 2254 String& setter_name = String::ZoneHandle( | 2249 String& setter_name = String::Handle(Field::SetterSymbol(*field->name)); |
| 2255 Field::SetterSymbol(*field->name)); | 2250 setter = Function::New(setter_name, RawFunction::kImplicitSetter, |
| 2256 Function& setter = Function::ZoneHandle( | 2251 field->has_static, field->has_final, |
| 2257 Function::New(setter_name, RawFunction::kImplicitSetter, | 2252 field->name_pos); |
| 2258 field->has_static, field->has_final, | |
| 2259 field->name_pos)); | |
| 2260 ParamList params; | 2253 ParamList params; |
| 2261 params.AddReceiver(token_index_); | 2254 params.AddReceiver(token_index_); |
| 2262 params.AddFinalParameter(token_index_, "value", field->type); | 2255 params.AddFinalParameter(token_index_, "value", field->type); |
| 2263 setter.set_result_type(Type::Handle(Type::VoidType())); | 2256 setter.set_result_type(Type::Handle(Type::VoidType())); |
| 2264 AddFormalParamsToFunction(¶ms, setter); | 2257 AddFormalParamsToFunction(¶ms, setter); |
| 2265 members->AddFunction(&setter); | 2258 members->AddFunction(setter); |
| 2266 } | 2259 } |
| 2267 } | 2260 } |
| 2268 | 2261 |
| 2269 if (CurrentToken() != Token::kCOMMA) { | 2262 if (CurrentToken() != Token::kCOMMA) { |
| 2270 break; | 2263 break; |
| 2271 } | 2264 } |
| 2272 ConsumeToken(); | 2265 ConsumeToken(); |
| 2273 field->name_pos = this->token_index_; | 2266 field->name_pos = this->token_index_; |
| 2274 field->name = ExpectIdentifier("field name expected"); | 2267 field->name = ExpectIdentifier("field name expected"); |
| 2275 } | 2268 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2506 } | 2499 } |
| 2507 ParseFieldDefinition(members, &member); | 2500 ParseFieldDefinition(members, &member); |
| 2508 } else { | 2501 } else { |
| 2509 UnexpectedToken(); | 2502 UnexpectedToken(); |
| 2510 } | 2503 } |
| 2511 current_member_ = NULL; | 2504 current_member_ = NULL; |
| 2512 members->AddMember(member); | 2505 members->AddMember(member); |
| 2513 } | 2506 } |
| 2514 | 2507 |
| 2515 | 2508 |
| 2516 void Parser::ParseClassDefinition(GrowableArray<const Class*>* classes) { | 2509 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { |
| 2517 TRACE_PARSER("ParseClassDefinition"); | 2510 TRACE_PARSER("ParseClassDefinition"); |
| 2518 const intptr_t class_pos = token_index_; | 2511 const intptr_t class_pos = token_index_; |
| 2519 ExpectToken(Token::kCLASS); | 2512 ExpectToken(Token::kCLASS); |
| 2520 const intptr_t classname_pos = token_index_; | 2513 const intptr_t classname_pos = token_index_; |
| 2521 String& class_name = *ExpectTypeIdentifier("class name expected"); | 2514 String& class_name = *ExpectTypeIdentifier("class name expected"); |
| 2522 if (FLAG_trace_parser) { | 2515 if (FLAG_trace_parser) { |
| 2523 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 2516 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 2524 } | 2517 } |
| 2525 Class& cls = Class::ZoneHandle(); | 2518 Class& cls = Class::Handle(); |
| 2526 Object& obj = Object::Handle(library_.LookupObject(class_name)); | 2519 Object& obj = Object::Handle(library_.LookupObject(class_name)); |
| 2527 if (obj.IsNull()) { | 2520 if (obj.IsNull()) { |
| 2528 cls = Class::New(class_name, script_, classname_pos); | 2521 cls = Class::New(class_name, script_, classname_pos); |
| 2529 library_.AddClass(cls); | 2522 library_.AddClass(cls); |
| 2530 } else { | 2523 } else { |
| 2531 if (!obj.IsClass()) { | 2524 if (!obj.IsClass()) { |
| 2532 ErrorMsg(classname_pos, "'%s' is already defined", | 2525 ErrorMsg(classname_pos, "'%s' is already defined", |
| 2533 class_name.ToCString()); | 2526 class_name.ToCString()); |
| 2534 } | 2527 } |
| 2535 cls ^= obj.raw(); | 2528 cls ^= obj.raw(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2579 } | 2572 } |
| 2580 | 2573 |
| 2581 ExpectToken(Token::kLBRACE); | 2574 ExpectToken(Token::kLBRACE); |
| 2582 ClassDesc members(cls, class_name, false, class_pos); | 2575 ClassDesc members(cls, class_name, false, class_pos); |
| 2583 while (CurrentToken() != Token::kRBRACE) { | 2576 while (CurrentToken() != Token::kRBRACE) { |
| 2584 ParseClassMemberDefinition(&members); | 2577 ParseClassMemberDefinition(&members); |
| 2585 } | 2578 } |
| 2586 ExpectToken(Token::kRBRACE); | 2579 ExpectToken(Token::kRBRACE); |
| 2587 | 2580 |
| 2588 CheckConstructors(&members); | 2581 CheckConstructors(&members); |
| 2589 cls.SetFields(Array::Handle(NewArray<Field>(members.fields()))); | 2582 |
| 2583 Array& array = Array::Handle(); |
| 2584 array = Array::MakeArray(members.fields()); |
| 2585 cls.SetFields(array); |
| 2586 |
| 2590 // Creating a new array for functions marks the class as parsed. | 2587 // Creating a new array for functions marks the class as parsed. |
| 2591 cls.SetFunctions(Array::Handle(NewArray<Function>(members.functions()))); | 2588 array = Array::MakeArray(members.functions()); |
| 2592 classes->Add(&cls); | 2589 cls.SetFunctions(array); |
| 2590 |
| 2591 pending_classes.Add(cls, Heap::kOld); |
| 2593 } | 2592 } |
| 2594 | 2593 |
| 2595 | 2594 |
| 2596 // 1. Add an implicit constructor if no explicit constructor is present. | 2595 // 1. Add an implicit constructor if no explicit constructor is present. |
| 2597 // 2. Check for cycles in constructor redirection. | 2596 // 2. Check for cycles in constructor redirection. |
| 2598 void Parser::CheckConstructors(ClassDesc* class_desc) { | 2597 void Parser::CheckConstructors(ClassDesc* class_desc) { |
| 2599 // Add an implicit constructor if no explicit constructor is present. | 2598 // Add an implicit constructor if no explicit constructor is present. |
| 2600 if (!class_desc->has_constructor()) { | 2599 if (!class_desc->has_constructor()) { |
| 2601 // The implicit constructor is unnamed, has no explicit parameter, | 2600 // The implicit constructor is unnamed, has no explicit parameter, |
| 2602 // and contains a supercall in the initializer list. | 2601 // and contains a supercall in the initializer list. |
| 2603 String& ctor_name = String::ZoneHandle( | 2602 String& ctor_name = String::ZoneHandle( |
| 2604 String::Concat(class_desc->class_name(), | 2603 String::Concat(class_desc->class_name(), |
| 2605 String::Handle(String::NewSymbol(".")))); | 2604 String::Handle(String::NewSymbol(".")))); |
| 2606 ctor_name = String::NewSymbol(ctor_name); | 2605 ctor_name = String::NewSymbol(ctor_name); |
| 2607 // The token position for the implicit constructor is the 'class' | 2606 // The token position for the implicit constructor is the 'class' |
| 2608 // keyword of the constructor's class. | 2607 // keyword of the constructor's class. |
| 2609 Function& ctor = Function::ZoneHandle( | 2608 Function& ctor = Function::Handle( |
| 2610 Function::New(ctor_name, | 2609 Function::New(ctor_name, |
| 2611 RawFunction::kConstructor, | 2610 RawFunction::kConstructor, |
| 2612 /* is_static = */ false, | 2611 /* is_static = */ false, |
| 2613 /* is_const = */ false, | 2612 /* is_const = */ false, |
| 2614 class_desc->token_pos())); | 2613 class_desc->token_pos())); |
| 2615 ParamList params; | 2614 ParamList params; |
| 2616 // Add implicit 'this' parameter. | 2615 // Add implicit 'this' parameter. |
| 2617 params.AddReceiver(token_index_); | 2616 params.AddReceiver(token_index_); |
| 2618 // Add implicit parameter for construction phase. | 2617 // Add implicit parameter for construction phase. |
| 2619 params.AddFinalParameter( | 2618 params.AddFinalParameter( |
| 2620 token_index_, | 2619 token_index_, |
| 2621 kPhaseParameterName, | 2620 kPhaseParameterName, |
| 2622 &Type::ZoneHandle(Type::DynamicType())); | 2621 &Type::ZoneHandle(Type::DynamicType())); |
| 2623 | 2622 |
| 2624 AddFormalParamsToFunction(¶ms, ctor); | 2623 AddFormalParamsToFunction(¶ms, ctor); |
| 2625 // The body of the constructor cannot modify the type arguments of the | 2624 // The body of the constructor cannot modify the type arguments of the |
| 2626 // constructed instance, which is passed in as a hidden parameter. | 2625 // constructed instance, which is passed in as a hidden parameter. |
| 2627 // Therefore, there is no need to set the result type to be checked. | 2626 // Therefore, there is no need to set the result type to be checked. |
| 2628 const AbstractType& result_type = Type::ZoneHandle(Type::DynamicType()); | 2627 const AbstractType& result_type = Type::ZoneHandle(Type::DynamicType()); |
| 2629 ctor.set_result_type(result_type); | 2628 ctor.set_result_type(result_type); |
| 2630 class_desc->AddFunction(&ctor); | 2629 class_desc->AddFunction(ctor); |
| 2631 } | 2630 } |
| 2632 | 2631 |
| 2633 // Check for cycles in constructor redirection. | 2632 // Check for cycles in constructor redirection. |
| 2634 const GrowableArray<MemberDesc>& members = class_desc->members(); | 2633 const GrowableArray<MemberDesc>& members = class_desc->members(); |
| 2635 for (int i = 0; i < members.length(); i++) { | 2634 for (int i = 0; i < members.length(); i++) { |
| 2636 MemberDesc* member = &members[i]; | 2635 MemberDesc* member = &members[i]; |
| 2637 GrowableArray<MemberDesc*> ctors; | 2636 GrowableArray<MemberDesc*> ctors; |
| 2638 while ((member != NULL) && (member->redirect_name != NULL)) { | 2637 while ((member != NULL) && (member->redirect_name != NULL)) { |
| 2639 ASSERT(member->IsConstructor()); | 2638 ASSERT(member->IsConstructor()); |
| 2640 // Check whether we have already seen this member. | 2639 // Check whether we have already seen this member. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2670 ConsumeToken(); | 2669 ConsumeToken(); |
| 2671 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { | 2670 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { |
| 2672 is_alias_name = true; | 2671 is_alias_name = true; |
| 2673 } | 2672 } |
| 2674 } | 2673 } |
| 2675 SetPosition(saved_pos); | 2674 SetPosition(saved_pos); |
| 2676 return is_alias_name; | 2675 return is_alias_name; |
| 2677 } | 2676 } |
| 2678 | 2677 |
| 2679 | 2678 |
| 2680 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { | 2679 void Parser::ParseFunctionTypeAlias( |
| 2680 const GrowableObjectArray& pending_classes) { |
| 2681 TRACE_PARSER("ParseFunctionTypeAlias"); | 2681 TRACE_PARSER("ParseFunctionTypeAlias"); |
| 2682 ExpectToken(Token::kTYPEDEF); | 2682 ExpectToken(Token::kTYPEDEF); |
| 2683 | 2683 |
| 2684 // Allocate an interface to hold the type parameters and their bounds. | 2684 // Allocate an interface to hold the type parameters and their bounds. |
| 2685 // Make it the owner of the function type descriptor. | 2685 // Make it the owner of the function type descriptor. |
| 2686 const Class& alias_owner = Class::Handle( | 2686 const Class& alias_owner = Class::Handle( |
| 2687 Class::New(String::Handle(String::NewSymbol(":alias_owner")), | 2687 Class::New(String::Handle(String::NewSymbol(":alias_owner")), |
| 2688 Script::Handle(), | 2688 Script::Handle(), |
| 2689 token_index_)); | 2689 token_index_)); |
| 2690 alias_owner.set_is_interface(); | 2690 alias_owner.set_is_interface(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2757 // Lookup alias name and report an error if it is already defined in | 2757 // Lookup alias name and report an error if it is already defined in |
| 2758 // the library scope. | 2758 // the library scope. |
| 2759 const Object& obj = Object::Handle(library_.LookupObject(*alias_name)); | 2759 const Object& obj = Object::Handle(library_.LookupObject(*alias_name)); |
| 2760 if (!obj.IsNull()) { | 2760 if (!obj.IsNull()) { |
| 2761 ErrorMsg(alias_name_pos, | 2761 ErrorMsg(alias_name_pos, |
| 2762 "'%s' is already defined", alias_name->ToCString()); | 2762 "'%s' is already defined", alias_name->ToCString()); |
| 2763 } | 2763 } |
| 2764 | 2764 |
| 2765 // Create the function type alias, but share the signature function of the | 2765 // Create the function type alias, but share the signature function of the |
| 2766 // canonical signature class. | 2766 // canonical signature class. |
| 2767 Class& function_type_alias = Class::ZoneHandle( | 2767 Class& function_type_alias = Class::Handle( |
| 2768 Class::NewSignatureClass(*alias_name, | 2768 Class::NewSignatureClass(*alias_name, |
| 2769 signature_function, | 2769 signature_function, |
| 2770 script_)); | 2770 script_)); |
| 2771 library_.AddClass(function_type_alias); | 2771 library_.AddClass(function_type_alias); |
| 2772 ExpectSemicolon(); | 2772 ExpectSemicolon(); |
| 2773 classes->Add(&function_type_alias); | 2773 pending_classes.Add(function_type_alias, Heap::kOld); |
| 2774 } | 2774 } |
| 2775 | 2775 |
| 2776 | 2776 |
| 2777 void Parser::ParseInterfaceDefinition(GrowableArray<const Class*>* classes) { | 2777 void Parser::ParseInterfaceDefinition( |
| 2778 const GrowableObjectArray& pending_classes) { |
| 2778 TRACE_PARSER("ParseInterfaceDefinition"); | 2779 TRACE_PARSER("ParseInterfaceDefinition"); |
| 2779 const intptr_t interface_pos = token_index_; | 2780 const intptr_t interface_pos = token_index_; |
| 2780 ExpectToken(Token::kINTERFACE); | 2781 ExpectToken(Token::kINTERFACE); |
| 2781 const intptr_t interfacename_pos = token_index_; | 2782 const intptr_t interfacename_pos = token_index_; |
| 2782 String& interface_name = *ExpectTypeIdentifier("interface name expected"); | 2783 String& interface_name = *ExpectTypeIdentifier("interface name expected"); |
| 2783 if (FLAG_trace_parser) { | 2784 if (FLAG_trace_parser) { |
| 2784 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); | 2785 OS::Print("TopLevel parsing interface '%s'\n", interface_name.ToCString()); |
| 2785 } | 2786 } |
| 2786 Class& interface = Class::ZoneHandle(); | 2787 Class& interface = Class::Handle(); |
| 2787 Object& obj = Object::Handle(library_.LookupObject(interface_name)); | 2788 Object& obj = Object::Handle(library_.LookupObject(interface_name)); |
| 2788 if (obj.IsNull()) { | 2789 if (obj.IsNull()) { |
| 2789 interface = Class::NewInterface(interface_name, script_, interfacename_pos); | 2790 interface = Class::NewInterface(interface_name, script_, interfacename_pos); |
| 2790 library_.AddClass(interface); | 2791 library_.AddClass(interface); |
| 2791 } else { | 2792 } else { |
| 2792 if (!obj.IsClass()) { | 2793 if (!obj.IsClass()) { |
| 2793 ErrorMsg(interfacename_pos, "'%s' is already defined", | 2794 ErrorMsg(interfacename_pos, "'%s' is already defined", |
| 2794 interface_name.ToCString()); | 2795 interface_name.ToCString()); |
| 2795 } | 2796 } |
| 2796 interface ^= obj.raw(); | 2797 interface ^= obj.raw(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2860 } | 2861 } |
| 2861 } | 2862 } |
| 2862 | 2863 |
| 2863 ExpectToken(Token::kLBRACE); | 2864 ExpectToken(Token::kLBRACE); |
| 2864 ClassDesc members(interface, interface_name, true, interface_pos); | 2865 ClassDesc members(interface, interface_name, true, interface_pos); |
| 2865 while (CurrentToken() != Token::kRBRACE) { | 2866 while (CurrentToken() != Token::kRBRACE) { |
| 2866 ParseClassMemberDefinition(&members); | 2867 ParseClassMemberDefinition(&members); |
| 2867 } | 2868 } |
| 2868 ExpectToken(Token::kRBRACE); | 2869 ExpectToken(Token::kRBRACE); |
| 2869 | 2870 |
| 2870 interface.SetFields(Array::Handle(NewArray<Field>(members.fields()))); | 2871 Array& array = Array::Handle(); |
| 2872 array = Array::MakeArray(members.fields()); |
| 2873 interface.SetFields(array); |
| 2874 |
| 2871 // Creating a new array for functions marks the interface as parsed. | 2875 // Creating a new array for functions marks the interface as parsed. |
| 2872 interface.SetFunctions( | 2876 array = Array::MakeArray(members.functions()); |
| 2873 Array::Handle(NewArray<Function>(members.functions()))); | 2877 interface.SetFunctions(array); |
| 2874 ASSERT(interface.is_interface()); | 2878 ASSERT(interface.is_interface()); |
| 2875 classes->Add(&interface); | 2879 |
| 2880 pending_classes.Add(interface, Heap::kOld); |
| 2876 } | 2881 } |
| 2877 | 2882 |
| 2878 | 2883 |
| 2879 // Consumes exactly one right angle bracket. If the current token is a single | 2884 // Consumes exactly one right angle bracket. If the current token is a single |
| 2880 // bracket token, it is consumed normally. However, if it is a double or triple | 2885 // bracket token, it is consumed normally. However, if it is a double or triple |
| 2881 // bracket, it is replaced by a single or double bracket token without | 2886 // bracket, it is replaced by a single or double bracket token without |
| 2882 // incrementing the token index. | 2887 // incrementing the token index. |
| 2883 void Parser::ConsumeRightAngleBracket() { | 2888 void Parser::ConsumeRightAngleBracket() { |
| 2884 if (token_kind_ == Token::kGT) { | 2889 if (token_kind_ == Token::kGT) { |
| 2885 ConsumeToken(); | 2890 ConsumeToken(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2920 ExpectIdentifier("name expected"); | 2925 ExpectIdentifier("name expected"); |
| 2921 } | 2926 } |
| 2922 SkipTypeArguments(); | 2927 SkipTypeArguments(); |
| 2923 } | 2928 } |
| 2924 } | 2929 } |
| 2925 | 2930 |
| 2926 | 2931 |
| 2927 void Parser::ParseTypeParameters(const Class& cls) { | 2932 void Parser::ParseTypeParameters(const Class& cls) { |
| 2928 TRACE_PARSER("ParseTypeParameters"); | 2933 TRACE_PARSER("ParseTypeParameters"); |
| 2929 if (CurrentToken() == Token::kLT) { | 2934 if (CurrentToken() == Token::kLT) { |
| 2930 GrowableArray<AbstractType*> type_parameters_array; | 2935 const GrowableObjectArray& type_parameters_array = |
| 2931 GrowableArray<AbstractType*> bounds_array; | 2936 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2937 const GrowableObjectArray& bounds_array = |
| 2938 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2932 intptr_t index = 0; | 2939 intptr_t index = 0; |
| 2940 AbstractType& type_parameter = TypeParameter::Handle(); |
| 2941 AbstractType& bound = Type::Handle(); |
| 2933 do { | 2942 do { |
| 2934 ConsumeToken(); | 2943 ConsumeToken(); |
| 2935 if (CurrentToken() != Token::kIDENT) { | 2944 if (CurrentToken() != Token::kIDENT) { |
| 2936 ErrorMsg("type parameter name expected"); | 2945 ErrorMsg("type parameter name expected"); |
| 2937 } | 2946 } |
| 2938 String& type_parameter_name = *CurrentLiteral(); | 2947 String& type_parameter_name = *CurrentLiteral(); |
| 2939 AbstractType& type_parameter = TypeParameter::ZoneHandle( | 2948 type_parameter = TypeParameter::New(index, |
| 2940 TypeParameter::New(index, type_parameter_name, token_index_)); | 2949 type_parameter_name, |
| 2950 token_index_); |
| 2941 ConsumeToken(); | 2951 ConsumeToken(); |
| 2942 AbstractType& bound = Type::ZoneHandle(Type::DynamicType()); | 2952 bound = Type::DynamicType(); |
| 2943 if (CurrentToken() == Token::kEXTENDS) { | 2953 if (CurrentToken() == Token::kEXTENDS) { |
| 2944 ConsumeToken(); | 2954 ConsumeToken(); |
| 2945 bound = ParseType(ClassFinalizer::kTryResolve); | 2955 bound = ParseType(ClassFinalizer::kTryResolve); |
| 2946 } | 2956 } |
| 2947 type_parameters_array.Add(&type_parameter); | 2957 type_parameters_array.Add(type_parameter); |
| 2948 bounds_array.Add(&bound); | 2958 bounds_array.Add(bound); |
| 2949 index++; | 2959 index++; |
| 2950 } while (CurrentToken() == Token::kCOMMA); | 2960 } while (CurrentToken() == Token::kCOMMA); |
| 2951 Token::Kind token = CurrentToken(); | 2961 Token::Kind token = CurrentToken(); |
| 2952 if ((token == Token::kGT) || (token == Token::kSHR)) { | 2962 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 2953 ConsumeRightAngleBracket(); | 2963 ConsumeRightAngleBracket(); |
| 2954 } else { | 2964 } else { |
| 2955 ErrorMsg("right angle bracket expected"); | 2965 ErrorMsg("right angle bracket expected"); |
| 2956 } | 2966 } |
| 2957 const TypeArguments& type_parameters = | 2967 const TypeArguments& type_parameters = |
| 2958 TypeArguments::Handle(NewTypeArguments(type_parameters_array)); | 2968 TypeArguments::Handle(NewTypeArguments(type_parameters_array)); |
| 2959 const TypeArguments& bounds = | 2969 const TypeArguments& bounds = |
| 2960 TypeArguments::Handle(NewTypeArguments(bounds_array)); | 2970 TypeArguments::Handle(NewTypeArguments(bounds_array)); |
| 2961 cls.set_type_parameters(type_parameters); | 2971 cls.set_type_parameters(type_parameters); |
| 2962 cls.set_type_parameter_bounds(bounds); | 2972 cls.set_type_parameter_bounds(bounds); |
| 2963 // Try to resolve the upper bounds, which will at least resolve the | 2973 // Try to resolve the upper bounds, which will at least resolve the |
| 2964 // referenced type parameters. | 2974 // referenced type parameters. |
| 2965 AbstractType& bound = AbstractType::Handle(); | |
| 2966 const intptr_t num_types = bounds.Length(); | 2975 const intptr_t num_types = bounds.Length(); |
| 2967 for (intptr_t i = 0; i < num_types; i++) { | 2976 for (intptr_t i = 0; i < num_types; i++) { |
| 2968 bound = bounds.TypeAt(i); | 2977 bound = bounds.TypeAt(i); |
| 2969 ResolveTypeFromClass(cls, ClassFinalizer::kTryResolve, &bound); | 2978 ResolveTypeFromClass(cls, ClassFinalizer::kTryResolve, &bound); |
| 2970 bounds.SetTypeAt(i, bound); | 2979 bounds.SetTypeAt(i, bound); |
| 2971 } | 2980 } |
| 2972 } | 2981 } |
| 2973 } | 2982 } |
| 2974 | 2983 |
| 2975 | 2984 |
| 2976 RawAbstractTypeArguments* Parser::ParseTypeArguments( | 2985 RawAbstractTypeArguments* Parser::ParseTypeArguments( |
| 2977 Error* malformed_error, | 2986 Error* malformed_error, |
| 2978 ClassFinalizer::FinalizationKind finalization) { | 2987 ClassFinalizer::FinalizationKind finalization) { |
| 2979 TRACE_PARSER("ParseTypeArguments"); | 2988 TRACE_PARSER("ParseTypeArguments"); |
| 2980 if (CurrentToken() == Token::kLT) { | 2989 if (CurrentToken() == Token::kLT) { |
| 2981 GrowableArray<AbstractType*> types; | 2990 const GrowableObjectArray& types = |
| 2991 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 2992 AbstractType& type = AbstractType::Handle(); |
| 2982 do { | 2993 do { |
| 2983 ConsumeToken(); | 2994 ConsumeToken(); |
| 2984 AbstractType& type = AbstractType::ZoneHandle(ParseType(finalization)); | 2995 type = ParseType(finalization); |
| 2985 types.Add(&type); | 2996 types.Add(type); |
| 2986 // Only keep the error for the first malformed type argument. | 2997 // Only keep the error for the first malformed type argument. |
| 2987 if (malformed_error->IsNull() && type.IsMalformed()) { | 2998 if (malformed_error->IsNull() && type.IsMalformed()) { |
| 2988 *malformed_error = type.malformed_error(); | 2999 *malformed_error = type.malformed_error(); |
| 2989 } | 3000 } |
| 2990 } while (CurrentToken() == Token::kCOMMA); | 3001 } while (CurrentToken() == Token::kCOMMA); |
| 2991 Token::Kind token = CurrentToken(); | 3002 Token::Kind token = CurrentToken(); |
| 2992 if ((token == Token::kGT) || (token == Token::kSHR)) { | 3003 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 2993 ConsumeRightAngleBracket(); | 3004 ConsumeRightAngleBracket(); |
| 2994 } else { | 3005 } else { |
| 2995 ErrorMsg("right angle bracket expected"); | 3006 ErrorMsg("right angle bracket expected"); |
| 2996 } | 3007 } |
| 2997 if (finalization != ClassFinalizer::kIgnore) { | 3008 if (finalization != ClassFinalizer::kIgnore) { |
| 2998 return NewTypeArguments(types); | 3009 return NewTypeArguments(types); |
| 2999 } | 3010 } |
| 3000 } | 3011 } |
| 3001 return TypeArguments::null(); | 3012 return TypeArguments::null(); |
| 3002 } | 3013 } |
| 3003 | 3014 |
| 3004 | 3015 |
| 3005 // Parse and return an array of interface types. | 3016 // Parse and return an array of interface types. |
| 3006 RawArray* Parser::ParseInterfaceList() { | 3017 RawArray* Parser::ParseInterfaceList() { |
| 3007 TRACE_PARSER("ParseInterfaceList"); | 3018 TRACE_PARSER("ParseInterfaceList"); |
| 3008 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 3019 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || |
| 3009 (CurrentToken() == Token::kEXTENDS)); | 3020 (CurrentToken() == Token::kEXTENDS)); |
| 3010 GrowableArray<AbstractType*> interfaces; | 3021 const GrowableObjectArray& interfaces = |
| 3022 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3011 String& interface_name = String::Handle(); | 3023 String& interface_name = String::Handle(); |
| 3024 AbstractType& interface = AbstractType::Handle(); |
| 3025 String& other_name = String::Handle(); |
| 3026 AbstractType& other_interface = AbstractType::Handle(); |
| 3012 do { | 3027 do { |
| 3013 ConsumeToken(); | 3028 ConsumeToken(); |
| 3014 intptr_t supertype_pos = token_index_; | 3029 intptr_t supertype_pos = token_index_; |
| 3015 AbstractType& interface = AbstractType::ZoneHandle( | 3030 interface = ParseType(ClassFinalizer::kTryResolve); |
| 3016 ParseType(ClassFinalizer::kTryResolve)); | |
| 3017 interface_name = interface.Name(); | 3031 interface_name = interface.Name(); |
| 3018 for (int i = 0; i < interfaces.length(); i++) { | 3032 for (int i = 0; i < interfaces.Length(); i++) { |
| 3019 String& other_name = String::Handle(interfaces[i]->Name()); | 3033 other_interface ^= interfaces.At(i); |
| 3034 other_name = other_interface.Name(); |
| 3020 if (interface_name.Equals(other_name)) { | 3035 if (interface_name.Equals(other_name)) { |
| 3021 ErrorMsg(supertype_pos, "Duplicate supertype '%s'", | 3036 ErrorMsg(supertype_pos, "Duplicate supertype '%s'", |
| 3022 interface_name.ToCString()); | 3037 interface_name.ToCString()); |
| 3023 } | 3038 } |
| 3024 } | 3039 } |
| 3025 interfaces.Add(&interface); | 3040 interfaces.Add(interface); |
| 3026 } while (CurrentToken() == Token::kCOMMA); | 3041 } while (CurrentToken() == Token::kCOMMA); |
| 3027 return NewArray<AbstractType>(interfaces); | 3042 return Array::MakeArray(interfaces); |
| 3028 } | 3043 } |
| 3029 | 3044 |
| 3030 | 3045 |
| 3031 void Parser::AddInterfaces(intptr_t interfaces_pos, | 3046 void Parser::AddInterfaces(intptr_t interfaces_pos, |
| 3032 const Class& cls, | 3047 const Class& cls, |
| 3033 const Array& interfaces) { | 3048 const Array& interfaces) { |
| 3034 GrowableArray<AbstractType*> all_interfaces; | 3049 const GrowableObjectArray& all_interfaces = |
| 3050 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3051 AbstractType& interface = AbstractType::Handle(); |
| 3035 // First get all the interfaces already implemented by class. | 3052 // First get all the interfaces already implemented by class. |
| 3036 Array& cls_interfaces = Array::Handle(cls.interfaces()); | 3053 Array& cls_interfaces = Array::Handle(cls.interfaces()); |
| 3037 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 3054 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 3038 AbstractType& interface = AbstractType::ZoneHandle(); | |
| 3039 interface ^= cls_interfaces.At(i); | 3055 interface ^= cls_interfaces.At(i); |
| 3040 all_interfaces.Add(&interface); | 3056 all_interfaces.Add(interface); |
| 3041 } | 3057 } |
| 3042 // Now add the new interfaces. | 3058 // Now add the new interfaces. |
| 3043 AbstractType& conflicting = AbstractType::Handle(); | 3059 AbstractType& conflicting = AbstractType::Handle(); |
| 3044 for (intptr_t i = 0; i < interfaces.Length(); i++) { | 3060 for (intptr_t i = 0; i < interfaces.Length(); i++) { |
| 3045 AbstractType& interface = AbstractType::ZoneHandle(); | 3061 AbstractType& interface = AbstractType::ZoneHandle(); |
| 3046 interface ^= interfaces.At(i); | 3062 interface ^= interfaces.At(i); |
| 3047 if (interface.IsTypeParameter()) { | 3063 if (interface.IsTypeParameter()) { |
| 3048 if (cls.is_interface()) { | 3064 if (cls.is_interface()) { |
| 3049 ErrorMsg(interfaces_pos, | 3065 ErrorMsg(interfaces_pos, |
| 3050 "interface '%s' may not extend type parameter '%s'", | 3066 "interface '%s' may not extend type parameter '%s'", |
| 3051 String::Handle(cls.Name()).ToCString(), | 3067 String::Handle(cls.Name()).ToCString(), |
| 3052 String::Handle(interface.Name()).ToCString()); | 3068 String::Handle(interface.Name()).ToCString()); |
| 3053 } else { | 3069 } else { |
| 3054 ErrorMsg(interfaces_pos, | 3070 ErrorMsg(interfaces_pos, |
| 3055 "class '%s' may not implement type parameter '%s'", | 3071 "class '%s' may not implement type parameter '%s'", |
| 3056 String::Handle(cls.Name()).ToCString(), | 3072 String::Handle(cls.Name()).ToCString(), |
| 3057 String::Handle(interface.Name()).ToCString()); | 3073 String::Handle(interface.Name()).ToCString()); |
| 3058 } | 3074 } |
| 3059 } | 3075 } |
| 3060 if (!ClassFinalizer::AddInterfaceIfUnique(&all_interfaces, | 3076 if (!ClassFinalizer::AddInterfaceIfUnique(all_interfaces, |
| 3061 &interface, | 3077 interface, |
| 3062 &conflicting)) { | 3078 &conflicting)) { |
| 3063 ASSERT(!conflicting.IsNull()); | 3079 ASSERT(!conflicting.IsNull()); |
| 3064 ErrorMsg(interfaces_pos, | 3080 ErrorMsg(interfaces_pos, |
| 3065 "interface '%s' conflicts with interface '%s'", | 3081 "interface '%s' conflicts with interface '%s'", |
| 3066 String::Handle(interface.Name()).ToCString(), | 3082 String::Handle(interface.Name()).ToCString(), |
| 3067 String::Handle(conflicting.Name()).ToCString()); | 3083 String::Handle(conflicting.Name()).ToCString()); |
| 3068 } | 3084 } |
| 3069 } | 3085 } |
| 3070 cls_interfaces = NewArray<AbstractType>(all_interfaces); | 3086 cls_interfaces = Array::MakeArray(all_interfaces); |
| 3071 cls.set_interfaces(cls_interfaces); | 3087 cls.set_interfaces(cls_interfaces); |
| 3072 } | 3088 } |
| 3073 | 3089 |
| 3074 | 3090 |
| 3075 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3091 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
| 3076 TRACE_PARSER("ParseTopLevelVariable"); | 3092 TRACE_PARSER("ParseTopLevelVariable"); |
| 3077 const bool is_final = (CurrentToken() == Token::kFINAL); | 3093 const bool is_final = (CurrentToken() == Token::kFINAL); |
| 3078 const bool is_static = true; | 3094 const bool is_static = true; |
| 3079 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( | 3095 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 3080 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : | 3096 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : |
| 3081 ClassFinalizer::kIgnore)); | 3097 ClassFinalizer::kIgnore)); |
| 3098 Field& field = Field::Handle(); |
| 3099 Function& getter = Function::Handle(); |
| 3082 while (true) { | 3100 while (true) { |
| 3083 const intptr_t name_pos = token_index_; | 3101 const intptr_t name_pos = token_index_; |
| 3084 String& var_name = *ExpectIdentifier("variable name expected"); | 3102 String& var_name = *ExpectIdentifier("variable name expected"); |
| 3085 | 3103 |
| 3086 if (library_.LookupObject(var_name) != Object::null()) { | 3104 if (library_.LookupObject(var_name) != Object::null()) { |
| 3087 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 3105 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 3088 } | 3106 } |
| 3089 String& accessor_name = String::Handle(Field::GetterName(var_name)); | 3107 String& accessor_name = String::Handle(Field::GetterName(var_name)); |
| 3090 if (library_.LookupObject(accessor_name) != Object::null()) { | 3108 if (library_.LookupObject(accessor_name) != Object::null()) { |
| 3091 ErrorMsg(name_pos, "getter for '%s' is already defined", | 3109 ErrorMsg(name_pos, "getter for '%s' is already defined", |
| 3092 var_name.ToCString()); | 3110 var_name.ToCString()); |
| 3093 } | 3111 } |
| 3094 accessor_name = Field::SetterName(var_name); | 3112 accessor_name = Field::SetterName(var_name); |
| 3095 if (library_.LookupObject(accessor_name) != Object::null()) { | 3113 if (library_.LookupObject(accessor_name) != Object::null()) { |
| 3096 ErrorMsg(name_pos, "setter for '%s' is already defined", | 3114 ErrorMsg(name_pos, "setter for '%s' is already defined", |
| 3097 var_name.ToCString()); | 3115 var_name.ToCString()); |
| 3098 } | 3116 } |
| 3099 | 3117 |
| 3100 Field& field = Field::ZoneHandle( | 3118 field = Field::New(var_name, is_static, is_final, name_pos); |
| 3101 Field::New(var_name, is_static, is_final, name_pos)); | |
| 3102 field.set_type(type); | 3119 field.set_type(type); |
| 3103 field.set_value(Instance::Handle(Instance::null())); | 3120 field.set_value(Instance::Handle(Instance::null())); |
| 3104 top_level->fields.Add(&field); | 3121 top_level->fields.Add(field); |
| 3105 library_.AddObject(field, var_name); | 3122 library_.AddObject(field, var_name); |
| 3106 if (CurrentToken() == Token::kASSIGN) { | 3123 if (CurrentToken() == Token::kASSIGN) { |
| 3107 ConsumeToken(); | 3124 ConsumeToken(); |
| 3108 SkipExpr(); | 3125 SkipExpr(); |
| 3109 field.set_value(Instance::Handle(Object::sentinel())); | 3126 field.set_value(Instance::Handle(Object::sentinel())); |
| 3110 // Create a static const getter. | 3127 // Create a static const getter. |
| 3111 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); | 3128 String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name)); |
| 3112 Function& getter = Function::ZoneHandle( | 3129 getter = Function::New(getter_name, RawFunction::kConstImplicitGetter, |
| 3113 Function::New(getter_name, RawFunction::kConstImplicitGetter, | 3130 is_static, is_final, name_pos); |
| 3114 is_static, is_final, name_pos)); | |
| 3115 getter.set_result_type(type); | 3131 getter.set_result_type(type); |
| 3116 top_level->functions.Add(&getter); | 3132 top_level->functions.Add(getter); |
| 3117 } else if (is_final) { | 3133 } else if (is_final) { |
| 3118 ErrorMsg(name_pos, "missing initializer for final variable"); | 3134 ErrorMsg(name_pos, "missing initializer for final variable"); |
| 3119 } | 3135 } |
| 3120 | 3136 |
| 3121 if (CurrentToken() == Token::kCOMMA) { | 3137 if (CurrentToken() == Token::kCOMMA) { |
| 3122 ConsumeToken(); | 3138 ConsumeToken(); |
| 3123 } else if (CurrentToken() == Token::kSEMICOLON) { | 3139 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 3124 ConsumeToken(); | 3140 ConsumeToken(); |
| 3125 break; | 3141 break; |
| 3126 } else { | 3142 } else { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3176 } else if (CurrentToken() == Token::kARROW) { | 3192 } else if (CurrentToken() == Token::kARROW) { |
| 3177 ConsumeToken(); | 3193 ConsumeToken(); |
| 3178 SkipExpr(); | 3194 SkipExpr(); |
| 3179 ExpectSemicolon(); | 3195 ExpectSemicolon(); |
| 3180 function_end_pos = token_index_; | 3196 function_end_pos = token_index_; |
| 3181 } else if (IsLiteral("native")) { | 3197 } else if (IsLiteral("native")) { |
| 3182 ParseNativeDeclaration(); | 3198 ParseNativeDeclaration(); |
| 3183 } else { | 3199 } else { |
| 3184 ErrorMsg("function block expected"); | 3200 ErrorMsg("function block expected"); |
| 3185 } | 3201 } |
| 3186 Function& func = Function::ZoneHandle( | 3202 Function& func = Function::Handle( |
| 3187 Function::New(func_name, RawFunction::kFunction, | 3203 Function::New(func_name, RawFunction::kFunction, |
| 3188 is_static, false, function_pos)); | 3204 is_static, false, function_pos)); |
| 3189 func.set_result_type(result_type); | 3205 func.set_result_type(result_type); |
| 3190 func.set_end_token_index(function_end_pos); | 3206 func.set_end_token_index(function_end_pos); |
| 3191 AddFormalParamsToFunction(¶ms, func); | 3207 AddFormalParamsToFunction(¶ms, func); |
| 3192 top_level->functions.Add(&func); | 3208 top_level->functions.Add(func); |
| 3193 library_.AddObject(func, func_name); | 3209 library_.AddObject(func, func_name); |
| 3194 } | 3210 } |
| 3195 | 3211 |
| 3196 | 3212 |
| 3197 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { | 3213 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { |
| 3198 TRACE_PARSER("ParseTopLevelAccessor"); | 3214 TRACE_PARSER("ParseTopLevelAccessor"); |
| 3199 const bool is_static = true; | 3215 const bool is_static = true; |
| 3200 AbstractType& result_type = AbstractType::Handle(); | 3216 AbstractType& result_type = AbstractType::Handle(); |
| 3201 bool is_getter = (CurrentToken() == Token::kGET); | 3217 bool is_getter = (CurrentToken() == Token::kGET); |
| 3202 if (CurrentToken() == Token::kGET || | 3218 if (CurrentToken() == Token::kGET || |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3256 SkipBlock(); | 3272 SkipBlock(); |
| 3257 } else if (CurrentToken() == Token::kARROW) { | 3273 } else if (CurrentToken() == Token::kARROW) { |
| 3258 ConsumeToken(); | 3274 ConsumeToken(); |
| 3259 SkipExpr(); | 3275 SkipExpr(); |
| 3260 ExpectSemicolon(); | 3276 ExpectSemicolon(); |
| 3261 } else if (IsLiteral("native")) { | 3277 } else if (IsLiteral("native")) { |
| 3262 ParseNativeDeclaration(); | 3278 ParseNativeDeclaration(); |
| 3263 } else { | 3279 } else { |
| 3264 ErrorMsg("function block expected"); | 3280 ErrorMsg("function block expected"); |
| 3265 } | 3281 } |
| 3266 Function& func = Function::ZoneHandle( | 3282 Function& func = Function::Handle( |
| 3267 Function::New(accessor_name, | 3283 Function::New(accessor_name, |
| 3268 is_getter? RawFunction::kGetterFunction : | 3284 is_getter? RawFunction::kGetterFunction : |
| 3269 RawFunction::kSetterFunction, | 3285 RawFunction::kSetterFunction, |
| 3270 is_static, false, accessor_pos)); | 3286 is_static, false, accessor_pos)); |
| 3271 func.set_result_type(result_type); | 3287 func.set_result_type(result_type); |
| 3272 AddFormalParamsToFunction(¶ms, func); | 3288 AddFormalParamsToFunction(¶ms, func); |
| 3273 top_level->functions.Add(&func); | 3289 top_level->functions.Add(func); |
| 3274 library_.AddObject(func, accessor_name); | 3290 library_.AddObject(func, accessor_name); |
| 3275 } | 3291 } |
| 3276 | 3292 |
| 3277 | 3293 |
| 3278 void Parser::ParseLibraryName() { | 3294 void Parser::ParseLibraryName() { |
| 3279 TRACE_PARSER("ParseLibraryName"); | 3295 TRACE_PARSER("ParseLibraryName"); |
| 3280 if ((script_.kind() == RawScript::kLibrary) && | 3296 if ((script_.kind() == RawScript::kLibrary) && |
| 3281 (CurrentToken() != Token::kLIBRARY)) { | 3297 (CurrentToken() != Token::kLIBRARY)) { |
| 3282 // Handle error case early to get consistent error message. | 3298 // Handle error case early to get consistent error message. |
| 3283 ExpectToken(Token::kLIBRARY); | 3299 ExpectToken(Token::kLIBRARY); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3437 ParseLibraryInclude(); | 3453 ParseLibraryInclude(); |
| 3438 ParseLibraryResource(); | 3454 ParseLibraryResource(); |
| 3439 } | 3455 } |
| 3440 | 3456 |
| 3441 | 3457 |
| 3442 void Parser::ParseTopLevel() { | 3458 void Parser::ParseTopLevel() { |
| 3443 TRACE_PARSER("ParseTopLevel"); | 3459 TRACE_PARSER("ParseTopLevel"); |
| 3444 // Collect the classes found at the top level in this growable array. | 3460 // Collect the classes found at the top level in this growable array. |
| 3445 // They need to be registered with class finalization after parsing | 3461 // They need to be registered with class finalization after parsing |
| 3446 // has been completed. | 3462 // has been completed. |
| 3447 GrowableArray<const Class*> classes; | 3463 Isolate* isolate = Isolate::Current(); |
| 3464 ObjectStore* object_store = isolate->object_store(); |
| 3465 const GrowableObjectArray& pending_classes = |
| 3466 GrowableObjectArray::Handle(isolate, object_store->pending_classes()); |
| 3448 SetPosition(0); | 3467 SetPosition(0); |
| 3449 is_top_level_ = true; | 3468 is_top_level_ = true; |
| 3450 TopLevel top_level; | 3469 TopLevel top_level; |
| 3451 Class& toplevel_class = Class::ZoneHandle( | 3470 Class& toplevel_class = Class::Handle( |
| 3452 Class::New(String::ZoneHandle(String::NewSymbol("::")), | 3471 Class::New(String::ZoneHandle(String::NewSymbol("::")), |
| 3453 script_, | 3472 script_, |
| 3454 token_index_)); | 3473 token_index_)); |
| 3455 toplevel_class.set_library(library_); | 3474 toplevel_class.set_library(library_); |
| 3456 | 3475 |
| 3457 if (is_library_source()) { | 3476 if (is_library_source()) { |
| 3458 ParseLibraryDefinition(); | 3477 ParseLibraryDefinition(); |
| 3459 } | 3478 } |
| 3460 | 3479 |
| 3461 while (true) { | 3480 while (true) { |
| 3462 set_current_class(Class::Handle()); // No current class. | 3481 set_current_class(Class::Handle()); // No current class. |
| 3463 if (CurrentToken() == Token::kCLASS) { | 3482 if (CurrentToken() == Token::kCLASS) { |
| 3464 ParseClassDefinition(&classes); | 3483 ParseClassDefinition(pending_classes); |
| 3465 } else if ((CurrentToken() == Token::kTYPEDEF) && | 3484 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 3466 (LookaheadToken(1) != Token::kLPAREN)) { | 3485 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3467 ParseFunctionTypeAlias(&classes); | 3486 ParseFunctionTypeAlias(pending_classes); |
| 3468 } else if (CurrentToken() == Token::kINTERFACE) { | 3487 } else if (CurrentToken() == Token::kINTERFACE) { |
| 3469 ParseInterfaceDefinition(&classes); | 3488 ParseInterfaceDefinition(pending_classes); |
| 3470 } else { | 3489 } else { |
| 3471 set_current_class(toplevel_class); | 3490 set_current_class(toplevel_class); |
| 3472 if (IsVariableDeclaration()) { | 3491 if (IsVariableDeclaration()) { |
| 3473 ParseTopLevelVariable(&top_level); | 3492 ParseTopLevelVariable(&top_level); |
| 3474 } else if (IsTopLevelFunction()) { | 3493 } else if (IsTopLevelFunction()) { |
| 3475 ParseTopLevelFunction(&top_level); | 3494 ParseTopLevelFunction(&top_level); |
| 3476 } else if (IsTopLevelAccessor()) { | 3495 } else if (IsTopLevelAccessor()) { |
| 3477 ParseTopLevelAccessor(&top_level); | 3496 ParseTopLevelAccessor(&top_level); |
| 3478 } else if (CurrentToken() == Token::kEOS) { | 3497 } else if (CurrentToken() == Token::kEOS) { |
| 3479 break; | 3498 break; |
| 3480 } else { | 3499 } else { |
| 3481 UnexpectedToken(); | 3500 UnexpectedToken(); |
| 3482 } | 3501 } |
| 3483 } | 3502 } |
| 3484 } | 3503 } |
| 3485 if ((top_level.fields.length() > 0) || (top_level.functions.length() > 0)) { | 3504 if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) { |
| 3486 toplevel_class.SetFields( | 3505 Array& array = Array::Handle(); |
| 3487 Array::Handle(NewArray<Field>(top_level.fields))); | 3506 |
| 3488 toplevel_class.SetFunctions( | 3507 array = Array::MakeArray(top_level.fields); |
| 3489 Array::Handle(NewArray<Function>(top_level.functions))); | 3508 toplevel_class.SetFields(array); |
| 3509 |
| 3510 array = Array::MakeArray(top_level.functions); |
| 3511 toplevel_class.SetFunctions(array); |
| 3512 |
| 3490 library_.AddAnonymousClass(toplevel_class); | 3513 library_.AddAnonymousClass(toplevel_class); |
| 3491 classes.Add(&toplevel_class); | 3514 pending_classes.Add(toplevel_class, Heap::kOld); |
| 3492 } | 3515 } |
| 3493 ClassFinalizer::AddPendingClasses(classes); | |
| 3494 } | 3516 } |
| 3495 | 3517 |
| 3496 | 3518 |
| 3497 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 3519 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
| 3498 Block* block = new Block(current_block_, | 3520 Block* block = new Block(current_block_, |
| 3499 outer_scope, | 3521 outer_scope, |
| 3500 new SequenceNode(token_index_, outer_scope)); | 3522 new SequenceNode(token_index_, outer_scope)); |
| 3501 current_block_ = block; | 3523 current_block_ = block; |
| 3502 } | 3524 } |
| 3503 | 3525 |
| (...skipping 2368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5872 bool require_const) { | 5894 bool require_const) { |
| 5873 TRACE_PARSER("ParseActualParameters"); | 5895 TRACE_PARSER("ParseActualParameters"); |
| 5874 ASSERT(CurrentToken() == Token::kLPAREN); | 5896 ASSERT(CurrentToken() == Token::kLPAREN); |
| 5875 const bool saved_mode = SetAllowFunctionLiterals(true); | 5897 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 5876 ArgumentListNode* arguments; | 5898 ArgumentListNode* arguments; |
| 5877 if (implicit_arguments == NULL) { | 5899 if (implicit_arguments == NULL) { |
| 5878 arguments = new ArgumentListNode(token_index_); | 5900 arguments = new ArgumentListNode(token_index_); |
| 5879 } else { | 5901 } else { |
| 5880 arguments = implicit_arguments; | 5902 arguments = implicit_arguments; |
| 5881 } | 5903 } |
| 5882 GrowableArray<const String*> names; | 5904 const GrowableObjectArray& names = |
| 5905 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 5883 bool named_argument_seen = false; | 5906 bool named_argument_seen = false; |
| 5884 if (LookaheadToken(1) != Token::kRPAREN) { | 5907 if (LookaheadToken(1) != Token::kRPAREN) { |
| 5908 String& arg_name = String::Handle(); |
| 5885 do { | 5909 do { |
| 5886 ASSERT((CurrentToken() == Token::kLPAREN) || | 5910 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 5887 (CurrentToken() == Token::kCOMMA)); | 5911 (CurrentToken() == Token::kCOMMA)); |
| 5888 ConsumeToken(); | 5912 ConsumeToken(); |
| 5889 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 5913 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 5890 named_argument_seen = true; | 5914 named_argument_seen = true; |
| 5891 // The canonicalization of the argument descriptor array built in the | 5915 // The canonicalization of the argument descriptor array built in the |
| 5892 // code generator requires that the names are symbols, i.e. | 5916 // code generator requires that the names are symbols, i.e. |
| 5893 // canonicalized strings. | 5917 // canonicalized strings. |
| 5894 ASSERT(CurrentLiteral()->IsSymbol()); | 5918 ASSERT(CurrentLiteral()->IsSymbol()); |
| 5895 for (int i = 0; i < names.length(); i++) { | 5919 for (int i = 0; i < names.Length(); i++) { |
| 5896 if (CurrentLiteral()->Equals(*names[i])) { | 5920 arg_name ^= names.At(i); |
| 5921 if (CurrentLiteral()->Equals(arg_name)) { |
| 5897 ErrorMsg("duplicate named argument"); | 5922 ErrorMsg("duplicate named argument"); |
| 5898 } | 5923 } |
| 5899 } | 5924 } |
| 5900 names.Add(CurrentLiteral()); | 5925 names.Add(*CurrentLiteral()); |
| 5901 ConsumeToken(); // ident. | 5926 ConsumeToken(); // ident. |
| 5902 ConsumeToken(); // colon. | 5927 ConsumeToken(); // colon. |
| 5903 } else if (named_argument_seen) { | 5928 } else if (named_argument_seen) { |
| 5904 ErrorMsg("named argument expected"); | 5929 ErrorMsg("named argument expected"); |
| 5905 } | 5930 } |
| 5906 arguments->Add(ParseExpr(require_const)); | 5931 arguments->Add(ParseExpr(require_const)); |
| 5907 } while (CurrentToken() == Token::kCOMMA); | 5932 } while (CurrentToken() == Token::kCOMMA); |
| 5908 } else { | 5933 } else { |
| 5909 ConsumeToken(); | 5934 ConsumeToken(); |
| 5910 } | 5935 } |
| 5911 ExpectToken(Token::kRPAREN); | 5936 ExpectToken(Token::kRPAREN); |
| 5912 SetAllowFunctionLiterals(saved_mode); | 5937 SetAllowFunctionLiterals(saved_mode); |
| 5913 if (named_argument_seen) { | 5938 if (named_argument_seen) { |
| 5914 arguments->set_names(Array::Handle(NewArray<const String>(names))); | 5939 arguments->set_names(Array::Handle(Array::MakeArray(names))); |
| 5915 } | 5940 } |
| 5916 return arguments; | 5941 return arguments; |
| 5917 } | 5942 } |
| 5918 | 5943 |
| 5919 | 5944 |
| 5920 AstNode* Parser::ParseStaticCall(const Class& cls, | 5945 AstNode* Parser::ParseStaticCall(const Class& cls, |
| 5921 const String& func_name, | 5946 const String& func_name, |
| 5922 intptr_t ident_pos) { | 5947 intptr_t ident_pos) { |
| 5923 TRACE_PARSER("ParseStaticCall"); | 5948 TRACE_PARSER("ParseStaticCall"); |
| 5924 const intptr_t call_pos = token_index_; | 5949 const intptr_t call_pos = token_index_; |
| (...skipping 2129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8054 void Parser::SkipQualIdent() { | 8079 void Parser::SkipQualIdent() { |
| 8055 ASSERT(IsIdentifier()); | 8080 ASSERT(IsIdentifier()); |
| 8056 ConsumeToken(); | 8081 ConsumeToken(); |
| 8057 if (CurrentToken() == Token::kPERIOD) { | 8082 if (CurrentToken() == Token::kPERIOD) { |
| 8058 ConsumeToken(); // Consume the kPERIOD token. | 8083 ConsumeToken(); // Consume the kPERIOD token. |
| 8059 ExpectIdentifier("identifier expected after '.'"); | 8084 ExpectIdentifier("identifier expected after '.'"); |
| 8060 } | 8085 } |
| 8061 } | 8086 } |
| 8062 | 8087 |
| 8063 } // namespace dart | 8088 } // namespace dart |
| OLD | NEW |