Chromium Code Reviews| 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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 MemberDesc() { | 349 MemberDesc() { |
| 350 Clear(); | 350 Clear(); |
| 351 } | 351 } |
| 352 void Clear() { | 352 void Clear() { |
| 353 has_abstract = false; | 353 has_abstract = false; |
| 354 has_final = false; | 354 has_final = false; |
| 355 has_const = false; | 355 has_const = false; |
| 356 has_static = false; | 356 has_static = false; |
| 357 has_var = false; | 357 has_var = false; |
| 358 has_factory = false; | 358 has_factory = false; |
| 359 is_operator = false; | |
| 359 type = NULL; | 360 type = NULL; |
| 360 name_pos = 0; | 361 name_pos = 0; |
| 361 name = NULL; | 362 name = NULL; |
| 362 redirect_name = NULL; | 363 redirect_name = NULL; |
| 363 params.Clear(); | 364 params.Clear(); |
| 364 kind = RawFunction::kFunction; | 365 kind = RawFunction::kFunction; |
| 365 } | 366 } |
| 366 bool IsConstructor() const { | 367 bool IsConstructor() const { |
| 367 return (kind == RawFunction::kConstructor) && !has_static; | 368 return (kind == RawFunction::kConstructor) && !has_static; |
| 368 } | 369 } |
| 369 bool IsFactory() const { | 370 bool IsFactory() const { |
| 370 return (kind == RawFunction::kConstructor) && has_static; | 371 return (kind == RawFunction::kConstructor) && has_static; |
| 371 } | 372 } |
| 372 bool IsFactoryOrConstructor() const { | 373 bool IsFactoryOrConstructor() const { |
| 373 return (kind == RawFunction::kConstructor); | 374 return (kind == RawFunction::kConstructor); |
| 374 } | 375 } |
| 375 bool IsGetter() const { | 376 bool IsGetter() const { |
| 376 return kind == RawFunction::kGetterFunction; | 377 return kind == RawFunction::kGetterFunction; |
| 377 } | 378 } |
| 378 bool IsSetter() const { | 379 bool IsSetter() const { |
| 379 return kind == RawFunction::kSetterFunction; | 380 return kind == RawFunction::kSetterFunction; |
| 380 } | 381 } |
| 381 bool has_abstract; | 382 bool has_abstract; |
| 382 bool has_final; | 383 bool has_final; |
| 383 bool has_const; | 384 bool has_const; |
| 384 bool has_static; | 385 bool has_static; |
| 385 bool has_var; | 386 bool has_var; |
| 386 bool has_factory; | 387 bool has_factory; |
| 388 bool is_operator; | |
| 387 const AbstractType* type; | 389 const AbstractType* type; |
| 388 intptr_t name_pos; | 390 intptr_t name_pos; |
| 389 String* name; | 391 String* name; |
| 390 String* redirect_name; // For constructors: NULL or redirected constructor. | 392 String* redirect_name; // For constructors: NULL or redirected constructor. |
| 391 ParamList params; | 393 ParamList params; |
| 392 RawFunction::Kind kind; | 394 RawFunction::Kind kind; |
| 393 }; | 395 }; |
| 394 | 396 |
| 395 | 397 |
| 396 class ClassDesc : public ValueObject { | 398 class ClassDesc : public ValueObject { |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 608 new LoadLocalNode(node_sequence->token_index(), *receiver)); | 610 new LoadLocalNode(node_sequence->token_index(), *receiver)); |
| 609 } | 611 } |
| 610 } | 612 } |
| 611 | 613 |
| 612 parsed_function->set_default_parameter_values(default_parameter_values); | 614 parsed_function->set_default_parameter_values(default_parameter_values); |
| 613 isolate->set_ast_node_id(prev_ast_node_id); | 615 isolate->set_ast_node_id(prev_ast_node_id); |
| 614 } | 616 } |
| 615 | 617 |
| 616 | 618 |
| 617 SequenceNode* Parser::ParseStaticConstGetter(const Function& func) { | 619 SequenceNode* Parser::ParseStaticConstGetter(const Function& func) { |
| 620 TRACE_PARSER("ParseStaticConstGetter"); | |
| 618 ParamList params; | 621 ParamList params; |
| 619 ASSERT(func.num_fixed_parameters() == 0); // static. | 622 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 620 ASSERT(func.num_optional_parameters() == 0); | 623 ASSERT(func.num_optional_parameters() == 0); |
| 621 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 624 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 622 | 625 |
| 623 // Build local scope for function and populate with the formal parameters. | 626 // Build local scope for function and populate with the formal parameters. |
| 624 OpenFunctionBlock(func); | 627 OpenFunctionBlock(func); |
| 625 AddFormalParamsToScope(¶ms, current_block_->scope); | 628 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 626 | 629 |
| 627 // Static const fields must have an initializer. | 630 // Static const fields must have an initializer. |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1139 if (signature_class.NumTypeParameters() > 0) { | 1142 if (signature_class.NumTypeParameters() > 0) { |
| 1140 CaptureReceiver(); | 1143 CaptureReceiver(); |
| 1141 } | 1144 } |
| 1142 } | 1145 } |
| 1143 } | 1146 } |
| 1144 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 1147 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 1145 } | 1148 } |
| 1146 | 1149 |
| 1147 | 1150 |
| 1148 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { | 1151 AstNode* Parser::ParseSuperFieldAccess(const String& field_name) { |
| 1152 TRACE_PARSER("ParseSuperFieldAccess"); | |
| 1149 const intptr_t field_pos = token_index_; | 1153 const intptr_t field_pos = token_index_; |
| 1150 const Class& super_class = Class::Handle(current_class().SuperClass()); | 1154 const Class& super_class = Class::Handle(current_class().SuperClass()); |
| 1151 if (super_class.IsNull()) { | 1155 if (super_class.IsNull()) { |
| 1152 ErrorMsg("class '%s' does not have a superclass", | 1156 ErrorMsg("class '%s' does not have a superclass", |
| 1153 String::Handle(current_class().Name()).ToCString()); | 1157 String::Handle(current_class().Name()).ToCString()); |
| 1154 } | 1158 } |
| 1155 AstNode* implicit_argument = LoadReceiver(field_pos); | 1159 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 1156 | 1160 |
| 1157 const String& getter_name = | 1161 const String& getter_name = |
| 1158 String::ZoneHandle(Field::GetterName(field_name)); | 1162 String::ZoneHandle(Field::GetterName(field_name)); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1352 | 1356 |
| 1353 | 1357 |
| 1354 struct FieldInitExpression { | 1358 struct FieldInitExpression { |
| 1355 Field* inst_field; | 1359 Field* inst_field; |
| 1356 AstNode* expr; | 1360 AstNode* expr; |
| 1357 }; | 1361 }; |
| 1358 | 1362 |
| 1359 | 1363 |
| 1360 void Parser::ParseInitializedInstanceFields(const Class& cls, | 1364 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 1361 GrowableArray<FieldInitExpression>* initializers) { | 1365 GrowableArray<FieldInitExpression>* initializers) { |
| 1366 TRACE_PARSER("ParseInitializedInstanceFields"); | |
| 1362 const Array& fields = Array::Handle(cls.fields()); | 1367 const Array& fields = Array::Handle(cls.fields()); |
| 1363 Field& f = Field::Handle(); | 1368 Field& f = Field::Handle(); |
| 1364 const intptr_t saved_pos = token_index_; | 1369 const intptr_t saved_pos = token_index_; |
| 1365 for (int i = 0; i < fields.Length(); i++) { | 1370 for (int i = 0; i < fields.Length(); i++) { |
| 1366 f ^= fields.At(i); | 1371 f ^= fields.At(i); |
| 1367 if (!f.is_static() && f.has_initializer()) { | 1372 if (!f.is_static() && f.has_initializer()) { |
| 1368 Field& field = Field::ZoneHandle(); | 1373 Field& field = Field::ZoneHandle(); |
| 1369 field ^= fields.At(i); | 1374 field ^= fields.At(i); |
| 1370 intptr_t field_pos = field.token_index(); | 1375 intptr_t field_pos = field.token_index(); |
| 1371 SetPosition(field_pos); | 1376 SetPosition(field_pos); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1419 // Generate implicit super() if we haven't seen an explicit super call | 1424 // Generate implicit super() if we haven't seen an explicit super call |
| 1420 // or constructor redirection. | 1425 // or constructor redirection. |
| 1421 GenerateSuperConstructorCall(cls, receiver); | 1426 GenerateSuperConstructorCall(cls, receiver); |
| 1422 } | 1427 } |
| 1423 CheckConstFieldsInitialized(cls); | 1428 CheckConstFieldsInitialized(cls); |
| 1424 } | 1429 } |
| 1425 | 1430 |
| 1426 | 1431 |
| 1427 void Parser::ParseConstructorRedirection(const Class& cls, | 1432 void Parser::ParseConstructorRedirection(const Class& cls, |
| 1428 LocalVariable* receiver) { | 1433 LocalVariable* receiver) { |
| 1434 TRACE_PARSER("ParseConstructorRedirection"); | |
| 1429 ASSERT(CurrentToken() == Token::kTHIS); | 1435 ASSERT(CurrentToken() == Token::kTHIS); |
| 1430 const intptr_t call_pos = token_index_; | 1436 const intptr_t call_pos = token_index_; |
| 1431 ConsumeToken(); | 1437 ConsumeToken(); |
| 1432 String& ctor_name = String::Handle(cls.Name()); | 1438 String& ctor_name = String::Handle(cls.Name()); |
| 1433 String& ctor_suffix = String::Handle(String::NewSymbol(".")); | 1439 String& ctor_suffix = String::Handle(String::NewSymbol(".")); |
| 1434 | 1440 |
| 1435 if (CurrentToken() == Token::kPERIOD) { | 1441 if (CurrentToken() == Token::kPERIOD) { |
| 1436 ConsumeToken(); | 1442 ConsumeToken(); |
| 1437 ctor_suffix = String::Concat( | 1443 ctor_suffix = String::Concat( |
| 1438 ctor_suffix, *ExpectIdentifier("constructor name expected")); | 1444 ctor_suffix, *ExpectIdentifier("constructor name expected")); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1512 // Empty constructor body. | 1518 // Empty constructor body. |
| 1513 SequenceNode* statements = CloseBlock(); | 1519 SequenceNode* statements = CloseBlock(); |
| 1514 return statements; | 1520 return statements; |
| 1515 } | 1521 } |
| 1516 | 1522 |
| 1517 | 1523 |
| 1518 // Parser is at the opening parenthesis of the formal parameter declaration | 1524 // Parser is at the opening parenthesis of the formal parameter declaration |
| 1519 // of function. Parse the formal parameters, initializers and code. | 1525 // of function. Parse the formal parameters, initializers and code. |
| 1520 SequenceNode* Parser::ParseConstructor(const Function& func, | 1526 SequenceNode* Parser::ParseConstructor(const Function& func, |
| 1521 Array& default_parameter_values) { | 1527 Array& default_parameter_values) { |
| 1528 TRACE_PARSER("ParseConstructor"); | |
| 1522 ASSERT(func.IsConstructor()); | 1529 ASSERT(func.IsConstructor()); |
| 1523 ASSERT(!func.IsFactory()); | 1530 ASSERT(!func.IsFactory()); |
| 1524 ASSERT(!func.is_static()); | 1531 ASSERT(!func.is_static()); |
| 1525 ASSERT(!func.IsLocalFunction()); | 1532 ASSERT(!func.IsLocalFunction()); |
| 1526 const Class& cls = Class::Handle(func.owner()); | 1533 const Class& cls = Class::Handle(func.owner()); |
| 1527 ASSERT(!cls.IsNull()); | 1534 ASSERT(!cls.IsNull()); |
| 1528 | 1535 |
| 1529 if (CurrentToken() == Token::kCLASS) { | 1536 if (CurrentToken() == Token::kCLASS) { |
| 1530 // Special case: implicit constructor. | 1537 // Special case: implicit constructor. |
| 1531 // The parser adds an implicit default constructor when a class | 1538 // The parser adds an implicit default constructor when a class |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1763 SequenceNode* statements = CloseBlock(); | 1770 SequenceNode* statements = CloseBlock(); |
| 1764 return statements; | 1771 return statements; |
| 1765 } | 1772 } |
| 1766 | 1773 |
| 1767 | 1774 |
| 1768 // Parser is at the opening parenthesis of the formal parameter | 1775 // Parser is at the opening parenthesis of the formal parameter |
| 1769 // declaration of the function or constructor. | 1776 // declaration of the function or constructor. |
| 1770 // Parse the formal parameters and code. | 1777 // Parse the formal parameters and code. |
| 1771 SequenceNode* Parser::ParseFunc(const Function& func, | 1778 SequenceNode* Parser::ParseFunc(const Function& func, |
| 1772 Array& default_parameter_values) { | 1779 Array& default_parameter_values) { |
| 1780 TRACE_PARSER("ParseFunc"); | |
| 1773 if (func.IsConstructor()) { | 1781 if (func.IsConstructor()) { |
| 1774 return ParseConstructor(func, default_parameter_values); | 1782 return ParseConstructor(func, default_parameter_values); |
| 1775 } | 1783 } |
| 1776 | 1784 |
| 1777 ASSERT(!func.IsConstructor()); | 1785 ASSERT(!func.IsConstructor()); |
| 1778 OpenFunctionBlock(func); // Build local scope for function. | 1786 OpenFunctionBlock(func); // Build local scope for function. |
| 1779 | 1787 |
| 1780 ParamList params; | 1788 ParamList params; |
| 1781 // Static functions do not have a receiver. | 1789 // Static functions do not have a receiver. |
| 1782 // An instance closure may capture and access the receiver, but via the | 1790 // An instance closure may capture and access the receiver, but via the |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1893 ExpectToken(Token::kASSIGN); | 1901 ExpectToken(Token::kASSIGN); |
| 1894 SetAllowFunctionLiterals(false); | 1902 SetAllowFunctionLiterals(false); |
| 1895 SkipExpr(); | 1903 SkipExpr(); |
| 1896 SetAllowFunctionLiterals(true); | 1904 SetAllowFunctionLiterals(true); |
| 1897 } | 1905 } |
| 1898 } while (CurrentToken() == Token::kCOMMA); | 1906 } while (CurrentToken() == Token::kCOMMA); |
| 1899 } | 1907 } |
| 1900 | 1908 |
| 1901 | 1909 |
| 1902 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 1910 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
| 1911 TRACE_PARSER("ParseQualIdent"); | |
| 1903 ASSERT(IsIdentifier()); | 1912 ASSERT(IsIdentifier()); |
| 1904 ASSERT(!current_class().IsNull()); | 1913 ASSERT(!current_class().IsNull()); |
| 1905 qual_ident->ident_pos = token_index_; | 1914 qual_ident->ident_pos = token_index_; |
| 1906 qual_ident->ident = CurrentLiteral(); | 1915 qual_ident->ident = CurrentLiteral(); |
| 1907 qual_ident->lib_prefix = NULL; | 1916 qual_ident->lib_prefix = NULL; |
| 1908 ConsumeToken(); | 1917 ConsumeToken(); |
| 1909 if (CurrentToken() == Token::kPERIOD) { | 1918 if (CurrentToken() == Token::kPERIOD) { |
| 1910 // An identifier cannot be resolved in a local scope when top level parsing. | 1919 // An identifier cannot be resolved in a local scope when top level parsing. |
| 1911 if (is_top_level_ || | 1920 if (is_top_level_ || |
| 1912 !ResolveIdentInLocalScope(qual_ident->ident_pos, | 1921 !ResolveIdentInLocalScope(qual_ident->ident_pos, |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1928 qual_ident->ident = | 1937 qual_ident->ident = |
| 1929 ExpectIdentifier("identifier expected after '.'"); | 1938 ExpectIdentifier("identifier expected after '.'"); |
| 1930 } | 1939 } |
| 1931 } | 1940 } |
| 1932 } | 1941 } |
| 1933 } | 1942 } |
| 1934 } | 1943 } |
| 1935 | 1944 |
| 1936 | 1945 |
| 1937 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 1946 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
| 1947 TRACE_PARSER("ParseMethodOrConstructor"); | |
| 1938 ASSERT(CurrentToken() == Token::kLPAREN); | 1948 ASSERT(CurrentToken() == Token::kLPAREN); |
| 1939 intptr_t method_pos = this->token_index_; | 1949 intptr_t method_pos = this->token_index_; |
| 1940 ASSERT(method->type != NULL); | 1950 ASSERT(method->type != NULL); |
| 1941 ASSERT(method->name_pos > 0); | 1951 ASSERT(method->name_pos > 0); |
| 1942 ASSERT(current_member_ == method); | 1952 ASSERT(current_member_ == method); |
| 1943 | 1953 |
| 1944 if (method->has_var) { | 1954 if (method->has_var) { |
| 1945 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); | 1955 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); |
| 1946 } | 1956 } |
| 1947 if (method->has_final) { | 1957 if (method->has_final) { |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2138 func.set_end_token_index(method_end_pos); | 2148 func.set_end_token_index(method_end_pos); |
| 2139 | 2149 |
| 2140 // No need to resolve parameter types yet, or add parameters to local scope. | 2150 // No need to resolve parameter types yet, or add parameters to local scope. |
| 2141 ASSERT(is_top_level_); | 2151 ASSERT(is_top_level_); |
| 2142 AddFormalParamsToFunction(&method->params, func); | 2152 AddFormalParamsToFunction(&method->params, func); |
| 2143 members->AddFunction(&func); | 2153 members->AddFunction(&func); |
| 2144 } | 2154 } |
| 2145 | 2155 |
| 2146 | 2156 |
| 2147 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 2157 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
| 2158 TRACE_PARSER("ParseFieldDefinition"); | |
| 2148 // The parser has read the first field name and is now at the token | 2159 // The parser has read the first field name and is now at the token |
| 2149 // after the field name. | 2160 // after the field name. |
| 2150 ASSERT(CurrentToken() == Token::kSEMICOLON || | 2161 ASSERT(CurrentToken() == Token::kSEMICOLON || |
| 2151 CurrentToken() == Token::kCOMMA || | 2162 CurrentToken() == Token::kCOMMA || |
| 2152 CurrentToken() == Token::kASSIGN); | 2163 CurrentToken() == Token::kASSIGN); |
| 2153 ASSERT(field->type != NULL); | 2164 ASSERT(field->type != NULL); |
| 2154 ASSERT(field->name_pos > 0); | 2165 ASSERT(field->name_pos > 0); |
| 2155 ASSERT(current_member_ == field); | 2166 ASSERT(current_member_ == field); |
| 2156 | 2167 |
| 2157 if (field->has_const) { | 2168 if (field->has_const) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2243 break; | 2254 break; |
| 2244 } | 2255 } |
| 2245 ConsumeToken(); | 2256 ConsumeToken(); |
| 2246 field->name_pos = this->token_index_; | 2257 field->name_pos = this->token_index_; |
| 2247 field->name = ExpectIdentifier("field name expected"); | 2258 field->name = ExpectIdentifier("field name expected"); |
| 2248 } | 2259 } |
| 2249 ExpectSemicolon(); | 2260 ExpectSemicolon(); |
| 2250 } | 2261 } |
| 2251 | 2262 |
| 2252 | 2263 |
| 2264 void Parser::CheckOperatorArity(const MemberDesc& member) { | |
| 2265 const String& assign_index_name = | |
| 2266 String::Handle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); | |
| 2267 const String& negate_name = | |
| 2268 String::Handle(String::NewSymbol(Token::Str(Token::kNEGATE))); | |
| 2269 const String& bit_not_name = | |
| 2270 String::Handle(String::NewSymbol(Token::Str(Token::kBIT_NOT))); | |
| 2271 intptr_t expected_num_parameters; // Includes receiver. | |
| 2272 if (member.name->Equals(assign_index_name)) { | |
| 2273 expected_num_parameters = 3; | |
| 2274 } else if (member.name->Equals(negate_name) || | |
| 2275 member.name->Equals(bit_not_name)) { | |
| 2276 expected_num_parameters = 1; | |
| 2277 } else { | |
| 2278 expected_num_parameters = 2; | |
| 2279 } | |
| 2280 if ((member.params.num_optional_parameters > 0) || | |
| 2281 (member.params.has_named_optional_parameters) || | |
| 2282 (member.params.num_fixed_parameters != expected_num_parameters)) { | |
| 2283 // Subtract receiver when reporting number of expected arguments. | |
| 2284 ErrorMsg(member.name_pos, "operator %s expects %d argument(s)", | |
| 2285 member.name->ToCString(), (expected_num_parameters - 1)); | |
| 2286 } | |
| 2287 } | |
| 2288 | |
| 2289 | |
| 2253 void Parser::ParseClassMemberDefinition(ClassDesc* members) { | 2290 void Parser::ParseClassMemberDefinition(ClassDesc* members) { |
| 2291 TRACE_PARSER("ParseClassMemberDefinition"); | |
| 2254 MemberDesc member; | 2292 MemberDesc member; |
| 2255 current_member_ = &member; | 2293 current_member_ = &member; |
| 2256 if ((CurrentToken() == Token::kABSTRACT) && | 2294 if ((CurrentToken() == Token::kABSTRACT) && |
| 2257 (LookaheadToken(1) != Token::kLPAREN)) { | 2295 (LookaheadToken(1) != Token::kLPAREN)) { |
| 2258 ConsumeToken(); | 2296 ConsumeToken(); |
| 2259 member.has_abstract = true; | 2297 member.has_abstract = true; |
| 2260 } | 2298 } |
| 2261 if ((CurrentToken() == Token::kSTATIC) && | 2299 if ((CurrentToken() == Token::kSTATIC) && |
| 2262 (LookaheadToken(1) != Token::kLPAREN)) { | 2300 (LookaheadToken(1) != Token::kLPAREN)) { |
| 2263 ConsumeToken(); | 2301 ConsumeToken(); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2402 (LookaheadToken(1) != Token::kCOMMA) && | 2440 (LookaheadToken(1) != Token::kCOMMA) && |
| 2403 (LookaheadToken(1) != Token::kSEMICOLON)) { | 2441 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 2404 ConsumeToken(); | 2442 ConsumeToken(); |
| 2405 if (!Token::CanBeOverloaded(CurrentToken())) { | 2443 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 2406 ErrorMsg("invalid operator overloading"); | 2444 ErrorMsg("invalid operator overloading"); |
| 2407 } | 2445 } |
| 2408 if (member.has_static) { | 2446 if (member.has_static) { |
| 2409 ErrorMsg("operator overloading functions cannot be static"); | 2447 ErrorMsg("operator overloading functions cannot be static"); |
| 2410 } | 2448 } |
| 2411 member.kind = RawFunction::kFunction; | 2449 member.kind = RawFunction::kFunction; |
| 2450 member.is_operator = true; | |
| 2412 member.name_pos = this->token_index_; | 2451 member.name_pos = this->token_index_; |
| 2413 member.name = | 2452 member.name = |
| 2414 &String::ZoneHandle(String::NewSymbol(Token::Str(CurrentToken()))); | 2453 &String::ZoneHandle(String::NewSymbol(Token::Str(CurrentToken()))); |
| 2415 ConsumeToken(); | 2454 ConsumeToken(); |
| 2416 } else if (IsIdentifier()) { | 2455 } else if (IsIdentifier()) { |
| 2417 member.name = CurrentLiteral(); | 2456 member.name = CurrentLiteral(); |
| 2418 member.name_pos = token_index_; | 2457 member.name_pos = token_index_; |
| 2419 ConsumeToken(); | 2458 ConsumeToken(); |
| 2420 } else { | 2459 } else { |
| 2421 ErrorMsg("identifier expected"); | 2460 ErrorMsg("identifier expected"); |
| 2422 } | 2461 } |
| 2423 | 2462 |
| 2424 ASSERT(member.name != NULL); | 2463 ASSERT(member.name != NULL); |
| 2425 if (CurrentToken() == Token::kLPAREN) { | 2464 if (CurrentToken() == Token::kLPAREN) { |
| 2426 if (members->is_interface() && member.has_static) { | 2465 if (members->is_interface() && member.has_static) { |
| 2427 if (member.has_factory) { | 2466 if (member.has_factory) { |
| 2428 ErrorMsg("factory constructors are not allowed in interfaces"); | 2467 ErrorMsg("factory constructors are not allowed in interfaces"); |
| 2429 } else { | 2468 } else { |
| 2430 ErrorMsg("static methods are not allowed in interfaces"); | 2469 ErrorMsg("static methods are not allowed in interfaces"); |
| 2431 } | 2470 } |
| 2432 } | 2471 } |
| 2433 // Constructor or method. | 2472 // Constructor or method. |
| 2434 if (member.type == NULL) { | 2473 if (member.type == NULL) { |
| 2435 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2474 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2436 } | 2475 } |
| 2437 ParseMethodOrConstructor(members, &member); | 2476 ParseMethodOrConstructor(members, &member); |
| 2477 if (member.is_operator) { | |
| 2478 CheckOperatorArity(member); | |
|
hausner
2012/02/16 17:39:36
Suggestion. I think this is unnecessarily complica
| |
| 2479 } | |
| 2438 } else if (CurrentToken() == Token::kSEMICOLON || | 2480 } else if (CurrentToken() == Token::kSEMICOLON || |
| 2439 CurrentToken() == Token::kCOMMA || | 2481 CurrentToken() == Token::kCOMMA || |
| 2440 CurrentToken() == Token::kASSIGN) { | 2482 CurrentToken() == Token::kASSIGN) { |
| 2441 // Field definition. | 2483 // Field definition. |
| 2442 if (member.type == NULL) { | 2484 if (member.type == NULL) { |
| 2443 if (member.has_final) { | 2485 if (member.has_final) { |
| 2444 member.type = &Type::ZoneHandle(Type::DynamicType()); | 2486 member.type = &Type::ZoneHandle(Type::DynamicType()); |
| 2445 } else { | 2487 } else { |
| 2446 ErrorMsg("missing 'var', 'final' or type in field declaration"); | 2488 ErrorMsg("missing 'var', 'final' or type in field declaration"); |
| 2447 } | 2489 } |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2859 if (CurrentToken() == Token::kPERIOD) { | 2901 if (CurrentToken() == Token::kPERIOD) { |
| 2860 ConsumeToken(); | 2902 ConsumeToken(); |
| 2861 ExpectIdentifier("name expected"); | 2903 ExpectIdentifier("name expected"); |
| 2862 } | 2904 } |
| 2863 SkipTypeArguments(); | 2905 SkipTypeArguments(); |
| 2864 } | 2906 } |
| 2865 } | 2907 } |
| 2866 | 2908 |
| 2867 | 2909 |
| 2868 void Parser::ParseTypeParameters(const Class& cls) { | 2910 void Parser::ParseTypeParameters(const Class& cls) { |
| 2911 TRACE_PARSER("ParseTypeParameters"); | |
| 2869 if (CurrentToken() == Token::kLT) { | 2912 if (CurrentToken() == Token::kLT) { |
| 2870 GrowableArray<AbstractType*> type_parameters_array; | 2913 GrowableArray<AbstractType*> type_parameters_array; |
| 2871 GrowableArray<AbstractType*> bounds_array; | 2914 GrowableArray<AbstractType*> bounds_array; |
| 2872 intptr_t index = 0; | 2915 intptr_t index = 0; |
| 2873 do { | 2916 do { |
| 2874 ConsumeToken(); | 2917 ConsumeToken(); |
| 2875 if (CurrentToken() != Token::kIDENT) { | 2918 if (CurrentToken() != Token::kIDENT) { |
| 2876 ErrorMsg("type parameter name expected"); | 2919 ErrorMsg("type parameter name expected"); |
| 2877 } | 2920 } |
| 2878 String& type_parameter_name = *CurrentLiteral(); | 2921 String& type_parameter_name = *CurrentLiteral(); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 2908 bound = bounds.TypeAt(i); | 2951 bound = bounds.TypeAt(i); |
| 2909 ResolveTypeFromClass(cls, kCanResolve, &bound); | 2952 ResolveTypeFromClass(cls, kCanResolve, &bound); |
| 2910 bounds.SetTypeAt(i, bound); | 2953 bounds.SetTypeAt(i, bound); |
| 2911 } | 2954 } |
| 2912 } | 2955 } |
| 2913 } | 2956 } |
| 2914 | 2957 |
| 2915 | 2958 |
| 2916 RawAbstractTypeArguments* Parser::ParseTypeArguments( | 2959 RawAbstractTypeArguments* Parser::ParseTypeArguments( |
| 2917 TypeResolution type_resolution) { | 2960 TypeResolution type_resolution) { |
| 2961 TRACE_PARSER("ParseTypeArguments"); | |
| 2918 if (CurrentToken() == Token::kLT) { | 2962 if (CurrentToken() == Token::kLT) { |
| 2919 GrowableArray<AbstractType*> types; | 2963 GrowableArray<AbstractType*> types; |
| 2920 do { | 2964 do { |
| 2921 ConsumeToken(); | 2965 ConsumeToken(); |
| 2922 AbstractType& type = AbstractType::ZoneHandle(ParseType(type_resolution)); | 2966 AbstractType& type = AbstractType::ZoneHandle(ParseType(type_resolution)); |
| 2923 types.Add(&type); | 2967 types.Add(&type); |
| 2924 } while (CurrentToken() == Token::kCOMMA); | 2968 } while (CurrentToken() == Token::kCOMMA); |
| 2925 Token::Kind token = CurrentToken(); | 2969 Token::Kind token = CurrentToken(); |
| 2926 if ((token == Token::kGT) || (token == Token::kSHR)) { | 2970 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 2927 ConsumeRightAngleBracket(); | 2971 ConsumeRightAngleBracket(); |
| 2928 } else { | 2972 } else { |
| 2929 ErrorMsg("right angle bracket expected"); | 2973 ErrorMsg("right angle bracket expected"); |
| 2930 } | 2974 } |
| 2931 if (type_resolution != kIgnore) { | 2975 if (type_resolution != kIgnore) { |
| 2932 return NewTypeArguments(types); | 2976 return NewTypeArguments(types); |
| 2933 } | 2977 } |
| 2934 } | 2978 } |
| 2935 return TypeArguments::null(); | 2979 return TypeArguments::null(); |
| 2936 } | 2980 } |
| 2937 | 2981 |
| 2938 | 2982 |
| 2939 // Parse and return an array of interface types. | 2983 // Parse and return an array of interface types. |
| 2940 RawArray* Parser::ParseInterfaceList() { | 2984 RawArray* Parser::ParseInterfaceList() { |
| 2985 TRACE_PARSER("ParseInterfaceList"); | |
| 2941 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 2986 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || |
| 2942 (CurrentToken() == Token::kEXTENDS)); | 2987 (CurrentToken() == Token::kEXTENDS)); |
| 2943 GrowableArray<AbstractType*> interfaces; | 2988 GrowableArray<AbstractType*> interfaces; |
| 2944 String& interface_name = String::Handle(); | 2989 String& interface_name = String::Handle(); |
| 2945 do { | 2990 do { |
| 2946 ConsumeToken(); | 2991 ConsumeToken(); |
| 2947 intptr_t supertype_pos = token_index_; | 2992 intptr_t supertype_pos = token_index_; |
| 2948 AbstractType& interface = AbstractType::ZoneHandle(ParseType(kCanResolve)); | 2993 AbstractType& interface = AbstractType::ZoneHandle(ParseType(kCanResolve)); |
| 2949 interface_name = interface.Name(); | 2994 interface_name = interface.Name(); |
| 2950 for (int i = 0; i < interfaces.length(); i++) { | 2995 for (int i = 0; i < interfaces.length(); i++) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2998 String::Handle(interface.Name()).ToCString(), | 3043 String::Handle(interface.Name()).ToCString(), |
| 2999 String::Handle(conflicting.Name()).ToCString()); | 3044 String::Handle(conflicting.Name()).ToCString()); |
| 3000 } | 3045 } |
| 3001 } | 3046 } |
| 3002 cls_interfaces = NewArray<AbstractType>(all_interfaces); | 3047 cls_interfaces = NewArray<AbstractType>(all_interfaces); |
| 3003 cls.set_interfaces(cls_interfaces); | 3048 cls.set_interfaces(cls_interfaces); |
| 3004 } | 3049 } |
| 3005 | 3050 |
| 3006 | 3051 |
| 3007 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3052 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
| 3053 TRACE_PARSER("ParseTopLevelVariable"); | |
| 3008 const bool is_final = (CurrentToken() == Token::kFINAL); | 3054 const bool is_final = (CurrentToken() == Token::kFINAL); |
| 3009 const bool is_static = true; | 3055 const bool is_static = true; |
| 3010 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( | 3056 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 3011 FLAG_enable_type_checks ? kCanResolve : kIgnore)); | 3057 FLAG_enable_type_checks ? kCanResolve : kIgnore)); |
| 3012 | 3058 |
| 3013 while (true) { | 3059 while (true) { |
| 3014 const intptr_t name_pos = token_index_; | 3060 const intptr_t name_pos = token_index_; |
| 3015 String& var_name = *ExpectIdentifier("variable name expected"); | 3061 String& var_name = *ExpectIdentifier("variable name expected"); |
| 3016 | 3062 |
| 3017 if (library_.LookupObject(var_name) != Object::null()) { | 3063 if (library_.LookupObject(var_name) != Object::null()) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3055 ConsumeToken(); | 3101 ConsumeToken(); |
| 3056 break; | 3102 break; |
| 3057 } else { | 3103 } else { |
| 3058 ExpectSemicolon(); // Reports error. | 3104 ExpectSemicolon(); // Reports error. |
| 3059 } | 3105 } |
| 3060 } | 3106 } |
| 3061 } | 3107 } |
| 3062 | 3108 |
| 3063 | 3109 |
| 3064 void Parser::ParseTopLevelFunction(TopLevel* top_level) { | 3110 void Parser::ParseTopLevelFunction(TopLevel* top_level) { |
| 3111 TRACE_PARSER("ParseTopLevelFunction"); | |
| 3065 AbstractType& result_type = Type::Handle(Type::DynamicType()); | 3112 AbstractType& result_type = Type::Handle(Type::DynamicType()); |
| 3066 const bool is_static = true; | 3113 const bool is_static = true; |
| 3067 if (CurrentToken() == Token::kVOID) { | 3114 if (CurrentToken() == Token::kVOID) { |
| 3068 ConsumeToken(); | 3115 ConsumeToken(); |
| 3069 result_type = Type::VoidType(); | 3116 result_type = Type::VoidType(); |
| 3070 } else { | 3117 } else { |
| 3071 // Parse optional type. | 3118 // Parse optional type. |
| 3072 if ((CurrentToken() == Token::kIDENT) && | 3119 if ((CurrentToken() == Token::kIDENT) && |
| 3073 (LookaheadToken(1) != Token::kLPAREN)) { | 3120 (LookaheadToken(1) != Token::kLPAREN)) { |
| 3074 result_type = ParseType(kCanResolve); | 3121 result_type = ParseType(kCanResolve); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3118 is_static, false, function_pos)); | 3165 is_static, false, function_pos)); |
| 3119 func.set_result_type(result_type); | 3166 func.set_result_type(result_type); |
| 3120 func.set_end_token_index(function_end_pos); | 3167 func.set_end_token_index(function_end_pos); |
| 3121 AddFormalParamsToFunction(¶ms, func); | 3168 AddFormalParamsToFunction(¶ms, func); |
| 3122 top_level->functions.Add(&func); | 3169 top_level->functions.Add(&func); |
| 3123 library_.AddObject(func, func_name); | 3170 library_.AddObject(func, func_name); |
| 3124 } | 3171 } |
| 3125 | 3172 |
| 3126 | 3173 |
| 3127 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { | 3174 void Parser::ParseTopLevelAccessor(TopLevel* top_level) { |
| 3175 TRACE_PARSER("ParseTopLevelAccessor"); | |
| 3128 const bool is_static = true; | 3176 const bool is_static = true; |
| 3129 AbstractType& result_type = AbstractType::Handle(); | 3177 AbstractType& result_type = AbstractType::Handle(); |
| 3130 bool is_getter = (CurrentToken() == Token::kGET); | 3178 bool is_getter = (CurrentToken() == Token::kGET); |
| 3131 if (CurrentToken() == Token::kGET || | 3179 if (CurrentToken() == Token::kGET || |
| 3132 CurrentToken() == Token::kSET) { | 3180 CurrentToken() == Token::kSET) { |
| 3133 ConsumeToken(); | 3181 ConsumeToken(); |
| 3134 result_type = Type::DynamicType(); | 3182 result_type = Type::DynamicType(); |
| 3135 } else { | 3183 } else { |
| 3136 if (CurrentToken() == Token::kVOID) { | 3184 if (CurrentToken() == Token::kVOID) { |
| 3137 ConsumeToken(); | 3185 ConsumeToken(); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3198 RawFunction::kSetterFunction, | 3246 RawFunction::kSetterFunction, |
| 3199 is_static, false, accessor_pos)); | 3247 is_static, false, accessor_pos)); |
| 3200 func.set_result_type(result_type); | 3248 func.set_result_type(result_type); |
| 3201 AddFormalParamsToFunction(¶ms, func); | 3249 AddFormalParamsToFunction(¶ms, func); |
| 3202 top_level->functions.Add(&func); | 3250 top_level->functions.Add(&func); |
| 3203 library_.AddObject(func, accessor_name); | 3251 library_.AddObject(func, accessor_name); |
| 3204 } | 3252 } |
| 3205 | 3253 |
| 3206 | 3254 |
| 3207 void Parser::ParseLibraryName() { | 3255 void Parser::ParseLibraryName() { |
| 3256 TRACE_PARSER("ParseLibraryName"); | |
| 3208 if ((script_.kind() == RawScript::kLibrary) && | 3257 if ((script_.kind() == RawScript::kLibrary) && |
| 3209 (CurrentToken() != Token::kLIBRARY)) { | 3258 (CurrentToken() != Token::kLIBRARY)) { |
| 3210 // Handle error case early to get consistent error message. | 3259 // Handle error case early to get consistent error message. |
| 3211 ExpectToken(Token::kLIBRARY); | 3260 ExpectToken(Token::kLIBRARY); |
| 3212 } | 3261 } |
| 3213 if (CurrentToken() == Token::kLIBRARY) { | 3262 if (CurrentToken() == Token::kLIBRARY) { |
| 3214 ConsumeToken(); | 3263 ConsumeToken(); |
| 3215 ExpectToken(Token::kLPAREN); | 3264 ExpectToken(Token::kLPAREN); |
| 3216 if (CurrentToken() != Token::kSTRING) { | 3265 if (CurrentToken() != Token::kSTRING) { |
| 3217 ErrorMsg("library name expected"); | 3266 ErrorMsg("library name expected"); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 3238 Api::NewLocalHandle(url), | 3287 Api::NewLocalHandle(url), |
| 3239 Api::NewLocalHandle(import_map)); | 3288 Api::NewLocalHandle(import_map)); |
| 3240 if (Dart_IsError(result)) { | 3289 if (Dart_IsError(result)) { |
| 3241 ErrorMsg(token_pos, "library handler failed: %s", Dart_GetError(result)); | 3290 ErrorMsg(token_pos, "library handler failed: %s", Dart_GetError(result)); |
| 3242 } | 3291 } |
| 3243 return result; | 3292 return result; |
| 3244 } | 3293 } |
| 3245 | 3294 |
| 3246 | 3295 |
| 3247 void Parser::ParseLibraryImport() { | 3296 void Parser::ParseLibraryImport() { |
| 3297 TRACE_PARSER("ParseLibraryImport"); | |
| 3248 while (CurrentToken() == Token::kIMPORT) { | 3298 while (CurrentToken() == Token::kIMPORT) { |
| 3249 const intptr_t import_pos = token_index_; | 3299 const intptr_t import_pos = token_index_; |
| 3250 ConsumeToken(); | 3300 ConsumeToken(); |
| 3251 ExpectToken(Token::kLPAREN); | 3301 ExpectToken(Token::kLPAREN); |
| 3252 if (CurrentToken() != Token::kSTRING) { | 3302 if (CurrentToken() != Token::kSTRING) { |
| 3253 ErrorMsg("library url expected"); | 3303 ErrorMsg("library url expected"); |
| 3254 } | 3304 } |
| 3255 const String& url = *ParseImportStringLiteral(); | 3305 const String& url = *ParseImportStringLiteral(); |
| 3256 String& prefix = String::Handle(); | 3306 String& prefix = String::Handle(); |
| 3257 if (CurrentToken() == Token::kCOMMA) { | 3307 if (CurrentToken() == Token::kCOMMA) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3303 } else { | 3353 } else { |
| 3304 library_prefix = LibraryPrefix::New(prefix, library); | 3354 library_prefix = LibraryPrefix::New(prefix, library); |
| 3305 library_.AddObject(library_prefix, prefix); | 3355 library_.AddObject(library_prefix, prefix); |
| 3306 } | 3356 } |
| 3307 } | 3357 } |
| 3308 } | 3358 } |
| 3309 } | 3359 } |
| 3310 | 3360 |
| 3311 | 3361 |
| 3312 void Parser::ParseLibraryInclude() { | 3362 void Parser::ParseLibraryInclude() { |
| 3363 TRACE_PARSER("ParseLibraryInclude"); | |
| 3313 const Array& import_map = Array::Handle(library_.import_map()); | 3364 const Array& import_map = Array::Handle(library_.import_map()); |
| 3314 while (CurrentToken() == Token::kSOURCE) { | 3365 while (CurrentToken() == Token::kSOURCE) { |
| 3315 const intptr_t source_pos = token_index_; | 3366 const intptr_t source_pos = token_index_; |
| 3316 ConsumeToken(); | 3367 ConsumeToken(); |
| 3317 ExpectToken(Token::kLPAREN); | 3368 ExpectToken(Token::kLPAREN); |
| 3318 if (CurrentToken() != Token::kSTRING) { | 3369 if (CurrentToken() != Token::kSTRING) { |
| 3319 ErrorMsg("source url expected"); | 3370 ErrorMsg("source url expected"); |
| 3320 } | 3371 } |
| 3321 const String& url = *ParseImportStringLiteral(); | 3372 const String& url = *ParseImportStringLiteral(); |
| 3322 ExpectToken(Token::kRPAREN); | 3373 ExpectToken(Token::kRPAREN); |
| 3323 ExpectToken(Token::kSEMICOLON); | 3374 ExpectToken(Token::kSEMICOLON); |
| 3324 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, | 3375 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, |
| 3325 source_pos, | 3376 source_pos, |
| 3326 url, | 3377 url, |
| 3327 import_map); | 3378 import_map); |
| 3328 const String& canon_url = String::CheckedHandle(Api::UnwrapHandle(handle)); | 3379 const String& canon_url = String::CheckedHandle(Api::UnwrapHandle(handle)); |
| 3329 CallLibraryTagHandler(kSourceTag, source_pos, canon_url, import_map); | 3380 CallLibraryTagHandler(kSourceTag, source_pos, canon_url, import_map); |
| 3330 } | 3381 } |
| 3331 } | 3382 } |
| 3332 | 3383 |
| 3333 | 3384 |
| 3334 void Parser::ParseLibraryDefinition() { | 3385 void Parser::ParseLibraryDefinition() { |
| 3386 TRACE_PARSER("ParseLibraryDefinition"); | |
| 3335 // Handle the script tag. | 3387 // Handle the script tag. |
| 3336 if (CurrentToken() == Token::kSCRIPTTAG) { | 3388 if (CurrentToken() == Token::kSCRIPTTAG) { |
| 3337 // Nothing to do for script tags except to skip them. | 3389 // Nothing to do for script tags except to skip them. |
| 3338 ConsumeToken(); | 3390 ConsumeToken(); |
| 3339 } | 3391 } |
| 3340 | 3392 |
| 3341 ParseLibraryName(); | 3393 ParseLibraryName(); |
| 3342 ParseLibraryImport(); | 3394 ParseLibraryImport(); |
| 3343 ParseLibraryInclude(); | 3395 ParseLibraryInclude(); |
| 3344 } | 3396 } |
| 3345 | 3397 |
| 3346 | 3398 |
| 3347 void Parser::ParseTopLevel() { | 3399 void Parser::ParseTopLevel() { |
| 3400 TRACE_PARSER("ParseTopLevel"); | |
| 3348 // Collect the classes found at the top level in this growable array. | 3401 // Collect the classes found at the top level in this growable array. |
| 3349 // They need to be registered with class finalization after parsing | 3402 // They need to be registered with class finalization after parsing |
| 3350 // has been completed. | 3403 // has been completed. |
| 3351 GrowableArray<const Class*> classes; | 3404 GrowableArray<const Class*> classes; |
| 3352 SetPosition(0); | 3405 SetPosition(0); |
| 3353 is_top_level_ = true; | 3406 is_top_level_ = true; |
| 3354 TopLevel top_level; | 3407 TopLevel top_level; |
| 3355 Class& toplevel_class = Class::ZoneHandle( | 3408 Class& toplevel_class = Class::ZoneHandle( |
| 3356 Class::New(String::ZoneHandle(String::NewSymbol("::")), | 3409 Class::New(String::ZoneHandle(String::NewSymbol("::")), |
| 3357 script_, | 3410 script_, |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3519 if (param_desc.is_final) { | 3572 if (param_desc.is_final) { |
| 3520 parameter->set_is_final(); | 3573 parameter->set_is_final(); |
| 3521 } | 3574 } |
| 3522 } | 3575 } |
| 3523 } | 3576 } |
| 3524 | 3577 |
| 3525 | 3578 |
| 3526 // Builds ReturnNode/NativeBodyNode for a native function. | 3579 // Builds ReturnNode/NativeBodyNode for a native function. |
| 3527 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 3580 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
| 3528 const Function& func) { | 3581 const Function& func) { |
| 3582 TRACE_PARSER("ParseNativeFunctionBlock"); | |
| 3529 const Class& cls = Class::Handle(func.owner()); | 3583 const Class& cls = Class::Handle(func.owner()); |
| 3530 const int num_parameters = params->parameters->length(); | 3584 const int num_parameters = params->parameters->length(); |
| 3531 | 3585 |
| 3532 // Parse the function name out. | 3586 // Parse the function name out. |
| 3533 const intptr_t native_pos = token_index_; | 3587 const intptr_t native_pos = token_index_; |
| 3534 const String& native_name = ParseNativeDeclaration(); | 3588 const String& native_name = ParseNativeDeclaration(); |
| 3535 | 3589 |
| 3536 // Now resolve the native function to the corresponding native entrypoint. | 3590 // Now resolve the native function to the corresponding native entrypoint. |
| 3537 NativeFunction native_function = NativeEntry::ResolveNative(cls, | 3591 NativeFunction native_function = NativeEntry::ResolveNative(cls, |
| 3538 native_name, | 3592 native_name, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3635 variable->set_is_final(); | 3689 variable->set_is_final(); |
| 3636 } | 3690 } |
| 3637 return initialization; | 3691 return initialization; |
| 3638 } | 3692 } |
| 3639 | 3693 |
| 3640 | 3694 |
| 3641 // Parses ('var' | 'final' [type] | type). | 3695 // Parses ('var' | 'final' [type] | type). |
| 3642 // The presence of 'final' must be detected and remembered before the call. | 3696 // The presence of 'final' must be detected and remembered before the call. |
| 3643 // If a type is parsed, it is resolved (or not) according to type_resolution. | 3697 // If a type is parsed, it is resolved (or not) according to type_resolution. |
| 3644 RawAbstractType* Parser::ParseFinalVarOrType(TypeResolution type_resolution) { | 3698 RawAbstractType* Parser::ParseFinalVarOrType(TypeResolution type_resolution) { |
| 3699 TRACE_PARSER("ParseFinalVarOrType"); | |
| 3645 if (CurrentToken() == Token::kVAR) { | 3700 if (CurrentToken() == Token::kVAR) { |
| 3646 ConsumeToken(); | 3701 ConsumeToken(); |
| 3647 return Type::DynamicType(); | 3702 return Type::DynamicType(); |
| 3648 } | 3703 } |
| 3649 bool type_is_optional = false; | 3704 bool type_is_optional = false; |
| 3650 if (CurrentToken() == Token::kFINAL) { | 3705 if (CurrentToken() == Token::kFINAL) { |
| 3651 ConsumeToken(); | 3706 ConsumeToken(); |
| 3652 type_is_optional = true; | 3707 type_is_optional = true; |
| 3653 } | 3708 } |
| 3654 if (CurrentToken() != Token::kIDENT) { | 3709 if (CurrentToken() != Token::kIDENT) { |
| (...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4345 ExpectToken(Token::kLPAREN); | 4400 ExpectToken(Token::kLPAREN); |
| 4346 AstNode* cond_expr = ParseExpr(kAllowConst); | 4401 AstNode* cond_expr = ParseExpr(kAllowConst); |
| 4347 ExpectToken(Token::kRPAREN); | 4402 ExpectToken(Token::kRPAREN); |
| 4348 ExpectSemicolon(); | 4403 ExpectSemicolon(); |
| 4349 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 4404 return new DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 4350 } | 4405 } |
| 4351 | 4406 |
| 4352 | 4407 |
| 4353 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 4408 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 4354 SourceLabel* label) { | 4409 SourceLabel* label) { |
| 4410 TRACE_PARSER("ParseForInStatement"); | |
| 4355 bool is_final = (CurrentToken() == Token::kFINAL); | 4411 bool is_final = (CurrentToken() == Token::kFINAL); |
| 4356 const String* loop_var_name = NULL; | 4412 const String* loop_var_name = NULL; |
| 4357 LocalVariable* loop_var = NULL; | 4413 LocalVariable* loop_var = NULL; |
| 4358 intptr_t loop_var_pos = 0; | 4414 intptr_t loop_var_pos = 0; |
| 4359 if (LookaheadToken(1) == Token::kIN) { | 4415 if (LookaheadToken(1) == Token::kIN) { |
| 4360 loop_var_pos = token_index_; | 4416 loop_var_pos = token_index_; |
| 4361 loop_var_name = ExpectIdentifier("variable name expected"); | 4417 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4362 } else { | 4418 } else { |
| 4363 // The case without a type is handled above, so require a type here. | 4419 // The case without a type is handled above, so require a type here. |
| 4364 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( | 4420 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4568 ArgumentListNode* arguments = new ArgumentListNode(begin); | 4624 ArgumentListNode* arguments = new ArgumentListNode(begin); |
| 4569 arguments->Add(new LiteralNode(begin, | 4625 arguments->Add(new LiteralNode(begin, |
| 4570 Integer::ZoneHandle(Integer::New(begin)))); | 4626 Integer::ZoneHandle(Integer::New(begin)))); |
| 4571 arguments->Add(new LiteralNode(end, | 4627 arguments->Add(new LiteralNode(end, |
| 4572 Integer::ZoneHandle(Integer::New(end)))); | 4628 Integer::ZoneHandle(Integer::New(end)))); |
| 4573 return MakeStaticCall(kAssertionErrorName, kThrowNewName, arguments); | 4629 return MakeStaticCall(kAssertionErrorName, kThrowNewName, arguments); |
| 4574 } | 4630 } |
| 4575 | 4631 |
| 4576 | 4632 |
| 4577 AstNode* Parser::ParseAssertStatement() { | 4633 AstNode* Parser::ParseAssertStatement() { |
| 4634 TRACE_PARSER("ParseAssertStatement"); | |
| 4578 ConsumeToken(); // Consume assert keyword. | 4635 ConsumeToken(); // Consume assert keyword. |
| 4579 ExpectToken(Token::kLPAREN); | 4636 ExpectToken(Token::kLPAREN); |
| 4580 const intptr_t condition_pos = token_index_; | 4637 const intptr_t condition_pos = token_index_; |
| 4581 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { | 4638 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { |
| 4582 SkipExpr(); | 4639 SkipExpr(); |
| 4583 ExpectToken(Token::kRPAREN); | 4640 ExpectToken(Token::kRPAREN); |
| 4584 return NULL; | 4641 return NULL; |
| 4585 } | 4642 } |
| 4586 AstNode* condition = ParseExpr(kAllowConst); | 4643 AstNode* condition = ParseExpr(kAllowConst); |
| 4587 const intptr_t condition_end = token_index_; | 4644 const intptr_t condition_end = token_index_; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4650 if (!added_to_scope) { | 4707 if (!added_to_scope) { |
| 4651 ErrorMsg(stack_trace_param.token_index, | 4708 ErrorMsg(stack_trace_param.token_index, |
| 4652 "name '%s' already exists in scope", | 4709 "name '%s' already exists in scope", |
| 4653 stack_trace_param.var->ToCString()); | 4710 stack_trace_param.var->ToCString()); |
| 4654 } | 4711 } |
| 4655 } | 4712 } |
| 4656 } | 4713 } |
| 4657 | 4714 |
| 4658 | 4715 |
| 4659 SequenceNode* Parser::ParseFinallyBlock() { | 4716 SequenceNode* Parser::ParseFinallyBlock() { |
| 4717 TRACE_PARSER("ParseFinallyBlock"); | |
| 4660 OpenBlock(); | 4718 OpenBlock(); |
| 4661 ExpectToken(Token::kLBRACE); | 4719 ExpectToken(Token::kLBRACE); |
| 4662 ParseStatementSequence(); | 4720 ParseStatementSequence(); |
| 4663 ExpectToken(Token::kRBRACE); | 4721 ExpectToken(Token::kRBRACE); |
| 4664 SequenceNode* finally_block = CloseBlock(); | 4722 SequenceNode* finally_block = CloseBlock(); |
| 4665 return finally_block; | 4723 return finally_block; |
| 4666 } | 4724 } |
| 4667 | 4725 |
| 4668 | 4726 |
| 4669 void Parser::PushTryBlock(Block* try_block) { | 4727 void Parser::PushTryBlock(Block* try_block) { |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4945 current_block_->statements->Add(try_catch_node); | 5003 current_block_->statements->Add(try_catch_node); |
| 4946 SequenceNode* sequence = CloseBlock(); | 5004 SequenceNode* sequence = CloseBlock(); |
| 4947 sequence->set_label(try_label); | 5005 sequence->set_label(try_label); |
| 4948 try_catch_node = sequence; | 5006 try_catch_node = sequence; |
| 4949 } | 5007 } |
| 4950 return try_catch_node; | 5008 return try_catch_node; |
| 4951 } | 5009 } |
| 4952 | 5010 |
| 4953 | 5011 |
| 4954 AstNode* Parser::ParseJump(String* label_name) { | 5012 AstNode* Parser::ParseJump(String* label_name) { |
| 5013 TRACE_PARSER("ParseJump"); | |
| 4955 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 5014 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
| 4956 Token::Kind jump_kind = CurrentToken(); | 5015 Token::Kind jump_kind = CurrentToken(); |
| 4957 const intptr_t jump_pos = token_index_; | 5016 const intptr_t jump_pos = token_index_; |
| 4958 SourceLabel* target = NULL; | 5017 SourceLabel* target = NULL; |
| 4959 ConsumeToken(); | 5018 ConsumeToken(); |
| 4960 if (IsIdentifier()) { | 5019 if (IsIdentifier()) { |
| 4961 // Explicit label after break/continue. | 5020 // Explicit label after break/continue. |
| 4962 const String& target_name = *CurrentLiteral(); | 5021 const String& target_name = *CurrentLiteral(); |
| 4963 ConsumeToken(); | 5022 ConsumeToken(); |
| 4964 // Handle pathological cases first. | 5023 // Handle pathological cases first. |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5802 kThrowNewName, | 5861 kThrowNewName, |
| 5803 arguments); | 5862 arguments); |
| 5804 } | 5863 } |
| 5805 } | 5864 } |
| 5806 CheckFunctionIsCallable(call_pos, func); | 5865 CheckFunctionIsCallable(call_pos, func); |
| 5807 return new StaticCallNode(call_pos, func, arguments); | 5866 return new StaticCallNode(call_pos, func, arguments); |
| 5808 } | 5867 } |
| 5809 | 5868 |
| 5810 | 5869 |
| 5811 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { | 5870 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { |
| 5871 TRACE_PARSER("ParseInstanceCall"); | |
| 5812 const intptr_t call_pos = token_index_; | 5872 const intptr_t call_pos = token_index_; |
| 5813 if (CurrentToken() != Token::kLPAREN) { | 5873 if (CurrentToken() != Token::kLPAREN) { |
| 5814 ErrorMsg(call_pos, "left parenthesis expected"); | 5874 ErrorMsg(call_pos, "left parenthesis expected"); |
| 5815 } | 5875 } |
| 5816 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 5876 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 5817 return new InstanceCallNode(call_pos, receiver, func_name, arguments); | 5877 return new InstanceCallNode(call_pos, receiver, func_name, arguments); |
| 5818 } | 5878 } |
| 5819 | 5879 |
| 5820 | 5880 |
| 5821 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 5881 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
| 5882 TRACE_PARSER("ParseClosureCall"); | |
| 5822 const intptr_t call_pos = token_index_; | 5883 const intptr_t call_pos = token_index_; |
| 5823 ASSERT(CurrentToken() == Token::kLPAREN); | 5884 ASSERT(CurrentToken() == Token::kLPAREN); |
| 5824 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 5885 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 5825 return new ClosureCallNode(call_pos, closure, arguments); | 5886 return new ClosureCallNode(call_pos, closure, arguments); |
| 5826 } | 5887 } |
| 5827 | 5888 |
| 5828 | 5889 |
| 5829 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, | 5890 AstNode* Parser::ParseInstanceFieldAccess(AstNode* receiver, |
| 5830 const String& field_name) { | 5891 const String& field_name) { |
| 5831 TRACE_PARSER("ParseInstanceFieldAccess"); | 5892 TRACE_PARSER("ParseInstanceFieldAccess"); |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6647 } | 6708 } |
| 6648 ErrorMsg(ident_pos, "import variable '%s' has not been defined", | 6709 ErrorMsg(ident_pos, "import variable '%s' has not been defined", |
| 6649 ident.ToCString()); | 6710 ident.ToCString()); |
| 6650 return String::null(); | 6711 return String::null(); |
| 6651 } | 6712 } |
| 6652 | 6713 |
| 6653 | 6714 |
| 6654 // Parses type = [ident "."] ident ["<" type { "," type } ">"] and resolve it | 6715 // Parses type = [ident "."] ident ["<" type { "," type } ">"] and resolve it |
| 6655 // according to the given type_resolution. | 6716 // according to the given type_resolution. |
| 6656 RawAbstractType* Parser::ParseType(TypeResolution type_resolution) { | 6717 RawAbstractType* Parser::ParseType(TypeResolution type_resolution) { |
| 6718 TRACE_PARSER("ParseType"); | |
| 6657 if (CurrentToken() != Token::kIDENT) { | 6719 if (CurrentToken() != Token::kIDENT) { |
| 6658 ErrorMsg("type name expected"); | 6720 ErrorMsg("type name expected"); |
| 6659 } | 6721 } |
| 6660 QualIdent type_name; | 6722 QualIdent type_name; |
| 6661 if (type_resolution == kIgnore) { | 6723 if (type_resolution == kIgnore) { |
| 6662 SkipQualIdent(); | 6724 SkipQualIdent(); |
| 6663 } else { | 6725 } else { |
| 6664 ParseQualIdent(&type_name); | 6726 ParseQualIdent(&type_name); |
| 6665 // An identifier cannot be resolved in a local scope when top level parsing. | 6727 // An identifier cannot be resolved in a local scope when top level parsing. |
| 6666 if (!is_top_level_ && | 6728 if (!is_top_level_ && |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7039 factory_param->Add(kv_pairs); | 7101 factory_param->Add(kv_pairs); |
| 7040 return new ConstructorCallNode(literal_pos, | 7102 return new ConstructorCallNode(literal_pos, |
| 7041 map_type_arguments, | 7103 map_type_arguments, |
| 7042 map_literal_factory, | 7104 map_literal_factory, |
| 7043 factory_param); | 7105 factory_param); |
| 7044 } | 7106 } |
| 7045 } | 7107 } |
| 7046 | 7108 |
| 7047 | 7109 |
| 7048 AstNode* Parser::ParseCompoundLiteral() { | 7110 AstNode* Parser::ParseCompoundLiteral() { |
| 7111 TRACE_PARSER("ParseCompoundLiteral"); | |
| 7049 bool is_const = false; | 7112 bool is_const = false; |
| 7050 if (CurrentToken() == Token::kCONST) { | 7113 if (CurrentToken() == Token::kCONST) { |
| 7051 is_const = true; | 7114 is_const = true; |
| 7052 ConsumeToken(); | 7115 ConsumeToken(); |
| 7053 } | 7116 } |
| 7054 const intptr_t type_pos = token_index_; | 7117 const intptr_t type_pos = token_index_; |
| 7055 AbstractTypeArguments& type_arguments = | 7118 AbstractTypeArguments& type_arguments = |
| 7056 AbstractTypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve)); | 7119 AbstractTypeArguments::ZoneHandle(ParseTypeArguments(kMustResolve)); |
| 7057 AstNode* primary = NULL; | 7120 AstNode* primary = NULL; |
| 7058 if ((CurrentToken() == Token::kLBRACK) || | 7121 if ((CurrentToken() == Token::kLBRACK) || |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7280 | 7343 |
| 7281 | 7344 |
| 7282 // A string literal consists of the concatenation of the next n tokens | 7345 // A string literal consists of the concatenation of the next n tokens |
| 7283 // that satisfy the EBNF grammar: | 7346 // that satisfy the EBNF grammar: |
| 7284 // literal = kSTRING {{ interpol }+ kSTRING } | 7347 // literal = kSTRING {{ interpol }+ kSTRING } |
| 7285 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 7348 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 7286 // In other words, the scanner breaks down interpolated strings so that | 7349 // In other words, the scanner breaks down interpolated strings so that |
| 7287 // a string literal always begins and ends with a kSTRING token, and | 7350 // a string literal always begins and ends with a kSTRING token, and |
| 7288 // there are never two kSTRING tokens next to each other. | 7351 // there are never two kSTRING tokens next to each other. |
| 7289 AstNode* Parser::ParseStringLiteral() { | 7352 AstNode* Parser::ParseStringLiteral() { |
| 7353 TRACE_PARSER("ParseStringLiteral"); | |
| 7290 AstNode* primary = NULL; | 7354 AstNode* primary = NULL; |
| 7291 const intptr_t literal_start = token_index_; | 7355 const intptr_t literal_start = token_index_; |
| 7292 if ((CurrentToken() == Token::kSTRING) && | 7356 if ((CurrentToken() == Token::kSTRING) && |
| 7293 (LookaheadToken(1) != Token::kINTERPOL_VAR) && | 7357 (LookaheadToken(1) != Token::kINTERPOL_VAR) && |
| 7294 (LookaheadToken(1) != Token::kINTERPOL_START)) { | 7358 (LookaheadToken(1) != Token::kINTERPOL_START)) { |
| 7295 // Common case: no interpolation. | 7359 // Common case: no interpolation. |
| 7296 primary = new LiteralNode(literal_start, *CurrentLiteral()); | 7360 primary = new LiteralNode(literal_start, *CurrentLiteral()); |
| 7297 ConsumeToken(); | 7361 ConsumeToken(); |
| 7298 return primary; | 7362 return primary; |
| 7299 } | 7363 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7335 | 7399 |
| 7336 | 7400 |
| 7337 // An import string literal consists of the concatenation of the next n tokens | 7401 // An import string literal consists of the concatenation of the next n tokens |
| 7338 // that satisfy the EBNF grammar: | 7402 // that satisfy the EBNF grammar: |
| 7339 // literal = kSTRING {{ interpol }+ kSTRING } | 7403 // literal = kSTRING {{ interpol }+ kSTRING } |
| 7340 // interpol = kINTERPOL_VAR | 7404 // interpol = kINTERPOL_VAR |
| 7341 // In other words, the scanner breaks down interpolated strings so that | 7405 // In other words, the scanner breaks down interpolated strings so that |
| 7342 // a string literal always begins and ends with a kSTRING token, and | 7406 // a string literal always begins and ends with a kSTRING token, and |
| 7343 // there are never two kSTRING tokens next to each other. | 7407 // there are never two kSTRING tokens next to each other. |
| 7344 String* Parser::ParseImportStringLiteral() { | 7408 String* Parser::ParseImportStringLiteral() { |
| 7409 TRACE_PARSER("ParseImportStringLiteral"); | |
| 7345 if ((CurrentToken() == Token::kSTRING) && | 7410 if ((CurrentToken() == Token::kSTRING) && |
| 7346 (LookaheadToken(1) != Token::kINTERPOL_VAR) && | 7411 (LookaheadToken(1) != Token::kINTERPOL_VAR) && |
| 7347 (LookaheadToken(1) != Token::kINTERPOL_START)) { | 7412 (LookaheadToken(1) != Token::kINTERPOL_START)) { |
| 7348 // Common case: no interpolation. | 7413 // Common case: no interpolation. |
| 7349 String* result = CurrentLiteral(); | 7414 String* result = CurrentLiteral(); |
| 7350 ConsumeToken(); | 7415 ConsumeToken(); |
| 7351 return result; | 7416 return result; |
| 7352 } | 7417 } |
| 7353 // String interpolation needed. | 7418 // String interpolation needed. |
| 7354 String& result = String::ZoneHandle(String::New("")); | 7419 String& result = String::ZoneHandle(String::New("")); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7788 void Parser::SkipQualIdent() { | 7853 void Parser::SkipQualIdent() { |
| 7789 ASSERT(IsIdentifier()); | 7854 ASSERT(IsIdentifier()); |
| 7790 ConsumeToken(); | 7855 ConsumeToken(); |
| 7791 if (CurrentToken() == Token::kPERIOD) { | 7856 if (CurrentToken() == Token::kPERIOD) { |
| 7792 ConsumeToken(); // Consume the kPERIOD token. | 7857 ConsumeToken(); // Consume the kPERIOD token. |
| 7793 ExpectIdentifier("identifier expected after '.'"); | 7858 ExpectIdentifier("identifier expected after '.'"); |
| 7794 } | 7859 } |
| 7795 } | 7860 } |
| 7796 | 7861 |
| 7797 } // namespace dart | 7862 } // namespace dart |
| OLD | NEW |