| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| 11 #include "vm/compiler.h" | 11 #include "vm/compiler.h" |
| 12 #include "vm/compiler_stats.h" | 12 #include "vm/compiler_stats.h" |
| 13 #include "vm/dart_api_impl.h" | 13 #include "vm/dart_api_impl.h" |
| 14 #include "vm/dart_entry.h" | 14 #include "vm/dart_entry.h" |
| 15 #include "vm/flags.h" | 15 #include "vm/flags.h" |
| 16 #include "vm/growable_array.h" | 16 #include "vm/growable_array.h" |
| 17 #include "vm/handles.h" | 17 #include "vm/handles.h" |
| 18 #include "vm/heap.h" | 18 #include "vm/heap.h" |
| 19 #include "vm/isolate.h" | 19 #include "vm/isolate.h" |
| 20 #include "vm/longjump.h" | 20 #include "vm/longjump.h" |
| 21 #include "vm/native_arguments.h" | 21 #include "vm/native_arguments.h" |
| 22 #include "vm/native_entry.h" | 22 #include "vm/native_entry.h" |
| 23 #include "vm/object.h" | 23 #include "vm/object.h" |
| 24 #include "vm/object_store.h" | 24 #include "vm/object_store.h" |
| 25 #include "vm/os.h" | 25 #include "vm/os.h" |
| 26 #include "vm/report.h" |
| 26 #include "vm/resolver.h" | 27 #include "vm/resolver.h" |
| 27 #include "vm/scanner.h" | 28 #include "vm/scanner.h" |
| 28 #include "vm/scopes.h" | 29 #include "vm/scopes.h" |
| 29 #include "vm/stack_frame.h" | 30 #include "vm/stack_frame.h" |
| 30 #include "vm/symbols.h" | 31 #include "vm/symbols.h" |
| 31 #include "vm/tags.h" | 32 #include "vm/tags.h" |
| 32 #include "vm/timer.h" | 33 #include "vm/timer.h" |
| 33 #include "vm/zone.h" | 34 #include "vm/zone.h" |
| 34 | 35 |
| 35 namespace dart { | 36 namespace dart { |
| 36 | 37 |
| 37 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); | 38 DEFINE_FLAG(bool, enable_asserts, false, "Enable assert statements."); |
| 38 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 39 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
| 39 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 40 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
| 40 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | |
| 41 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); | |
| 42 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); | 41 DEFINE_FLAG(bool, warn_mixin_typedef, true, "Warning on legacy mixin typedef."); |
| 43 DECLARE_FLAG(bool, error_on_bad_type); | 42 DECLARE_FLAG(bool, error_on_bad_type); |
| 44 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 43 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 44 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 46 | 45 |
| 47 static void CheckedModeHandler(bool value) { | 46 static void CheckedModeHandler(bool value) { |
| 48 FLAG_enable_asserts = value; | 47 FLAG_enable_asserts = value; |
| 49 FLAG_enable_type_checks = value; | 48 FLAG_enable_type_checks = value; |
| 50 } | 49 } |
| 51 | 50 |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 VMTagScope tagScope(isolate, VMTag::kCompileTopLevelTagId); | 383 VMTagScope tagScope(isolate, VMTag::kCompileTopLevelTagId); |
| 385 Parser parser(script, library, 0); | 384 Parser parser(script, library, 0); |
| 386 parser.ParseTopLevel(); | 385 parser.ParseTopLevel(); |
| 387 } | 386 } |
| 388 | 387 |
| 389 | 388 |
| 390 void Parser::ComputeCurrentToken() { | 389 void Parser::ComputeCurrentToken() { |
| 391 ASSERT(token_kind_ == Token::kILLEGAL); | 390 ASSERT(token_kind_ == Token::kILLEGAL); |
| 392 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 391 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| 393 if (token_kind_ == Token::kERROR) { | 392 if (token_kind_ == Token::kERROR) { |
| 394 ErrorMsg(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 393 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
| 395 } | 394 } |
| 396 } | 395 } |
| 397 | 396 |
| 398 | 397 |
| 399 Token::Kind Parser::LookaheadToken(int num_tokens) { | 398 Token::Kind Parser::LookaheadToken(int num_tokens) { |
| 400 CompilerStats::num_tokens_lookahead++; | 399 CompilerStats::num_tokens_lookahead++; |
| 401 CompilerStats::num_token_checks++; | 400 CompilerStats::num_token_checks++; |
| 402 return tokens_iterator_.LookaheadTokenKind(num_tokens); | 401 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
| 403 } | 402 } |
| 404 | 403 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 417 } | 416 } |
| 418 | 417 |
| 419 | 418 |
| 420 RawInteger* Parser::CurrentIntegerLiteral() const { | 419 RawInteger* Parser::CurrentIntegerLiteral() const { |
| 421 literal_token_ ^= tokens_iterator_.CurrentToken(); | 420 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 422 ASSERT(literal_token_.kind() == Token::kINTEGER); | 421 ASSERT(literal_token_.kind() == Token::kINTEGER); |
| 423 RawInteger* ri = Integer::RawCast(literal_token_.value()); | 422 RawInteger* ri = Integer::RawCast(literal_token_.value()); |
| 424 if (FLAG_throw_on_javascript_int_overflow) { | 423 if (FLAG_throw_on_javascript_int_overflow) { |
| 425 const Integer& i = Integer::Handle(I, ri); | 424 const Integer& i = Integer::Handle(I, ri); |
| 426 if (i.CheckJavascriptIntegerOverflow()) { | 425 if (i.CheckJavascriptIntegerOverflow()) { |
| 427 ErrorMsg(TokenPos(), | 426 ReportError(TokenPos(), |
| 428 "Integer literal does not fit in a Javascript integer: %s.", | 427 "Integer literal does not fit in a Javascript integer: %s.", |
| 429 i.ToCString()); | 428 i.ToCString()); |
| 430 } | 429 } |
| 431 } | 430 } |
| 432 return ri; | 431 return ri; |
| 433 } | 432 } |
| 434 | 433 |
| 435 | 434 |
| 436 // A QualIdent is an optionally qualified identifier. | 435 // A QualIdent is an optionally qualified identifier. |
| 437 struct QualIdent { | 436 struct QualIdent { |
| 438 QualIdent() { | 437 QualIdent() { |
| 439 Clear(); | 438 Clear(); |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 ConsumeToken(); | 919 ConsumeToken(); |
| 921 intptr_t expr_pos = TokenPos(); | 920 intptr_t expr_pos = TokenPos(); |
| 922 if (!IsIdentifier()) { | 921 if (!IsIdentifier()) { |
| 923 ExpectIdentifier("identifier expected"); | 922 ExpectIdentifier("identifier expected"); |
| 924 } | 923 } |
| 925 // Reject expressions with deferred library prefix eagerly. | 924 // Reject expressions with deferred library prefix eagerly. |
| 926 Object& obj = Object::Handle(I, | 925 Object& obj = Object::Handle(I, |
| 927 library_.LookupLocalObject(*CurrentLiteral())); | 926 library_.LookupLocalObject(*CurrentLiteral())); |
| 928 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 927 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
| 929 if (LibraryPrefix::Cast(obj).is_deferred_load()) { | 928 if (LibraryPrefix::Cast(obj).is_deferred_load()) { |
| 930 ErrorMsg("Metadata must be compile-time constant"); | 929 ReportError("Metadata must be compile-time constant"); |
| 931 } | 930 } |
| 932 } | 931 } |
| 933 AstNode* expr = NULL; | 932 AstNode* expr = NULL; |
| 934 if ((LookaheadToken(1) == Token::kLPAREN) || | 933 if ((LookaheadToken(1) == Token::kLPAREN) || |
| 935 ((LookaheadToken(1) == Token::kPERIOD) && | 934 ((LookaheadToken(1) == Token::kPERIOD) && |
| 936 (LookaheadToken(3) == Token::kLPAREN)) || | 935 (LookaheadToken(3) == Token::kLPAREN)) || |
| 937 ((LookaheadToken(1) == Token::kPERIOD) && | 936 ((LookaheadToken(1) == Token::kPERIOD) && |
| 938 (LookaheadToken(3) == Token::kPERIOD) && | 937 (LookaheadToken(3) == Token::kPERIOD) && |
| 939 (LookaheadToken(5) == Token::kLPAREN))) { | 938 (LookaheadToken(5) == Token::kLPAREN))) { |
| 940 expr = ParseNewOperator(Token::kCONST); | 939 expr = ParseNewOperator(Token::kCONST); |
| 941 } else { | 940 } else { |
| 942 // Can be x, C.x, or L.C.x. | 941 // Can be x, C.x, or L.C.x. |
| 943 expr = ParsePrimary(); // Consumes x, C or L.C. | 942 expr = ParsePrimary(); // Consumes x, C or L.C. |
| 944 Class& cls = Class::Handle(I); | 943 Class& cls = Class::Handle(I); |
| 945 if (expr->IsPrimaryNode()) { | 944 if (expr->IsPrimaryNode()) { |
| 946 PrimaryNode* primary_node = expr->AsPrimaryNode(); | 945 PrimaryNode* primary_node = expr->AsPrimaryNode(); |
| 947 if (primary_node->primary().IsClass()) { | 946 if (primary_node->primary().IsClass()) { |
| 948 // If the primary node referred to a class we are loading a | 947 // If the primary node referred to a class we are loading a |
| 949 // qualified static field. | 948 // qualified static field. |
| 950 cls ^= primary_node->primary().raw(); | 949 cls ^= primary_node->primary().raw(); |
| 951 } else { | 950 } else { |
| 952 ErrorMsg(expr_pos, "Metadata expressions must refer to a const field " | 951 ReportError(expr_pos, |
| 953 "or constructor"); | 952 "Metadata expressions must refer to a const field " |
| 953 "or constructor"); |
| 954 } | 954 } |
| 955 } | 955 } |
| 956 if (CurrentToken() == Token::kPERIOD) { | 956 if (CurrentToken() == Token::kPERIOD) { |
| 957 // C.x or L.C.X. | 957 // C.x or L.C.X. |
| 958 if (cls.IsNull()) { | 958 if (cls.IsNull()) { |
| 959 ErrorMsg(expr_pos, "Metadata expressions must refer to a const field " | 959 ReportError(expr_pos, |
| 960 "or constructor"); | 960 "Metadata expressions must refer to a const field " |
| 961 "or constructor"); |
| 961 } | 962 } |
| 962 ConsumeToken(); | 963 ConsumeToken(); |
| 963 const intptr_t ident_pos = TokenPos(); | 964 const intptr_t ident_pos = TokenPos(); |
| 964 String* ident = ExpectIdentifier("identifier expected"); | 965 String* ident = ExpectIdentifier("identifier expected"); |
| 965 const Field& field = Field::Handle(I, cls.LookupStaticField(*ident)); | 966 const Field& field = Field::Handle(I, cls.LookupStaticField(*ident)); |
| 966 if (field.IsNull()) { | 967 if (field.IsNull()) { |
| 967 ErrorMsg(ident_pos, | 968 ReportError(ident_pos, |
| 968 "Class '%s' has no field '%s'", | 969 "Class '%s' has no field '%s'", |
| 969 cls.ToCString(), | 970 cls.ToCString(), |
| 970 ident->ToCString()); | 971 ident->ToCString()); |
| 971 } | 972 } |
| 972 if (!field.is_const()) { | 973 if (!field.is_const()) { |
| 973 ErrorMsg(ident_pos, | 974 ReportError(ident_pos, |
| 974 "Field '%s' of class '%s' is not const", | 975 "Field '%s' of class '%s' is not const", |
| 975 ident->ToCString(), | 976 ident->ToCString(), |
| 976 cls.ToCString()); | 977 cls.ToCString()); |
| 977 } | 978 } |
| 978 expr = GenerateStaticFieldLookup(field, ident_pos); | 979 expr = GenerateStaticFieldLookup(field, ident_pos); |
| 979 } | 980 } |
| 980 } | 981 } |
| 981 if (expr->EvalConstExpr() == NULL) { | 982 if (expr->EvalConstExpr() == NULL) { |
| 982 ErrorMsg(expr_pos, "expression must be a compile-time constant"); | 983 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 983 } | 984 } |
| 984 const Instance& val = EvaluateConstExpr(expr_pos, expr); | 985 const Instance& val = EvaluateConstExpr(expr_pos, expr); |
| 985 meta_values.Add(val); | 986 meta_values.Add(val); |
| 986 } | 987 } |
| 987 return Array::MakeArray(meta_values); | 988 return Array::MakeArray(meta_values); |
| 988 } | 989 } |
| 989 | 990 |
| 990 | 991 |
| 991 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 992 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
| 992 TRACE_PARSER("ParseStaticFinalGetter"); | 993 TRACE_PARSER("ParseStaticFinalGetter"); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1011 const intptr_t expr_pos = TokenPos(); | 1012 const intptr_t expr_pos = TokenPos(); |
| 1012 if (field.is_const()) { | 1013 if (field.is_const()) { |
| 1013 // We don't want to use ParseConstExpr() here because we don't want | 1014 // We don't want to use ParseConstExpr() here because we don't want |
| 1014 // the constant folding code to create, compile and execute a code | 1015 // the constant folding code to create, compile and execute a code |
| 1015 // fragment to evaluate the expression. Instead, we just make sure | 1016 // fragment to evaluate the expression. Instead, we just make sure |
| 1016 // the static const field initializer is a constant expression and | 1017 // the static const field initializer is a constant expression and |
| 1017 // leave the evaluation to the getter function. | 1018 // leave the evaluation to the getter function. |
| 1018 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1019 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1019 // This getter will only be called once at compile time. | 1020 // This getter will only be called once at compile time. |
| 1020 if (expr->EvalConstExpr() == NULL) { | 1021 if (expr->EvalConstExpr() == NULL) { |
| 1021 ErrorMsg(expr_pos, "initializer is not a valid compile-time constant"); | 1022 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
| 1022 } | 1023 } |
| 1023 ReturnNode* return_node = new ReturnNode(ident_pos, expr); | 1024 ReturnNode* return_node = new ReturnNode(ident_pos, expr); |
| 1024 current_block_->statements->Add(return_node); | 1025 current_block_->statements->Add(return_node); |
| 1025 } else { | 1026 } else { |
| 1026 // This getter may be called each time the static field is accessed. | 1027 // This getter may be called each time the static field is accessed. |
| 1027 // The following generated code lazily initializes the field: | 1028 // The following generated code lazily initializes the field: |
| 1028 // if (field.value === transition_sentinel) { | 1029 // if (field.value === transition_sentinel) { |
| 1029 // field.value = null; | 1030 // field.value = null; |
| 1030 // throw("circular dependency in field initialization"); | 1031 // throw("circular dependency in field initialization"); |
| 1031 // } | 1032 // } |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 break; | 1507 break; |
| 1507 case Token::kEOS: | 1508 case Token::kEOS: |
| 1508 unexpected_token_found = true; | 1509 unexpected_token_found = true; |
| 1509 break; | 1510 break; |
| 1510 default: | 1511 default: |
| 1511 // nothing. | 1512 // nothing. |
| 1512 break; | 1513 break; |
| 1513 } | 1514 } |
| 1514 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); | 1515 } while (!token_stack.is_empty() && is_match && !unexpected_token_found); |
| 1515 if (!is_match) { | 1516 if (!is_match) { |
| 1516 ErrorMsg(token_pos, "unbalanced '%s'", Token::Str(token)); | 1517 ReportError(token_pos, "unbalanced '%s'", Token::Str(token)); |
| 1517 } else if (unexpected_token_found) { | 1518 } else if (unexpected_token_found) { |
| 1518 ErrorMsg(block_start_pos, "unterminated block"); | 1519 ReportError(block_start_pos, "unterminated block"); |
| 1519 } | 1520 } |
| 1520 } | 1521 } |
| 1521 | 1522 |
| 1522 | 1523 |
| 1523 void Parser::ParseFormalParameter(bool allow_explicit_default_value, | 1524 void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
| 1524 bool evaluate_metadata, | 1525 bool evaluate_metadata, |
| 1525 ParamList* params) { | 1526 ParamList* params) { |
| 1526 TRACE_PARSER("ParseFormalParameter"); | 1527 TRACE_PARSER("ParseFormalParameter"); |
| 1527 ParamDesc parameter; | 1528 ParamDesc parameter; |
| 1528 bool var_seen = false; | 1529 bool var_seen = false; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1555 ConsumeToken(); | 1556 ConsumeToken(); |
| 1556 // This must later be changed to a closure type if we recognize | 1557 // This must later be changed to a closure type if we recognize |
| 1557 // a closure/function type parameter. We check this at the end | 1558 // a closure/function type parameter. We check this at the end |
| 1558 // of ParseFormalParameter. | 1559 // of ParseFormalParameter. |
| 1559 parameter.type = &Type::ZoneHandle(I, Type::VoidType()); | 1560 parameter.type = &Type::ZoneHandle(I, Type::VoidType()); |
| 1560 } | 1561 } |
| 1561 if (parameter.type == NULL) { | 1562 if (parameter.type == NULL) { |
| 1562 // At this point, we must see an identifier for the type or the | 1563 // At this point, we must see an identifier for the type or the |
| 1563 // function parameter. | 1564 // function parameter. |
| 1564 if (!IsIdentifier()) { | 1565 if (!IsIdentifier()) { |
| 1565 ErrorMsg("parameter name or type expected"); | 1566 ReportError("parameter name or type expected"); |
| 1566 } | 1567 } |
| 1567 // We have not seen a parameter type yet, so we check if the next | 1568 // We have not seen a parameter type yet, so we check if the next |
| 1568 // identifier could represent a type before parsing it. | 1569 // identifier could represent a type before parsing it. |
| 1569 Token::Kind follower = LookaheadToken(1); | 1570 Token::Kind follower = LookaheadToken(1); |
| 1570 // We have an identifier followed by a 'follower' token. | 1571 // We have an identifier followed by a 'follower' token. |
| 1571 // We either parse a type or assume that no type is specified. | 1572 // We either parse a type or assume that no type is specified. |
| 1572 if ((follower == Token::kLT) || // Parameterized type. | 1573 if ((follower == Token::kLT) || // Parameterized type. |
| 1573 (follower == Token::kPERIOD) || // Qualified class name of type. | 1574 (follower == Token::kPERIOD) || // Qualified class name of type. |
| 1574 Token::IsIdentifier(follower) || // Parameter name following a type. | 1575 Token::IsIdentifier(follower) || // Parameter name following a type. |
| 1575 (follower == Token::kTHIS)) { // Field parameter following a type. | 1576 (follower == Token::kTHIS)) { // Field parameter following a type. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1595 | 1596 |
| 1596 // At this point, we must see an identifier for the parameter name. | 1597 // At this point, we must see an identifier for the parameter name. |
| 1597 parameter.name_pos = TokenPos(); | 1598 parameter.name_pos = TokenPos(); |
| 1598 parameter.name = ExpectIdentifier("parameter name expected"); | 1599 parameter.name = ExpectIdentifier("parameter name expected"); |
| 1599 if (parameter.is_field_initializer) { | 1600 if (parameter.is_field_initializer) { |
| 1600 params->has_field_initializer = true; | 1601 params->has_field_initializer = true; |
| 1601 } | 1602 } |
| 1602 | 1603 |
| 1603 if (params->has_optional_named_parameters && | 1604 if (params->has_optional_named_parameters && |
| 1604 (parameter.name->CharAt(0) == '_')) { | 1605 (parameter.name->CharAt(0) == '_')) { |
| 1605 ErrorMsg(parameter.name_pos, "named parameter must not be private"); | 1606 ReportError(parameter.name_pos, "named parameter must not be private"); |
| 1606 } | 1607 } |
| 1607 | 1608 |
| 1608 // Check for duplicate formal parameters. | 1609 // Check for duplicate formal parameters. |
| 1609 const intptr_t num_existing_parameters = | 1610 const intptr_t num_existing_parameters = |
| 1610 params->num_fixed_parameters + params->num_optional_parameters; | 1611 params->num_fixed_parameters + params->num_optional_parameters; |
| 1611 for (intptr_t i = 0; i < num_existing_parameters; i++) { | 1612 for (intptr_t i = 0; i < num_existing_parameters; i++) { |
| 1612 ParamDesc& existing_parameter = (*params->parameters)[i]; | 1613 ParamDesc& existing_parameter = (*params->parameters)[i]; |
| 1613 if (existing_parameter.name->Equals(*parameter.name)) { | 1614 if (existing_parameter.name->Equals(*parameter.name)) { |
| 1614 ErrorMsg(parameter.name_pos, "duplicate formal parameter '%s'", | 1615 ReportError(parameter.name_pos, "duplicate formal parameter '%s'", |
| 1615 parameter.name->ToCString()); | 1616 parameter.name->ToCString()); |
| 1616 } | 1617 } |
| 1617 } | 1618 } |
| 1618 | 1619 |
| 1619 if (CurrentToken() == Token::kLPAREN) { | 1620 if (CurrentToken() == Token::kLPAREN) { |
| 1620 // This parameter is probably a closure. If we saw the keyword 'var' | 1621 // This parameter is probably a closure. If we saw the keyword 'var' |
| 1621 // or 'final', a closure is not legal here and we ignore the | 1622 // or 'final', a closure is not legal here and we ignore the |
| 1622 // opening parens. | 1623 // opening parens. |
| 1623 if (!var_seen && !parameter.is_final) { | 1624 if (!var_seen && !parameter.is_final) { |
| 1624 // The parsed parameter type is actually the function result type. | 1625 // The parsed parameter type is actually the function result type. |
| 1625 const AbstractType& result_type = | 1626 const AbstractType& result_type = |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 ASSERT(!signature_type.IsMalbounded()); | 1685 ASSERT(!signature_type.IsMalbounded()); |
| 1685 // The type of the parameter is now the signature type. | 1686 // The type of the parameter is now the signature type. |
| 1686 parameter.type = &signature_type; | 1687 parameter.type = &signature_type; |
| 1687 } | 1688 } |
| 1688 } | 1689 } |
| 1689 | 1690 |
| 1690 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) { | 1691 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) { |
| 1691 if ((!params->has_optional_positional_parameters && | 1692 if ((!params->has_optional_positional_parameters && |
| 1692 !params->has_optional_named_parameters) || | 1693 !params->has_optional_named_parameters) || |
| 1693 !allow_explicit_default_value) { | 1694 !allow_explicit_default_value) { |
| 1694 ErrorMsg("parameter must not specify a default value"); | 1695 ReportError("parameter must not specify a default value"); |
| 1695 } | 1696 } |
| 1696 if (params->has_optional_positional_parameters) { | 1697 if (params->has_optional_positional_parameters) { |
| 1697 ExpectToken(Token::kASSIGN); | 1698 ExpectToken(Token::kASSIGN); |
| 1698 } else { | 1699 } else { |
| 1699 ExpectToken(Token::kCOLON); | 1700 ExpectToken(Token::kCOLON); |
| 1700 } | 1701 } |
| 1701 params->num_optional_parameters++; | 1702 params->num_optional_parameters++; |
| 1702 params->has_explicit_default_values = true; // Also if explicitly NULL. | 1703 params->has_explicit_default_values = true; // Also if explicitly NULL. |
| 1703 if (is_top_level_) { | 1704 if (is_top_level_) { |
| 1704 // Skip default value parsing. | 1705 // Skip default value parsing. |
| 1705 SkipExpr(); | 1706 SkipExpr(); |
| 1706 } else { | 1707 } else { |
| 1707 const Object& const_value = ParseConstExpr()->literal(); | 1708 const Object& const_value = ParseConstExpr()->literal(); |
| 1708 parameter.default_value = &const_value; | 1709 parameter.default_value = &const_value; |
| 1709 } | 1710 } |
| 1710 } else { | 1711 } else { |
| 1711 if (params->has_optional_positional_parameters || | 1712 if (params->has_optional_positional_parameters || |
| 1712 params->has_optional_named_parameters) { | 1713 params->has_optional_named_parameters) { |
| 1713 // Implicit default value is null. | 1714 // Implicit default value is null. |
| 1714 params->num_optional_parameters++; | 1715 params->num_optional_parameters++; |
| 1715 parameter.default_value = &Object::ZoneHandle(); | 1716 parameter.default_value = &Object::ZoneHandle(); |
| 1716 } else { | 1717 } else { |
| 1717 params->num_fixed_parameters++; | 1718 params->num_fixed_parameters++; |
| 1718 ASSERT(params->num_optional_parameters == 0); | 1719 ASSERT(params->num_optional_parameters == 0); |
| 1719 } | 1720 } |
| 1720 } | 1721 } |
| 1721 if (parameter.type->IsVoidType()) { | 1722 if (parameter.type->IsVoidType()) { |
| 1722 ErrorMsg("parameter '%s' may not be 'void'", parameter.name->ToCString()); | 1723 ReportError("parameter '%s' may not be 'void'", |
| 1724 parameter.name->ToCString()); |
| 1723 } | 1725 } |
| 1724 if (params->implicitly_final) { | 1726 if (params->implicitly_final) { |
| 1725 parameter.is_final = true; | 1727 parameter.is_final = true; |
| 1726 } | 1728 } |
| 1727 params->parameters->Add(parameter); | 1729 params->parameters->Add(parameter); |
| 1728 } | 1730 } |
| 1729 | 1731 |
| 1730 | 1732 |
| 1731 // Parses a sequence of normal or optional formal parameters. | 1733 // Parses a sequence of normal or optional formal parameters. |
| 1732 void Parser::ParseFormalParameters(bool allow_explicit_default_values, | 1734 void Parser::ParseFormalParameters(bool allow_explicit_default_values, |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1776 if (params->has_optional_positional_parameters) { | 1778 if (params->has_optional_positional_parameters) { |
| 1777 CheckToken(Token::kRBRACK, "',' or ']' expected"); | 1779 CheckToken(Token::kRBRACK, "',' or ']' expected"); |
| 1778 } else { | 1780 } else { |
| 1779 CheckToken(Token::kRBRACE, "',' or '}' expected"); | 1781 CheckToken(Token::kRBRACE, "',' or '}' expected"); |
| 1780 } | 1782 } |
| 1781 ConsumeToken(); // ']' or '}'. | 1783 ConsumeToken(); // ']' or '}'. |
| 1782 } | 1784 } |
| 1783 if ((CurrentToken() != Token::kRPAREN) && | 1785 if ((CurrentToken() != Token::kRPAREN) && |
| 1784 !params->has_optional_positional_parameters && | 1786 !params->has_optional_positional_parameters && |
| 1785 !params->has_optional_named_parameters) { | 1787 !params->has_optional_named_parameters) { |
| 1786 ErrorMsg("',' or ')' expected"); | 1788 ReportError("',' or ')' expected"); |
| 1787 } | 1789 } |
| 1788 } else { | 1790 } else { |
| 1789 ConsumeToken(); | 1791 ConsumeToken(); |
| 1790 } | 1792 } |
| 1791 ExpectToken(Token::kRPAREN); | 1793 ExpectToken(Token::kRPAREN); |
| 1792 } | 1794 } |
| 1793 | 1795 |
| 1794 | 1796 |
| 1795 String& Parser::ParseNativeDeclaration() { | 1797 String& Parser::ParseNativeDeclaration() { |
| 1796 TRACE_PARSER("ParseNativeDeclaration"); | 1798 TRACE_PARSER("ParseNativeDeclaration"); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1807 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1809 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1808 // the same name. If it is still not found, return noSuchMethod and | 1810 // the same name. If it is still not found, return noSuchMethod and |
| 1809 // set is_no_such_method to true.. | 1811 // set is_no_such_method to true.. |
| 1810 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1812 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1811 const String& name, | 1813 const String& name, |
| 1812 ArgumentListNode* arguments, | 1814 ArgumentListNode* arguments, |
| 1813 bool resolve_getter, | 1815 bool resolve_getter, |
| 1814 bool* is_no_such_method) { | 1816 bool* is_no_such_method) { |
| 1815 const Class& super_class = Class::Handle(I, current_class().SuperClass()); | 1817 const Class& super_class = Class::Handle(I, current_class().SuperClass()); |
| 1816 if (super_class.IsNull()) { | 1818 if (super_class.IsNull()) { |
| 1817 ErrorMsg(token_pos, "class '%s' does not have a superclass", | 1819 ReportError(token_pos, "class '%s' does not have a superclass", |
| 1818 String::Handle(I, current_class().Name()).ToCString()); | 1820 String::Handle(I, current_class().Name()).ToCString()); |
| 1819 } | 1821 } |
| 1820 Function& super_func = Function::Handle(I, | 1822 Function& super_func = Function::Handle(I, |
| 1821 Resolver::ResolveDynamicAnyArgs(super_class, name)); | 1823 Resolver::ResolveDynamicAnyArgs(super_class, name)); |
| 1822 if (!super_func.IsNull() && | 1824 if (!super_func.IsNull() && |
| 1823 !super_func.AreValidArguments(arguments->length(), | 1825 !super_func.AreValidArguments(arguments->length(), |
| 1824 arguments->names(), | 1826 arguments->names(), |
| 1825 NULL)) { | 1827 NULL)) { |
| 1826 super_func = Function::null(); | 1828 super_func = Function::null(); |
| 1827 } else if (super_func.IsNull() && resolve_getter) { | 1829 } else if (super_func.IsNull() && resolve_getter) { |
| 1828 const String& getter_name = String::ZoneHandle(I, Field::GetterName(name)); | 1830 const String& getter_name = String::ZoneHandle(I, Field::GetterName(name)); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1979 operator_function_name, | 1981 operator_function_name, |
| 1980 op_arguments, | 1982 op_arguments, |
| 1981 kResolveGetter, | 1983 kResolveGetter, |
| 1982 &is_no_such_method)); | 1984 &is_no_such_method)); |
| 1983 if (is_no_such_method) { | 1985 if (is_no_such_method) { |
| 1984 op_arguments = BuildNoSuchMethodArguments( | 1986 op_arguments = BuildNoSuchMethodArguments( |
| 1985 super_pos, operator_function_name, *op_arguments, NULL, true); | 1987 super_pos, operator_function_name, *op_arguments, NULL, true); |
| 1986 } | 1988 } |
| 1987 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 1989 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
| 1988 } else { | 1990 } else { |
| 1989 ErrorMsg(super_pos, "illegal super operator call"); | 1991 ReportError(super_pos, "illegal super operator call"); |
| 1990 } | 1992 } |
| 1991 return super_op; | 1993 return super_op; |
| 1992 } | 1994 } |
| 1993 | 1995 |
| 1994 | 1996 |
| 1995 AstNode* Parser::ParseSuperOperator() { | 1997 AstNode* Parser::ParseSuperOperator() { |
| 1996 TRACE_PARSER("ParseSuperOperator"); | 1998 TRACE_PARSER("ParseSuperOperator"); |
| 1997 AstNode* super_op = NULL; | 1999 AstNode* super_op = NULL; |
| 1998 const intptr_t operator_pos = TokenPos(); | 2000 const intptr_t operator_pos = TokenPos(); |
| 1999 | 2001 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2070 } | 2072 } |
| 2071 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2073 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 2072 } | 2074 } |
| 2073 | 2075 |
| 2074 | 2076 |
| 2075 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2077 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
| 2076 intptr_t field_pos) { | 2078 intptr_t field_pos) { |
| 2077 TRACE_PARSER("ParseSuperFieldAccess"); | 2079 TRACE_PARSER("ParseSuperFieldAccess"); |
| 2078 const Class& super_class = Class::ZoneHandle(I, current_class().SuperClass()); | 2080 const Class& super_class = Class::ZoneHandle(I, current_class().SuperClass()); |
| 2079 if (super_class.IsNull()) { | 2081 if (super_class.IsNull()) { |
| 2080 ErrorMsg("class '%s' does not have a superclass", | 2082 ReportError("class '%s' does not have a superclass", |
| 2081 String::Handle(I, current_class().Name()).ToCString()); | 2083 String::Handle(I, current_class().Name()).ToCString()); |
| 2082 } | 2084 } |
| 2083 AstNode* implicit_argument = LoadReceiver(field_pos); | 2085 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 2084 | 2086 |
| 2085 const String& getter_name = | 2087 const String& getter_name = |
| 2086 String::ZoneHandle(I, Field::GetterName(field_name)); | 2088 String::ZoneHandle(I, Field::GetterName(field_name)); |
| 2087 const Function& super_getter = Function::ZoneHandle(I, | 2089 const Function& super_getter = Function::ZoneHandle(I, |
| 2088 Resolver::ResolveDynamicAnyArgs(super_class, getter_name)); | 2090 Resolver::ResolveDynamicAnyArgs(super_class, getter_name)); |
| 2089 if (super_getter.IsNull()) { | 2091 if (super_getter.IsNull()) { |
| 2090 const String& setter_name = | 2092 const String& setter_name = |
| 2091 String::ZoneHandle(I, Field::SetterName(field_name)); | 2093 String::ZoneHandle(I, Field::SetterName(field_name)); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 // Add the constructor name 'n' to the super constructor. | 2156 // Add the constructor name 'n' to the super constructor. |
| 2155 ctor_name = String::SubString(ctor_name, class_name.Length() + 1); | 2157 ctor_name = String::SubString(ctor_name, class_name.Length() + 1); |
| 2156 super_ctor_name = String::Concat(super_ctor_name, ctor_name); | 2158 super_ctor_name = String::Concat(super_ctor_name, ctor_name); |
| 2157 } | 2159 } |
| 2158 } | 2160 } |
| 2159 | 2161 |
| 2160 // Resolve super constructor function and check arguments. | 2162 // Resolve super constructor function and check arguments. |
| 2161 const Function& super_ctor = Function::ZoneHandle(I, | 2163 const Function& super_ctor = Function::ZoneHandle(I, |
| 2162 super_class.LookupConstructor(super_ctor_name)); | 2164 super_class.LookupConstructor(super_ctor_name)); |
| 2163 if (super_ctor.IsNull()) { | 2165 if (super_ctor.IsNull()) { |
| 2164 ErrorMsg(supercall_pos, | 2166 ReportError(supercall_pos, |
| 2165 "unresolved implicit call to super constructor '%s()'", | 2167 "unresolved implicit call to super constructor '%s()'", |
| 2166 String::Handle(I, super_class.Name()).ToCString()); | 2168 String::Handle(I, super_class.Name()).ToCString()); |
| 2167 } | 2169 } |
| 2168 if (current_function().is_const() && !super_ctor.is_const()) { | 2170 if (current_function().is_const() && !super_ctor.is_const()) { |
| 2169 ErrorMsg(supercall_pos, "implicit call to non-const super constructor"); | 2171 ReportError(supercall_pos, "implicit call to non-const super constructor"); |
| 2170 } | 2172 } |
| 2171 | 2173 |
| 2172 String& error_message = String::Handle(I); | 2174 String& error_message = String::Handle(I); |
| 2173 if (!super_ctor.AreValidArguments(arguments->length(), | 2175 if (!super_ctor.AreValidArguments(arguments->length(), |
| 2174 arguments->names(), | 2176 arguments->names(), |
| 2175 &error_message)) { | 2177 &error_message)) { |
| 2176 ErrorMsg(supercall_pos, | 2178 ReportError(supercall_pos, |
| 2177 "invalid arguments passed to super constructor '%s()': %s", | 2179 "invalid arguments passed to super constructor '%s()': %s", |
| 2178 String::Handle(I, super_class.Name()).ToCString(), | 2180 String::Handle(I, super_class.Name()).ToCString(), |
| 2179 error_message.ToCString()); | 2181 error_message.ToCString()); |
| 2180 } | 2182 } |
| 2181 current_block_->statements->Add( | 2183 current_block_->statements->Add( |
| 2182 new StaticCallNode(supercall_pos, super_ctor, arguments)); | 2184 new StaticCallNode(supercall_pos, super_ctor, arguments)); |
| 2183 } | 2185 } |
| 2184 | 2186 |
| 2185 | 2187 |
| 2186 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 2188 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
| 2187 LocalVariable* receiver) { | 2189 LocalVariable* receiver) { |
| 2188 TRACE_PARSER("ParseSuperInitializer"); | 2190 TRACE_PARSER("ParseSuperInitializer"); |
| 2189 ASSERT(CurrentToken() == Token::kSUPER); | 2191 ASSERT(CurrentToken() == Token::kSUPER); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2214 arguments->Add(phase_parameter); | 2216 arguments->Add(phase_parameter); |
| 2215 // 'this' parameter must not be accessible to the other super call arguments. | 2217 // 'this' parameter must not be accessible to the other super call arguments. |
| 2216 receiver->set_invisible(true); | 2218 receiver->set_invisible(true); |
| 2217 ParseActualParameters(arguments, kAllowConst); | 2219 ParseActualParameters(arguments, kAllowConst); |
| 2218 receiver->set_invisible(false); | 2220 receiver->set_invisible(false); |
| 2219 | 2221 |
| 2220 // Resolve the constructor. | 2222 // Resolve the constructor. |
| 2221 const Function& super_ctor = Function::ZoneHandle(I, | 2223 const Function& super_ctor = Function::ZoneHandle(I, |
| 2222 super_class.LookupConstructor(ctor_name)); | 2224 super_class.LookupConstructor(ctor_name)); |
| 2223 if (super_ctor.IsNull()) { | 2225 if (super_ctor.IsNull()) { |
| 2224 ErrorMsg(supercall_pos, | 2226 ReportError(supercall_pos, |
| 2225 "super class constructor '%s' not found", | 2227 "super class constructor '%s' not found", |
| 2226 ctor_name.ToCString()); | 2228 ctor_name.ToCString()); |
| 2227 } | 2229 } |
| 2228 if (current_function().is_const() && !super_ctor.is_const()) { | 2230 if (current_function().is_const() && !super_ctor.is_const()) { |
| 2229 ErrorMsg(supercall_pos, "super constructor must be const"); | 2231 ReportError(supercall_pos, "super constructor must be const"); |
| 2230 } | 2232 } |
| 2231 String& error_message = String::Handle(I); | 2233 String& error_message = String::Handle(I); |
| 2232 if (!super_ctor.AreValidArguments(arguments->length(), | 2234 if (!super_ctor.AreValidArguments(arguments->length(), |
| 2233 arguments->names(), | 2235 arguments->names(), |
| 2234 &error_message)) { | 2236 &error_message)) { |
| 2235 ErrorMsg(supercall_pos, | 2237 ReportError(supercall_pos, |
| 2236 "invalid arguments passed to super class constructor '%s': %s", | 2238 "invalid arguments passed to super class constructor '%s': %s", |
| 2237 ctor_name.ToCString(), | 2239 ctor_name.ToCString(), |
| 2238 error_message.ToCString()); | 2240 error_message.ToCString()); |
| 2239 } | 2241 } |
| 2240 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2242 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 2241 } | 2243 } |
| 2242 | 2244 |
| 2243 | 2245 |
| 2244 AstNode* Parser::ParseInitializer(const Class& cls, | 2246 AstNode* Parser::ParseInitializer(const Class& cls, |
| 2245 LocalVariable* receiver, | 2247 LocalVariable* receiver, |
| 2246 GrowableArray<Field*>* initialized_fields) { | 2248 GrowableArray<Field*>* initialized_fields) { |
| 2247 TRACE_PARSER("ParseInitializer"); | 2249 TRACE_PARSER("ParseInitializer"); |
| 2248 const intptr_t field_pos = TokenPos(); | 2250 const intptr_t field_pos = TokenPos(); |
| 2249 if (CurrentToken() == Token::kTHIS) { | 2251 if (CurrentToken() == Token::kTHIS) { |
| 2250 ConsumeToken(); | 2252 ConsumeToken(); |
| 2251 ExpectToken(Token::kPERIOD); | 2253 ExpectToken(Token::kPERIOD); |
| 2252 } | 2254 } |
| 2253 const String& field_name = *ExpectIdentifier("field name expected"); | 2255 const String& field_name = *ExpectIdentifier("field name expected"); |
| 2254 ExpectToken(Token::kASSIGN); | 2256 ExpectToken(Token::kASSIGN); |
| 2255 | 2257 |
| 2256 const bool saved_mode = SetAllowFunctionLiterals(false); | 2258 const bool saved_mode = SetAllowFunctionLiterals(false); |
| 2257 // "this" must not be accessible in initializer expressions. | 2259 // "this" must not be accessible in initializer expressions. |
| 2258 receiver->set_invisible(true); | 2260 receiver->set_invisible(true); |
| 2259 AstNode* init_expr = ParseConditionalExpr(); | 2261 AstNode* init_expr = ParseConditionalExpr(); |
| 2260 if (CurrentToken() == Token::kCASCADE) { | 2262 if (CurrentToken() == Token::kCASCADE) { |
| 2261 init_expr = ParseCascades(init_expr); | 2263 init_expr = ParseCascades(init_expr); |
| 2262 } | 2264 } |
| 2263 receiver->set_invisible(false); | 2265 receiver->set_invisible(false); |
| 2264 SetAllowFunctionLiterals(saved_mode); | 2266 SetAllowFunctionLiterals(saved_mode); |
| 2265 if (current_function().is_const() && !init_expr->IsPotentiallyConst()) { | 2267 if (current_function().is_const() && !init_expr->IsPotentiallyConst()) { |
| 2266 ErrorMsg(field_pos, | 2268 ReportError(field_pos, |
| 2267 "initializer expression must be compile time constant."); | 2269 "initializer expression must be compile time constant."); |
| 2268 } | 2270 } |
| 2269 Field& field = Field::ZoneHandle(I, cls.LookupInstanceField(field_name)); | 2271 Field& field = Field::ZoneHandle(I, cls.LookupInstanceField(field_name)); |
| 2270 if (field.IsNull()) { | 2272 if (field.IsNull()) { |
| 2271 ErrorMsg(field_pos, "unresolved reference to instance field '%s'", | 2273 ReportError(field_pos, "unresolved reference to instance field '%s'", |
| 2272 field_name.ToCString()); | 2274 field_name.ToCString()); |
| 2273 } | 2275 } |
| 2274 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); | 2276 CheckDuplicateFieldInit(field_pos, initialized_fields, &field); |
| 2275 AstNode* instance = new LoadLocalNode(field_pos, receiver); | 2277 AstNode* instance = new LoadLocalNode(field_pos, receiver); |
| 2276 EnsureExpressionTemp(); | 2278 EnsureExpressionTemp(); |
| 2277 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); | 2279 return new StoreInstanceFieldNode(field_pos, instance, field, init_expr); |
| 2278 } | 2280 } |
| 2279 | 2281 |
| 2280 | 2282 |
| 2281 void Parser::CheckFieldsInitialized(const Class& cls) { | 2283 void Parser::CheckFieldsInitialized(const Class& cls) { |
| 2282 const Array& fields = Array::Handle(I, cls.fields()); | 2284 const Array& fields = Array::Handle(I, cls.fields()); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2397 } | 2399 } |
| 2398 | 2400 |
| 2399 | 2401 |
| 2400 void Parser::CheckDuplicateFieldInit(intptr_t init_pos, | 2402 void Parser::CheckDuplicateFieldInit(intptr_t init_pos, |
| 2401 GrowableArray<Field*>* initialized_fields, | 2403 GrowableArray<Field*>* initialized_fields, |
| 2402 Field* field) { | 2404 Field* field) { |
| 2403 ASSERT(!field->is_static()); | 2405 ASSERT(!field->is_static()); |
| 2404 for (int i = 0; i < initialized_fields->length(); i++) { | 2406 for (int i = 0; i < initialized_fields->length(); i++) { |
| 2405 Field* initialized_field = (*initialized_fields)[i]; | 2407 Field* initialized_field = (*initialized_fields)[i]; |
| 2406 if (initialized_field->raw() == field->raw()) { | 2408 if (initialized_field->raw() == field->raw()) { |
| 2407 ErrorMsg(init_pos, | 2409 ReportError(init_pos, |
| 2408 "duplicate initialization for field %s", | 2410 "duplicate initialization for field %s", |
| 2409 String::Handle(I, field->name()).ToCString()); | 2411 String::Handle(I, field->name()).ToCString()); |
| 2410 } | 2412 } |
| 2411 } | 2413 } |
| 2412 initialized_fields->Add(field); | 2414 initialized_fields->Add(field); |
| 2413 } | 2415 } |
| 2414 | 2416 |
| 2415 | 2417 |
| 2416 void Parser::ParseInitializers(const Class& cls, | 2418 void Parser::ParseInitializers(const Class& cls, |
| 2417 LocalVariable* receiver, | 2419 LocalVariable* receiver, |
| 2418 GrowableArray<Field*>* initialized_fields) { | 2420 GrowableArray<Field*>* initialized_fields) { |
| 2419 TRACE_PARSER("ParseInitializers"); | 2421 TRACE_PARSER("ParseInitializers"); |
| 2420 bool super_init_seen = false; | 2422 bool super_init_seen = false; |
| 2421 if (CurrentToken() == Token::kCOLON) { | 2423 if (CurrentToken() == Token::kCOLON) { |
| 2422 do { | 2424 do { |
| 2423 ConsumeToken(); // Colon or comma. | 2425 ConsumeToken(); // Colon or comma. |
| 2424 AstNode* init_statement; | 2426 AstNode* init_statement; |
| 2425 if (CurrentToken() == Token::kSUPER) { | 2427 if (CurrentToken() == Token::kSUPER) { |
| 2426 if (super_init_seen) { | 2428 if (super_init_seen) { |
| 2427 ErrorMsg("duplicate call to super constructor"); | 2429 ReportError("duplicate call to super constructor"); |
| 2428 } | 2430 } |
| 2429 init_statement = ParseSuperInitializer(cls, receiver); | 2431 init_statement = ParseSuperInitializer(cls, receiver); |
| 2430 super_init_seen = true; | 2432 super_init_seen = true; |
| 2431 } else { | 2433 } else { |
| 2432 init_statement = ParseInitializer(cls, receiver, initialized_fields); | 2434 init_statement = ParseInitializer(cls, receiver, initialized_fields); |
| 2433 } | 2435 } |
| 2434 current_block_->statements->Add(init_statement); | 2436 current_block_->statements->Add(init_statement); |
| 2435 } while (CurrentToken() == Token::kCOMMA); | 2437 } while (CurrentToken() == Token::kCOMMA); |
| 2436 } | 2438 } |
| 2437 if (!super_init_seen) { | 2439 if (!super_init_seen) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 ASSERT(phase_param != NULL); | 2471 ASSERT(phase_param != NULL); |
| 2470 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); | 2472 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); |
| 2471 arguments->Add(phase_argument); | 2473 arguments->Add(phase_argument); |
| 2472 receiver->set_invisible(true); | 2474 receiver->set_invisible(true); |
| 2473 ParseActualParameters(arguments, kAllowConst); | 2475 ParseActualParameters(arguments, kAllowConst); |
| 2474 receiver->set_invisible(false); | 2476 receiver->set_invisible(false); |
| 2475 // Resolve the constructor. | 2477 // Resolve the constructor. |
| 2476 const Function& redirect_ctor = Function::ZoneHandle(I, | 2478 const Function& redirect_ctor = Function::ZoneHandle(I, |
| 2477 cls.LookupConstructor(ctor_name)); | 2479 cls.LookupConstructor(ctor_name)); |
| 2478 if (redirect_ctor.IsNull()) { | 2480 if (redirect_ctor.IsNull()) { |
| 2479 ErrorMsg(call_pos, "constructor '%s' not found", ctor_name.ToCString()); | 2481 ReportError(call_pos, "constructor '%s' not found", ctor_name.ToCString()); |
| 2480 } | 2482 } |
| 2481 String& error_message = String::Handle(I); | 2483 String& error_message = String::Handle(I); |
| 2482 if (!redirect_ctor.AreValidArguments(arguments->length(), | 2484 if (!redirect_ctor.AreValidArguments(arguments->length(), |
| 2483 arguments->names(), | 2485 arguments->names(), |
| 2484 &error_message)) { | 2486 &error_message)) { |
| 2485 ErrorMsg(call_pos, | 2487 ReportError(call_pos, |
| 2486 "invalid arguments passed to constructor '%s': %s", | 2488 "invalid arguments passed to constructor '%s': %s", |
| 2487 ctor_name.ToCString(), | 2489 ctor_name.ToCString(), |
| 2488 error_message.ToCString()); | 2490 error_message.ToCString()); |
| 2489 } | 2491 } |
| 2490 current_block_->statements->Add( | 2492 current_block_->statements->Add( |
| 2491 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 2493 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 2492 } | 2494 } |
| 2493 | 2495 |
| 2494 | 2496 |
| 2495 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2497 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 2496 ASSERT(func.IsConstructor()); | 2498 ASSERT(func.IsConstructor()); |
| 2497 ASSERT(func.Owner() == current_class().raw()); | 2499 ASSERT(func.Owner() == current_class().raw()); |
| 2498 const intptr_t ctor_pos = TokenPos(); | 2500 const intptr_t ctor_pos = TokenPos(); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2529 current_class().IsMixinApplication()) { | 2531 current_class().IsMixinApplication()) { |
| 2530 // At this point we don't support forwarding constructors | 2532 // At this point we don't support forwarding constructors |
| 2531 // that have optional parameters because we don't know the default | 2533 // that have optional parameters because we don't know the default |
| 2532 // values of the optional parameters. We would have to compile the super | 2534 // values of the optional parameters. We would have to compile the super |
| 2533 // constructor to get the default values. Also, the spec is not clear | 2535 // constructor to get the default values. Also, the spec is not clear |
| 2534 // whether optional parameters are even allowed in this situation. | 2536 // whether optional parameters are even allowed in this situation. |
| 2535 // TODO(hausner): Remove this limitation if the language spec indeed | 2537 // TODO(hausner): Remove this limitation if the language spec indeed |
| 2536 // allows optional parameters. | 2538 // allows optional parameters. |
| 2537 if (func.HasOptionalParameters()) { | 2539 if (func.HasOptionalParameters()) { |
| 2538 const Class& super_class = Class::Handle(I, current_class().SuperClass()); | 2540 const Class& super_class = Class::Handle(I, current_class().SuperClass()); |
| 2539 ErrorMsg(ctor_pos, | 2541 ReportError(ctor_pos, |
| 2540 "cannot generate an implicit mixin application constructor " | 2542 "cannot generate an implicit mixin application constructor " |
| 2541 "forwarding to a super class constructor with optional " | 2543 "forwarding to a super class constructor with optional " |
| 2542 "parameters; add a constructor without optional parameters " | 2544 "parameters; add a constructor without optional parameters " |
| 2543 "to class '%s' that redirects to the constructor with optional " | 2545 "to class '%s' that redirects to the constructor with " |
| 2544 "parameters and invoke it via super from a constructor of the " | 2546 "optional parameters and invoke it via super from a " |
| 2545 "class extending the mixin application", | 2547 "constructor of the class extending the mixin application", |
| 2546 String::Handle(I, super_class.Name()).ToCString()); | 2548 String::Handle(I, super_class.Name()).ToCString()); |
| 2547 } | 2549 } |
| 2548 | 2550 |
| 2549 // Prepare user-defined arguments to be forwarded to super call. | 2551 // Prepare user-defined arguments to be forwarded to super call. |
| 2550 // The first user-defined argument is at position 2. | 2552 // The first user-defined argument is at position 2. |
| 2551 forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos); | 2553 forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos); |
| 2552 for (int i = 2; i < func.NumParameters(); i++) { | 2554 for (int i = 2; i < func.NumParameters(); i++) { |
| 2553 LocalVariable* param = new LocalVariable( | 2555 LocalVariable* param = new LocalVariable( |
| 2554 Scanner::kNoSourcePos, | 2556 Scanner::kNoSourcePos, |
| 2555 String::ZoneHandle(I, func.ParameterNameAt(i)), | 2557 String::ZoneHandle(I, func.ParameterNameAt(i)), |
| 2556 Type::ZoneHandle(I, Type::DynamicType())); | 2558 Type::ZoneHandle(I, Type::DynamicType())); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2573 | 2575 |
| 2574 | 2576 |
| 2575 void Parser::CheckRecursiveInvocation() { | 2577 void Parser::CheckRecursiveInvocation() { |
| 2576 const GrowableObjectArray& pending_functions = | 2578 const GrowableObjectArray& pending_functions = |
| 2577 GrowableObjectArray::Handle(I, | 2579 GrowableObjectArray::Handle(I, |
| 2578 I->object_store()->pending_functions()); | 2580 I->object_store()->pending_functions()); |
| 2579 for (int i = 0; i < pending_functions.Length(); i++) { | 2581 for (int i = 0; i < pending_functions.Length(); i++) { |
| 2580 if (pending_functions.At(i) == current_function().raw()) { | 2582 if (pending_functions.At(i) == current_function().raw()) { |
| 2581 const String& fname = | 2583 const String& fname = |
| 2582 String::Handle(I, current_function().UserVisibleName()); | 2584 String::Handle(I, current_function().UserVisibleName()); |
| 2583 ErrorMsg("circular dependency for function %s", fname.ToCString()); | 2585 ReportError("circular dependency for function %s", fname.ToCString()); |
| 2584 } | 2586 } |
| 2585 } | 2587 } |
| 2586 ASSERT(!unregister_pending_function_); | 2588 ASSERT(!unregister_pending_function_); |
| 2587 pending_functions.Add(current_function()); | 2589 pending_functions.Add(current_function()); |
| 2588 unregister_pending_function_ = true; | 2590 unregister_pending_function_ = true; |
| 2589 } | 2591 } |
| 2590 | 2592 |
| 2591 | 2593 |
| 2592 // Parser is at the opening parenthesis of the formal parameter declaration | 2594 // Parser is at the opening parenthesis of the formal parameter declaration |
| 2593 // of function. Parse the formal parameters, initializers and code. | 2595 // of function. Parse the formal parameters, initializers and code. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2670 if (params.has_field_initializer) { | 2672 if (params.has_field_initializer) { |
| 2671 // First two parameters are implicit receiver and phase. | 2673 // First two parameters are implicit receiver and phase. |
| 2672 ASSERT(params.parameters->length() >= 2); | 2674 ASSERT(params.parameters->length() >= 2); |
| 2673 for (int i = 2; i < params.parameters->length(); i++) { | 2675 for (int i = 2; i < params.parameters->length(); i++) { |
| 2674 ParamDesc& param = (*params.parameters)[i]; | 2676 ParamDesc& param = (*params.parameters)[i]; |
| 2675 if (param.is_field_initializer) { | 2677 if (param.is_field_initializer) { |
| 2676 const String& field_name = *param.name; | 2678 const String& field_name = *param.name; |
| 2677 Field& field = | 2679 Field& field = |
| 2678 Field::ZoneHandle(I, cls.LookupInstanceField(field_name)); | 2680 Field::ZoneHandle(I, cls.LookupInstanceField(field_name)); |
| 2679 if (field.IsNull()) { | 2681 if (field.IsNull()) { |
| 2680 ErrorMsg(param.name_pos, | 2682 ReportError(param.name_pos, |
| 2681 "unresolved reference to instance field '%s'", | 2683 "unresolved reference to instance field '%s'", |
| 2682 field_name.ToCString()); | 2684 field_name.ToCString()); |
| 2683 } | 2685 } |
| 2684 if (is_redirecting_constructor) { | 2686 if (is_redirecting_constructor) { |
| 2685 ErrorMsg(param.name_pos, | 2687 ReportError(param.name_pos, |
| 2686 "redirecting constructors may not have " | 2688 "redirecting constructors may not have " |
| 2687 "initializing formal parameters"); | 2689 "initializing formal parameters"); |
| 2688 } | 2690 } |
| 2689 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); | 2691 CheckDuplicateFieldInit(param.name_pos, &initialized_fields, &field); |
| 2690 | 2692 |
| 2691 if (!param.has_explicit_type) { | 2693 if (!param.has_explicit_type) { |
| 2692 const AbstractType& field_type = | 2694 const AbstractType& field_type = |
| 2693 AbstractType::ZoneHandle(I, field.type()); | 2695 AbstractType::ZoneHandle(I, field.type()); |
| 2694 param.type = &field_type; | 2696 param.type = &field_type; |
| 2695 // Parameter type was already set to dynamic when parsing the class | 2697 // Parameter type was already set to dynamic when parsing the class |
| 2696 // declaration: fix it. | 2698 // declaration: fix it. |
| 2697 func.SetParameterTypeAt(i, field_type); | 2699 func.SetParameterTypeAt(i, field_type); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2835 } | 2837 } |
| 2836 | 2838 |
| 2837 if (CurrentToken() == Token::kLBRACE) { | 2839 if (CurrentToken() == Token::kLBRACE) { |
| 2838 // We checked in the top-level parse phase that a redirecting | 2840 // We checked in the top-level parse phase that a redirecting |
| 2839 // constructor does not have a body. | 2841 // constructor does not have a body. |
| 2840 ASSERT(!is_redirecting_constructor); | 2842 ASSERT(!is_redirecting_constructor); |
| 2841 ConsumeToken(); | 2843 ConsumeToken(); |
| 2842 ParseStatementSequence(); | 2844 ParseStatementSequence(); |
| 2843 ExpectToken(Token::kRBRACE); | 2845 ExpectToken(Token::kRBRACE); |
| 2844 } else if (CurrentToken() == Token::kARROW) { | 2846 } else if (CurrentToken() == Token::kARROW) { |
| 2845 ErrorMsg("constructors may not return a value"); | 2847 ReportError("constructors may not return a value"); |
| 2846 } else if (IsLiteral("native")) { | 2848 } else if (IsLiteral("native")) { |
| 2847 ErrorMsg("native constructors not supported"); | 2849 ReportError("native constructors not supported"); |
| 2848 } else if (CurrentToken() == Token::kSEMICOLON) { | 2850 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 2849 // Some constructors have no function body. | 2851 // Some constructors have no function body. |
| 2850 ConsumeToken(); | 2852 ConsumeToken(); |
| 2851 if (func.is_external()) { | 2853 if (func.is_external()) { |
| 2852 // Body of an external method contains a single throw. | 2854 // Body of an external method contains a single throw. |
| 2853 const String& function_name = String::ZoneHandle(func.name()); | 2855 const String& function_name = String::ZoneHandle(func.name()); |
| 2854 current_block_->statements->Add( | 2856 current_block_->statements->Add( |
| 2855 ThrowNoSuchMethodError(TokenPos(), | 2857 ThrowNoSuchMethodError(TokenPos(), |
| 2856 cls, | 2858 cls, |
| 2857 function_name, | 2859 function_name, |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2956 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2958 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 2957 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 2959 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); |
| 2958 ASSERT(func.NumParameters() == params.parameters->length()); | 2960 ASSERT(func.NumParameters() == params.parameters->length()); |
| 2959 | 2961 |
| 2960 // Check whether the function has any field initializer formal parameters, | 2962 // Check whether the function has any field initializer formal parameters, |
| 2961 // which are not allowed in non-constructor functions. | 2963 // which are not allowed in non-constructor functions. |
| 2962 if (params.has_field_initializer) { | 2964 if (params.has_field_initializer) { |
| 2963 for (int i = 0; i < params.parameters->length(); i++) { | 2965 for (int i = 0; i < params.parameters->length(); i++) { |
| 2964 ParamDesc& param = (*params.parameters)[i]; | 2966 ParamDesc& param = (*params.parameters)[i]; |
| 2965 if (param.is_field_initializer) { | 2967 if (param.is_field_initializer) { |
| 2966 ErrorMsg(param.name_pos, | 2968 ReportError(param.name_pos, |
| 2967 "field initializer only allowed in constructors"); | 2969 "field initializer only allowed in constructors"); |
| 2968 } | 2970 } |
| 2969 } | 2971 } |
| 2970 } | 2972 } |
| 2971 // Populate function scope with the formal parameters. | 2973 // Populate function scope with the formal parameters. |
| 2972 AddFormalParamsToScope(¶ms, current_block_->scope); | 2974 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2973 | 2975 |
| 2974 if (FLAG_enable_type_checks && | 2976 if (FLAG_enable_type_checks && |
| 2975 (current_block_->scope->function_level() > 0)) { | 2977 (current_block_->scope->function_level() > 0)) { |
| 2976 // We are parsing, but not compiling, a local function. | 2978 // We are parsing, but not compiling, a local function. |
| 2977 // The instantiator may be required at run time for generic type checks. | 2979 // The instantiator may be required at run time for generic type checks. |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3170 | 3172 |
| 3171 | 3173 |
| 3172 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3174 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
| 3173 TRACE_PARSER("ParseMethodOrConstructor"); | 3175 TRACE_PARSER("ParseMethodOrConstructor"); |
| 3174 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); | 3176 ASSERT(CurrentToken() == Token::kLPAREN || method->IsGetter()); |
| 3175 ASSERT(method->type != NULL); | 3177 ASSERT(method->type != NULL); |
| 3176 ASSERT(method->name_pos > 0); | 3178 ASSERT(method->name_pos > 0); |
| 3177 ASSERT(current_member_ == method); | 3179 ASSERT(current_member_ == method); |
| 3178 | 3180 |
| 3179 if (method->has_var) { | 3181 if (method->has_var) { |
| 3180 ErrorMsg(method->name_pos, "keyword var not allowed for methods"); | 3182 ReportError(method->name_pos, "keyword var not allowed for methods"); |
| 3181 } | 3183 } |
| 3182 if (method->has_final) { | 3184 if (method->has_final) { |
| 3183 ErrorMsg(method->name_pos, "'final' not allowed for methods"); | 3185 ReportError(method->name_pos, "'final' not allowed for methods"); |
| 3184 } | 3186 } |
| 3185 if (method->has_abstract && method->has_static) { | 3187 if (method->has_abstract && method->has_static) { |
| 3186 ErrorMsg(method->name_pos, | 3188 ReportError(method->name_pos, |
| 3187 "static method '%s' cannot be abstract", | 3189 "static method '%s' cannot be abstract", |
| 3188 method->name->ToCString()); | 3190 method->name->ToCString()); |
| 3189 } | 3191 } |
| 3190 if (method->has_const && !method->IsFactoryOrConstructor()) { | 3192 if (method->has_const && !method->IsFactoryOrConstructor()) { |
| 3191 ErrorMsg(method->name_pos, "'const' not allowed for methods"); | 3193 ReportError(method->name_pos, "'const' not allowed for methods"); |
| 3192 } | 3194 } |
| 3193 if (method->has_abstract && method->IsFactoryOrConstructor()) { | 3195 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
| 3194 ErrorMsg(method->name_pos, "constructor cannot be abstract"); | 3196 ReportError(method->name_pos, "constructor cannot be abstract"); |
| 3195 } | 3197 } |
| 3196 if (method->has_const && method->IsConstructor()) { | 3198 if (method->has_const && method->IsConstructor()) { |
| 3197 current_class().set_is_const(); | 3199 current_class().set_is_const(); |
| 3198 } | 3200 } |
| 3199 | 3201 |
| 3200 // Parse the formal parameters. | 3202 // Parse the formal parameters. |
| 3201 const bool are_implicitly_final = method->has_const; | 3203 const bool are_implicitly_final = method->has_const; |
| 3202 const bool allow_explicit_default_values = true; | 3204 const bool allow_explicit_default_values = true; |
| 3203 const intptr_t formal_param_pos = TokenPos(); | 3205 const intptr_t formal_param_pos = TokenPos(); |
| 3204 method->params.Clear(); | 3206 method->params.Clear(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3252 method->name = &String::ZoneHandle(I, Field::GetterSymbol(*method->name)); | 3254 method->name = &String::ZoneHandle(I, Field::GetterSymbol(*method->name)); |
| 3253 } else { | 3255 } else { |
| 3254 ASSERT(method->IsSetter()); | 3256 ASSERT(method->IsSetter()); |
| 3255 expected_num_parameters = (method->has_static) ? 1 : 2; | 3257 expected_num_parameters = (method->has_static) ? 1 : 2; |
| 3256 method->dict_name = &String::ZoneHandle(I, | 3258 method->dict_name = &String::ZoneHandle(I, |
| 3257 String::Concat(*method->name, Symbols::Equals())); | 3259 String::Concat(*method->name, Symbols::Equals())); |
| 3258 method->name = &String::ZoneHandle(I, Field::SetterSymbol(*method->name)); | 3260 method->name = &String::ZoneHandle(I, Field::SetterSymbol(*method->name)); |
| 3259 } | 3261 } |
| 3260 if ((method->params.num_fixed_parameters != expected_num_parameters) || | 3262 if ((method->params.num_fixed_parameters != expected_num_parameters) || |
| 3261 (method->params.num_optional_parameters != 0)) { | 3263 (method->params.num_optional_parameters != 0)) { |
| 3262 ErrorMsg(method->name_pos, "illegal %s parameters", | 3264 ReportError(method->name_pos, "illegal %s parameters", |
| 3263 method->IsGetter() ? "getter" : "setter"); | 3265 method->IsGetter() ? "getter" : "setter"); |
| 3264 } | 3266 } |
| 3265 } | 3267 } |
| 3266 | 3268 |
| 3267 // Parse redirecting factory constructor. | 3269 // Parse redirecting factory constructor. |
| 3268 Type& redirection_type = Type::Handle(I); | 3270 Type& redirection_type = Type::Handle(I); |
| 3269 String& redirection_identifier = String::Handle(I); | 3271 String& redirection_identifier = String::Handle(I); |
| 3270 bool is_redirecting = false; | 3272 bool is_redirecting = false; |
| 3271 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { | 3273 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
| 3272 // Default parameter values are disallowed in redirecting factories. | 3274 // Default parameter values are disallowed in redirecting factories. |
| 3273 if (method->params.has_explicit_default_values) { | 3275 if (method->params.has_explicit_default_values) { |
| 3274 ErrorMsg("redirecting factory '%s' may not specify default values " | 3276 ReportError("redirecting factory '%s' may not specify default values " |
| 3275 "for optional parameters", | 3277 "for optional parameters", |
| 3276 method->name->ToCString()); | 3278 method->name->ToCString()); |
| 3277 } | 3279 } |
| 3278 if (method->has_external) { | 3280 if (method->has_external) { |
| 3279 ErrorMsg(TokenPos(), | 3281 ReportError(TokenPos(), |
| 3280 "external factory constructor '%s' may not have redirection", | 3282 "external factory constructor '%s' may not have redirection", |
| 3281 method->name->ToCString()); | 3283 method->name->ToCString()); |
| 3282 } | 3284 } |
| 3283 ConsumeToken(); | 3285 ConsumeToken(); |
| 3284 const intptr_t type_pos = TokenPos(); | 3286 const intptr_t type_pos = TokenPos(); |
| 3285 is_redirecting = true; | 3287 is_redirecting = true; |
| 3286 const AbstractType& type = AbstractType::Handle(I, | 3288 const AbstractType& type = AbstractType::Handle(I, |
| 3287 ParseType(ClassFinalizer::kResolveTypeParameters)); | 3289 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 3288 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3290 if (!type.IsMalformed() && type.IsTypeParameter()) { |
| 3289 // Replace the type with a malformed type and compile a throw when called. | 3291 // Replace the type with a malformed type and compile a throw when called. |
| 3290 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 3292 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
| 3291 Error::Handle(I), // No previous error. | 3293 Error::Handle(I), // No previous error. |
| 3292 script_, | 3294 script_, |
| 3293 type_pos, | 3295 type_pos, |
| 3294 "factory '%s' may not redirect to type parameter '%s'", | 3296 "factory '%s' may not redirect to type parameter '%s'", |
| 3295 method->name->ToCString(), | 3297 method->name->ToCString(), |
| 3296 String::Handle(I, type.UserVisibleName()).ToCString()); | 3298 String::Handle(I, type.UserVisibleName()).ToCString()); |
| 3297 } else { | 3299 } else { |
| 3298 // We handle malformed and malbounded redirection type at run time. | 3300 // We handle malformed and malbounded redirection type at run time. |
| 3299 redirection_type ^= type.raw(); | 3301 redirection_type ^= type.raw(); |
| 3300 } | 3302 } |
| 3301 if (CurrentToken() == Token::kPERIOD) { | 3303 if (CurrentToken() == Token::kPERIOD) { |
| 3302 // Named constructor or factory. | 3304 // Named constructor or factory. |
| 3303 ConsumeToken(); | 3305 ConsumeToken(); |
| 3304 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); | 3306 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
| 3305 } | 3307 } |
| 3306 } else if (CurrentToken() == Token::kCOLON) { | 3308 } else if (CurrentToken() == Token::kCOLON) { |
| 3307 // Parse initializers. | 3309 // Parse initializers. |
| 3308 if (!method->IsConstructor()) { | 3310 if (!method->IsConstructor()) { |
| 3309 ErrorMsg("initializers only allowed on constructors"); | 3311 ReportError("initializers only allowed on constructors"); |
| 3310 } | 3312 } |
| 3311 if (method->has_external) { | 3313 if (method->has_external) { |
| 3312 ErrorMsg(TokenPos(), | 3314 ReportError(TokenPos(), |
| 3313 "external constructor '%s' may not have initializers", | 3315 "external constructor '%s' may not have initializers", |
| 3314 method->name->ToCString()); | 3316 method->name->ToCString()); |
| 3315 } | 3317 } |
| 3316 if ((LookaheadToken(1) == Token::kTHIS) && | 3318 if ((LookaheadToken(1) == Token::kTHIS) && |
| 3317 ((LookaheadToken(2) == Token::kLPAREN) || | 3319 ((LookaheadToken(2) == Token::kLPAREN) || |
| 3318 LookaheadToken(4) == Token::kLPAREN)) { | 3320 LookaheadToken(4) == Token::kLPAREN)) { |
| 3319 // Redirected constructor: either this(...) or this.xxx(...). | 3321 // Redirected constructor: either this(...) or this.xxx(...). |
| 3320 is_redirecting = true; | 3322 is_redirecting = true; |
| 3321 if (method->params.has_field_initializer) { | 3323 if (method->params.has_field_initializer) { |
| 3322 // Constructors that redirect to another constructor must not | 3324 // Constructors that redirect to another constructor must not |
| 3323 // initialize any fields using field initializer parameters. | 3325 // initialize any fields using field initializer parameters. |
| 3324 ErrorMsg(formal_param_pos, "Redirecting constructor " | 3326 ReportError(formal_param_pos, "Redirecting constructor " |
| 3325 "may not use field initializer parameters"); | 3327 "may not use field initializer parameters"); |
| 3326 } | 3328 } |
| 3327 ConsumeToken(); // Colon. | 3329 ConsumeToken(); // Colon. |
| 3328 ExpectToken(Token::kTHIS); | 3330 ExpectToken(Token::kTHIS); |
| 3329 String& redir_name = String::ZoneHandle(I, | 3331 String& redir_name = String::ZoneHandle(I, |
| 3330 String::Concat(members->class_name(), Symbols::Dot())); | 3332 String::Concat(members->class_name(), Symbols::Dot())); |
| 3331 if (CurrentToken() == Token::kPERIOD) { | 3333 if (CurrentToken() == Token::kPERIOD) { |
| 3332 ConsumeToken(); | 3334 ConsumeToken(); |
| 3333 redir_name = String::Concat(redir_name, | 3335 redir_name = String::Concat(redir_name, |
| 3334 *ExpectIdentifier("constructor name expected")); | 3336 *ExpectIdentifier("constructor name expected")); |
| 3335 } | 3337 } |
| 3336 method->redirect_name = &redir_name; | 3338 method->redirect_name = &redir_name; |
| 3337 CheckToken(Token::kLPAREN); | 3339 CheckToken(Token::kLPAREN); |
| 3338 SkipToMatchingParenthesis(); | 3340 SkipToMatchingParenthesis(); |
| 3339 } else { | 3341 } else { |
| 3340 SkipInitializers(); | 3342 SkipInitializers(); |
| 3341 } | 3343 } |
| 3342 } | 3344 } |
| 3343 | 3345 |
| 3344 // Only constructors can redirect to another method. | 3346 // Only constructors can redirect to another method. |
| 3345 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3347 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
| 3346 | 3348 |
| 3347 if (method->IsConstructor() && | 3349 if (method->IsConstructor() && |
| 3348 method->has_external && | 3350 method->has_external && |
| 3349 method->params.has_field_initializer) { | 3351 method->params.has_field_initializer) { |
| 3350 ErrorMsg(method->name_pos, | 3352 ReportError(method->name_pos, |
| 3351 "external constructor '%s' may not have field initializers", | 3353 "external constructor '%s' may not have field initializers", |
| 3352 method->name->ToCString()); | 3354 method->name->ToCString()); |
| 3353 } | 3355 } |
| 3354 | 3356 |
| 3355 intptr_t method_end_pos = TokenPos(); | 3357 intptr_t method_end_pos = TokenPos(); |
| 3356 if ((CurrentToken() == Token::kLBRACE) || | 3358 if ((CurrentToken() == Token::kLBRACE) || |
| 3357 (CurrentToken() == Token::kARROW)) { | 3359 (CurrentToken() == Token::kARROW)) { |
| 3358 if (method->has_abstract) { | 3360 if (method->has_abstract) { |
| 3359 ErrorMsg(TokenPos(), | 3361 ReportError(TokenPos(), |
| 3360 "abstract method '%s' may not have a function body", | 3362 "abstract method '%s' may not have a function body", |
| 3361 method->name->ToCString()); | 3363 method->name->ToCString()); |
| 3362 } else if (method->has_external) { | 3364 } else if (method->has_external) { |
| 3363 ErrorMsg(TokenPos(), | 3365 ReportError(TokenPos(), |
| 3364 "external %s '%s' may not have a function body", | 3366 "external %s '%s' may not have a function body", |
| 3365 method->IsFactoryOrConstructor() ? "constructor" : "method", | 3367 method->IsFactoryOrConstructor() ? "constructor" : "method", |
| 3366 method->name->ToCString()); | 3368 method->name->ToCString()); |
| 3367 } else if (method->IsConstructor() && method->has_const) { | 3369 } else if (method->IsConstructor() && method->has_const) { |
| 3368 ErrorMsg(TokenPos(), | 3370 ReportError(TokenPos(), |
| 3369 "const constructor '%s' may not have a function body", | 3371 "const constructor '%s' may not have a function body", |
| 3370 method->name->ToCString()); | 3372 method->name->ToCString()); |
| 3371 } else if (method->IsFactory() && method->has_const) { | 3373 } else if (method->IsFactory() && method->has_const) { |
| 3372 ErrorMsg(TokenPos(), | 3374 ReportError(TokenPos(), |
| 3373 "const factory '%s' may not have a function body", | 3375 "const factory '%s' may not have a function body", |
| 3374 method->name->ToCString()); | 3376 method->name->ToCString()); |
| 3375 } | 3377 } |
| 3376 if (method->redirect_name != NULL) { | 3378 if (method->redirect_name != NULL) { |
| 3377 ErrorMsg(method->name_pos, | 3379 ReportError(method->name_pos, |
| 3378 "Constructor with redirection may not have a function body"); | 3380 "Constructor with redirection may not have a function body"); |
| 3379 } | 3381 } |
| 3380 if (CurrentToken() == Token::kLBRACE) { | 3382 if (CurrentToken() == Token::kLBRACE) { |
| 3381 SkipBlock(); | 3383 SkipBlock(); |
| 3382 method_end_pos = TokenPos(); | 3384 method_end_pos = TokenPos(); |
| 3383 ExpectToken(Token::kRBRACE); | 3385 ExpectToken(Token::kRBRACE); |
| 3384 } else { | 3386 } else { |
| 3385 ConsumeToken(); | 3387 ConsumeToken(); |
| 3386 SkipExpr(); | 3388 SkipExpr(); |
| 3387 method_end_pos = TokenPos(); | 3389 method_end_pos = TokenPos(); |
| 3388 ExpectSemicolon(); | 3390 ExpectSemicolon(); |
| 3389 } | 3391 } |
| 3390 } else if (IsLiteral("native")) { | 3392 } else if (IsLiteral("native")) { |
| 3391 if (method->has_abstract) { | 3393 if (method->has_abstract) { |
| 3392 ErrorMsg(method->name_pos, | 3394 ReportError(method->name_pos, |
| 3393 "abstract method '%s' may not have a function body", | 3395 "abstract method '%s' may not have a function body", |
| 3394 method->name->ToCString()); | 3396 method->name->ToCString()); |
| 3395 } else if (method->IsConstructor() && method->has_const) { | 3397 } else if (method->IsConstructor() && method->has_const) { |
| 3396 ErrorMsg(method->name_pos, | 3398 ReportError(method->name_pos, |
| 3397 "const constructor '%s' may not be native", | 3399 "const constructor '%s' may not be native", |
| 3398 method->name->ToCString()); | 3400 method->name->ToCString()); |
| 3399 } | 3401 } |
| 3400 if (method->redirect_name != NULL) { | 3402 if (method->redirect_name != NULL) { |
| 3401 ErrorMsg(method->name_pos, | 3403 ReportError(method->name_pos, |
| 3402 "Constructor with redirection may not have a function body"); | 3404 "Constructor with redirection may not have a function body"); |
| 3403 } | 3405 } |
| 3404 ParseNativeDeclaration(); | 3406 ParseNativeDeclaration(); |
| 3405 method_end_pos = TokenPos(); | 3407 method_end_pos = TokenPos(); |
| 3406 ExpectSemicolon(); | 3408 ExpectSemicolon(); |
| 3407 method->has_native = true; | 3409 method->has_native = true; |
| 3408 } else { | 3410 } else { |
| 3409 // We haven't found a method body. Issue error if one is required. | 3411 // We haven't found a method body. Issue error if one is required. |
| 3410 const bool must_have_body = | 3412 const bool must_have_body = |
| 3411 method->has_static && | 3413 method->has_static && |
| 3412 !method->has_external && | 3414 !method->has_external && |
| 3413 redirection_type.IsNull(); | 3415 redirection_type.IsNull(); |
| 3414 if (must_have_body) { | 3416 if (must_have_body) { |
| 3415 ErrorMsg(method->name_pos, | 3417 ReportError(method->name_pos, |
| 3416 "function body expected for method '%s'", | 3418 "function body expected for method '%s'", |
| 3417 method->name->ToCString()); | 3419 method->name->ToCString()); |
| 3418 } | 3420 } |
| 3419 | 3421 |
| 3420 if (CurrentToken() == Token::kSEMICOLON) { | 3422 if (CurrentToken() == Token::kSEMICOLON) { |
| 3421 ConsumeToken(); | 3423 ConsumeToken(); |
| 3422 if (!method->has_static && | 3424 if (!method->has_static && |
| 3423 !method->has_external && | 3425 !method->has_external && |
| 3424 !method->IsConstructor()) { | 3426 !method->IsConstructor()) { |
| 3425 // Methods, getters and setters without a body are | 3427 // Methods, getters and setters without a body are |
| 3426 // implicitly abstract. | 3428 // implicitly abstract. |
| 3427 method->has_abstract = true; | 3429 method->has_abstract = true; |
| 3428 } | 3430 } |
| 3429 } else { | 3431 } else { |
| 3430 // Signature is not followed by semicolon or body. Issue an | 3432 // Signature is not followed by semicolon or body. Issue an |
| 3431 // appropriate error. | 3433 // appropriate error. |
| 3432 const bool must_have_semicolon = | 3434 const bool must_have_semicolon = |
| 3433 (method->redirect_name != NULL) || | 3435 (method->redirect_name != NULL) || |
| 3434 (method->IsConstructor() && method->has_const) || | 3436 (method->IsConstructor() && method->has_const) || |
| 3435 method->has_external; | 3437 method->has_external; |
| 3436 if (must_have_semicolon) { | 3438 if (must_have_semicolon) { |
| 3437 ExpectSemicolon(); | 3439 ExpectSemicolon(); |
| 3438 } else { | 3440 } else { |
| 3439 ErrorMsg(method->name_pos, | 3441 ReportError(method->name_pos, |
| 3440 "function body or semicolon expected for method '%s'", | 3442 "function body or semicolon expected for method '%s'", |
| 3441 method->name->ToCString()); | 3443 method->name->ToCString()); |
| 3442 } | 3444 } |
| 3443 } | 3445 } |
| 3444 } | 3446 } |
| 3445 | 3447 |
| 3446 RawFunction::Kind function_kind; | 3448 RawFunction::Kind function_kind; |
| 3447 if (method->IsFactoryOrConstructor()) { | 3449 if (method->IsFactoryOrConstructor()) { |
| 3448 function_kind = RawFunction::kConstructor; | 3450 function_kind = RawFunction::kConstructor; |
| 3449 } else if (method->IsGetter()) { | 3451 } else if (method->IsGetter()) { |
| 3450 function_kind = RawFunction::kGetterFunction; | 3452 function_kind = RawFunction::kGetterFunction; |
| 3451 } else if (method->IsSetter()) { | 3453 } else if (method->IsSetter()) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3501 ASSERT(CurrentToken() == Token::kSEMICOLON || | 3503 ASSERT(CurrentToken() == Token::kSEMICOLON || |
| 3502 CurrentToken() == Token::kCOMMA || | 3504 CurrentToken() == Token::kCOMMA || |
| 3503 CurrentToken() == Token::kASSIGN); | 3505 CurrentToken() == Token::kASSIGN); |
| 3504 ASSERT(field->type != NULL); | 3506 ASSERT(field->type != NULL); |
| 3505 ASSERT(field->name_pos > 0); | 3507 ASSERT(field->name_pos > 0); |
| 3506 ASSERT(current_member_ == field); | 3508 ASSERT(current_member_ == field); |
| 3507 // All const fields are also final. | 3509 // All const fields are also final. |
| 3508 ASSERT(!field->has_const || field->has_final); | 3510 ASSERT(!field->has_const || field->has_final); |
| 3509 | 3511 |
| 3510 if (field->has_abstract) { | 3512 if (field->has_abstract) { |
| 3511 ErrorMsg("keyword 'abstract' not allowed in field declaration"); | 3513 ReportError("keyword 'abstract' not allowed in field declaration"); |
| 3512 } | 3514 } |
| 3513 if (field->has_external) { | 3515 if (field->has_external) { |
| 3514 ErrorMsg("keyword 'external' not allowed in field declaration"); | 3516 ReportError("keyword 'external' not allowed in field declaration"); |
| 3515 } | 3517 } |
| 3516 if (field->has_factory) { | 3518 if (field->has_factory) { |
| 3517 ErrorMsg("keyword 'factory' not allowed in field declaration"); | 3519 ReportError("keyword 'factory' not allowed in field declaration"); |
| 3518 } | 3520 } |
| 3519 if (!field->has_static && field->has_const) { | 3521 if (!field->has_static && field->has_const) { |
| 3520 ErrorMsg(field->name_pos, "instance field may not be 'const'"); | 3522 ReportError(field->name_pos, "instance field may not be 'const'"); |
| 3521 } | 3523 } |
| 3522 Function& getter = Function::Handle(I); | 3524 Function& getter = Function::Handle(I); |
| 3523 Function& setter = Function::Handle(I); | 3525 Function& setter = Function::Handle(I); |
| 3524 Field& class_field = Field::ZoneHandle(I); | 3526 Field& class_field = Field::ZoneHandle(I); |
| 3525 Instance& init_value = Instance::Handle(I); | 3527 Instance& init_value = Instance::Handle(I); |
| 3526 while (true) { | 3528 while (true) { |
| 3527 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3529 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3528 bool has_simple_literal = false; | 3530 bool has_simple_literal = false; |
| 3529 if (has_initializer) { | 3531 if (has_initializer) { |
| 3530 ConsumeToken(); | 3532 ConsumeToken(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3542 // mode), the field value is reset and a kImplicitStaticFinalGetter is | 3544 // mode), the field value is reset and a kImplicitStaticFinalGetter is |
| 3543 // created at finalization time. | 3545 // created at finalization time. |
| 3544 if (LookaheadToken(1) == Token::kSEMICOLON) { | 3546 if (LookaheadToken(1) == Token::kSEMICOLON) { |
| 3545 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); | 3547 has_simple_literal = IsSimpleLiteral(*field->type, &init_value); |
| 3546 } | 3548 } |
| 3547 SkipExpr(); | 3549 SkipExpr(); |
| 3548 } else { | 3550 } else { |
| 3549 // Static const and static final fields must have an initializer. | 3551 // Static const and static final fields must have an initializer. |
| 3550 // Static const fields are implicitly final. | 3552 // Static const fields are implicitly final. |
| 3551 if (field->has_static && field->has_final) { | 3553 if (field->has_static && field->has_final) { |
| 3552 ErrorMsg(field->name_pos, | 3554 ReportError(field->name_pos, |
| 3553 "static %s field '%s' must have an initializer expression", | 3555 "static %s field '%s' must have an initializer expression", |
| 3554 field->has_const ? "const" : "final", | 3556 field->has_const ? "const" : "final", |
| 3555 field->name->ToCString()); | 3557 field->name->ToCString()); |
| 3556 } | 3558 } |
| 3557 } | 3559 } |
| 3558 | 3560 |
| 3559 // Create the field object. | 3561 // Create the field object. |
| 3560 class_field = Field::New(*field->name, | 3562 class_field = Field::New(*field->name, |
| 3561 field->has_static, | 3563 field->has_static, |
| 3562 field->has_final, | 3564 field->has_final, |
| 3563 field->has_const, | 3565 field->has_const, |
| 3564 current_class(), | 3566 current_class(), |
| 3565 field->name_pos); | 3567 field->name_pos); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3667 } else if ((op == Token::kBIT_NOT) || (op == Token::kNEGATE)) { | 3669 } else if ((op == Token::kBIT_NOT) || (op == Token::kNEGATE)) { |
| 3668 expected_num_parameters = 1; | 3670 expected_num_parameters = 1; |
| 3669 } else { | 3671 } else { |
| 3670 expected_num_parameters = 2; | 3672 expected_num_parameters = 2; |
| 3671 } | 3673 } |
| 3672 if ((member.params.num_optional_parameters > 0) || | 3674 if ((member.params.num_optional_parameters > 0) || |
| 3673 member.params.has_optional_positional_parameters || | 3675 member.params.has_optional_positional_parameters || |
| 3674 member.params.has_optional_named_parameters || | 3676 member.params.has_optional_named_parameters || |
| 3675 (member.params.num_fixed_parameters != expected_num_parameters)) { | 3677 (member.params.num_fixed_parameters != expected_num_parameters)) { |
| 3676 // Subtract receiver when reporting number of expected arguments. | 3678 // Subtract receiver when reporting number of expected arguments. |
| 3677 ErrorMsg(member.name_pos, "operator %s expects %" Pd " argument(s)", | 3679 ReportError(member.name_pos, "operator %s expects %" Pd " argument(s)", |
| 3678 member.name->ToCString(), (expected_num_parameters - 1)); | 3680 member.name->ToCString(), (expected_num_parameters - 1)); |
| 3679 } | 3681 } |
| 3680 } | 3682 } |
| 3681 | 3683 |
| 3682 | 3684 |
| 3683 void Parser::CheckMemberNameConflict(ClassDesc* members, | 3685 void Parser::CheckMemberNameConflict(ClassDesc* members, |
| 3684 MemberDesc* member) { | 3686 MemberDesc* member) { |
| 3685 const String& name = *member->DictName(); | 3687 const String& name = *member->DictName(); |
| 3686 if (name.Equals(members->class_name())) { | 3688 if (name.Equals(members->class_name())) { |
| 3687 ErrorMsg(member->name_pos, | 3689 ReportError(member->name_pos, |
| 3688 "%s '%s' conflicts with class name", | 3690 "%s '%s' conflicts with class name", |
| 3689 member->ToCString(), | 3691 member->ToCString(), |
| 3690 name.ToCString()); | 3692 name.ToCString()); |
| 3691 } | 3693 } |
| 3692 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { | 3694 if (members->clazz().LookupTypeParameter(name) != TypeParameter::null()) { |
| 3693 ErrorMsg(member->name_pos, | 3695 ReportError(member->name_pos, |
| 3694 "%s '%s' conflicts with type parameter", | 3696 "%s '%s' conflicts with type parameter", |
| 3695 member->ToCString(), | 3697 member->ToCString(), |
| 3696 name.ToCString()); | 3698 name.ToCString()); |
| 3697 } | 3699 } |
| 3698 for (int i = 0; i < members->members().length(); i++) { | 3700 for (int i = 0; i < members->members().length(); i++) { |
| 3699 MemberDesc* existing_member = &members->members()[i]; | 3701 MemberDesc* existing_member = &members->members()[i]; |
| 3700 if (name.Equals(*existing_member->DictName())) { | 3702 if (name.Equals(*existing_member->DictName())) { |
| 3701 ErrorMsg(member->name_pos, | 3703 ReportError(member->name_pos, |
| 3702 "%s '%s' conflicts with previously declared %s", | 3704 "%s '%s' conflicts with previously declared %s", |
| 3703 member->ToCString(), | 3705 member->ToCString(), |
| 3704 name.ToCString(), | 3706 name.ToCString(), |
| 3705 existing_member->ToCString()); | 3707 existing_member->ToCString()); |
| 3706 } | 3708 } |
| 3707 } | 3709 } |
| 3708 } | 3710 } |
| 3709 | 3711 |
| 3710 | 3712 |
| 3711 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 3713 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
| 3712 intptr_t metadata_pos) { | 3714 intptr_t metadata_pos) { |
| 3713 TRACE_PARSER("ParseClassMemberDefinition"); | 3715 TRACE_PARSER("ParseClassMemberDefinition"); |
| 3714 MemberDesc member; | 3716 MemberDesc member; |
| 3715 current_member_ = &member; | 3717 current_member_ = &member; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3727 } | 3729 } |
| 3728 if (CurrentToken() == Token::kCONST) { | 3730 if (CurrentToken() == Token::kCONST) { |
| 3729 ConsumeToken(); | 3731 ConsumeToken(); |
| 3730 member.has_const = true; | 3732 member.has_const = true; |
| 3731 } else if (CurrentToken() == Token::kFINAL) { | 3733 } else if (CurrentToken() == Token::kFINAL) { |
| 3732 ConsumeToken(); | 3734 ConsumeToken(); |
| 3733 member.has_final = true; | 3735 member.has_final = true; |
| 3734 } | 3736 } |
| 3735 if (CurrentToken() == Token::kVAR) { | 3737 if (CurrentToken() == Token::kVAR) { |
| 3736 if (member.has_const) { | 3738 if (member.has_const) { |
| 3737 ErrorMsg("identifier expected after 'const'"); | 3739 ReportError("identifier expected after 'const'"); |
| 3738 } | 3740 } |
| 3739 if (member.has_final) { | 3741 if (member.has_final) { |
| 3740 ErrorMsg("identifier expected after 'final'"); | 3742 ReportError("identifier expected after 'final'"); |
| 3741 } | 3743 } |
| 3742 ConsumeToken(); | 3744 ConsumeToken(); |
| 3743 member.has_var = true; | 3745 member.has_var = true; |
| 3744 // The member type is the 'dynamic' type. | 3746 // The member type is the 'dynamic' type. |
| 3745 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 3747 member.type = &Type::ZoneHandle(I, Type::DynamicType()); |
| 3746 } else if (CurrentToken() == Token::kFACTORY) { | 3748 } else if (CurrentToken() == Token::kFACTORY) { |
| 3747 ConsumeToken(); | 3749 ConsumeToken(); |
| 3748 if (member.has_static) { | 3750 if (member.has_static) { |
| 3749 ErrorMsg("factory method cannot be explicitly marked static"); | 3751 ReportError("factory method cannot be explicitly marked static"); |
| 3750 } | 3752 } |
| 3751 member.has_factory = true; | 3753 member.has_factory = true; |
| 3752 member.has_static = true; | 3754 member.has_static = true; |
| 3753 // The result type depends on the name of the factory method. | 3755 // The result type depends on the name of the factory method. |
| 3754 } | 3756 } |
| 3755 // Optionally parse a type. | 3757 // Optionally parse a type. |
| 3756 if (CurrentToken() == Token::kVOID) { | 3758 if (CurrentToken() == Token::kVOID) { |
| 3757 if (member.has_var || member.has_factory) { | 3759 if (member.has_var || member.has_factory) { |
| 3758 ErrorMsg("void not expected"); | 3760 ReportError("void not expected"); |
| 3759 } | 3761 } |
| 3760 ConsumeToken(); | 3762 ConsumeToken(); |
| 3761 ASSERT(member.type == NULL); | 3763 ASSERT(member.type == NULL); |
| 3762 member.type = &Type::ZoneHandle(I, Type::VoidType()); | 3764 member.type = &Type::ZoneHandle(I, Type::VoidType()); |
| 3763 } else if (CurrentToken() == Token::kIDENT) { | 3765 } else if (CurrentToken() == Token::kIDENT) { |
| 3764 // This is either a type name or the name of a method/constructor/field. | 3766 // This is either a type name or the name of a method/constructor/field. |
| 3765 if ((member.type == NULL) && !member.has_factory) { | 3767 if ((member.type == NULL) && !member.has_factory) { |
| 3766 // We have not seen a member type yet, so we check if the next | 3768 // We have not seen a member type yet, so we check if the next |
| 3767 // identifier could represent a type before parsing it. | 3769 // identifier could represent a type before parsing it. |
| 3768 Token::Kind follower = LookaheadToken(1); | 3770 Token::Kind follower = LookaheadToken(1); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3788 // Optionally parse a (possibly named) constructor name or factory. | 3790 // Optionally parse a (possibly named) constructor name or factory. |
| 3789 if (IsIdentifier() && | 3791 if (IsIdentifier() && |
| 3790 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 3792 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 3791 member.name_pos = TokenPos(); | 3793 member.name_pos = TokenPos(); |
| 3792 member.name = CurrentLiteral(); // Unqualified identifier. | 3794 member.name = CurrentLiteral(); // Unqualified identifier. |
| 3793 ConsumeToken(); | 3795 ConsumeToken(); |
| 3794 if (member.has_factory) { | 3796 if (member.has_factory) { |
| 3795 // The factory name may be qualified, but the first identifier must match | 3797 // The factory name may be qualified, but the first identifier must match |
| 3796 // the name of the immediately enclosing class. | 3798 // the name of the immediately enclosing class. |
| 3797 if (!member.name->Equals(members->class_name())) { | 3799 if (!member.name->Equals(members->class_name())) { |
| 3798 ErrorMsg(member.name_pos, "factory name must be '%s'", | 3800 ReportError(member.name_pos, "factory name must be '%s'", |
| 3799 members->class_name().ToCString()); | 3801 members->class_name().ToCString()); |
| 3800 } | 3802 } |
| 3801 } else if (member.has_static) { | 3803 } else if (member.has_static) { |
| 3802 ErrorMsg(member.name_pos, "constructor cannot be static"); | 3804 ReportError(member.name_pos, "constructor cannot be static"); |
| 3803 } | 3805 } |
| 3804 if (member.type != NULL) { | 3806 if (member.type != NULL) { |
| 3805 ErrorMsg(member.name_pos, "constructor must not specify return type"); | 3807 ReportError(member.name_pos, "constructor must not specify return type"); |
| 3806 } | 3808 } |
| 3807 // Do not bypass class resolution by using current_class() directly, since | 3809 // Do not bypass class resolution by using current_class() directly, since |
| 3808 // it may be a patch class. | 3810 // it may be a patch class. |
| 3809 const Object& result_type_class = Object::Handle(I, | 3811 const Object& result_type_class = Object::Handle(I, |
| 3810 UnresolvedClass::New(LibraryPrefix::Handle(I), | 3812 UnresolvedClass::New(LibraryPrefix::Handle(I), |
| 3811 *member.name, | 3813 *member.name, |
| 3812 member.name_pos)); | 3814 member.name_pos)); |
| 3813 // The type arguments of the result type are the type parameters of the | 3815 // The type arguments of the result type are the type parameters of the |
| 3814 // current class. Note that in the case of a patch class, they are copied | 3816 // current class. Note that in the case of a patch class, they are copied |
| 3815 // from the class being patched. | 3817 // from the class being patched. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3856 if (member.type == NULL) { | 3858 if (member.type == NULL) { |
| 3857 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 3859 member.type = &Type::ZoneHandle(I, Type::DynamicType()); |
| 3858 } | 3860 } |
| 3859 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && | 3861 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && |
| 3860 (LookaheadToken(1) != Token::kLPAREN) && | 3862 (LookaheadToken(1) != Token::kLPAREN) && |
| 3861 (LookaheadToken(1) != Token::kASSIGN) && | 3863 (LookaheadToken(1) != Token::kASSIGN) && |
| 3862 (LookaheadToken(1) != Token::kCOMMA) && | 3864 (LookaheadToken(1) != Token::kCOMMA) && |
| 3863 (LookaheadToken(1) != Token::kSEMICOLON)) { | 3865 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 3864 ConsumeToken(); | 3866 ConsumeToken(); |
| 3865 if (!Token::CanBeOverloaded(CurrentToken())) { | 3867 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 3866 ErrorMsg("invalid operator overloading"); | 3868 ReportError("invalid operator overloading"); |
| 3867 } | 3869 } |
| 3868 if (member.has_static) { | 3870 if (member.has_static) { |
| 3869 ErrorMsg("operator overloading functions cannot be static"); | 3871 ReportError("operator overloading functions cannot be static"); |
| 3870 } | 3872 } |
| 3871 member.operator_token = CurrentToken(); | 3873 member.operator_token = CurrentToken(); |
| 3872 member.has_operator = true; | 3874 member.has_operator = true; |
| 3873 member.kind = RawFunction::kRegularFunction; | 3875 member.kind = RawFunction::kRegularFunction; |
| 3874 member.name_pos = this->TokenPos(); | 3876 member.name_pos = this->TokenPos(); |
| 3875 member.name = | 3877 member.name = |
| 3876 &String::ZoneHandle(I, Symbols::New(Token::Str(member.operator_token))); | 3878 &String::ZoneHandle(I, Symbols::New(Token::Str(member.operator_token))); |
| 3877 ConsumeToken(); | 3879 ConsumeToken(); |
| 3878 } else if (IsIdentifier()) { | 3880 } else if (IsIdentifier()) { |
| 3879 member.name = CurrentLiteral(); | 3881 member.name = CurrentLiteral(); |
| 3880 member.name_pos = TokenPos(); | 3882 member.name_pos = TokenPos(); |
| 3881 ConsumeToken(); | 3883 ConsumeToken(); |
| 3882 } else { | 3884 } else { |
| 3883 ErrorMsg("identifier expected"); | 3885 ReportError("identifier expected"); |
| 3884 } | 3886 } |
| 3885 | 3887 |
| 3886 ASSERT(member.name != NULL); | 3888 ASSERT(member.name != NULL); |
| 3887 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { | 3889 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { |
| 3888 // Constructor or method. | 3890 // Constructor or method. |
| 3889 if (member.type == NULL) { | 3891 if (member.type == NULL) { |
| 3890 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 3892 member.type = &Type::ZoneHandle(I, Type::DynamicType()); |
| 3891 } | 3893 } |
| 3892 ASSERT(member.IsFactory() == member.has_factory); | 3894 ASSERT(member.IsFactory() == member.has_factory); |
| 3893 ParseMethodOrConstructor(members, &member); | 3895 ParseMethodOrConstructor(members, &member); |
| 3894 } else if (CurrentToken() == Token::kSEMICOLON || | 3896 } else if (CurrentToken() == Token::kSEMICOLON || |
| 3895 CurrentToken() == Token::kCOMMA || | 3897 CurrentToken() == Token::kCOMMA || |
| 3896 CurrentToken() == Token::kASSIGN) { | 3898 CurrentToken() == Token::kASSIGN) { |
| 3897 // Field definition. | 3899 // Field definition. |
| 3898 if (member.has_const) { | 3900 if (member.has_const) { |
| 3899 // const fields are implicitly final. | 3901 // const fields are implicitly final. |
| 3900 member.has_final = true; | 3902 member.has_final = true; |
| 3901 } | 3903 } |
| 3902 if (member.type == NULL) { | 3904 if (member.type == NULL) { |
| 3903 if (member.has_final) { | 3905 if (member.has_final) { |
| 3904 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 3906 member.type = &Type::ZoneHandle(I, Type::DynamicType()); |
| 3905 } else { | 3907 } else { |
| 3906 ErrorMsg("missing 'var', 'final', 'const' or type" | 3908 ReportError("missing 'var', 'final', 'const' or type" |
| 3907 " in field declaration"); | 3909 " in field declaration"); |
| 3908 } | 3910 } |
| 3909 } | 3911 } |
| 3910 ParseFieldDefinition(members, &member); | 3912 ParseFieldDefinition(members, &member); |
| 3911 } else { | 3913 } else { |
| 3912 UnexpectedToken(); | 3914 UnexpectedToken(); |
| 3913 } | 3915 } |
| 3914 current_member_ = NULL; | 3916 current_member_ = NULL; |
| 3915 CheckMemberNameConflict(members, &member); | 3917 CheckMemberNameConflict(members, &member); |
| 3916 members->AddMember(member); | 3918 members->AddMember(member); |
| 3917 } | 3919 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3937 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 3939 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 3938 if (FLAG_trace_parser) { | 3940 if (FLAG_trace_parser) { |
| 3939 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 3941 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 3940 } | 3942 } |
| 3941 Class& cls = Class::Handle(I); | 3943 Class& cls = Class::Handle(I); |
| 3942 TypeArguments& orig_type_parameters = TypeArguments::Handle(I); | 3944 TypeArguments& orig_type_parameters = TypeArguments::Handle(I); |
| 3943 Object& obj = Object::Handle(I, | 3945 Object& obj = Object::Handle(I, |
| 3944 library_.LookupLocalObject(class_name)); | 3946 library_.LookupLocalObject(class_name)); |
| 3945 if (obj.IsNull()) { | 3947 if (obj.IsNull()) { |
| 3946 if (is_patch) { | 3948 if (is_patch) { |
| 3947 ErrorMsg(classname_pos, "missing class '%s' cannot be patched", | 3949 ReportError(classname_pos, "missing class '%s' cannot be patched", |
| 3948 class_name.ToCString()); | 3950 class_name.ToCString()); |
| 3949 } | 3951 } |
| 3950 cls = Class::New(class_name, script_, classname_pos); | 3952 cls = Class::New(class_name, script_, classname_pos); |
| 3951 library_.AddClass(cls); | 3953 library_.AddClass(cls); |
| 3952 } else { | 3954 } else { |
| 3953 if (!obj.IsClass()) { | 3955 if (!obj.IsClass()) { |
| 3954 ErrorMsg(classname_pos, "'%s' is already defined", | 3956 ReportError(classname_pos, "'%s' is already defined", |
| 3955 class_name.ToCString()); | 3957 class_name.ToCString()); |
| 3956 } | 3958 } |
| 3957 cls ^= obj.raw(); | 3959 cls ^= obj.raw(); |
| 3958 if (is_patch) { | 3960 if (is_patch) { |
| 3959 // Preserve and reuse the original type parameters and bounds since the | 3961 // Preserve and reuse the original type parameters and bounds since the |
| 3960 // ones defined in the patch class will not be finalized. | 3962 // ones defined in the patch class will not be finalized. |
| 3961 orig_type_parameters = cls.type_parameters(); | 3963 orig_type_parameters = cls.type_parameters(); |
| 3962 // A patch class must be given the same name as the class it is patching, | 3964 // A patch class must be given the same name as the class it is patching, |
| 3963 // otherwise the generic signature classes it defines will not match the | 3965 // otherwise the generic signature classes it defines will not match the |
| 3964 // patched generic signature classes. Therefore, new signature classes | 3966 // patched generic signature classes. Therefore, new signature classes |
| 3965 // will be introduced and the original ones will not get finalized. | 3967 // will be introduced and the original ones will not get finalized. |
| 3966 cls = Class::New(class_name, script_, classname_pos); | 3968 cls = Class::New(class_name, script_, classname_pos); |
| 3967 cls.set_library(library_); | 3969 cls.set_library(library_); |
| 3968 } else { | 3970 } else { |
| 3969 // Not patching a class, but it has been found. This must be one of the | 3971 // Not patching a class, but it has been found. This must be one of the |
| 3970 // pre-registered classes from object.cc or a duplicate definition. | 3972 // pre-registered classes from object.cc or a duplicate definition. |
| 3971 if (!(cls.is_prefinalized() || | 3973 if (!(cls.is_prefinalized() || |
| 3972 RawObject::IsTypedDataViewClassId(cls.id()))) { | 3974 RawObject::IsTypedDataViewClassId(cls.id()))) { |
| 3973 ErrorMsg(classname_pos, "class '%s' is already defined", | 3975 ReportError(classname_pos, "class '%s' is already defined", |
| 3974 class_name.ToCString()); | 3976 class_name.ToCString()); |
| 3975 } | 3977 } |
| 3976 // Pre-registered classes need their scripts connected at this time. | 3978 // Pre-registered classes need their scripts connected at this time. |
| 3977 cls.set_script(script_); | 3979 cls.set_script(script_); |
| 3978 cls.set_token_pos(classname_pos); | 3980 cls.set_token_pos(classname_pos); |
| 3979 } | 3981 } |
| 3980 } | 3982 } |
| 3981 ASSERT(!cls.IsNull()); | 3983 ASSERT(!cls.IsNull()); |
| 3982 ASSERT(cls.functions() == Object::empty_array().raw()); | 3984 ASSERT(cls.functions() == Object::empty_array().raw()); |
| 3983 set_current_class(cls); | 3985 set_current_class(cls); |
| 3984 ParseTypeParameters(cls); | 3986 ParseTypeParameters(cls); |
| 3985 if (is_patch) { | 3987 if (is_patch) { |
| 3986 // Check that the new type parameters are identical to the original ones. | 3988 // Check that the new type parameters are identical to the original ones. |
| 3987 const TypeArguments& new_type_parameters = | 3989 const TypeArguments& new_type_parameters = |
| 3988 TypeArguments::Handle(I, cls.type_parameters()); | 3990 TypeArguments::Handle(I, cls.type_parameters()); |
| 3989 const int new_type_params_count = | 3991 const int new_type_params_count = |
| 3990 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); | 3992 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); |
| 3991 const int orig_type_params_count = | 3993 const int orig_type_params_count = |
| 3992 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); | 3994 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); |
| 3993 if (new_type_params_count != orig_type_params_count) { | 3995 if (new_type_params_count != orig_type_params_count) { |
| 3994 ErrorMsg(classname_pos, | 3996 ReportError(classname_pos, |
| 3995 "class '%s' must be patched with identical type parameters", | 3997 "class '%s' must be patched with identical type parameters", |
| 3996 class_name.ToCString()); | 3998 class_name.ToCString()); |
| 3997 } | 3999 } |
| 3998 TypeParameter& new_type_param = TypeParameter::Handle(I); | 4000 TypeParameter& new_type_param = TypeParameter::Handle(I); |
| 3999 TypeParameter& orig_type_param = TypeParameter::Handle(I); | 4001 TypeParameter& orig_type_param = TypeParameter::Handle(I); |
| 4000 String& new_name = String::Handle(I); | 4002 String& new_name = String::Handle(I); |
| 4001 String& orig_name = String::Handle(I); | 4003 String& orig_name = String::Handle(I); |
| 4002 AbstractType& new_bound = AbstractType::Handle(I); | 4004 AbstractType& new_bound = AbstractType::Handle(I); |
| 4003 AbstractType& orig_bound = AbstractType::Handle(I); | 4005 AbstractType& orig_bound = AbstractType::Handle(I); |
| 4004 for (int i = 0; i < new_type_params_count; i++) { | 4006 for (int i = 0; i < new_type_params_count; i++) { |
| 4005 new_type_param ^= new_type_parameters.TypeAt(i); | 4007 new_type_param ^= new_type_parameters.TypeAt(i); |
| 4006 orig_type_param ^= orig_type_parameters.TypeAt(i); | 4008 orig_type_param ^= orig_type_parameters.TypeAt(i); |
| 4007 new_name = new_type_param.name(); | 4009 new_name = new_type_param.name(); |
| 4008 orig_name = orig_type_param.name(); | 4010 orig_name = orig_type_param.name(); |
| 4009 if (!new_name.Equals(orig_name)) { | 4011 if (!new_name.Equals(orig_name)) { |
| 4010 ErrorMsg(new_type_param.token_pos(), | 4012 ReportError(new_type_param.token_pos(), |
| 4011 "type parameter '%s' of patch class '%s' does not match " | 4013 "type parameter '%s' of patch class '%s' does not match " |
| 4012 "original type parameter '%s'", | 4014 "original type parameter '%s'", |
| 4013 new_name.ToCString(), | 4015 new_name.ToCString(), |
| 4014 class_name.ToCString(), | 4016 class_name.ToCString(), |
| 4015 orig_name.ToCString()); | 4017 orig_name.ToCString()); |
| 4016 } | 4018 } |
| 4017 new_bound = new_type_param.bound(); | 4019 new_bound = new_type_param.bound(); |
| 4018 orig_bound = orig_type_param.bound(); | 4020 orig_bound = orig_type_param.bound(); |
| 4019 if (!new_bound.Equals(orig_bound)) { | 4021 if (!new_bound.Equals(orig_bound)) { |
| 4020 ErrorMsg(new_type_param.token_pos(), | 4022 ReportError(new_type_param.token_pos(), |
| 4021 "bound '%s' of type parameter '%s' of patch class '%s' does " | 4023 "bound '%s' of type parameter '%s' of patch class '%s' " |
| 4022 "not match original type parameter bound '%s'", | 4024 "does not match original type parameter bound '%s'", |
| 4023 String::Handle(new_bound.UserVisibleName()).ToCString(), | 4025 String::Handle(new_bound.UserVisibleName()).ToCString(), |
| 4024 new_name.ToCString(), | 4026 new_name.ToCString(), |
| 4025 class_name.ToCString(), | 4027 class_name.ToCString(), |
| 4026 String::Handle(orig_bound.UserVisibleName()).ToCString()); | 4028 String::Handle(orig_bound.UserVisibleName()).ToCString()); |
| 4027 } | 4029 } |
| 4028 } | 4030 } |
| 4029 cls.set_type_parameters(orig_type_parameters); | 4031 cls.set_type_parameters(orig_type_parameters); |
| 4030 } | 4032 } |
| 4031 | 4033 |
| 4032 if (is_abstract) { | 4034 if (is_abstract) { |
| 4033 cls.set_is_abstract(); | 4035 cls.set_is_abstract(); |
| 4034 } | 4036 } |
| 4035 if (metadata_pos >= 0) { | 4037 if (metadata_pos >= 0) { |
| 4036 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); | 4038 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 4037 } | 4039 } |
| 4038 | 4040 |
| 4039 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | 4041 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
| 4040 if (is_mixin_declaration && is_patch) { | 4042 if (is_mixin_declaration && is_patch) { |
| 4041 ErrorMsg(classname_pos, | 4043 ReportError(classname_pos, |
| 4042 "mixin application '%s' may not be a patch class", | 4044 "mixin application '%s' may not be a patch class", |
| 4043 class_name.ToCString()); | 4045 class_name.ToCString()); |
| 4044 } | 4046 } |
| 4045 | 4047 |
| 4046 AbstractType& super_type = Type::Handle(I); | 4048 AbstractType& super_type = Type::Handle(I); |
| 4047 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 4049 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
| 4048 ConsumeToken(); // extends or = | 4050 ConsumeToken(); // extends or = |
| 4049 const intptr_t type_pos = TokenPos(); | 4051 const intptr_t type_pos = TokenPos(); |
| 4050 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4052 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4051 if (super_type.IsMalformedOrMalbounded()) { | 4053 if (super_type.IsMalformedOrMalbounded()) { |
| 4052 ErrorMsg(Error::Handle(I, super_type.error())); | 4054 ReportError(Error::Handle(I, super_type.error())); |
| 4053 } | 4055 } |
| 4054 if (super_type.IsDynamicType()) { | 4056 if (super_type.IsDynamicType()) { |
| 4055 // Unlikely here, since super type is not resolved yet. | 4057 // Unlikely here, since super type is not resolved yet. |
| 4056 ErrorMsg(type_pos, | 4058 ReportError(type_pos, |
| 4057 "class '%s' may not extend 'dynamic'", | 4059 "class '%s' may not extend 'dynamic'", |
| 4058 class_name.ToCString()); | 4060 class_name.ToCString()); |
| 4059 } | 4061 } |
| 4060 if (super_type.IsTypeParameter()) { | 4062 if (super_type.IsTypeParameter()) { |
| 4061 ErrorMsg(type_pos, | 4063 ReportError(type_pos, |
| 4062 "class '%s' may not extend type parameter '%s'", | 4064 "class '%s' may not extend type parameter '%s'", |
| 4063 class_name.ToCString(), | 4065 class_name.ToCString(), |
| 4064 String::Handle(I, | 4066 String::Handle(I, |
| 4065 super_type.UserVisibleName()).ToCString()); | 4067 super_type.UserVisibleName()).ToCString()); |
| 4066 } | 4068 } |
| 4067 // The class finalizer will check whether the super type is malbounded. | 4069 // The class finalizer will check whether the super type is malbounded. |
| 4068 if (is_mixin_declaration) { | 4070 if (is_mixin_declaration) { |
| 4069 if (CurrentToken() != Token::kWITH) { | 4071 if (CurrentToken() != Token::kWITH) { |
| 4070 ErrorMsg("mixin application clause 'with type' expected"); | 4072 ReportError("mixin application clause 'with type' expected"); |
| 4071 } | 4073 } |
| 4072 cls.set_is_mixin_app_alias(); | 4074 cls.set_is_mixin_app_alias(); |
| 4073 cls.set_is_synthesized_class(); | 4075 cls.set_is_synthesized_class(); |
| 4074 } | 4076 } |
| 4075 if (CurrentToken() == Token::kWITH) { | 4077 if (CurrentToken() == Token::kWITH) { |
| 4076 super_type = ParseMixins(super_type); | 4078 super_type = ParseMixins(super_type); |
| 4077 } | 4079 } |
| 4078 } else { | 4080 } else { |
| 4079 // No extends clause: implicitly extend Object, unless Object itself. | 4081 // No extends clause: implicitly extend Object, unless Object itself. |
| 4080 if (!cls.IsObjectClass()) { | 4082 if (!cls.IsObjectClass()) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4149 | 4151 |
| 4150 if (cls.is_patch()) { | 4152 if (cls.is_patch()) { |
| 4151 // Apply the changes to the patched class looked up above. | 4153 // Apply the changes to the patched class looked up above. |
| 4152 Object& obj = Object::Handle(I, | 4154 Object& obj = Object::Handle(I, |
| 4153 library_.LookupLocalObject(class_name)); | 4155 library_.LookupLocalObject(class_name)); |
| 4154 // The patched class must not be finalized yet. | 4156 // The patched class must not be finalized yet. |
| 4155 const Class& orig_class = Class::Cast(obj); | 4157 const Class& orig_class = Class::Cast(obj); |
| 4156 ASSERT(!orig_class.is_finalized()); | 4158 ASSERT(!orig_class.is_finalized()); |
| 4157 Error& error = Error::Handle(I); | 4159 Error& error = Error::Handle(I); |
| 4158 if (!orig_class.ApplyPatch(cls, &error)) { | 4160 if (!orig_class.ApplyPatch(cls, &error)) { |
| 4159 AppendErrorMsg(error, class_pos, "applying patch failed"); | 4161 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
| 4160 } | 4162 } |
| 4161 } | 4163 } |
| 4162 } | 4164 } |
| 4163 | 4165 |
| 4164 | 4166 |
| 4165 // Add an implicit constructor to the given class. | 4167 // Add an implicit constructor to the given class. |
| 4166 void Parser::AddImplicitConstructor(const Class& cls) { | 4168 void Parser::AddImplicitConstructor(const Class& cls) { |
| 4167 // The implicit constructor is unnamed, has no explicit parameter. | 4169 // The implicit constructor is unnamed, has no explicit parameter. |
| 4168 String& ctor_name = String::ZoneHandle(I, cls.Name()); | 4170 String& ctor_name = String::ZoneHandle(I, cls.Name()); |
| 4169 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 4171 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4211 MemberDesc* member = &members[i]; | 4213 MemberDesc* member = &members[i]; |
| 4212 if (member->redirect_name == NULL) { | 4214 if (member->redirect_name == NULL) { |
| 4213 continue; | 4215 continue; |
| 4214 } | 4216 } |
| 4215 GrowableArray<MemberDesc*> ctors; | 4217 GrowableArray<MemberDesc*> ctors; |
| 4216 while ((member != NULL) && (member->redirect_name != NULL)) { | 4218 while ((member != NULL) && (member->redirect_name != NULL)) { |
| 4217 ASSERT(member->IsConstructor()); | 4219 ASSERT(member->IsConstructor()); |
| 4218 // Check whether we have already seen this member. | 4220 // Check whether we have already seen this member. |
| 4219 for (int i = 0; i < ctors.length(); i++) { | 4221 for (int i = 0; i < ctors.length(); i++) { |
| 4220 if (ctors[i] == member) { | 4222 if (ctors[i] == member) { |
| 4221 ErrorMsg(member->name_pos, | 4223 ReportError(member->name_pos, |
| 4222 "cyclic reference in constructor redirection"); | 4224 "cyclic reference in constructor redirection"); |
| 4223 } | 4225 } |
| 4224 } | 4226 } |
| 4225 // We haven't seen this member. Add it to the list and follow | 4227 // We haven't seen this member. Add it to the list and follow |
| 4226 // the next redirection. If we can't find the constructor to | 4228 // the next redirection. If we can't find the constructor to |
| 4227 // which the current one redirects, we ignore the unresolved | 4229 // which the current one redirects, we ignore the unresolved |
| 4228 // reference. We'll catch it later when the constructor gets | 4230 // reference. We'll catch it later when the constructor gets |
| 4229 // compiled. | 4231 // compiled. |
| 4230 ctors.Add(member); | 4232 ctors.Add(member); |
| 4231 member = class_desc->LookupMember(*member->redirect_name); | 4233 member = class_desc->LookupMember(*member->redirect_name); |
| 4232 } | 4234 } |
| 4233 } | 4235 } |
| 4234 } | 4236 } |
| 4235 | 4237 |
| 4236 | 4238 |
| 4237 void Parser::ParseMixinAppAlias( | 4239 void Parser::ParseMixinAppAlias( |
| 4238 const GrowableObjectArray& pending_classes, | 4240 const GrowableObjectArray& pending_classes, |
| 4239 const Class& toplevel_class, | 4241 const Class& toplevel_class, |
| 4240 intptr_t metadata_pos) { | 4242 intptr_t metadata_pos) { |
| 4241 TRACE_PARSER("ParseMixinAppAlias"); | 4243 TRACE_PARSER("ParseMixinAppAlias"); |
| 4242 const intptr_t classname_pos = TokenPos(); | 4244 const intptr_t classname_pos = TokenPos(); |
| 4243 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4245 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4244 if (FLAG_trace_parser) { | 4246 if (FLAG_trace_parser) { |
| 4245 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4247 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
| 4246 class_name.ToCString()); | 4248 class_name.ToCString()); |
| 4247 } | 4249 } |
| 4248 const Object& obj = Object::Handle(I, | 4250 const Object& obj = Object::Handle(I, |
| 4249 library_.LookupLocalObject(class_name)); | 4251 library_.LookupLocalObject(class_name)); |
| 4250 if (!obj.IsNull()) { | 4252 if (!obj.IsNull()) { |
| 4251 ErrorMsg(classname_pos, "'%s' is already defined", | 4253 ReportError(classname_pos, "'%s' is already defined", |
| 4252 class_name.ToCString()); | 4254 class_name.ToCString()); |
| 4253 } | 4255 } |
| 4254 const Class& mixin_application = | 4256 const Class& mixin_application = |
| 4255 Class::Handle(I, Class::New(class_name, script_, classname_pos)); | 4257 Class::Handle(I, Class::New(class_name, script_, classname_pos)); |
| 4256 mixin_application.set_is_mixin_app_alias(); | 4258 mixin_application.set_is_mixin_app_alias(); |
| 4257 library_.AddClass(mixin_application); | 4259 library_.AddClass(mixin_application); |
| 4258 set_current_class(mixin_application); | 4260 set_current_class(mixin_application); |
| 4259 ParseTypeParameters(mixin_application); | 4261 ParseTypeParameters(mixin_application); |
| 4260 | 4262 |
| 4261 ExpectToken(Token::kASSIGN); | 4263 ExpectToken(Token::kASSIGN); |
| 4262 | 4264 |
| 4263 if (CurrentToken() == Token::kABSTRACT) { | 4265 if (CurrentToken() == Token::kABSTRACT) { |
| 4264 mixin_application.set_is_abstract(); | 4266 mixin_application.set_is_abstract(); |
| 4265 ConsumeToken(); | 4267 ConsumeToken(); |
| 4266 } | 4268 } |
| 4267 | 4269 |
| 4268 const intptr_t type_pos = TokenPos(); | 4270 const intptr_t type_pos = TokenPos(); |
| 4269 AbstractType& type = | 4271 AbstractType& type = |
| 4270 AbstractType::Handle(I, | 4272 AbstractType::Handle(I, |
| 4271 ParseType(ClassFinalizer::kResolveTypeParameters)); | 4273 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 4272 if (type.IsTypeParameter()) { | 4274 if (type.IsTypeParameter()) { |
| 4273 ErrorMsg(type_pos, | 4275 ReportError(type_pos, |
| 4274 "class '%s' may not extend type parameter '%s'", | 4276 "class '%s' may not extend type parameter '%s'", |
| 4275 class_name.ToCString(), | 4277 class_name.ToCString(), |
| 4276 String::Handle(I, type.UserVisibleName()).ToCString()); | 4278 String::Handle(I, type.UserVisibleName()).ToCString()); |
| 4277 } | 4279 } |
| 4278 | 4280 |
| 4279 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 4281 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
| 4280 type = ParseMixins(type); | 4282 type = ParseMixins(type); |
| 4281 | 4283 |
| 4282 mixin_application.set_super_type(type); | 4284 mixin_application.set_super_type(type); |
| 4283 mixin_application.set_is_synthesized_class(); | 4285 mixin_application.set_is_synthesized_class(); |
| 4284 | 4286 |
| 4285 // This mixin application alias needs an implicit constructor, but it is | 4287 // This mixin application alias needs an implicit constructor, but it is |
| 4286 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4288 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4337 | 4339 |
| 4338 | 4340 |
| 4339 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4341 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| 4340 const Class& toplevel_class, | 4342 const Class& toplevel_class, |
| 4341 intptr_t metadata_pos) { | 4343 intptr_t metadata_pos) { |
| 4342 TRACE_PARSER("ParseTypedef"); | 4344 TRACE_PARSER("ParseTypedef"); |
| 4343 ExpectToken(Token::kTYPEDEF); | 4345 ExpectToken(Token::kTYPEDEF); |
| 4344 | 4346 |
| 4345 if (IsMixinAppAlias()) { | 4347 if (IsMixinAppAlias()) { |
| 4346 if (FLAG_warn_mixin_typedef) { | 4348 if (FLAG_warn_mixin_typedef) { |
| 4347 Warning("deprecated mixin application typedef"); | 4349 ReportWarning(TokenPos(), "deprecated mixin application typedef"); |
| 4348 } | 4350 } |
| 4349 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); | 4351 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); |
| 4350 return; | 4352 return; |
| 4351 } | 4353 } |
| 4352 | 4354 |
| 4353 // Parse the result type of the function type. | 4355 // Parse the result type of the function type. |
| 4354 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); | 4356 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); |
| 4355 if (CurrentToken() == Token::kVOID) { | 4357 if (CurrentToken() == Token::kVOID) { |
| 4356 ConsumeToken(); | 4358 ConsumeToken(); |
| 4357 result_type = Type::VoidType(); | 4359 result_type = Type::VoidType(); |
| 4358 } else if (!IsFunctionTypeAliasName()) { | 4360 } else if (!IsFunctionTypeAliasName()) { |
| 4359 // Type annotations in typedef are never ignored, even in production mode. | 4361 // Type annotations in typedef are never ignored, even in production mode. |
| 4360 // Wait until we have an owner class before resolving the result type. | 4362 // Wait until we have an owner class before resolving the result type. |
| 4361 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 4363 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 4362 } | 4364 } |
| 4363 | 4365 |
| 4364 const intptr_t alias_name_pos = TokenPos(); | 4366 const intptr_t alias_name_pos = TokenPos(); |
| 4365 const String* alias_name = | 4367 const String* alias_name = |
| 4366 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 4368 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
| 4367 | 4369 |
| 4368 // Lookup alias name and report an error if it is already defined in | 4370 // Lookup alias name and report an error if it is already defined in |
| 4369 // the library scope. | 4371 // the library scope. |
| 4370 const Object& obj = Object::Handle(I, | 4372 const Object& obj = Object::Handle(I, |
| 4371 library_.LookupLocalObject(*alias_name)); | 4373 library_.LookupLocalObject(*alias_name)); |
| 4372 if (!obj.IsNull()) { | 4374 if (!obj.IsNull()) { |
| 4373 ErrorMsg(alias_name_pos, | 4375 ReportError(alias_name_pos, |
| 4374 "'%s' is already defined", alias_name->ToCString()); | 4376 "'%s' is already defined", alias_name->ToCString()); |
| 4375 } | 4377 } |
| 4376 | 4378 |
| 4377 // Create the function type alias signature class. It will be linked to its | 4379 // Create the function type alias signature class. It will be linked to its |
| 4378 // signature function after it has been parsed. The type parameters, in order | 4380 // signature function after it has been parsed. The type parameters, in order |
| 4379 // to be properly finalized, need to be associated to this signature class as | 4381 // to be properly finalized, need to be associated to this signature class as |
| 4380 // they are parsed. | 4382 // they are parsed. |
| 4381 const Class& function_type_alias = Class::Handle(I, | 4383 const Class& function_type_alias = Class::Handle(I, |
| 4382 Class::NewSignatureClass(*alias_name, | 4384 Class::NewSignatureClass(*alias_name, |
| 4383 Function::Handle(I), | 4385 Function::Handle(I), |
| 4384 script_, | 4386 script_, |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4504 void Parser::SkipTypeArguments() { | 4506 void Parser::SkipTypeArguments() { |
| 4505 if (CurrentToken() == Token::kLT) { | 4507 if (CurrentToken() == Token::kLT) { |
| 4506 do { | 4508 do { |
| 4507 ConsumeToken(); | 4509 ConsumeToken(); |
| 4508 SkipType(false); | 4510 SkipType(false); |
| 4509 } while (CurrentToken() == Token::kCOMMA); | 4511 } while (CurrentToken() == Token::kCOMMA); |
| 4510 Token::Kind token = CurrentToken(); | 4512 Token::Kind token = CurrentToken(); |
| 4511 if ((token == Token::kGT) || (token == Token::kSHR)) { | 4513 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 4512 ConsumeRightAngleBracket(); | 4514 ConsumeRightAngleBracket(); |
| 4513 } else { | 4515 } else { |
| 4514 ErrorMsg("right angle bracket expected"); | 4516 ReportError("right angle bracket expected"); |
| 4515 } | 4517 } |
| 4516 } | 4518 } |
| 4517 } | 4519 } |
| 4518 | 4520 |
| 4519 | 4521 |
| 4520 void Parser::SkipType(bool allow_void) { | 4522 void Parser::SkipType(bool allow_void) { |
| 4521 if (CurrentToken() == Token::kVOID) { | 4523 if (CurrentToken() == Token::kVOID) { |
| 4522 if (!allow_void) { | 4524 if (!allow_void) { |
| 4523 ErrorMsg("'void' not allowed here"); | 4525 ReportError("'void' not allowed here"); |
| 4524 } | 4526 } |
| 4525 ConsumeToken(); | 4527 ConsumeToken(); |
| 4526 } else { | 4528 } else { |
| 4527 ExpectIdentifier("type name expected"); | 4529 ExpectIdentifier("type name expected"); |
| 4528 if (CurrentToken() == Token::kPERIOD) { | 4530 if (CurrentToken() == Token::kPERIOD) { |
| 4529 ConsumeToken(); | 4531 ConsumeToken(); |
| 4530 ExpectIdentifier("name expected"); | 4532 ExpectIdentifier("name expected"); |
| 4531 } | 4533 } |
| 4532 SkipTypeArguments(); | 4534 SkipTypeArguments(); |
| 4533 } | 4535 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4548 ConsumeToken(); | 4550 ConsumeToken(); |
| 4549 const intptr_t metadata_pos = SkipMetadata(); | 4551 const intptr_t metadata_pos = SkipMetadata(); |
| 4550 const intptr_t type_parameter_pos = TokenPos(); | 4552 const intptr_t type_parameter_pos = TokenPos(); |
| 4551 String& type_parameter_name = | 4553 String& type_parameter_name = |
| 4552 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 4554 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
| 4553 // Check for duplicate type parameters. | 4555 // Check for duplicate type parameters. |
| 4554 for (intptr_t i = 0; i < index; i++) { | 4556 for (intptr_t i = 0; i < index; i++) { |
| 4555 existing_type_parameter ^= type_parameters_array.At(i); | 4557 existing_type_parameter ^= type_parameters_array.At(i); |
| 4556 existing_type_parameter_name = existing_type_parameter.name(); | 4558 existing_type_parameter_name = existing_type_parameter.name(); |
| 4557 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 4559 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
| 4558 ErrorMsg(type_parameter_pos, "duplicate type parameter '%s'", | 4560 ReportError(type_parameter_pos, "duplicate type parameter '%s'", |
| 4559 type_parameter_name.ToCString()); | 4561 type_parameter_name.ToCString()); |
| 4560 } | 4562 } |
| 4561 } | 4563 } |
| 4562 if (CurrentToken() == Token::kEXTENDS) { | 4564 if (CurrentToken() == Token::kEXTENDS) { |
| 4563 ConsumeToken(); | 4565 ConsumeToken(); |
| 4564 // A bound may refer to the owner of the type parameter it applies to, | 4566 // A bound may refer to the owner of the type parameter it applies to, |
| 4565 // i.e. to the class or interface currently being parsed. | 4567 // i.e. to the class or interface currently being parsed. |
| 4566 // Postpone resolution in order to avoid resolving the class and its | 4568 // Postpone resolution in order to avoid resolving the class and its |
| 4567 // type parameters, as they are not fully parsed yet. | 4569 // type parameters, as they are not fully parsed yet. |
| 4568 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 4570 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
| 4569 } else { | 4571 } else { |
| 4570 type_parameter_bound = I->object_store()->object_type(); | 4572 type_parameter_bound = I->object_store()->object_type(); |
| 4571 } | 4573 } |
| 4572 type_parameter = TypeParameter::New(cls, | 4574 type_parameter = TypeParameter::New(cls, |
| 4573 index, | 4575 index, |
| 4574 type_parameter_name, | 4576 type_parameter_name, |
| 4575 type_parameter_bound, | 4577 type_parameter_bound, |
| 4576 type_parameter_pos); | 4578 type_parameter_pos); |
| 4577 type_parameters_array.Add(type_parameter); | 4579 type_parameters_array.Add(type_parameter); |
| 4578 if (metadata_pos >= 0) { | 4580 if (metadata_pos >= 0) { |
| 4579 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 4581 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
| 4580 } | 4582 } |
| 4581 index++; | 4583 index++; |
| 4582 } while (CurrentToken() == Token::kCOMMA); | 4584 } while (CurrentToken() == Token::kCOMMA); |
| 4583 Token::Kind token = CurrentToken(); | 4585 Token::Kind token = CurrentToken(); |
| 4584 if ((token == Token::kGT) || (token == Token::kSHR)) { | 4586 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 4585 ConsumeRightAngleBracket(); | 4587 ConsumeRightAngleBracket(); |
| 4586 } else { | 4588 } else { |
| 4587 ErrorMsg("right angle bracket expected"); | 4589 ReportError("right angle bracket expected"); |
| 4588 } | 4590 } |
| 4589 const TypeArguments& type_parameters = | 4591 const TypeArguments& type_parameters = |
| 4590 TypeArguments::Handle(I, | 4592 TypeArguments::Handle(I, |
| 4591 NewTypeArguments(type_parameters_array)); | 4593 NewTypeArguments(type_parameters_array)); |
| 4592 cls.set_type_parameters(type_parameters); | 4594 cls.set_type_parameters(type_parameters); |
| 4593 // Try to resolve the upper bounds, which will at least resolve the | 4595 // Try to resolve the upper bounds, which will at least resolve the |
| 4594 // referenced type parameters. | 4596 // referenced type parameters. |
| 4595 const intptr_t num_types = type_parameters.Length(); | 4597 const intptr_t num_types = type_parameters.Length(); |
| 4596 for (intptr_t i = 0; i < num_types; i++) { | 4598 for (intptr_t i = 0; i < num_types; i++) { |
| 4597 type_parameter ^= type_parameters.TypeAt(i); | 4599 type_parameter ^= type_parameters.TypeAt(i); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4618 // Map a malformed type argument to dynamic. | 4620 // Map a malformed type argument to dynamic. |
| 4619 if (type.IsMalformed()) { | 4621 if (type.IsMalformed()) { |
| 4620 type = Type::DynamicType(); | 4622 type = Type::DynamicType(); |
| 4621 } | 4623 } |
| 4622 types.Add(type); | 4624 types.Add(type); |
| 4623 } while (CurrentToken() == Token::kCOMMA); | 4625 } while (CurrentToken() == Token::kCOMMA); |
| 4624 Token::Kind token = CurrentToken(); | 4626 Token::Kind token = CurrentToken(); |
| 4625 if ((token == Token::kGT) || (token == Token::kSHR)) { | 4627 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 4626 ConsumeRightAngleBracket(); | 4628 ConsumeRightAngleBracket(); |
| 4627 } else { | 4629 } else { |
| 4628 ErrorMsg("right angle bracket expected"); | 4630 ReportError("right angle bracket expected"); |
| 4629 } | 4631 } |
| 4630 if (finalization != ClassFinalizer::kIgnore) { | 4632 if (finalization != ClassFinalizer::kIgnore) { |
| 4631 return NewTypeArguments(types); | 4633 return NewTypeArguments(types); |
| 4632 } | 4634 } |
| 4633 } | 4635 } |
| 4634 return TypeArguments::null(); | 4636 return TypeArguments::null(); |
| 4635 } | 4637 } |
| 4636 | 4638 |
| 4637 | 4639 |
| 4638 // Parse interface list and add to class cls. | 4640 // Parse interface list and add to class cls. |
| 4639 void Parser::ParseInterfaceList(const Class& cls) { | 4641 void Parser::ParseInterfaceList(const Class& cls) { |
| 4640 TRACE_PARSER("ParseInterfaceList"); | 4642 TRACE_PARSER("ParseInterfaceList"); |
| 4641 ASSERT(CurrentToken() == Token::kIMPLEMENTS); | 4643 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
| 4642 const GrowableObjectArray& all_interfaces = | 4644 const GrowableObjectArray& all_interfaces = |
| 4643 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 4645 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 4644 AbstractType& interface = AbstractType::Handle(I); | 4646 AbstractType& interface = AbstractType::Handle(I); |
| 4645 // First get all the interfaces already implemented by class. | 4647 // First get all the interfaces already implemented by class. |
| 4646 Array& cls_interfaces = Array::Handle(I, cls.interfaces()); | 4648 Array& cls_interfaces = Array::Handle(I, cls.interfaces()); |
| 4647 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 4649 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 4648 interface ^= cls_interfaces.At(i); | 4650 interface ^= cls_interfaces.At(i); |
| 4649 all_interfaces.Add(interface); | 4651 all_interfaces.Add(interface); |
| 4650 } | 4652 } |
| 4651 // Now parse and add the new interfaces. | 4653 // Now parse and add the new interfaces. |
| 4652 do { | 4654 do { |
| 4653 ConsumeToken(); | 4655 ConsumeToken(); |
| 4654 intptr_t interface_pos = TokenPos(); | 4656 intptr_t interface_pos = TokenPos(); |
| 4655 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 4657 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4656 if (interface.IsTypeParameter()) { | 4658 if (interface.IsTypeParameter()) { |
| 4657 ErrorMsg(interface_pos, | 4659 ReportError(interface_pos, |
| 4658 "type parameter '%s' may not be used in interface list", | 4660 "type parameter '%s' may not be used in interface list", |
| 4659 String::Handle(I, | 4661 String::Handle(I, interface.UserVisibleName()).ToCString()); |
| 4660 interface.UserVisibleName()).ToCString()); | |
| 4661 } | 4662 } |
| 4662 all_interfaces.Add(interface); | 4663 all_interfaces.Add(interface); |
| 4663 } while (CurrentToken() == Token::kCOMMA); | 4664 } while (CurrentToken() == Token::kCOMMA); |
| 4664 cls_interfaces = Array::MakeArray(all_interfaces); | 4665 cls_interfaces = Array::MakeArray(all_interfaces); |
| 4665 cls.set_interfaces(cls_interfaces); | 4666 cls.set_interfaces(cls_interfaces); |
| 4666 } | 4667 } |
| 4667 | 4668 |
| 4668 | 4669 |
| 4669 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 4670 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
| 4670 TRACE_PARSER("ParseMixins"); | 4671 TRACE_PARSER("ParseMixins"); |
| 4671 ASSERT(CurrentToken() == Token::kWITH); | 4672 ASSERT(CurrentToken() == Token::kWITH); |
| 4672 const GrowableObjectArray& mixin_types = | 4673 const GrowableObjectArray& mixin_types = |
| 4673 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 4674 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 4674 AbstractType& mixin_type = AbstractType::Handle(I); | 4675 AbstractType& mixin_type = AbstractType::Handle(I); |
| 4675 do { | 4676 do { |
| 4676 ConsumeToken(); | 4677 ConsumeToken(); |
| 4677 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4678 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4678 if (mixin_type.IsDynamicType()) { | 4679 if (mixin_type.IsDynamicType()) { |
| 4679 // The string 'dynamic' is not resolved yet at this point, but a malformed | 4680 // The string 'dynamic' is not resolved yet at this point, but a malformed |
| 4680 // type mapped to dynamic can be encountered here. | 4681 // type mapped to dynamic can be encountered here. |
| 4681 ErrorMsg(mixin_type.token_pos(), "illegal mixin of a malformed type"); | 4682 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); |
| 4682 } | 4683 } |
| 4683 if (mixin_type.IsTypeParameter()) { | 4684 if (mixin_type.IsTypeParameter()) { |
| 4684 ErrorMsg(mixin_type.token_pos(), | 4685 ReportError(mixin_type.token_pos(), |
| 4685 "mixin type '%s' may not be a type parameter", | 4686 "mixin type '%s' may not be a type parameter", |
| 4686 String::Handle(I, | 4687 String::Handle(I, mixin_type.UserVisibleName()).ToCString()); |
| 4687 mixin_type.UserVisibleName()).ToCString()); | |
| 4688 } | 4688 } |
| 4689 mixin_types.Add(mixin_type); | 4689 mixin_types.Add(mixin_type); |
| 4690 } while (CurrentToken() == Token::kCOMMA); | 4690 } while (CurrentToken() == Token::kCOMMA); |
| 4691 return MixinAppType::New(super_type, | 4691 return MixinAppType::New(super_type, |
| 4692 Array::Handle(I, Array::MakeArray(mixin_types))); | 4692 Array::Handle(I, Array::MakeArray(mixin_types))); |
| 4693 } | 4693 } |
| 4694 | 4694 |
| 4695 | 4695 |
| 4696 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 4696 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
| 4697 intptr_t metadata_pos) { | 4697 intptr_t metadata_pos) { |
| 4698 TRACE_PARSER("ParseTopLevelVariable"); | 4698 TRACE_PARSER("ParseTopLevelVariable"); |
| 4699 const bool is_const = (CurrentToken() == Token::kCONST); | 4699 const bool is_const = (CurrentToken() == Token::kCONST); |
| 4700 // Const fields are implicitly final. | 4700 // Const fields are implicitly final. |
| 4701 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 4701 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 4702 const bool is_static = true; | 4702 const bool is_static = true; |
| 4703 const AbstractType& type = AbstractType::ZoneHandle(I, | 4703 const AbstractType& type = AbstractType::ZoneHandle(I, |
| 4704 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 4704 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
| 4705 Field& field = Field::Handle(I); | 4705 Field& field = Field::Handle(I); |
| 4706 Function& getter = Function::Handle(I); | 4706 Function& getter = Function::Handle(I); |
| 4707 while (true) { | 4707 while (true) { |
| 4708 const intptr_t name_pos = TokenPos(); | 4708 const intptr_t name_pos = TokenPos(); |
| 4709 String& var_name = *ExpectIdentifier("variable name expected"); | 4709 String& var_name = *ExpectIdentifier("variable name expected"); |
| 4710 | 4710 |
| 4711 if (library_.LookupLocalObject(var_name) != Object::null()) { | 4711 if (library_.LookupLocalObject(var_name) != Object::null()) { |
| 4712 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 4712 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 4713 } | 4713 } |
| 4714 | 4714 |
| 4715 // Check whether a getter or setter for this name exists. A const | 4715 // Check whether a getter or setter for this name exists. A const |
| 4716 // or final field implies a setter which throws a NoSuchMethodError, | 4716 // or final field implies a setter which throws a NoSuchMethodError, |
| 4717 // thus we need to check for conflicts with existing setters and | 4717 // thus we need to check for conflicts with existing setters and |
| 4718 // getters. | 4718 // getters. |
| 4719 String& accessor_name = String::Handle(I, | 4719 String& accessor_name = String::Handle(I, |
| 4720 Field::GetterName(var_name)); | 4720 Field::GetterName(var_name)); |
| 4721 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4721 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 4722 ErrorMsg(name_pos, "getter for '%s' is already defined", | 4722 ReportError(name_pos, "getter for '%s' is already defined", |
| 4723 var_name.ToCString()); | 4723 var_name.ToCString()); |
| 4724 } | 4724 } |
| 4725 accessor_name = Field::SetterName(var_name); | 4725 accessor_name = Field::SetterName(var_name); |
| 4726 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4726 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 4727 ErrorMsg(name_pos, "setter for '%s' is already defined", | 4727 ReportError(name_pos, "setter for '%s' is already defined", |
| 4728 var_name.ToCString()); | 4728 var_name.ToCString()); |
| 4729 } | 4729 } |
| 4730 | 4730 |
| 4731 field = Field::New(var_name, is_static, is_final, is_const, | 4731 field = Field::New(var_name, is_static, is_final, is_const, |
| 4732 current_class(), name_pos); | 4732 current_class(), name_pos); |
| 4733 field.set_type(type); | 4733 field.set_type(type); |
| 4734 field.set_value(Instance::Handle(I, Instance::null())); | 4734 field.set_value(Instance::Handle(I, Instance::null())); |
| 4735 top_level->fields.Add(field); | 4735 top_level->fields.Add(field); |
| 4736 library_.AddObject(field, var_name); | 4736 library_.AddObject(field, var_name); |
| 4737 if (metadata_pos >= 0) { | 4737 if (metadata_pos >= 0) { |
| 4738 library_.AddFieldMetadata(field, metadata_pos); | 4738 library_.AddFieldMetadata(field, metadata_pos); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4764 top_level->functions.Add(getter); | 4764 top_level->functions.Add(getter); |
| 4765 | 4765 |
| 4766 // Create initializer function. | 4766 // Create initializer function. |
| 4767 if (!field.is_const()) { | 4767 if (!field.is_const()) { |
| 4768 const Function& init_function = Function::ZoneHandle(I, | 4768 const Function& init_function = Function::ZoneHandle(I, |
| 4769 Function::NewStaticInitializer(field)); | 4769 Function::NewStaticInitializer(field)); |
| 4770 top_level->functions.Add(init_function); | 4770 top_level->functions.Add(init_function); |
| 4771 } | 4771 } |
| 4772 } | 4772 } |
| 4773 } else if (is_final) { | 4773 } else if (is_final) { |
| 4774 ErrorMsg(name_pos, "missing initializer for final or const variable"); | 4774 ReportError(name_pos, "missing initializer for final or const variable"); |
| 4775 } | 4775 } |
| 4776 | 4776 |
| 4777 if (CurrentToken() == Token::kCOMMA) { | 4777 if (CurrentToken() == Token::kCOMMA) { |
| 4778 ConsumeToken(); | 4778 ConsumeToken(); |
| 4779 } else if (CurrentToken() == Token::kSEMICOLON) { | 4779 } else if (CurrentToken() == Token::kSEMICOLON) { |
| 4780 ConsumeToken(); | 4780 ConsumeToken(); |
| 4781 break; | 4781 break; |
| 4782 } else { | 4782 } else { |
| 4783 ExpectSemicolon(); // Reports error. | 4783 ExpectSemicolon(); // Reports error. |
| 4784 } | 4784 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 4812 if ((CurrentToken() == Token::kIDENT) && | 4812 if ((CurrentToken() == Token::kIDENT) && |
| 4813 (LookaheadToken(1) != Token::kLPAREN)) { | 4813 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4814 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4814 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4815 } | 4815 } |
| 4816 } | 4816 } |
| 4817 const intptr_t name_pos = TokenPos(); | 4817 const intptr_t name_pos = TokenPos(); |
| 4818 const String& func_name = *ExpectIdentifier("function name expected"); | 4818 const String& func_name = *ExpectIdentifier("function name expected"); |
| 4819 | 4819 |
| 4820 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 4820 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
| 4821 if (found && !is_patch) { | 4821 if (found && !is_patch) { |
| 4822 ErrorMsg(name_pos, "'%s' is already defined", func_name.ToCString()); | 4822 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 4823 } else if (!found && is_patch) { | 4823 } else if (!found && is_patch) { |
| 4824 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); | 4824 ReportError(name_pos, "missing '%s' cannot be patched", |
| 4825 func_name.ToCString()); |
| 4825 } | 4826 } |
| 4826 String& accessor_name = String::Handle(I, | 4827 String& accessor_name = String::Handle(I, |
| 4827 Field::GetterName(func_name)); | 4828 Field::GetterName(func_name)); |
| 4828 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4829 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 4829 ErrorMsg(name_pos, "'%s' is already defined as getter", | 4830 ReportError(name_pos, "'%s' is already defined as getter", |
| 4830 func_name.ToCString()); | 4831 func_name.ToCString()); |
| 4831 } | 4832 } |
| 4832 // A setter named x= may co-exist with a function named x, thus we do | 4833 // A setter named x= may co-exist with a function named x, thus we do |
| 4833 // not need to check setters. | 4834 // not need to check setters. |
| 4834 | 4835 |
| 4835 CheckToken(Token::kLPAREN); | 4836 CheckToken(Token::kLPAREN); |
| 4836 const intptr_t function_pos = TokenPos(); | 4837 const intptr_t function_pos = TokenPos(); |
| 4837 ParamList params; | 4838 ParamList params; |
| 4838 const bool allow_explicit_default_values = true; | 4839 const bool allow_explicit_default_values = true; |
| 4839 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 4840 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 4840 | 4841 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4851 ConsumeToken(); | 4852 ConsumeToken(); |
| 4852 SkipExpr(); | 4853 SkipExpr(); |
| 4853 function_end_pos = TokenPos(); | 4854 function_end_pos = TokenPos(); |
| 4854 ExpectSemicolon(); | 4855 ExpectSemicolon(); |
| 4855 } else if (IsLiteral("native")) { | 4856 } else if (IsLiteral("native")) { |
| 4856 ParseNativeDeclaration(); | 4857 ParseNativeDeclaration(); |
| 4857 function_end_pos = TokenPos(); | 4858 function_end_pos = TokenPos(); |
| 4858 ExpectSemicolon(); | 4859 ExpectSemicolon(); |
| 4859 is_native = true; | 4860 is_native = true; |
| 4860 } else { | 4861 } else { |
| 4861 ErrorMsg("function block expected"); | 4862 ReportError("function block expected"); |
| 4862 } | 4863 } |
| 4863 Function& func = Function::Handle(I, | 4864 Function& func = Function::Handle(I, |
| 4864 Function::New(func_name, | 4865 Function::New(func_name, |
| 4865 RawFunction::kRegularFunction, | 4866 RawFunction::kRegularFunction, |
| 4866 is_static, | 4867 is_static, |
| 4867 /* is_const = */ false, | 4868 /* is_const = */ false, |
| 4868 /* is_abstract = */ false, | 4869 /* is_abstract = */ false, |
| 4869 is_external, | 4870 is_external, |
| 4870 is_native, | 4871 is_native, |
| 4871 current_class(), | 4872 current_class(), |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4938 int expected_num_parameters = -1; | 4939 int expected_num_parameters = -1; |
| 4939 if (is_getter) { | 4940 if (is_getter) { |
| 4940 expected_num_parameters = 0; | 4941 expected_num_parameters = 0; |
| 4941 accessor_name = Field::GetterSymbol(*field_name); | 4942 accessor_name = Field::GetterSymbol(*field_name); |
| 4942 } else { | 4943 } else { |
| 4943 expected_num_parameters = 1; | 4944 expected_num_parameters = 1; |
| 4944 accessor_name = Field::SetterSymbol(*field_name); | 4945 accessor_name = Field::SetterSymbol(*field_name); |
| 4945 } | 4946 } |
| 4946 if ((params.num_fixed_parameters != expected_num_parameters) || | 4947 if ((params.num_fixed_parameters != expected_num_parameters) || |
| 4947 (params.num_optional_parameters != 0)) { | 4948 (params.num_optional_parameters != 0)) { |
| 4948 ErrorMsg(name_pos, "illegal %s parameters", | 4949 ReportError(name_pos, "illegal %s parameters", |
| 4949 is_getter ? "getter" : "setter"); | 4950 is_getter ? "getter" : "setter"); |
| 4950 } | 4951 } |
| 4951 | 4952 |
| 4952 // Check whether this getter conflicts with a function or top-level variable | 4953 // Check whether this getter conflicts with a function or top-level variable |
| 4953 // with the same name. | 4954 // with the same name. |
| 4954 if (is_getter && | 4955 if (is_getter && |
| 4955 (library_.LookupLocalObject(*field_name) != Object::null())) { | 4956 (library_.LookupLocalObject(*field_name) != Object::null())) { |
| 4956 ErrorMsg(name_pos, "'%s' is already defined in this library", | 4957 ReportError(name_pos, "'%s' is already defined in this library", |
| 4957 field_name->ToCString()); | 4958 field_name->ToCString()); |
| 4958 } | 4959 } |
| 4959 // Check whether this setter conflicts with the implicit setter | 4960 // Check whether this setter conflicts with the implicit setter |
| 4960 // of a top-level variable with the same name. | 4961 // of a top-level variable with the same name. |
| 4961 if (!is_getter && | 4962 if (!is_getter && |
| 4962 (library_.LookupLocalField(*field_name) != Object::null())) { | 4963 (library_.LookupLocalField(*field_name) != Object::null())) { |
| 4963 ErrorMsg(name_pos, "Variable '%s' is already defined in this library", | 4964 ReportError(name_pos, "Variable '%s' is already defined in this library", |
| 4964 field_name->ToCString()); | 4965 field_name->ToCString()); |
| 4965 } | 4966 } |
| 4966 bool found = library_.LookupLocalObject(accessor_name) != Object::null(); | 4967 bool found = library_.LookupLocalObject(accessor_name) != Object::null(); |
| 4967 if (found && !is_patch) { | 4968 if (found && !is_patch) { |
| 4968 ErrorMsg(name_pos, "%s for '%s' is already defined", | 4969 ReportError(name_pos, "%s for '%s' is already defined", |
| 4969 is_getter ? "getter" : "setter", | 4970 is_getter ? "getter" : "setter", |
| 4970 field_name->ToCString()); | 4971 field_name->ToCString()); |
| 4971 } else if (!found && is_patch) { | 4972 } else if (!found && is_patch) { |
| 4972 ErrorMsg(name_pos, "missing %s for '%s' cannot be patched", | 4973 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
| 4973 is_getter ? "getter" : "setter", | 4974 is_getter ? "getter" : "setter", |
| 4974 field_name->ToCString()); | 4975 field_name->ToCString()); |
| 4975 } | 4976 } |
| 4976 | 4977 |
| 4977 intptr_t accessor_end_pos = accessor_pos; | 4978 intptr_t accessor_end_pos = accessor_pos; |
| 4978 bool is_native = false; | 4979 bool is_native = false; |
| 4979 if (is_external) { | 4980 if (is_external) { |
| 4980 accessor_end_pos = TokenPos(); | 4981 accessor_end_pos = TokenPos(); |
| 4981 ExpectSemicolon(); | 4982 ExpectSemicolon(); |
| 4982 } else if (CurrentToken() == Token::kLBRACE) { | 4983 } else if (CurrentToken() == Token::kLBRACE) { |
| 4983 SkipBlock(); | 4984 SkipBlock(); |
| 4984 accessor_end_pos = TokenPos(); | 4985 accessor_end_pos = TokenPos(); |
| 4985 ExpectToken(Token::kRBRACE); | 4986 ExpectToken(Token::kRBRACE); |
| 4986 } else if (CurrentToken() == Token::kARROW) { | 4987 } else if (CurrentToken() == Token::kARROW) { |
| 4987 ConsumeToken(); | 4988 ConsumeToken(); |
| 4988 SkipExpr(); | 4989 SkipExpr(); |
| 4989 accessor_end_pos = TokenPos(); | 4990 accessor_end_pos = TokenPos(); |
| 4990 ExpectSemicolon(); | 4991 ExpectSemicolon(); |
| 4991 } else if (IsLiteral("native")) { | 4992 } else if (IsLiteral("native")) { |
| 4992 ParseNativeDeclaration(); | 4993 ParseNativeDeclaration(); |
| 4993 accessor_end_pos = TokenPos(); | 4994 accessor_end_pos = TokenPos(); |
| 4994 ExpectSemicolon(); | 4995 ExpectSemicolon(); |
| 4995 is_native = true; | 4996 is_native = true; |
| 4996 } else { | 4997 } else { |
| 4997 ErrorMsg("function block expected"); | 4998 ReportError("function block expected"); |
| 4998 } | 4999 } |
| 4999 Function& func = Function::Handle(I, | 5000 Function& func = Function::Handle(I, |
| 5000 Function::New(accessor_name, | 5001 Function::New(accessor_name, |
| 5001 is_getter ? RawFunction::kGetterFunction : | 5002 is_getter ? RawFunction::kGetterFunction : |
| 5002 RawFunction::kSetterFunction, | 5003 RawFunction::kSetterFunction, |
| 5003 is_static, | 5004 is_static, |
| 5004 /* is_const = */ false, | 5005 /* is_const = */ false, |
| 5005 /* is_abstract = */ false, | 5006 /* is_abstract = */ false, |
| 5006 is_external, | 5007 is_external, |
| 5007 is_native, | 5008 is_native, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 5030 intptr_t token_pos, | 5031 intptr_t token_pos, |
| 5031 const String& url) { | 5032 const String& url) { |
| 5032 Dart_LibraryTagHandler handler = I->library_tag_handler(); | 5033 Dart_LibraryTagHandler handler = I->library_tag_handler(); |
| 5033 if (handler == NULL) { | 5034 if (handler == NULL) { |
| 5034 if (url.StartsWith(Symbols::DartScheme())) { | 5035 if (url.StartsWith(Symbols::DartScheme())) { |
| 5035 if (tag == Dart_kCanonicalizeUrl) { | 5036 if (tag == Dart_kCanonicalizeUrl) { |
| 5036 return url.raw(); | 5037 return url.raw(); |
| 5037 } | 5038 } |
| 5038 return Object::null(); | 5039 return Object::null(); |
| 5039 } | 5040 } |
| 5040 ErrorMsg(token_pos, "no library handler registered"); | 5041 ReportError(token_pos, "no library handler registered"); |
| 5041 } | 5042 } |
| 5042 // Block class finalization attempts when calling into the library | 5043 // Block class finalization attempts when calling into the library |
| 5043 // tag handler. | 5044 // tag handler. |
| 5044 I->BlockClassFinalization(); | 5045 I->BlockClassFinalization(); |
| 5045 Api::Scope api_scope(I); | 5046 Api::Scope api_scope(I); |
| 5046 Dart_Handle result = handler(tag, | 5047 Dart_Handle result = handler(tag, |
| 5047 Api::NewHandle(I, library_.raw()), | 5048 Api::NewHandle(I, library_.raw()), |
| 5048 Api::NewHandle(I, url.raw())); | 5049 Api::NewHandle(I, url.raw())); |
| 5049 I->UnblockClassFinalization(); | 5050 I->UnblockClassFinalization(); |
| 5050 if (Dart_IsError(result)) { | 5051 if (Dart_IsError(result)) { |
| 5051 // In case of an error we append an explanatory error message to the | 5052 // In case of an error we append an explanatory error message to the |
| 5052 // error obtained from the library tag handler. | 5053 // error obtained from the library tag handler. |
| 5053 Error& prev_error = Error::Handle(I); | 5054 Error& prev_error = Error::Handle(I); |
| 5054 prev_error ^= Api::UnwrapHandle(result); | 5055 prev_error ^= Api::UnwrapHandle(result); |
| 5055 AppendErrorMsg(prev_error, token_pos, "library handler failed"); | 5056 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); |
| 5056 } | 5057 } |
| 5057 if (tag == Dart_kCanonicalizeUrl) { | 5058 if (tag == Dart_kCanonicalizeUrl) { |
| 5058 if (!Dart_IsString(result)) { | 5059 if (!Dart_IsString(result)) { |
| 5059 ErrorMsg(token_pos, "library handler failed URI canonicalization"); | 5060 ReportError(token_pos, "library handler failed URI canonicalization"); |
| 5060 } | 5061 } |
| 5061 } | 5062 } |
| 5062 return Api::UnwrapHandle(result); | 5063 return Api::UnwrapHandle(result); |
| 5063 } | 5064 } |
| 5064 | 5065 |
| 5065 | 5066 |
| 5066 void Parser::ParseLibraryName() { | 5067 void Parser::ParseLibraryName() { |
| 5067 ASSERT(CurrentToken() == Token::kLIBRARY); | 5068 ASSERT(CurrentToken() == Token::kLIBRARY); |
| 5068 ConsumeToken(); | 5069 ConsumeToken(); |
| 5069 String& lib_name = *ExpectIdentifier("library name expected"); | 5070 String& lib_name = *ExpectIdentifier("library name expected"); |
| 5070 if (CurrentToken() == Token::kPERIOD) { | 5071 if (CurrentToken() == Token::kPERIOD) { |
| 5071 while (CurrentToken() == Token::kPERIOD) { | 5072 while (CurrentToken() == Token::kPERIOD) { |
| 5072 ConsumeToken(); | 5073 ConsumeToken(); |
| 5073 lib_name = String::Concat(lib_name, Symbols::Dot()); | 5074 lib_name = String::Concat(lib_name, Symbols::Dot()); |
| 5074 lib_name = String::Concat(lib_name, | 5075 lib_name = String::Concat(lib_name, |
| 5075 *ExpectIdentifier("malformed library name")); | 5076 *ExpectIdentifier("malformed library name")); |
| 5076 } | 5077 } |
| 5077 lib_name = Symbols::New(lib_name); | 5078 lib_name = Symbols::New(lib_name); |
| 5078 } | 5079 } |
| 5079 library_.SetName(lib_name); | 5080 library_.SetName(lib_name); |
| 5080 ExpectSemicolon(); | 5081 ExpectSemicolon(); |
| 5081 } | 5082 } |
| 5082 | 5083 |
| 5083 | 5084 |
| 5084 void Parser::ParseIdentList(GrowableObjectArray* names) { | 5085 void Parser::ParseIdentList(GrowableObjectArray* names) { |
| 5085 if (!IsIdentifier()) { | 5086 if (!IsIdentifier()) { |
| 5086 ErrorMsg("identifier expected"); | 5087 ReportError("identifier expected"); |
| 5087 } | 5088 } |
| 5088 while (IsIdentifier()) { | 5089 while (IsIdentifier()) { |
| 5089 names->Add(*CurrentLiteral()); | 5090 names->Add(*CurrentLiteral()); |
| 5090 ConsumeToken(); // Identifier. | 5091 ConsumeToken(); // Identifier. |
| 5091 if (CurrentToken() != Token::kCOMMA) { | 5092 if (CurrentToken() != Token::kCOMMA) { |
| 5092 return; | 5093 return; |
| 5093 } | 5094 } |
| 5094 ConsumeToken(); // Comma. | 5095 ConsumeToken(); // Comma. |
| 5095 } | 5096 } |
| 5096 } | 5097 } |
| 5097 | 5098 |
| 5098 | 5099 |
| 5099 void Parser::ParseLibraryImportExport(intptr_t metadata_pos) { | 5100 void Parser::ParseLibraryImportExport(intptr_t metadata_pos) { |
| 5100 bool is_import = (CurrentToken() == Token::kIMPORT); | 5101 bool is_import = (CurrentToken() == Token::kIMPORT); |
| 5101 bool is_export = (CurrentToken() == Token::kEXPORT); | 5102 bool is_export = (CurrentToken() == Token::kEXPORT); |
| 5102 ASSERT(is_import || is_export); | 5103 ASSERT(is_import || is_export); |
| 5103 const intptr_t import_pos = TokenPos(); | 5104 const intptr_t import_pos = TokenPos(); |
| 5104 ConsumeToken(); | 5105 ConsumeToken(); |
| 5105 CheckToken(Token::kSTRING, "library url expected"); | 5106 CheckToken(Token::kSTRING, "library url expected"); |
| 5106 AstNode* url_literal = ParseStringLiteral(false); | 5107 AstNode* url_literal = ParseStringLiteral(false); |
| 5107 ASSERT(url_literal->IsLiteralNode()); | 5108 ASSERT(url_literal->IsLiteralNode()); |
| 5108 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 5109 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
| 5109 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 5110 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
| 5110 if (url.Length() == 0) { | 5111 if (url.Length() == 0) { |
| 5111 ErrorMsg("library url expected"); | 5112 ReportError("library url expected"); |
| 5112 } | 5113 } |
| 5113 bool is_deferred_import = false; | 5114 bool is_deferred_import = false; |
| 5114 if (is_import && (IsLiteral("deferred"))) { | 5115 if (is_import && (IsLiteral("deferred"))) { |
| 5115 is_deferred_import = true; | 5116 is_deferred_import = true; |
| 5116 ConsumeToken(); | 5117 ConsumeToken(); |
| 5117 CheckToken(Token::kAS, "'as' expected"); | 5118 CheckToken(Token::kAS, "'as' expected"); |
| 5118 } | 5119 } |
| 5119 String& prefix = String::Handle(I); | 5120 String& prefix = String::Handle(I); |
| 5120 intptr_t prefix_pos = 0; | 5121 intptr_t prefix_pos = 0; |
| 5121 if (is_import && (CurrentToken() == Token::kAS)) { | 5122 if (is_import && (CurrentToken() == Token::kAS)) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5180 if (metadata_pos >= 0) { | 5181 if (metadata_pos >= 0) { |
| 5181 ns.AddMetadata(metadata_pos, current_class()); | 5182 ns.AddMetadata(metadata_pos, current_class()); |
| 5182 } | 5183 } |
| 5183 | 5184 |
| 5184 if (is_import) { | 5185 if (is_import) { |
| 5185 // Ensure that private dart:_ libraries are only imported into dart: | 5186 // Ensure that private dart:_ libraries are only imported into dart: |
| 5186 // libraries. | 5187 // libraries. |
| 5187 const String& lib_url = String::Handle(I, library_.url()); | 5188 const String& lib_url = String::Handle(I, library_.url()); |
| 5188 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 5189 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
| 5189 !lib_url.StartsWith(Symbols::DartScheme())) { | 5190 !lib_url.StartsWith(Symbols::DartScheme())) { |
| 5190 ErrorMsg(import_pos, "private library is not accessible"); | 5191 ReportError(import_pos, "private library is not accessible"); |
| 5191 } | 5192 } |
| 5192 if (prefix.IsNull() || (prefix.Length() == 0)) { | 5193 if (prefix.IsNull() || (prefix.Length() == 0)) { |
| 5193 ASSERT(!is_deferred_import); | 5194 ASSERT(!is_deferred_import); |
| 5194 library_.AddImport(ns); | 5195 library_.AddImport(ns); |
| 5195 } else { | 5196 } else { |
| 5196 LibraryPrefix& library_prefix = LibraryPrefix::Handle(I); | 5197 LibraryPrefix& library_prefix = LibraryPrefix::Handle(I); |
| 5197 library_prefix = library_.LookupLocalLibraryPrefix(prefix); | 5198 library_prefix = library_.LookupLocalLibraryPrefix(prefix); |
| 5198 if (!library_prefix.IsNull()) { | 5199 if (!library_prefix.IsNull()) { |
| 5199 // Check that prefix names of deferred import clauses are | 5200 // Check that prefix names of deferred import clauses are |
| 5200 // unique. | 5201 // unique. |
| 5201 if (!is_deferred_import && library_prefix.is_deferred_load()) { | 5202 if (!is_deferred_import && library_prefix.is_deferred_load()) { |
| 5202 ErrorMsg(prefix_pos, | 5203 ReportError(prefix_pos, |
| 5203 "prefix '%s' already used in a deferred import clause", | 5204 "prefix '%s' already used in a deferred import clause", |
| 5204 prefix.ToCString()); | 5205 prefix.ToCString()); |
| 5205 } | 5206 } |
| 5206 if (is_deferred_import) { | 5207 if (is_deferred_import) { |
| 5207 ErrorMsg(prefix_pos, "prefix of deferred import must be uniqe"); | 5208 ReportError(prefix_pos, "prefix of deferred import must be uniqe"); |
| 5208 } | 5209 } |
| 5209 library_prefix.AddImport(ns); | 5210 library_prefix.AddImport(ns); |
| 5210 } else { | 5211 } else { |
| 5211 library_prefix = | 5212 library_prefix = |
| 5212 LibraryPrefix::New(prefix, ns, is_deferred_import, library_); | 5213 LibraryPrefix::New(prefix, ns, is_deferred_import, library_); |
| 5213 library_.AddObject(library_prefix, prefix); | 5214 library_.AddObject(library_prefix, prefix); |
| 5214 } | 5215 } |
| 5215 } | 5216 } |
| 5216 } else { | 5217 } else { |
| 5217 ASSERT(is_export); | 5218 ASSERT(is_export); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 5247 ASSERT(script_.kind() != RawScript::kSourceTag); | 5248 ASSERT(script_.kind() != RawScript::kSourceTag); |
| 5248 | 5249 |
| 5249 // We may read metadata tokens that are part of the toplevel | 5250 // We may read metadata tokens that are part of the toplevel |
| 5250 // declaration that follows the library definitions. Therefore, we | 5251 // declaration that follows the library definitions. Therefore, we |
| 5251 // need to remember the position of the last token that was | 5252 // need to remember the position of the last token that was |
| 5252 // successfully consumed. | 5253 // successfully consumed. |
| 5253 intptr_t rewind_pos = TokenPos(); | 5254 intptr_t rewind_pos = TokenPos(); |
| 5254 intptr_t metadata_pos = SkipMetadata(); | 5255 intptr_t metadata_pos = SkipMetadata(); |
| 5255 if (CurrentToken() == Token::kLIBRARY) { | 5256 if (CurrentToken() == Token::kLIBRARY) { |
| 5256 if (is_patch_source()) { | 5257 if (is_patch_source()) { |
| 5257 ErrorMsg("patch cannot override library name"); | 5258 ReportError("patch cannot override library name"); |
| 5258 } | 5259 } |
| 5259 ParseLibraryName(); | 5260 ParseLibraryName(); |
| 5260 if (metadata_pos >= 0) { | 5261 if (metadata_pos >= 0) { |
| 5261 library_.AddLibraryMetadata(current_class(), metadata_pos); | 5262 library_.AddLibraryMetadata(current_class(), metadata_pos); |
| 5262 } | 5263 } |
| 5263 rewind_pos = TokenPos(); | 5264 rewind_pos = TokenPos(); |
| 5264 metadata_pos = SkipMetadata(); | 5265 metadata_pos = SkipMetadata(); |
| 5265 } | 5266 } |
| 5266 while ((CurrentToken() == Token::kIMPORT) || | 5267 while ((CurrentToken() == Token::kIMPORT) || |
| 5267 (CurrentToken() == Token::kEXPORT)) { | 5268 (CurrentToken() == Token::kEXPORT)) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5285 } | 5286 } |
| 5286 SetPosition(rewind_pos); | 5287 SetPosition(rewind_pos); |
| 5287 } | 5288 } |
| 5288 | 5289 |
| 5289 | 5290 |
| 5290 void Parser::ParsePartHeader() { | 5291 void Parser::ParsePartHeader() { |
| 5291 SkipMetadata(); | 5292 SkipMetadata(); |
| 5292 CheckToken(Token::kPART, "'part of' expected"); | 5293 CheckToken(Token::kPART, "'part of' expected"); |
| 5293 ConsumeToken(); | 5294 ConsumeToken(); |
| 5294 if (!IsLiteral("of")) { | 5295 if (!IsLiteral("of")) { |
| 5295 ErrorMsg("'part of' expected"); | 5296 ReportError("'part of' expected"); |
| 5296 } | 5297 } |
| 5297 ConsumeToken(); | 5298 ConsumeToken(); |
| 5298 // The VM is not required to check that the library name matches the | 5299 // The VM is not required to check that the library name matches the |
| 5299 // name of the current library, so we ignore it. | 5300 // name of the current library, so we ignore it. |
| 5300 ExpectIdentifier("library name expected"); | 5301 ExpectIdentifier("library name expected"); |
| 5301 while (CurrentToken() == Token::kPERIOD) { | 5302 while (CurrentToken() == Token::kPERIOD) { |
| 5302 ConsumeToken(); | 5303 ConsumeToken(); |
| 5303 ExpectIdentifier("malformed library name"); | 5304 ExpectIdentifier("malformed library name"); |
| 5304 } | 5305 } |
| 5305 ExpectSemicolon(); | 5306 ExpectSemicolon(); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5459 // with the formal parameter types and names. | 5460 // with the formal parameter types and names. |
| 5460 void Parser::AddFormalParamsToFunction(const ParamList* params, | 5461 void Parser::AddFormalParamsToFunction(const ParamList* params, |
| 5461 const Function& func) { | 5462 const Function& func) { |
| 5462 ASSERT((params != NULL) && (params->parameters != NULL)); | 5463 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 5463 ASSERT((params->num_optional_parameters > 0) == | 5464 ASSERT((params->num_optional_parameters > 0) == |
| 5464 (params->has_optional_positional_parameters || | 5465 (params->has_optional_positional_parameters || |
| 5465 params->has_optional_named_parameters)); | 5466 params->has_optional_named_parameters)); |
| 5466 if (!Utils::IsInt(16, params->num_fixed_parameters) || | 5467 if (!Utils::IsInt(16, params->num_fixed_parameters) || |
| 5467 !Utils::IsInt(16, params->num_optional_parameters)) { | 5468 !Utils::IsInt(16, params->num_optional_parameters)) { |
| 5468 const Script& script = Script::Handle(Class::Handle(func.Owner()).script()); | 5469 const Script& script = Script::Handle(Class::Handle(func.Owner()).script()); |
| 5469 const Error& error = Error::Handle(LanguageError::NewFormatted( | 5470 Report::MessageF(Report::kError, script, func.token_pos(), |
| 5470 Error::Handle(), script, func.token_pos(), | 5471 "too many formal parameters"); |
| 5471 LanguageError::kError, Heap::kNew, | |
| 5472 "too many formal parameters")); | |
| 5473 ErrorMsg(error); | |
| 5474 } | 5472 } |
| 5475 func.set_num_fixed_parameters(params->num_fixed_parameters); | 5473 func.set_num_fixed_parameters(params->num_fixed_parameters); |
| 5476 func.SetNumOptionalParameters(params->num_optional_parameters, | 5474 func.SetNumOptionalParameters(params->num_optional_parameters, |
| 5477 params->has_optional_positional_parameters); | 5475 params->has_optional_positional_parameters); |
| 5478 const int num_parameters = params->parameters->length(); | 5476 const int num_parameters = params->parameters->length(); |
| 5479 ASSERT(num_parameters == func.NumParameters()); | 5477 ASSERT(num_parameters == func.NumParameters()); |
| 5480 func.set_parameter_types(Array::Handle(Array::New(num_parameters, | 5478 func.set_parameter_types(Array::Handle(Array::New(num_parameters, |
| 5481 Heap::kOld))); | 5479 Heap::kOld))); |
| 5482 func.set_parameter_names(Array::Handle(Array::New(num_parameters, | 5480 func.set_parameter_names(Array::Handle(Array::New(num_parameters, |
| 5483 Heap::kOld))); | 5481 Heap::kOld))); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5495 ASSERT((params != NULL) && (params->parameters != NULL)); | 5493 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 5496 ASSERT(scope != NULL); | 5494 ASSERT(scope != NULL); |
| 5497 const int num_parameters = params->parameters->length(); | 5495 const int num_parameters = params->parameters->length(); |
| 5498 for (int i = 0; i < num_parameters; i++) { | 5496 for (int i = 0; i < num_parameters; i++) { |
| 5499 ParamDesc& param_desc = (*params->parameters)[i]; | 5497 ParamDesc& param_desc = (*params->parameters)[i]; |
| 5500 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); | 5498 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); |
| 5501 const String* name = param_desc.name; | 5499 const String* name = param_desc.name; |
| 5502 LocalVariable* parameter = new(I) LocalVariable( | 5500 LocalVariable* parameter = new(I) LocalVariable( |
| 5503 param_desc.name_pos, *name, *param_desc.type); | 5501 param_desc.name_pos, *name, *param_desc.type); |
| 5504 if (!scope->InsertParameterAt(i, parameter)) { | 5502 if (!scope->InsertParameterAt(i, parameter)) { |
| 5505 ErrorMsg(param_desc.name_pos, | 5503 ReportError(param_desc.name_pos, |
| 5506 "name '%s' already exists in scope", | 5504 "name '%s' already exists in scope", |
| 5507 param_desc.name->ToCString()); | 5505 param_desc.name->ToCString()); |
| 5508 } | 5506 } |
| 5509 param_desc.var = parameter; | 5507 param_desc.var = parameter; |
| 5510 if (param_desc.is_final) { | 5508 if (param_desc.is_final) { |
| 5511 parameter->set_is_final(); | 5509 parameter->set_is_final(); |
| 5512 } | 5510 } |
| 5513 if (param_desc.is_field_initializer) { | 5511 if (param_desc.is_field_initializer) { |
| 5514 parameter->set_invisible(true); | 5512 parameter->set_invisible(true); |
| 5515 } | 5513 } |
| 5516 } | 5514 } |
| 5517 } | 5515 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5529 // Parse the function name out. | 5527 // Parse the function name out. |
| 5530 const intptr_t native_pos = TokenPos(); | 5528 const intptr_t native_pos = TokenPos(); |
| 5531 const String& native_name = ParseNativeDeclaration(); | 5529 const String& native_name = ParseNativeDeclaration(); |
| 5532 | 5530 |
| 5533 // Now resolve the native function to the corresponding native entrypoint. | 5531 // Now resolve the native function to the corresponding native entrypoint. |
| 5534 const int num_params = NativeArguments::ParameterCountForResolution(func); | 5532 const int num_params = NativeArguments::ParameterCountForResolution(func); |
| 5535 bool auto_setup_scope = true; | 5533 bool auto_setup_scope = true; |
| 5536 NativeFunction native_function = NativeEntry::ResolveNative( | 5534 NativeFunction native_function = NativeEntry::ResolveNative( |
| 5537 library, native_name, num_params, &auto_setup_scope); | 5535 library, native_name, num_params, &auto_setup_scope); |
| 5538 if (native_function == NULL) { | 5536 if (native_function == NULL) { |
| 5539 ErrorMsg(native_pos, | 5537 ReportError(native_pos, |
| 5540 "native function '%s' (%" Pd " arguments) cannot be found", | 5538 "native function '%s' (%" Pd " arguments) cannot be found", |
| 5541 native_name.ToCString(), func.NumParameters()); | 5539 native_name.ToCString(), func.NumParameters()); |
| 5542 } | 5540 } |
| 5543 func.SetIsNativeAutoSetupScope(auto_setup_scope); | 5541 func.SetIsNativeAutoSetupScope(auto_setup_scope); |
| 5544 | 5542 |
| 5545 // Now add the NativeBodyNode and return statement. | 5543 // Now add the NativeBodyNode and return statement. |
| 5546 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); | 5544 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); |
| 5547 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); | 5545 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); |
| 5548 current_block_->statements->Add(new(I) ReturnNode( | 5546 current_block_->statements->Add(new(I) ReturnNode( |
| 5549 TokenPos(), new(I) NativeBodyNode( | 5547 TokenPos(), new(I) NativeBodyNode( |
| 5550 TokenPos(), | 5548 TokenPos(), |
| 5551 Function::ZoneHandle(I, func.raw()), | 5549 Function::ZoneHandle(I, func.raw()), |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5589 ASSERT(found); | 5587 ASSERT(found); |
| 5590 } | 5588 } |
| 5591 | 5589 |
| 5592 | 5590 |
| 5593 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 5591 AstNode* Parser::LoadReceiver(intptr_t token_pos) { |
| 5594 // A nested function may access 'this', referring to the receiver of the | 5592 // A nested function may access 'this', referring to the receiver of the |
| 5595 // outermost enclosing function. | 5593 // outermost enclosing function. |
| 5596 const bool kTestOnly = false; | 5594 const bool kTestOnly = false; |
| 5597 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 5595 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 5598 if (receiver == NULL) { | 5596 if (receiver == NULL) { |
| 5599 ErrorMsg(token_pos, "illegal implicit access to receiver 'this'"); | 5597 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
| 5600 } | 5598 } |
| 5601 return new(I) LoadLocalNode(TokenPos(), receiver); | 5599 return new(I) LoadLocalNode(TokenPos(), receiver); |
| 5602 } | 5600 } |
| 5603 | 5601 |
| 5604 | 5602 |
| 5605 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) { | 5603 AstNode* Parser::LoadTypeArgumentsParameter(intptr_t token_pos) { |
| 5606 // A nested function may access ':type_arguments' to use as instantiator, | 5604 // A nested function may access ':type_arguments' to use as instantiator, |
| 5607 // referring to the implicit first parameter of the outermost enclosing | 5605 // referring to the implicit first parameter of the outermost enclosing |
| 5608 // factory function. | 5606 // factory function. |
| 5609 const bool kTestOnly = false; | 5607 const bool kTestOnly = false; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 5638 const intptr_t assign_pos = TokenPos(); | 5636 const intptr_t assign_pos = TokenPos(); |
| 5639 ConsumeToken(); | 5637 ConsumeToken(); |
| 5640 AstNode* expr = ParseExpr(is_const, kConsumeCascades); | 5638 AstNode* expr = ParseExpr(is_const, kConsumeCascades); |
| 5641 initialization = new(I) StoreLocalNode( | 5639 initialization = new(I) StoreLocalNode( |
| 5642 assign_pos, variable, expr); | 5640 assign_pos, variable, expr); |
| 5643 if (is_const) { | 5641 if (is_const) { |
| 5644 ASSERT(expr->IsLiteralNode()); | 5642 ASSERT(expr->IsLiteralNode()); |
| 5645 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 5643 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 5646 } | 5644 } |
| 5647 } else if (is_final || is_const) { | 5645 } else if (is_final || is_const) { |
| 5648 ErrorMsg(ident_pos, | 5646 ReportError(ident_pos, |
| 5649 "missing initialization of 'final' or 'const' variable"); | 5647 "missing initialization of 'final' or 'const' variable"); |
| 5650 } else { | 5648 } else { |
| 5651 // Initialize variable with null. | 5649 // Initialize variable with null. |
| 5652 AstNode* null_expr = new(I) LiteralNode( | 5650 AstNode* null_expr = new(I) LiteralNode( |
| 5653 ident_pos, Instance::ZoneHandle(I)); | 5651 ident_pos, Instance::ZoneHandle(I)); |
| 5654 initialization = new(I) StoreLocalNode( | 5652 initialization = new(I) StoreLocalNode( |
| 5655 ident_pos, variable, null_expr); | 5653 ident_pos, variable, null_expr); |
| 5656 } | 5654 } |
| 5657 | 5655 |
| 5658 ASSERT(current_block_ != NULL); | 5656 ASSERT(current_block_ != NULL); |
| 5659 const intptr_t previous_pos = | 5657 const intptr_t previous_pos = |
| 5660 current_block_->scope->PreviousReferencePos(ident); | 5658 current_block_->scope->PreviousReferencePos(ident); |
| 5661 if (previous_pos >= 0) { | 5659 if (previous_pos >= 0) { |
| 5662 ASSERT(!script_.IsNull()); | 5660 ASSERT(!script_.IsNull()); |
| 5663 if (previous_pos > ident_pos) { | 5661 if (previous_pos > ident_pos) { |
| 5664 ErrorMsg(ident_pos, | 5662 ReportError(ident_pos, |
| 5665 "initializer of '%s' may not refer to itself", | 5663 "initializer of '%s' may not refer to itself", |
| 5666 ident.ToCString()); | 5664 ident.ToCString()); |
| 5667 | 5665 |
| 5668 } else { | 5666 } else { |
| 5669 intptr_t line_number; | 5667 intptr_t line_number; |
| 5670 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 5668 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| 5671 ErrorMsg(ident_pos, | 5669 ReportError(ident_pos, |
| 5672 "identifier '%s' previously used in line %" Pd "", | 5670 "identifier '%s' previously used in line %" Pd "", |
| 5673 ident.ToCString(), | 5671 ident.ToCString(), |
| 5674 line_number); | 5672 line_number); |
| 5675 } | 5673 } |
| 5676 } | 5674 } |
| 5677 | 5675 |
| 5678 // Add variable to scope after parsing the initalizer expression. | 5676 // Add variable to scope after parsing the initalizer expression. |
| 5679 // The expression must not be able to refer to the variable. | 5677 // The expression must not be able to refer to the variable. |
| 5680 if (!current_block_->scope->AddVariable(variable)) { | 5678 if (!current_block_->scope->AddVariable(variable)) { |
| 5681 LocalVariable* existing_var = | 5679 LocalVariable* existing_var = |
| 5682 current_block_->scope->LookupVariable(variable->name(), true); | 5680 current_block_->scope->LookupVariable(variable->name(), true); |
| 5683 ASSERT(existing_var != NULL); | 5681 ASSERT(existing_var != NULL); |
| 5684 if (existing_var->owner() == current_block_->scope) { | 5682 if (existing_var->owner() == current_block_->scope) { |
| 5685 ErrorMsg(ident_pos, "identifier '%s' already defined", | 5683 ReportError(ident_pos, "identifier '%s' already defined", |
| 5686 variable->name().ToCString()); | 5684 variable->name().ToCString()); |
| 5687 } else { | 5685 } else { |
| 5688 ErrorMsg(ident_pos, | 5686 ReportError(ident_pos, "'%s' from outer scope has already been used, " |
| 5689 "'%s' from outer scope has already been used, cannot redefine", | 5687 "cannot redefine", |
| 5690 variable->name().ToCString()); | 5688 variable->name().ToCString()); |
| 5691 } | 5689 } |
| 5692 } | 5690 } |
| 5693 if (is_final || is_const) { | 5691 if (is_final || is_const) { |
| 5694 variable->set_is_final(); | 5692 variable->set_is_final(); |
| 5695 } | 5693 } |
| 5696 return initialization; | 5694 return initialization; |
| 5697 } | 5695 } |
| 5698 | 5696 |
| 5699 | 5697 |
| 5700 // Parses ('var' | 'final' [type] | 'const' [type] | type). | 5698 // Parses ('var' | 'final' [type] | 'const' [type] | type). |
| 5701 // The presence of 'final' or 'const' must be detected and remembered | 5699 // The presence of 'final' or 'const' must be detected and remembered |
| 5702 // before the call. If a type is parsed, it may be resolved and finalized | 5700 // before the call. If a type is parsed, it may be resolved and finalized |
| 5703 // according to the given type finalization mode. | 5701 // according to the given type finalization mode. |
| 5704 RawAbstractType* Parser::ParseConstFinalVarOrType( | 5702 RawAbstractType* Parser::ParseConstFinalVarOrType( |
| 5705 ClassFinalizer::FinalizationKind finalization) { | 5703 ClassFinalizer::FinalizationKind finalization) { |
| 5706 TRACE_PARSER("ParseConstFinalVarOrType"); | 5704 TRACE_PARSER("ParseConstFinalVarOrType"); |
| 5707 if (CurrentToken() == Token::kVAR) { | 5705 if (CurrentToken() == Token::kVAR) { |
| 5708 ConsumeToken(); | 5706 ConsumeToken(); |
| 5709 return Type::DynamicType(); | 5707 return Type::DynamicType(); |
| 5710 } | 5708 } |
| 5711 bool type_is_optional = false; | 5709 bool type_is_optional = false; |
| 5712 if ((CurrentToken() == Token::kFINAL) || (CurrentToken() == Token::kCONST)) { | 5710 if ((CurrentToken() == Token::kFINAL) || (CurrentToken() == Token::kCONST)) { |
| 5713 ConsumeToken(); | 5711 ConsumeToken(); |
| 5714 type_is_optional = true; | 5712 type_is_optional = true; |
| 5715 } | 5713 } |
| 5716 if (CurrentToken() != Token::kIDENT) { | 5714 if (CurrentToken() != Token::kIDENT) { |
| 5717 if (type_is_optional) { | 5715 if (type_is_optional) { |
| 5718 return Type::DynamicType(); | 5716 return Type::DynamicType(); |
| 5719 } else { | 5717 } else { |
| 5720 ErrorMsg("type name expected"); | 5718 ReportError("type name expected"); |
| 5721 } | 5719 } |
| 5722 } | 5720 } |
| 5723 if (type_is_optional) { | 5721 if (type_is_optional) { |
| 5724 Token::Kind follower = LookaheadToken(1); | 5722 Token::Kind follower = LookaheadToken(1); |
| 5725 // We have an identifier followed by a 'follower' token. | 5723 // We have an identifier followed by a 'follower' token. |
| 5726 // We either parse a type or return now. | 5724 // We either parse a type or return now. |
| 5727 if ((follower != Token::kLT) && // Parameterized type. | 5725 if ((follower != Token::kLT) && // Parameterized type. |
| 5728 (follower != Token::kPERIOD) && // Qualified class name of type. | 5726 (follower != Token::kPERIOD) && // Qualified class name of type. |
| 5729 !Token::IsIdentifier(follower) && // Variable name following a type. | 5727 !Token::IsIdentifier(follower) && // Variable name following a type. |
| 5730 (follower != Token::kTHIS)) { // Field parameter following a type. | 5728 (follower != Token::kTHIS)) { // Field parameter following a type. |
| 5731 return Type::DynamicType(); | 5729 return Type::DynamicType(); |
| 5732 } | 5730 } |
| 5733 } | 5731 } |
| 5734 return ParseType(finalization); | 5732 return ParseType(finalization); |
| 5735 } | 5733 } |
| 5736 | 5734 |
| 5737 | 5735 |
| 5738 // Returns ast nodes of the variable initialization. Variables without an | 5736 // Returns ast nodes of the variable initialization. Variables without an |
| 5739 // explicit initializer are initialized to null. If several variables are | 5737 // explicit initializer are initialized to null. If several variables are |
| 5740 // declared, the individual initializers are collected in a sequence node. | 5738 // declared, the individual initializers are collected in a sequence node. |
| 5741 AstNode* Parser::ParseVariableDeclarationList() { | 5739 AstNode* Parser::ParseVariableDeclarationList() { |
| 5742 TRACE_PARSER("ParseVariableDeclarationList"); | 5740 TRACE_PARSER("ParseVariableDeclarationList"); |
| 5743 SkipMetadata(); | 5741 SkipMetadata(); |
| 5744 bool is_final = (CurrentToken() == Token::kFINAL); | 5742 bool is_final = (CurrentToken() == Token::kFINAL); |
| 5745 bool is_const = (CurrentToken() == Token::kCONST); | 5743 bool is_const = (CurrentToken() == Token::kCONST); |
| 5746 const AbstractType& type = AbstractType::ZoneHandle(I, | 5744 const AbstractType& type = AbstractType::ZoneHandle(I, |
| 5747 ParseConstFinalVarOrType(FLAG_enable_type_checks ? | 5745 ParseConstFinalVarOrType(FLAG_enable_type_checks ? |
| 5748 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); | 5746 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); |
| 5749 if (!IsIdentifier()) { | 5747 if (!IsIdentifier()) { |
| 5750 ErrorMsg("identifier expected"); | 5748 ReportError("identifier expected"); |
| 5751 } | 5749 } |
| 5752 | 5750 |
| 5753 AstNode* initializers = ParseVariableDeclaration(type, is_final, is_const); | 5751 AstNode* initializers = ParseVariableDeclaration(type, is_final, is_const); |
| 5754 ASSERT(initializers != NULL); | 5752 ASSERT(initializers != NULL); |
| 5755 while (CurrentToken() == Token::kCOMMA) { | 5753 while (CurrentToken() == Token::kCOMMA) { |
| 5756 ConsumeToken(); | 5754 ConsumeToken(); |
| 5757 if (!IsIdentifier()) { | 5755 if (!IsIdentifier()) { |
| 5758 ErrorMsg("identifier expected after comma"); | 5756 ReportError("identifier expected after comma"); |
| 5759 } | 5757 } |
| 5760 // We have a second initializer. Allocate a sequence node now. | 5758 // We have a second initializer. Allocate a sequence node now. |
| 5761 // The sequence does not own the current scope. Set its own scope to NULL. | 5759 // The sequence does not own the current scope. Set its own scope to NULL. |
| 5762 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), | 5760 SequenceNode* sequence = NodeAsSequenceNode(initializers->token_pos(), |
| 5763 initializers, | 5761 initializers, |
| 5764 NULL); | 5762 NULL); |
| 5765 sequence->Add(ParseVariableDeclaration(type, is_final, is_const)); | 5763 sequence->Add(ParseVariableDeclaration(type, is_final, is_const)); |
| 5766 initializers = sequence; | 5764 initializers = sequence; |
| 5767 } | 5765 } |
| 5768 return initializers; | 5766 return initializers; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5795 | 5793 |
| 5796 // Check that the function name has not been referenced | 5794 // Check that the function name has not been referenced |
| 5797 // before this declaration. | 5795 // before this declaration. |
| 5798 ASSERT(current_block_ != NULL); | 5796 ASSERT(current_block_ != NULL); |
| 5799 const intptr_t previous_pos = | 5797 const intptr_t previous_pos = |
| 5800 current_block_->scope->PreviousReferencePos(*function_name); | 5798 current_block_->scope->PreviousReferencePos(*function_name); |
| 5801 if (previous_pos >= 0) { | 5799 if (previous_pos >= 0) { |
| 5802 ASSERT(!script_.IsNull()); | 5800 ASSERT(!script_.IsNull()); |
| 5803 intptr_t line_number; | 5801 intptr_t line_number; |
| 5804 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 5802 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| 5805 ErrorMsg(name_pos, | 5803 ReportError(name_pos, |
| 5806 "identifier '%s' previously used in line %" Pd "", | 5804 "identifier '%s' previously used in line %" Pd "", |
| 5807 function_name->ToCString(), | 5805 function_name->ToCString(), |
| 5808 line_number); | 5806 line_number); |
| 5809 } | 5807 } |
| 5810 } | 5808 } |
| 5811 CheckToken(Token::kLPAREN); | 5809 CheckToken(Token::kLPAREN); |
| 5812 | 5810 |
| 5813 // Check whether we have parsed this closure function before, in a previous | 5811 // Check whether we have parsed this closure function before, in a previous |
| 5814 // compilation. If so, reuse the function object, else create a new one | 5812 // compilation. If so, reuse the function object, else create a new one |
| 5815 // and register it in the current class. | 5813 // and register it in the current class. |
| 5816 // Note that we cannot share the same closure function between the closurized | 5814 // Note that we cannot share the same closure function between the closurized |
| 5817 // and non-closurized versions of the same parent function. | 5815 // and non-closurized versions of the same parent function. |
| 5818 Function& function = Function::ZoneHandle(I); | 5816 Function& function = Function::ZoneHandle(I); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5858 function_type); | 5856 function_type); |
| 5859 function_variable->set_is_final(); | 5857 function_variable->set_is_final(); |
| 5860 ASSERT(current_block_ != NULL); | 5858 ASSERT(current_block_ != NULL); |
| 5861 ASSERT(current_block_->scope != NULL); | 5859 ASSERT(current_block_->scope != NULL); |
| 5862 if (!current_block_->scope->AddVariable(function_variable)) { | 5860 if (!current_block_->scope->AddVariable(function_variable)) { |
| 5863 LocalVariable* existing_var = | 5861 LocalVariable* existing_var = |
| 5864 current_block_->scope->LookupVariable(function_variable->name(), | 5862 current_block_->scope->LookupVariable(function_variable->name(), |
| 5865 true); | 5863 true); |
| 5866 ASSERT(existing_var != NULL); | 5864 ASSERT(existing_var != NULL); |
| 5867 if (existing_var->owner() == current_block_->scope) { | 5865 if (existing_var->owner() == current_block_->scope) { |
| 5868 ErrorMsg(function_pos, "identifier '%s' already defined", | 5866 ReportError(function_pos, "identifier '%s' already defined", |
| 5869 function_variable->name().ToCString()); | 5867 function_variable->name().ToCString()); |
| 5870 } else { | 5868 } else { |
| 5871 ErrorMsg(function_pos, | 5869 ReportError(function_pos, |
| 5872 "'%s' from outer scope has already been used, cannot redefine", | 5870 "'%s' from outer scope has already been used, " |
| 5873 function_variable->name().ToCString()); | 5871 "cannot redefine", |
| 5872 function_variable->name().ToCString()); |
| 5874 } | 5873 } |
| 5875 } | 5874 } |
| 5876 } | 5875 } |
| 5877 | 5876 |
| 5878 // Parse the local function. | 5877 // Parse the local function. |
| 5879 Array& default_parameter_values = Array::Handle(I); | 5878 Array& default_parameter_values = Array::Handle(I); |
| 5880 SequenceNode* statements = Parser::ParseFunc(function, | 5879 SequenceNode* statements = Parser::ParseFunc(function, |
| 5881 &default_parameter_values); | 5880 &default_parameter_values); |
| 5882 | 5881 |
| 5883 // Now that the local function has formal parameters, lookup the signature | 5882 // Now that the local function has formal parameters, lookup the signature |
| (...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6304 while (CurrentToken() != Token::kRBRACE) { | 6303 while (CurrentToken() != Token::kRBRACE) { |
| 6305 const intptr_t statement_pos = TokenPos(); | 6304 const intptr_t statement_pos = TokenPos(); |
| 6306 AstNode* statement = ParseStatement(); | 6305 AstNode* statement = ParseStatement(); |
| 6307 // Do not add statements with no effect (e.g., LoadLocalNode). | 6306 // Do not add statements with no effect (e.g., LoadLocalNode). |
| 6308 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 6307 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
| 6309 // Skip load local. | 6308 // Skip load local. |
| 6310 continue; | 6309 continue; |
| 6311 } | 6310 } |
| 6312 if (statement != NULL) { | 6311 if (statement != NULL) { |
| 6313 if (!dead_code_allowed && abrupt_completing_seen) { | 6312 if (!dead_code_allowed && abrupt_completing_seen) { |
| 6314 ErrorMsg(statement_pos, "dead code after abrupt completing statement"); | 6313 ReportError(statement_pos, |
| 6314 "dead code after abrupt completing statement"); |
| 6315 } | 6315 } |
| 6316 current_block_->statements->Add(statement); | 6316 current_block_->statements->Add(statement); |
| 6317 abrupt_completing_seen |= IsAbruptCompleting(statement); | 6317 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 6318 } | 6318 } |
| 6319 } | 6319 } |
| 6320 } | 6320 } |
| 6321 | 6321 |
| 6322 | 6322 |
| 6323 // Parse nested statement of if, while, for, etc. We automatically generate | 6323 // Parse nested statement of if, while, for, etc. We automatically generate |
| 6324 // a sequence of one statement if there are no curly braces. | 6324 // a sequence of one statement if there are no curly braces. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6403 const intptr_t num_expressions = values.length(); | 6403 const intptr_t num_expressions = values.length(); |
| 6404 if (num_expressions == 0) { | 6404 if (num_expressions == 0) { |
| 6405 return Object::dynamic_class(); | 6405 return Object::dynamic_class(); |
| 6406 } | 6406 } |
| 6407 const Instance& first_value = values[0]->literal(); | 6407 const Instance& first_value = values[0]->literal(); |
| 6408 for (intptr_t i = 0; i < num_expressions; i++) { | 6408 for (intptr_t i = 0; i < num_expressions; i++) { |
| 6409 const Instance& val = values[i]->literal(); | 6409 const Instance& val = values[i]->literal(); |
| 6410 const intptr_t val_pos = values[i]->token_pos(); | 6410 const intptr_t val_pos = values[i]->token_pos(); |
| 6411 if (first_value.IsInteger()) { | 6411 if (first_value.IsInteger()) { |
| 6412 if (!val.IsInteger()) { | 6412 if (!val.IsInteger()) { |
| 6413 ErrorMsg(val_pos, "expected case expression of type int"); | 6413 ReportError(val_pos, "expected case expression of type int"); |
| 6414 } | 6414 } |
| 6415 continue; | 6415 continue; |
| 6416 } | 6416 } |
| 6417 if (first_value.IsString()) { | 6417 if (first_value.IsString()) { |
| 6418 if (!val.IsString()) { | 6418 if (!val.IsString()) { |
| 6419 ErrorMsg(val_pos, "expected case expression of type String"); | 6419 ReportError(val_pos, "expected case expression of type String"); |
| 6420 } | 6420 } |
| 6421 continue; | 6421 continue; |
| 6422 } | 6422 } |
| 6423 if (val.IsDouble()) { | 6423 if (val.IsDouble()) { |
| 6424 ErrorMsg(val_pos, "case expression may not be of type double"); | 6424 ReportError(val_pos, "case expression may not be of type double"); |
| 6425 } | 6425 } |
| 6426 if (val.clazz() != first_value.clazz()) { | 6426 if (val.clazz() != first_value.clazz()) { |
| 6427 ErrorMsg(val_pos, "all case expressions must be of same type"); | 6427 ReportError(val_pos, "all case expressions must be of same type"); |
| 6428 } | 6428 } |
| 6429 if (i == 0) { | 6429 if (i == 0) { |
| 6430 // The value is of some type other than int, String or double. | 6430 // The value is of some type other than int, String or double. |
| 6431 // Check that the type class does not override the == operator. | 6431 // Check that the type class does not override the == operator. |
| 6432 // Check this only in the first loop iteration since all values | 6432 // Check this only in the first loop iteration since all values |
| 6433 // are of the same type, which we check above. | 6433 // are of the same type, which we check above. |
| 6434 if (ImplementsEqualOperator(val)) { | 6434 if (ImplementsEqualOperator(val)) { |
| 6435 ErrorMsg(val_pos, | 6435 ReportError(val_pos, |
| 6436 "type class of case expression must not implement operator =="); | 6436 "type class of case expression must not " |
| 6437 "implement operator =="); |
| 6437 } | 6438 } |
| 6438 } | 6439 } |
| 6439 } | 6440 } |
| 6440 if (first_value.IsInteger()) { | 6441 if (first_value.IsInteger()) { |
| 6441 return Type::Handle(I, Type::IntType()).type_class(); | 6442 return Type::Handle(I, Type::IntType()).type_class(); |
| 6442 } else if (first_value.IsString()) { | 6443 } else if (first_value.IsString()) { |
| 6443 return Type::Handle(I, Type::StringType()).type_class(); | 6444 return Type::Handle(I, Type::StringType()).type_class(); |
| 6444 } | 6445 } |
| 6445 return first_value.clazz(); | 6446 return first_value.clazz(); |
| 6446 } | 6447 } |
| 6447 | 6448 |
| 6448 | 6449 |
| 6449 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 6450 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 6450 GrowableArray<LiteralNode*>* case_expr_values, | 6451 GrowableArray<LiteralNode*>* case_expr_values, |
| 6451 SourceLabel* case_label) { | 6452 SourceLabel* case_label) { |
| 6452 TRACE_PARSER("ParseCaseClause"); | 6453 TRACE_PARSER("ParseCaseClause"); |
| 6453 bool default_seen = false; | 6454 bool default_seen = false; |
| 6454 const intptr_t case_pos = TokenPos(); | 6455 const intptr_t case_pos = TokenPos(); |
| 6455 // The case expressions node sequence does not own the enclosing scope. | 6456 // The case expressions node sequence does not own the enclosing scope. |
| 6456 SequenceNode* case_expressions = new(I) SequenceNode(case_pos, NULL); | 6457 SequenceNode* case_expressions = new(I) SequenceNode(case_pos, NULL); |
| 6457 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 6458 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 6458 if (CurrentToken() == Token::kCASE) { | 6459 if (CurrentToken() == Token::kCASE) { |
| 6459 if (default_seen) { | 6460 if (default_seen) { |
| 6460 ErrorMsg("default clause must be last case"); | 6461 ReportError("default clause must be last case"); |
| 6461 } | 6462 } |
| 6462 ConsumeToken(); // Keyword case. | 6463 ConsumeToken(); // Keyword case. |
| 6463 const intptr_t expr_pos = TokenPos(); | 6464 const intptr_t expr_pos = TokenPos(); |
| 6464 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); | 6465 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
| 6465 ASSERT(expr->IsLiteralNode()); | 6466 ASSERT(expr->IsLiteralNode()); |
| 6466 case_expr_values->Add(expr->AsLiteralNode()); | 6467 case_expr_values->Add(expr->AsLiteralNode()); |
| 6467 | 6468 |
| 6468 AstNode* switch_expr_load = new(I) LoadLocalNode( | 6469 AstNode* switch_expr_load = new(I) LoadLocalNode( |
| 6469 case_pos, switch_expr_value); | 6470 case_pos, switch_expr_value); |
| 6470 AstNode* case_comparison = new(I) ComparisonNode( | 6471 AstNode* case_comparison = new(I) ComparisonNode( |
| 6471 expr_pos, Token::kEQ, expr, switch_expr_load); | 6472 expr_pos, Token::kEQ, expr, switch_expr_load); |
| 6472 case_expressions->Add(case_comparison); | 6473 case_expressions->Add(case_comparison); |
| 6473 } else { | 6474 } else { |
| 6474 if (default_seen) { | 6475 if (default_seen) { |
| 6475 ErrorMsg("only one default clause is allowed"); | 6476 ReportError("only one default clause is allowed"); |
| 6476 } | 6477 } |
| 6477 ConsumeToken(); // Keyword default. | 6478 ConsumeToken(); // Keyword default. |
| 6478 default_seen = true; | 6479 default_seen = true; |
| 6479 // The default case always succeeds. | 6480 // The default case always succeeds. |
| 6480 } | 6481 } |
| 6481 ExpectToken(Token::kCOLON); | 6482 ExpectToken(Token::kCOLON); |
| 6482 } | 6483 } |
| 6483 | 6484 |
| 6484 OpenBlock(); | 6485 OpenBlock(); |
| 6485 bool abrupt_completing_seen = false; | 6486 bool abrupt_completing_seen = false; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6572 if (case_label == NULL) { | 6573 if (case_label == NULL) { |
| 6573 // Label does not exist yet. Add it to scope of switch statement. | 6574 // Label does not exist yet. Add it to scope of switch statement. |
| 6574 case_label = new(I) SourceLabel( | 6575 case_label = new(I) SourceLabel( |
| 6575 label_pos, *label_name, SourceLabel::kCase); | 6576 label_pos, *label_name, SourceLabel::kCase); |
| 6576 current_block_->scope->AddLabel(case_label); | 6577 current_block_->scope->AddLabel(case_label); |
| 6577 } else if (case_label->kind() == SourceLabel::kForward) { | 6578 } else if (case_label->kind() == SourceLabel::kForward) { |
| 6578 // We have seen a 'continue' with this label name. Resolve | 6579 // We have seen a 'continue' with this label name. Resolve |
| 6579 // the forward reference. | 6580 // the forward reference. |
| 6580 case_label->ResolveForwardReference(); | 6581 case_label->ResolveForwardReference(); |
| 6581 } else { | 6582 } else { |
| 6582 ErrorMsg(label_pos, "label '%s' already exists in scope", | 6583 ReportError(label_pos, "label '%s' already exists in scope", |
| 6583 label_name->ToCString()); | 6584 label_name->ToCString()); |
| 6584 } | 6585 } |
| 6585 ASSERT(case_label->kind() == SourceLabel::kCase); | 6586 ASSERT(case_label->kind() == SourceLabel::kCase); |
| 6586 } | 6587 } |
| 6587 if (CurrentToken() == Token::kCASE || | 6588 if (CurrentToken() == Token::kCASE || |
| 6588 CurrentToken() == Token::kDEFAULT) { | 6589 CurrentToken() == Token::kDEFAULT) { |
| 6589 if (default_seen) { | 6590 if (default_seen) { |
| 6590 ErrorMsg("no case clauses allowed after default clause"); | 6591 ReportError("no case clauses allowed after default clause"); |
| 6591 } | 6592 } |
| 6592 CaseNode* case_clause = | 6593 CaseNode* case_clause = |
| 6593 ParseCaseClause(temp_variable, &case_expr_values, case_label); | 6594 ParseCaseClause(temp_variable, &case_expr_values, case_label); |
| 6594 default_seen = case_clause->contains_default(); | 6595 default_seen = case_clause->contains_default(); |
| 6595 current_block_->statements->Add(case_clause); | 6596 current_block_->statements->Add(case_clause); |
| 6596 } else if (CurrentToken() != Token::kRBRACE) { | 6597 } else if (CurrentToken() != Token::kRBRACE) { |
| 6597 ErrorMsg("'case' or '}' expected"); | 6598 ReportError("'case' or '}' expected"); |
| 6598 } else if (case_label != NULL) { | 6599 } else if (case_label != NULL) { |
| 6599 ErrorMsg("expecting at least one case clause after label"); | 6600 ReportError("expecting at least one case clause after label"); |
| 6600 } else { | 6601 } else { |
| 6601 break; | 6602 break; |
| 6602 } | 6603 } |
| 6603 } | 6604 } |
| 6604 | 6605 |
| 6605 // Check that all expressions in case clauses are of the same class, | 6606 // Check that all expressions in case clauses are of the same class, |
| 6606 // or implement int, double or String. Patch the type of the temporary | 6607 // or implement int, double or String. Patch the type of the temporary |
| 6607 // variable holding the switch expression to match the type of the | 6608 // variable holding the switch expression to match the type of the |
| 6608 // case clause constants. | 6609 // case clause constants. |
| 6609 temp_var_type.set_type_class( | 6610 temp_var_type.set_type_class( |
| 6610 Class::Handle(I, CheckCaseExpressions(case_expr_values))); | 6611 Class::Handle(I, CheckCaseExpressions(case_expr_values))); |
| 6611 | 6612 |
| 6612 // Check for unresolved label references. | 6613 // Check for unresolved label references. |
| 6613 SourceLabel* unresolved_label = | 6614 SourceLabel* unresolved_label = |
| 6614 current_block_->scope->CheckUnresolvedLabels(); | 6615 current_block_->scope->CheckUnresolvedLabels(); |
| 6615 if (unresolved_label != NULL) { | 6616 if (unresolved_label != NULL) { |
| 6616 ErrorMsg("unresolved reference to label '%s'", | 6617 ReportError("unresolved reference to label '%s'", |
| 6617 unresolved_label->name().ToCString()); | 6618 unresolved_label->name().ToCString()); |
| 6618 } | 6619 } |
| 6619 | 6620 |
| 6620 SequenceNode* switch_body = CloseBlock(); | 6621 SequenceNode* switch_body = CloseBlock(); |
| 6621 ExpectToken(Token::kRBRACE); | 6622 ExpectToken(Token::kRBRACE); |
| 6622 return new(I) SwitchNode(switch_pos, label, switch_body); | 6623 return new(I) SwitchNode(switch_pos, label, switch_body); |
| 6623 } | 6624 } |
| 6624 | 6625 |
| 6625 | 6626 |
| 6626 AstNode* Parser::ParseWhileStatement(String* label_name) { | 6627 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 6627 TRACE_PARSER("ParseWhileStatement"); | 6628 TRACE_PARSER("ParseWhileStatement"); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6653 ExpectSemicolon(); | 6654 ExpectSemicolon(); |
| 6654 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 6655 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 6655 } | 6656 } |
| 6656 | 6657 |
| 6657 | 6658 |
| 6658 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 6659 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 6659 SourceLabel* label) { | 6660 SourceLabel* label) { |
| 6660 TRACE_PARSER("ParseForInStatement"); | 6661 TRACE_PARSER("ParseForInStatement"); |
| 6661 bool is_final = (CurrentToken() == Token::kFINAL); | 6662 bool is_final = (CurrentToken() == Token::kFINAL); |
| 6662 if (CurrentToken() == Token::kCONST) { | 6663 if (CurrentToken() == Token::kCONST) { |
| 6663 ErrorMsg("Loop variable cannot be 'const'"); | 6664 ReportError("Loop variable cannot be 'const'"); |
| 6664 } | 6665 } |
| 6665 const String* loop_var_name = NULL; | 6666 const String* loop_var_name = NULL; |
| 6666 LocalVariable* loop_var = NULL; | 6667 LocalVariable* loop_var = NULL; |
| 6667 intptr_t loop_var_pos = 0; | 6668 intptr_t loop_var_pos = 0; |
| 6668 if (LookaheadToken(1) == Token::kIN) { | 6669 if (LookaheadToken(1) == Token::kIN) { |
| 6669 loop_var_pos = TokenPos(); | 6670 loop_var_pos = TokenPos(); |
| 6670 loop_var_name = ExpectIdentifier("variable name expected"); | 6671 loop_var_name = ExpectIdentifier("variable name expected"); |
| 6671 } else { | 6672 } else { |
| 6672 // The case without a type is handled above, so require a type here. | 6673 // The case without a type is handled above, so require a type here. |
| 6673 const AbstractType& type = | 6674 const AbstractType& type = |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6925 exception_param->var = var; | 6926 exception_param->var = var; |
| 6926 } | 6927 } |
| 6927 if (stack_trace_param->name != NULL) { | 6928 if (stack_trace_param->name != NULL) { |
| 6928 LocalVariable* var = new(I) LocalVariable( | 6929 LocalVariable* var = new(I) LocalVariable( |
| 6929 stack_trace_param->token_pos, | 6930 stack_trace_param->token_pos, |
| 6930 *stack_trace_param->name, | 6931 *stack_trace_param->name, |
| 6931 *stack_trace_param->type); | 6932 *stack_trace_param->type); |
| 6932 var->set_is_final(); | 6933 var->set_is_final(); |
| 6933 bool added_to_scope = scope->AddVariable(var); | 6934 bool added_to_scope = scope->AddVariable(var); |
| 6934 if (!added_to_scope) { | 6935 if (!added_to_scope) { |
| 6935 ErrorMsg(stack_trace_param->token_pos, | 6936 ReportError(stack_trace_param->token_pos, |
| 6936 "name '%s' already exists in scope", | 6937 "name '%s' already exists in scope", |
| 6937 stack_trace_param->name->ToCString()); | 6938 stack_trace_param->name->ToCString()); |
| 6938 } | 6939 } |
| 6939 stack_trace_param->var = var; | 6940 stack_trace_param->var = var; |
| 6940 } | 6941 } |
| 6941 } | 6942 } |
| 6942 | 6943 |
| 6943 | 6944 |
| 6944 SequenceNode* Parser::ParseFinallyBlock() { | 6945 SequenceNode* Parser::ParseFinallyBlock() { |
| 6945 TRACE_PARSER("ParseFinallyBlock"); | 6946 TRACE_PARSER("ParseFinallyBlock"); |
| 6946 OpenBlock(); | 6947 OpenBlock(); |
| 6947 ExpectToken(Token::kLBRACE); | 6948 ExpectToken(Token::kLBRACE); |
| 6948 ParseStatementSequence(); | 6949 ParseStatementSequence(); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7246 // Now parse the 'try' block. | 7247 // Now parse the 'try' block. |
| 7247 OpenBlock(); | 7248 OpenBlock(); |
| 7248 PushTryBlock(current_block_); | 7249 PushTryBlock(current_block_); |
| 7249 ExpectToken(Token::kLBRACE); | 7250 ExpectToken(Token::kLBRACE); |
| 7250 ParseStatementSequence(); | 7251 ParseStatementSequence(); |
| 7251 ExpectToken(Token::kRBRACE); | 7252 ExpectToken(Token::kRBRACE); |
| 7252 SequenceNode* try_block = CloseBlock(); | 7253 SequenceNode* try_block = CloseBlock(); |
| 7253 | 7254 |
| 7254 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && | 7255 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && |
| 7255 (CurrentToken() != Token::kFINALLY)) { | 7256 (CurrentToken() != Token::kFINALLY)) { |
| 7256 ErrorMsg("catch or finally clause expected"); | 7257 ReportError("catch or finally clause expected"); |
| 7257 } | 7258 } |
| 7258 | 7259 |
| 7259 // Now parse the 'catch' blocks if any. | 7260 // Now parse the 'catch' blocks if any. |
| 7260 try_blocks_list_->enter_catch(); | 7261 try_blocks_list_->enter_catch(); |
| 7261 const intptr_t handler_pos = TokenPos(); | 7262 const intptr_t handler_pos = TokenPos(); |
| 7262 const GrowableObjectArray& handler_types = | 7263 const GrowableObjectArray& handler_types = |
| 7263 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 7264 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); |
| 7264 bool needs_stack_trace = false; | 7265 bool needs_stack_trace = false; |
| 7265 SequenceNode* catch_handler_list = | 7266 SequenceNode* catch_handler_list = |
| 7266 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, | 7267 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7330 const intptr_t jump_pos = TokenPos(); | 7331 const intptr_t jump_pos = TokenPos(); |
| 7331 SourceLabel* target = NULL; | 7332 SourceLabel* target = NULL; |
| 7332 ConsumeToken(); | 7333 ConsumeToken(); |
| 7333 if (IsIdentifier()) { | 7334 if (IsIdentifier()) { |
| 7334 // Explicit label after break/continue. | 7335 // Explicit label after break/continue. |
| 7335 const String& target_name = *CurrentLiteral(); | 7336 const String& target_name = *CurrentLiteral(); |
| 7336 ConsumeToken(); | 7337 ConsumeToken(); |
| 7337 // Handle pathological cases first. | 7338 // Handle pathological cases first. |
| 7338 if (label_name != NULL && target_name.Equals(*label_name)) { | 7339 if (label_name != NULL && target_name.Equals(*label_name)) { |
| 7339 if (jump_kind == Token::kCONTINUE) { | 7340 if (jump_kind == Token::kCONTINUE) { |
| 7340 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 7341 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", |
| 7341 target_name.ToCString()); | 7342 target_name.ToCString()); |
| 7342 } | 7343 } |
| 7343 // L: break L; is a no-op. | 7344 // L: break L; is a no-op. |
| 7344 return NULL; | 7345 return NULL; |
| 7345 } | 7346 } |
| 7346 target = current_block_->scope->LookupLabel(target_name); | 7347 target = current_block_->scope->LookupLabel(target_name); |
| 7347 if (target == NULL && jump_kind == Token::kCONTINUE) { | 7348 if (target == NULL && jump_kind == Token::kCONTINUE) { |
| 7348 // Either a reference to a non-existent label, or a forward reference | 7349 // Either a reference to a non-existent label, or a forward reference |
| 7349 // to a case label that we haven't seen yet. If we are inside a switch | 7350 // to a case label that we haven't seen yet. If we are inside a switch |
| 7350 // statement, create a "forward reference" label in the scope of | 7351 // statement, create a "forward reference" label in the scope of |
| 7351 // the switch statement. | 7352 // the switch statement. |
| 7352 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); | 7353 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); |
| 7353 if (switch_scope != NULL) { | 7354 if (switch_scope != NULL) { |
| 7354 // We found a switch scope. Enter a forward reference to the label. | 7355 // We found a switch scope. Enter a forward reference to the label. |
| 7355 target = new(I) SourceLabel( | 7356 target = new(I) SourceLabel( |
| 7356 TokenPos(), target_name, SourceLabel::kForward); | 7357 TokenPos(), target_name, SourceLabel::kForward); |
| 7357 switch_scope->AddLabel(target); | 7358 switch_scope->AddLabel(target); |
| 7358 } | 7359 } |
| 7359 } | 7360 } |
| 7360 if (target == NULL) { | 7361 if (target == NULL) { |
| 7361 ErrorMsg(jump_pos, "label '%s' not found", target_name.ToCString()); | 7362 ReportError(jump_pos, "label '%s' not found", target_name.ToCString()); |
| 7362 } | 7363 } |
| 7363 } else { | 7364 } else { |
| 7364 target = current_block_->scope->LookupInnermostLabel(jump_kind); | 7365 target = current_block_->scope->LookupInnermostLabel(jump_kind); |
| 7365 if (target == NULL) { | 7366 if (target == NULL) { |
| 7366 ErrorMsg(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); | 7367 ReportError(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); |
| 7367 } | 7368 } |
| 7368 } | 7369 } |
| 7369 ASSERT(target != NULL); | 7370 ASSERT(target != NULL); |
| 7370 if (jump_kind == Token::kCONTINUE) { | 7371 if (jump_kind == Token::kCONTINUE) { |
| 7371 if (target->kind() == SourceLabel::kSwitch) { | 7372 if (target->kind() == SourceLabel::kSwitch) { |
| 7372 ErrorMsg(jump_pos, "'continue' jump to switch statement is illegal"); | 7373 ReportError(jump_pos, "'continue' jump to switch statement is illegal"); |
| 7373 } else if (target->kind() == SourceLabel::kStatement) { | 7374 } else if (target->kind() == SourceLabel::kStatement) { |
| 7374 ErrorMsg(jump_pos, "'continue' jump to label '%s' is illegal", | 7375 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", |
| 7375 target->name().ToCString()); | 7376 target->name().ToCString()); |
| 7376 } | 7377 } |
| 7377 } | 7378 } |
| 7378 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { | 7379 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { |
| 7379 ErrorMsg(jump_pos, "'break' to case clause label is illegal"); | 7380 ReportError(jump_pos, "'break' to case clause label is illegal"); |
| 7380 } | 7381 } |
| 7381 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 7382 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 7382 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 7383 ReportError(jump_pos, "'%s' target must be in same function context", |
| 7383 Token::Str(jump_kind)); | 7384 Token::Str(jump_kind)); |
| 7384 } | 7385 } |
| 7385 return new(I) JumpNode(jump_pos, jump_kind, target); | 7386 return new(I) JumpNode(jump_pos, jump_kind, target); |
| 7386 } | 7387 } |
| 7387 | 7388 |
| 7388 | 7389 |
| 7389 AstNode* Parser::ParseStatement() { | 7390 AstNode* Parser::ParseStatement() { |
| 7390 TRACE_PARSER("ParseStatement"); | 7391 TRACE_PARSER("ParseStatement"); |
| 7391 AstNode* statement = NULL; | 7392 AstNode* statement = NULL; |
| 7392 intptr_t label_pos = 0; | 7393 intptr_t label_pos = 0; |
| 7393 String* label_name = NULL; | 7394 String* label_name = NULL; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 7413 } else if (token == Token::kSWITCH) { | 7414 } else if (token == Token::kSWITCH) { |
| 7414 statement = ParseSwitchStatement(label_name); | 7415 statement = ParseSwitchStatement(label_name); |
| 7415 } else if (token == Token::kTRY) { | 7416 } else if (token == Token::kTRY) { |
| 7416 statement = ParseTryStatement(label_name); | 7417 statement = ParseTryStatement(label_name); |
| 7417 } else if (token == Token::kRETURN) { | 7418 } else if (token == Token::kRETURN) { |
| 7418 const intptr_t return_pos = TokenPos(); | 7419 const intptr_t return_pos = TokenPos(); |
| 7419 ConsumeToken(); | 7420 ConsumeToken(); |
| 7420 if (CurrentToken() != Token::kSEMICOLON) { | 7421 if (CurrentToken() != Token::kSEMICOLON) { |
| 7421 if (current_function().IsConstructor() && | 7422 if (current_function().IsConstructor() && |
| 7422 (current_block_->scope->function_level() == 0)) { | 7423 (current_block_->scope->function_level() == 0)) { |
| 7423 ErrorMsg(return_pos, "return of a value not allowed in constructors"); | 7424 ReportError(return_pos, |
| 7425 "return of a value not allowed in constructors"); |
| 7424 } | 7426 } |
| 7425 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 7427 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 7426 statement = new(I) ReturnNode(statement_pos, expr); | 7428 statement = new(I) ReturnNode(statement_pos, expr); |
| 7427 } else { | 7429 } else { |
| 7428 statement = new(I) ReturnNode(statement_pos); | 7430 statement = new(I) ReturnNode(statement_pos); |
| 7429 } | 7431 } |
| 7430 AddNodeForFinallyInlining(statement); | 7432 AddNodeForFinallyInlining(statement); |
| 7431 ExpectSemicolon(); | 7433 ExpectSemicolon(); |
| 7432 } else if (token == Token::kIF) { | 7434 } else if (token == Token::kIF) { |
| 7433 statement = ParseIfStatement(label_name); | 7435 statement = ParseIfStatement(label_name); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 7463 ExpectSemicolon(); | 7465 ExpectSemicolon(); |
| 7464 } else if (token == Token::kSEMICOLON) { | 7466 } else if (token == Token::kSEMICOLON) { |
| 7465 // Empty statement, nothing to do. | 7467 // Empty statement, nothing to do. |
| 7466 ConsumeToken(); | 7468 ConsumeToken(); |
| 7467 } else if (token == Token::kRETHROW) { | 7469 } else if (token == Token::kRETHROW) { |
| 7468 // Rethrow of current exception. | 7470 // Rethrow of current exception. |
| 7469 ConsumeToken(); | 7471 ConsumeToken(); |
| 7470 ExpectSemicolon(); | 7472 ExpectSemicolon(); |
| 7471 // Check if it is ok to do a rethrow. | 7473 // Check if it is ok to do a rethrow. |
| 7472 if ((try_blocks_list_ == NULL) || !try_blocks_list_->inside_catch()) { | 7474 if ((try_blocks_list_ == NULL) || !try_blocks_list_->inside_catch()) { |
| 7473 ErrorMsg(statement_pos, "rethrow of an exception is not valid here"); | 7475 ReportError(statement_pos, "rethrow of an exception is not valid here"); |
| 7474 } | 7476 } |
| 7475 // The exception and stack trace variables are bound in the block | 7477 // The exception and stack trace variables are bound in the block |
| 7476 // containing the try. | 7478 // containing the try. |
| 7477 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); | 7479 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); |
| 7478 ASSERT(scope != NULL); | 7480 ASSERT(scope != NULL); |
| 7479 LocalVariable* excp_var = | 7481 LocalVariable* excp_var = |
| 7480 scope->LocalLookupVariable(Symbols::ExceptionVar()); | 7482 scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 7481 ASSERT(excp_var != NULL); | 7483 ASSERT(excp_var != NULL); |
| 7482 LocalVariable* trace_var = | 7484 LocalVariable* trace_var = |
| 7483 scope->LocalLookupVariable(Symbols::StackTraceVar()); | 7485 scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 7484 ASSERT(trace_var != NULL); | 7486 ASSERT(trace_var != NULL); |
| 7485 statement = new(I) ThrowNode( | 7487 statement = new(I) ThrowNode( |
| 7486 statement_pos, | 7488 statement_pos, |
| 7487 new(I) LoadLocalNode(statement_pos, excp_var), | 7489 new(I) LoadLocalNode(statement_pos, excp_var), |
| 7488 new(I) LoadLocalNode(statement_pos, trace_var)); | 7490 new(I) LoadLocalNode(statement_pos, trace_var)); |
| 7489 } else { | 7491 } else { |
| 7490 statement = ParseExpr(kAllowConst, kConsumeCascades); | 7492 statement = ParseExpr(kAllowConst, kConsumeCascades); |
| 7491 ExpectSemicolon(); | 7493 ExpectSemicolon(); |
| 7492 } | 7494 } |
| 7493 return statement; | 7495 return statement; |
| 7494 } | 7496 } |
| 7495 | 7497 |
| 7496 | 7498 |
| 7497 void Parser::ErrorMsg(intptr_t token_pos, const char* format, ...) const { | 7499 void Parser::ReportError(const Error& error) { |
| 7498 va_list args; | 7500 Report::LongJump(error); |
| 7499 va_start(args, format); | |
| 7500 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( | |
| 7501 Error::Handle(I), script_, token_pos, | |
| 7502 LanguageError::kError, Heap::kNew, format, args)); | |
| 7503 va_end(args); | |
| 7504 I->long_jump_base()->Jump(1, error); | |
| 7505 UNREACHABLE(); | 7501 UNREACHABLE(); |
| 7506 } | 7502 } |
| 7507 | 7503 |
| 7508 | 7504 |
| 7509 void Parser::ErrorMsg(const char* format, ...) { | 7505 void Parser::ReportErrors(const Error& prev_error, |
| 7506 const Script& script, intptr_t token_pos, |
| 7507 const char* format, ...) { |
| 7510 va_list args; | 7508 va_list args; |
| 7511 va_start(args, format); | 7509 va_start(args, format); |
| 7512 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( | 7510 Report::LongJumpV(prev_error, script, token_pos, format, args); |
| 7513 Error::Handle(I), script_, TokenPos(), | |
| 7514 LanguageError::kError, Heap::kNew, format, args)); | |
| 7515 va_end(args); | 7511 va_end(args); |
| 7516 I->long_jump_base()->Jump(1, error); | |
| 7517 UNREACHABLE(); | 7512 UNREACHABLE(); |
| 7518 } | 7513 } |
| 7519 | 7514 |
| 7520 | 7515 |
| 7521 void Parser::ErrorMsg(const Error& error) { | 7516 void Parser::ReportError(intptr_t token_pos, const char* format, ...) const { |
| 7522 Isolate::Current()->long_jump_base()->Jump(1, error); | 7517 va_list args; |
| 7518 va_start(args, format); |
| 7519 Report::MessageV(Report::kError, script_, token_pos, format, args); |
| 7520 va_end(args); |
| 7523 UNREACHABLE(); | 7521 UNREACHABLE(); |
| 7524 } | 7522 } |
| 7525 | 7523 |
| 7526 | 7524 |
| 7527 void Parser::AppendErrorMsg( | 7525 void Parser::ReportError(const char* format, ...) const { |
| 7528 const Error& prev_error, intptr_t token_pos, const char* format, ...) { | |
| 7529 va_list args; | 7526 va_list args; |
| 7530 va_start(args, format); | 7527 va_start(args, format); |
| 7531 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( | 7528 Report::MessageV(Report::kError, script_, TokenPos(), format, args); |
| 7532 prev_error, script_, token_pos, | |
| 7533 LanguageError::kError, Heap::kNew, | |
| 7534 format, args)); | |
| 7535 va_end(args); | 7529 va_end(args); |
| 7536 I->long_jump_base()->Jump(1, error); | |
| 7537 UNREACHABLE(); | 7530 UNREACHABLE(); |
| 7538 } | 7531 } |
| 7539 | 7532 |
| 7540 | 7533 |
| 7541 void Parser::Warning(intptr_t token_pos, const char* format, ...) { | 7534 void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const { |
| 7542 if (FLAG_silent_warnings) return; | |
| 7543 va_list args; | 7535 va_list args; |
| 7544 va_start(args, format); | 7536 va_start(args, format); |
| 7545 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( | 7537 Report::MessageV(Report::kWarning, script_, token_pos, format, args); |
| 7546 Error::Handle(I), script_, token_pos, | |
| 7547 LanguageError::kWarning, Heap::kNew, | |
| 7548 format, args)); | |
| 7549 va_end(args); | 7538 va_end(args); |
| 7550 if (FLAG_warning_as_error) { | |
| 7551 I->long_jump_base()->Jump(1, error); | |
| 7552 UNREACHABLE(); | |
| 7553 } else { | |
| 7554 OS::Print("%s", error.ToErrorCString()); | |
| 7555 va_start(args, format); | |
| 7556 Exceptions::TraceJSWarningV(script_, token_pos, format, args); | |
| 7557 va_end(args); | |
| 7558 } | |
| 7559 } | 7539 } |
| 7560 | 7540 |
| 7561 | 7541 |
| 7562 void Parser::Warning(const char* format, ...) { | 7542 void Parser::ReportWarning(const char* format, ...) const { |
| 7563 if (FLAG_silent_warnings) return; | |
| 7564 va_list args; | 7543 va_list args; |
| 7565 va_start(args, format); | 7544 va_start(args, format); |
| 7566 const Error& error = Error::Handle(I, LanguageError::NewFormattedV( | 7545 Report::MessageV(Report::kWarning, script_, TokenPos(), format, args); |
| 7567 Error::Handle(I), script_, TokenPos(), | |
| 7568 LanguageError::kWarning, Heap::kNew, | |
| 7569 format, args)); | |
| 7570 va_end(args); | 7546 va_end(args); |
| 7571 if (FLAG_warning_as_error) { | |
| 7572 I->long_jump_base()->Jump(1, error); | |
| 7573 UNREACHABLE(); | |
| 7574 } else { | |
| 7575 OS::Print("%s", error.ToErrorCString()); | |
| 7576 va_start(args, format); | |
| 7577 Exceptions::TraceJSWarningV(script_, TokenPos(), format, args); | |
| 7578 va_end(args); | |
| 7579 } | |
| 7580 } | |
| 7581 | |
| 7582 | |
| 7583 void Parser::Unimplemented(const char* msg) { | |
| 7584 ErrorMsg(TokenPos(), "%s", msg); | |
| 7585 } | 7547 } |
| 7586 | 7548 |
| 7587 | 7549 |
| 7588 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { | 7550 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { |
| 7589 if (CurrentToken() != token_expected) { | 7551 if (CurrentToken() != token_expected) { |
| 7590 if (msg != NULL) { | 7552 if (msg != NULL) { |
| 7591 ErrorMsg("%s", msg); | 7553 ReportError("%s", msg); |
| 7592 } else { | 7554 } else { |
| 7593 ErrorMsg("'%s' expected", Token::Str(token_expected)); | 7555 ReportError("'%s' expected", Token::Str(token_expected)); |
| 7594 } | 7556 } |
| 7595 } | 7557 } |
| 7596 } | 7558 } |
| 7597 | 7559 |
| 7598 | 7560 |
| 7599 void Parser::ExpectToken(Token::Kind token_expected) { | 7561 void Parser::ExpectToken(Token::Kind token_expected) { |
| 7600 if (CurrentToken() != token_expected) { | 7562 if (CurrentToken() != token_expected) { |
| 7601 ErrorMsg("'%s' expected", Token::Str(token_expected)); | 7563 ReportError("'%s' expected", Token::Str(token_expected)); |
| 7602 } | 7564 } |
| 7603 ConsumeToken(); | 7565 ConsumeToken(); |
| 7604 } | 7566 } |
| 7605 | 7567 |
| 7606 | 7568 |
| 7607 void Parser::ExpectSemicolon() { | 7569 void Parser::ExpectSemicolon() { |
| 7608 if (CurrentToken() != Token::kSEMICOLON) { | 7570 if (CurrentToken() != Token::kSEMICOLON) { |
| 7609 ErrorMsg("semicolon expected"); | 7571 ReportError("semicolon expected"); |
| 7610 } | 7572 } |
| 7611 ConsumeToken(); | 7573 ConsumeToken(); |
| 7612 } | 7574 } |
| 7613 | 7575 |
| 7614 | 7576 |
| 7615 void Parser::UnexpectedToken() { | 7577 void Parser::UnexpectedToken() { |
| 7616 ErrorMsg("unexpected token '%s'", | 7578 ReportError("unexpected token '%s'", |
| 7617 CurrentToken() == Token::kIDENT ? | 7579 CurrentToken() == Token::kIDENT ? |
| 7618 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); | 7580 CurrentLiteral()->ToCString() : Token::Str(CurrentToken())); |
| 7619 } | 7581 } |
| 7620 | 7582 |
| 7621 | 7583 |
| 7622 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { | 7584 String* Parser::ExpectUserDefinedTypeIdentifier(const char* msg) { |
| 7623 if (CurrentToken() != Token::kIDENT) { | 7585 if (CurrentToken() != Token::kIDENT) { |
| 7624 ErrorMsg("%s", msg); | 7586 ReportError("%s", msg); |
| 7625 } | 7587 } |
| 7626 String* ident = CurrentLiteral(); | 7588 String* ident = CurrentLiteral(); |
| 7627 if (ident->Equals("dynamic")) { | 7589 if (ident->Equals("dynamic")) { |
| 7628 ErrorMsg("%s", msg); | 7590 ReportError("%s", msg); |
| 7629 } | 7591 } |
| 7630 ConsumeToken(); | 7592 ConsumeToken(); |
| 7631 return ident; | 7593 return ident; |
| 7632 } | 7594 } |
| 7633 | 7595 |
| 7634 | 7596 |
| 7635 // Check whether current token is an identifier or a built-in identifier. | 7597 // Check whether current token is an identifier or a built-in identifier. |
| 7636 String* Parser::ExpectIdentifier(const char* msg) { | 7598 String* Parser::ExpectIdentifier(const char* msg) { |
| 7637 if (!IsIdentifier()) { | 7599 if (!IsIdentifier()) { |
| 7638 ErrorMsg("%s", msg); | 7600 ReportError("%s", msg); |
| 7639 } | 7601 } |
| 7640 String* ident = CurrentLiteral(); | 7602 String* ident = CurrentLiteral(); |
| 7641 ConsumeToken(); | 7603 ConsumeToken(); |
| 7642 return ident; | 7604 return ident; |
| 7643 } | 7605 } |
| 7644 | 7606 |
| 7645 | 7607 |
| 7646 bool Parser::IsLiteral(const char* literal) { | 7608 bool Parser::IsLiteral(const char* literal) { |
| 7647 return IsIdentifier() && CurrentLiteral()->Equals(literal); | 7609 return IsIdentifier() && CurrentLiteral()->Equals(literal); |
| 7648 } | 7610 } |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7781 arguments); | 7743 arguments); |
| 7782 } | 7744 } |
| 7783 | 7745 |
| 7784 | 7746 |
| 7785 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 7747 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
| 7786 TRACE_PARSER("ParseBinaryExpr"); | 7748 TRACE_PARSER("ParseBinaryExpr"); |
| 7787 ASSERT(min_preced >= Token::Precedence(Token::kOR)); | 7749 ASSERT(min_preced >= Token::Precedence(Token::kOR)); |
| 7788 AstNode* left_operand = ParseUnaryExpr(); | 7750 AstNode* left_operand = ParseUnaryExpr(); |
| 7789 if (left_operand->IsPrimaryNode() && | 7751 if (left_operand->IsPrimaryNode() && |
| 7790 (left_operand->AsPrimaryNode()->IsSuper())) { | 7752 (left_operand->AsPrimaryNode()->IsSuper())) { |
| 7791 ErrorMsg(left_operand->token_pos(), "illegal use of 'super'"); | 7753 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
| 7792 } | 7754 } |
| 7793 int current_preced = Token::Precedence(CurrentToken()); | 7755 int current_preced = Token::Precedence(CurrentToken()); |
| 7794 while (current_preced >= min_preced) { | 7756 while (current_preced >= min_preced) { |
| 7795 while (Token::Precedence(CurrentToken()) == current_preced) { | 7757 while (Token::Precedence(CurrentToken()) == current_preced) { |
| 7796 Token::Kind op_kind = CurrentToken(); | 7758 Token::Kind op_kind = CurrentToken(); |
| 7797 const intptr_t op_pos = TokenPos(); | 7759 const intptr_t op_pos = TokenPos(); |
| 7798 ConsumeToken(); | 7760 ConsumeToken(); |
| 7799 AstNode* right_operand = NULL; | 7761 AstNode* right_operand = NULL; |
| 7800 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 7762 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
| 7801 right_operand = ParseBinaryExpr(current_preced + 1); | 7763 right_operand = ParseBinaryExpr(current_preced + 1); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7978 return new(I) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); | 7940 return new(I) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); |
| 7979 case Token::kASSIGN_SHL: | 7941 case Token::kASSIGN_SHL: |
| 7980 return new(I) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); | 7942 return new(I) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); |
| 7981 case Token::kASSIGN_OR: | 7943 case Token::kASSIGN_OR: |
| 7982 return new(I) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); | 7944 return new(I) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); |
| 7983 case Token::kASSIGN_AND: | 7945 case Token::kASSIGN_AND: |
| 7984 return new(I) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); | 7946 return new(I) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); |
| 7985 case Token::kASSIGN_XOR: | 7947 case Token::kASSIGN_XOR: |
| 7986 return new(I) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); | 7948 return new(I) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); |
| 7987 default: | 7949 default: |
| 7988 ErrorMsg(op_pos, "internal error: ExpandAssignableOp '%s' unimplemented", | 7950 ReportError(op_pos, |
| 7989 Token::Name(assignment_op)); | 7951 "internal error: ExpandAssignableOp '%s' unimplemented", |
| 7952 Token::Name(assignment_op)); |
| 7990 UNIMPLEMENTED(); | 7953 UNIMPLEMENTED(); |
| 7991 return NULL; | 7954 return NULL; |
| 7992 } | 7955 } |
| 7993 } | 7956 } |
| 7994 | 7957 |
| 7995 | 7958 |
| 7996 // Evaluates the value of the compile time constant expression | 7959 // Evaluates the value of the compile time constant expression |
| 7997 // and returns a literal node for the value. | 7960 // and returns a literal node for the value. |
| 7998 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { | 7961 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { |
| 7999 if (expr->IsLiteralNode()) { | 7962 if (expr->IsLiteralNode()) { |
| 8000 return expr; | 7963 return expr; |
| 8001 } | 7964 } |
| 8002 if (expr->EvalConstExpr() == NULL) { | 7965 if (expr->EvalConstExpr() == NULL) { |
| 8003 ErrorMsg(expr_pos, "expression is not a valid compile-time constant"); | 7966 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
| 8004 } | 7967 } |
| 8005 return new(I) LiteralNode( | 7968 return new(I) LiteralNode( |
| 8006 expr_pos, EvaluateConstExpr(expr_pos, expr)); | 7969 expr_pos, EvaluateConstExpr(expr_pos, expr)); |
| 8007 } | 7970 } |
| 8008 | 7971 |
| 8009 | 7972 |
| 8010 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 7973 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
| 8011 AstNode* node = *expr; | 7974 AstNode* node = *expr; |
| 8012 intptr_t token_pos = node->token_pos(); | 7975 intptr_t token_pos = node->token_pos(); |
| 8013 LetNode* result = new(I) LetNode(token_pos); | 7976 LetNode* result = new(I) LetNode(token_pos); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8080 } else if (original->IsLoadStaticFieldNode()) { | 8043 } else if (original->IsLoadStaticFieldNode()) { |
| 8081 name = original->AsLoadStaticFieldNode()->field().name(); | 8044 name = original->AsLoadStaticFieldNode()->field().name(); |
| 8082 target_cls = &Class::Handle(I, | 8045 target_cls = &Class::Handle(I, |
| 8083 original->AsLoadStaticFieldNode()->field().owner()); | 8046 original->AsLoadStaticFieldNode()->field().owner()); |
| 8084 } else if ((left_ident != NULL) && | 8047 } else if ((left_ident != NULL) && |
| 8085 (original->IsLiteralNode() || | 8048 (original->IsLiteralNode() || |
| 8086 original->IsLoadLocalNode())) { | 8049 original->IsLoadLocalNode())) { |
| 8087 name = left_ident->raw(); | 8050 name = left_ident->raw(); |
| 8088 } | 8051 } |
| 8089 if (name.IsNull()) { | 8052 if (name.IsNull()) { |
| 8090 ErrorMsg(left_pos, "expression is not assignable"); | 8053 ReportError(left_pos, "expression is not assignable"); |
| 8091 } | 8054 } |
| 8092 result = ThrowNoSuchMethodError( | 8055 result = ThrowNoSuchMethodError( |
| 8093 original->token_pos(), | 8056 original->token_pos(), |
| 8094 *target_cls, | 8057 *target_cls, |
| 8095 String::Handle(I, Field::SetterName(name)), | 8058 String::Handle(I, Field::SetterName(name)), |
| 8096 NULL, // No arguments. | 8059 NULL, // No arguments. |
| 8097 InvocationMirror::kStatic, | 8060 InvocationMirror::kStatic, |
| 8098 original->IsLoadLocalNode() ? | 8061 original->IsLoadLocalNode() ? |
| 8099 InvocationMirror::kLocalVar : InvocationMirror::kSetter, | 8062 InvocationMirror::kLocalVar : InvocationMirror::kSetter, |
| 8100 NULL); // No existing function. | 8063 NULL); // No existing function. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 8117 while (CurrentToken() == Token::kCASCADE) { | 8080 while (CurrentToken() == Token::kCASCADE) { |
| 8118 cascade_pos = TokenPos(); | 8081 cascade_pos = TokenPos(); |
| 8119 LoadLocalNode* load_cascade_receiver = | 8082 LoadLocalNode* load_cascade_receiver = |
| 8120 new(I) LoadLocalNode(cascade_pos, cascade_receiver_var); | 8083 new(I) LoadLocalNode(cascade_pos, cascade_receiver_var); |
| 8121 if (Token::IsIdentifier(LookaheadToken(1))) { | 8084 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 8122 // Replace .. with . for ParseSelectors(). | 8085 // Replace .. with . for ParseSelectors(). |
| 8123 token_kind_ = Token::kPERIOD; | 8086 token_kind_ = Token::kPERIOD; |
| 8124 } else if (LookaheadToken(1) == Token::kLBRACK) { | 8087 } else if (LookaheadToken(1) == Token::kLBRACK) { |
| 8125 ConsumeToken(); | 8088 ConsumeToken(); |
| 8126 } else { | 8089 } else { |
| 8127 ErrorMsg("identifier or [ expected after .."); | 8090 ReportError("identifier or [ expected after .."); |
| 8128 } | 8091 } |
| 8129 String* expr_ident = | 8092 String* expr_ident = |
| 8130 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8093 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8131 const intptr_t expr_pos = TokenPos(); | 8094 const intptr_t expr_pos = TokenPos(); |
| 8132 expr = ParseSelectors(load_cascade_receiver, true); | 8095 expr = ParseSelectors(load_cascade_receiver, true); |
| 8133 | 8096 |
| 8134 // Assignments after a cascade are part of the cascade. The | 8097 // Assignments after a cascade are part of the cascade. The |
| 8135 // assigned expression must not contain cascades. | 8098 // assigned expression must not contain cascades. |
| 8136 if (Token::IsAssignmentOperator(CurrentToken())) { | 8099 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 8137 Token::Kind assignment_op = CurrentToken(); | 8100 Token::Kind assignment_op = CurrentToken(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8185 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 8148 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 8186 bool consume_cascades) { | 8149 bool consume_cascades) { |
| 8187 TRACE_PARSER("ParseExpr"); | 8150 TRACE_PARSER("ParseExpr"); |
| 8188 String* expr_ident = | 8151 String* expr_ident = |
| 8189 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8152 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8190 const intptr_t expr_pos = TokenPos(); | 8153 const intptr_t expr_pos = TokenPos(); |
| 8191 | 8154 |
| 8192 if (CurrentToken() == Token::kTHROW) { | 8155 if (CurrentToken() == Token::kTHROW) { |
| 8193 ConsumeToken(); | 8156 ConsumeToken(); |
| 8194 if (CurrentToken() == Token::kSEMICOLON) { | 8157 if (CurrentToken() == Token::kSEMICOLON) { |
| 8195 ErrorMsg("expression expected after throw"); | 8158 ReportError("expression expected after throw"); |
| 8196 } | 8159 } |
| 8197 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 8160 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 8198 return new(I) ThrowNode(expr_pos, expr, NULL); | 8161 return new(I) ThrowNode(expr_pos, expr, NULL); |
| 8199 } | 8162 } |
| 8200 AstNode* expr = ParseConditionalExpr(); | 8163 AstNode* expr = ParseConditionalExpr(); |
| 8201 if (!Token::IsAssignmentOperator(CurrentToken())) { | 8164 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 8202 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 8165 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
| 8203 return ParseCascades(expr); | 8166 return ParseCascades(expr); |
| 8204 } | 8167 } |
| 8205 if (require_compiletime_const) { | 8168 if (require_compiletime_const) { |
| 8206 expr = FoldConstExpr(expr_pos, expr); | 8169 expr = FoldConstExpr(expr_pos, expr); |
| 8207 } else { | 8170 } else { |
| 8208 expr = LiteralIfStaticConst(I, expr); | 8171 expr = LiteralIfStaticConst(I, expr); |
| 8209 } | 8172 } |
| 8210 return expr; | 8173 return expr; |
| 8211 } | 8174 } |
| 8212 // Assignment expressions. | 8175 // Assignment expressions. |
| 8213 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 8176 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 8214 ErrorMsg(expr_pos, "expression is not assignable"); | 8177 ReportError(expr_pos, "expression is not assignable"); |
| 8215 } | 8178 } |
| 8216 const Token::Kind assignment_op = CurrentToken(); | 8179 const Token::Kind assignment_op = CurrentToken(); |
| 8217 const intptr_t assignment_pos = TokenPos(); | 8180 const intptr_t assignment_pos = TokenPos(); |
| 8218 ConsumeToken(); | 8181 ConsumeToken(); |
| 8219 const intptr_t right_expr_pos = TokenPos(); | 8182 const intptr_t right_expr_pos = TokenPos(); |
| 8220 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 8183 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 8221 ErrorMsg(right_expr_pos, "expression is not a valid compile-time constant"); | 8184 ReportError(right_expr_pos, |
| 8185 "expression is not a valid compile-time constant"); |
| 8222 } | 8186 } |
| 8223 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 8187 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 8224 if (assignment_op != Token::kASSIGN) { | 8188 if (assignment_op != Token::kASSIGN) { |
| 8225 // Compound assignment: store inputs with side effects into temp. locals. | 8189 // Compound assignment: store inputs with side effects into temp. locals. |
| 8226 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 8190 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 8227 AstNode* assigned_value = | 8191 AstNode* assigned_value = |
| 8228 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 8192 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 8229 AstNode* assign_expr = | 8193 AstNode* assign_expr = |
| 8230 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 8194 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
| 8231 ASSERT(assign_expr != NULL); | 8195 ASSERT(assign_expr != NULL); |
| 8232 let_expr->AddNode(assign_expr); | 8196 let_expr->AddNode(assign_expr); |
| 8233 return let_expr; | 8197 return let_expr; |
| 8234 } else { | 8198 } else { |
| 8235 AstNode* assigned_value = LiteralIfStaticConst(I, right_expr); | 8199 AstNode* assigned_value = LiteralIfStaticConst(I, right_expr); |
| 8236 AstNode* assign_expr = | 8200 AstNode* assign_expr = |
| 8237 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 8201 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
| 8238 ASSERT(assign_expr != NULL); | 8202 ASSERT(assign_expr != NULL); |
| 8239 return assign_expr; | 8203 return assign_expr; |
| 8240 } | 8204 } |
| 8241 } | 8205 } |
| 8242 | 8206 |
| 8243 | 8207 |
| 8244 LiteralNode* Parser::ParseConstExpr() { | 8208 LiteralNode* Parser::ParseConstExpr() { |
| 8245 TRACE_PARSER("ParseConstExpr"); | 8209 TRACE_PARSER("ParseConstExpr"); |
| 8246 intptr_t expr_pos = TokenPos(); | 8210 intptr_t expr_pos = TokenPos(); |
| 8247 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 8211 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
| 8248 if (!expr->IsLiteralNode()) { | 8212 if (!expr->IsLiteralNode()) { |
| 8249 ErrorMsg(expr_pos, "expression must be a compile-time constant"); | 8213 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 8250 } | 8214 } |
| 8251 return expr->AsLiteralNode(); | 8215 return expr->AsLiteralNode(); |
| 8252 } | 8216 } |
| 8253 | 8217 |
| 8254 | 8218 |
| 8255 AstNode* Parser::ParseConditionalExpr() { | 8219 AstNode* Parser::ParseConditionalExpr() { |
| 8256 TRACE_PARSER("ParseConditionalExpr"); | 8220 TRACE_PARSER("ParseConditionalExpr"); |
| 8257 const intptr_t expr_pos = TokenPos(); | 8221 const intptr_t expr_pos = TokenPos(); |
| 8258 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 8222 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); |
| 8259 if (CurrentToken() == Token::kCONDITIONAL) { | 8223 if (CurrentToken() == Token::kCONDITIONAL) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 8285 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 8249 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
| 8286 } | 8250 } |
| 8287 } else if (IsIncrementOperator(CurrentToken())) { | 8251 } else if (IsIncrementOperator(CurrentToken())) { |
| 8288 Token::Kind incr_op = CurrentToken(); | 8252 Token::Kind incr_op = CurrentToken(); |
| 8289 ConsumeToken(); | 8253 ConsumeToken(); |
| 8290 String* expr_ident = | 8254 String* expr_ident = |
| 8291 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8255 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8292 const intptr_t expr_pos = TokenPos(); | 8256 const intptr_t expr_pos = TokenPos(); |
| 8293 expr = ParseUnaryExpr(); | 8257 expr = ParseUnaryExpr(); |
| 8294 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 8258 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 8295 ErrorMsg(expr_pos, "expression is not assignable"); | 8259 ReportError(expr_pos, "expression is not assignable"); |
| 8296 } | 8260 } |
| 8297 // Is prefix. | 8261 // Is prefix. |
| 8298 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 8262 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 8299 Token::Kind binary_op = | 8263 Token::Kind binary_op = |
| 8300 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 8264 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 8301 BinaryOpNode* add = new(I) BinaryOpNode( | 8265 BinaryOpNode* add = new(I) BinaryOpNode( |
| 8302 op_pos, | 8266 op_pos, |
| 8303 binary_op, | 8267 binary_op, |
| 8304 expr, | 8268 expr, |
| 8305 new(I) LiteralNode(op_pos, Smi::ZoneHandle(I, Smi::New(1)))); | 8269 new(I) LiteralNode(op_pos, Smi::ZoneHandle(I, Smi::New(1)))); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8337 ConsumeToken(); | 8301 ConsumeToken(); |
| 8338 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 8302 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 8339 named_argument_seen = true; | 8303 named_argument_seen = true; |
| 8340 // The canonicalization of the arguments descriptor array built in | 8304 // The canonicalization of the arguments descriptor array built in |
| 8341 // the code generator requires that the names are symbols, i.e. | 8305 // the code generator requires that the names are symbols, i.e. |
| 8342 // canonicalized strings. | 8306 // canonicalized strings. |
| 8343 ASSERT(CurrentLiteral()->IsSymbol()); | 8307 ASSERT(CurrentLiteral()->IsSymbol()); |
| 8344 for (int i = 0; i < names.Length(); i++) { | 8308 for (int i = 0; i < names.Length(); i++) { |
| 8345 arg_name ^= names.At(i); | 8309 arg_name ^= names.At(i); |
| 8346 if (CurrentLiteral()->Equals(arg_name)) { | 8310 if (CurrentLiteral()->Equals(arg_name)) { |
| 8347 ErrorMsg("duplicate named argument"); | 8311 ReportError("duplicate named argument"); |
| 8348 } | 8312 } |
| 8349 } | 8313 } |
| 8350 names.Add(*CurrentLiteral()); | 8314 names.Add(*CurrentLiteral()); |
| 8351 ConsumeToken(); // ident. | 8315 ConsumeToken(); // ident. |
| 8352 ConsumeToken(); // colon. | 8316 ConsumeToken(); // colon. |
| 8353 } else if (named_argument_seen) { | 8317 } else if (named_argument_seen) { |
| 8354 ErrorMsg("named argument expected"); | 8318 ReportError("named argument expected"); |
| 8355 } | 8319 } |
| 8356 arguments->Add(ParseExpr(require_const, kConsumeCascades)); | 8320 arguments->Add(ParseExpr(require_const, kConsumeCascades)); |
| 8357 } while (CurrentToken() == Token::kCOMMA); | 8321 } while (CurrentToken() == Token::kCOMMA); |
| 8358 } else { | 8322 } else { |
| 8359 ConsumeToken(); | 8323 ConsumeToken(); |
| 8360 } | 8324 } |
| 8361 ExpectToken(Token::kRPAREN); | 8325 ExpectToken(Token::kRPAREN); |
| 8362 SetAllowFunctionLiterals(saved_mode); | 8326 SetAllowFunctionLiterals(saved_mode); |
| 8363 if (named_argument_seen) { | 8327 if (named_argument_seen) { |
| 8364 arguments->set_names(Array::Handle(I, Array::MakeArray(names))); | 8328 arguments->set_names(Array::Handle(I, Array::MakeArray(names))); |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8574 if (func.is_static()) { | 8538 if (func.is_static()) { |
| 8575 // Static function access. | 8539 // Static function access. |
| 8576 ClosureNode* closure = | 8540 ClosureNode* closure = |
| 8577 CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 8541 CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
| 8578 closure->set_is_deferred(primary->is_deferred_reference()); | 8542 closure->set_is_deferred(primary->is_deferred_reference()); |
| 8579 return closure; | 8543 return closure; |
| 8580 } else { | 8544 } else { |
| 8581 // Instance function access. | 8545 // Instance function access. |
| 8582 if (current_function().is_static() || | 8546 if (current_function().is_static() || |
| 8583 current_function().IsInFactoryScope()) { | 8547 current_function().IsInFactoryScope()) { |
| 8584 ErrorMsg(primary->token_pos(), | 8548 ReportError(primary->token_pos(), |
| 8585 "cannot access instance method '%s' from static method", | 8549 "cannot access instance method '%s' from static method", |
| 8586 funcname.ToCString()); | 8550 funcname.ToCString()); |
| 8587 } | 8551 } |
| 8588 AstNode* receiver = LoadReceiver(primary->token_pos()); | 8552 AstNode* receiver = LoadReceiver(primary->token_pos()); |
| 8589 return CallGetter(primary->token_pos(), receiver, funcname); | 8553 return CallGetter(primary->token_pos(), receiver, funcname); |
| 8590 } | 8554 } |
| 8591 UNREACHABLE(); | 8555 UNREACHABLE(); |
| 8592 return NULL; | 8556 return NULL; |
| 8593 } | 8557 } |
| 8594 | 8558 |
| 8595 | 8559 |
| 8596 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 8560 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
| 8597 AstNode* left = primary; | 8561 AstNode* left = primary; |
| 8598 while (true) { | 8562 while (true) { |
| 8599 AstNode* selector = NULL; | 8563 AstNode* selector = NULL; |
| 8600 if (CurrentToken() == Token::kPERIOD) { | 8564 if (CurrentToken() == Token::kPERIOD) { |
| 8601 ConsumeToken(); | 8565 ConsumeToken(); |
| 8602 if (left->IsPrimaryNode()) { | 8566 if (left->IsPrimaryNode()) { |
| 8603 PrimaryNode* primary_node = left->AsPrimaryNode(); | 8567 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 8604 const intptr_t primary_pos = primary_node->token_pos(); | 8568 const intptr_t primary_pos = primary_node->token_pos(); |
| 8605 if (primary_node->primary().IsFunction()) { | 8569 if (primary_node->primary().IsFunction()) { |
| 8606 left = LoadClosure(primary_node); | 8570 left = LoadClosure(primary_node); |
| 8607 } else if (primary_node->primary().IsTypeParameter()) { | 8571 } else if (primary_node->primary().IsTypeParameter()) { |
| 8608 if (current_function().is_static()) { | 8572 if (current_function().is_static()) { |
| 8609 const String& name = String::ZoneHandle(I, | 8573 const String& name = String::ZoneHandle(I, |
| 8610 TypeParameter::Cast(primary_node->primary()).name()); | 8574 TypeParameter::Cast(primary_node->primary()).name()); |
| 8611 ErrorMsg(primary_pos, | 8575 ReportError(primary_pos, |
| 8612 "cannot access type parameter '%s' from static function", | 8576 "cannot access type parameter '%s' " |
| 8613 name.ToCString()); | 8577 "from static function", |
| 8578 name.ToCString()); |
| 8614 } | 8579 } |
| 8615 if (current_block_->scope->function_level() > 0) { | 8580 if (current_block_->scope->function_level() > 0) { |
| 8616 // Make sure that the instantiator is captured. | 8581 // Make sure that the instantiator is captured. |
| 8617 CaptureInstantiator(); | 8582 CaptureInstantiator(); |
| 8618 } | 8583 } |
| 8619 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 8584 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); |
| 8620 type_parameter ^= ClassFinalizer::FinalizeType( | 8585 type_parameter ^= ClassFinalizer::FinalizeType( |
| 8621 current_class(), | 8586 current_class(), |
| 8622 TypeParameter::Cast(primary_node->primary()), | 8587 TypeParameter::Cast(primary_node->primary()), |
| 8623 ClassFinalizer::kCanonicalize); | 8588 ClassFinalizer::kCanonicalize); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8686 primary_pos, Heap::kOld)); | 8651 primary_pos, Heap::kOld)); |
| 8687 type ^= ClassFinalizer::FinalizeType( | 8652 type ^= ClassFinalizer::FinalizeType( |
| 8688 current_class(), type, ClassFinalizer::kCanonicalize); | 8653 current_class(), type, ClassFinalizer::kCanonicalize); |
| 8689 // Type may be malbounded, but not malformed. | 8654 // Type may be malbounded, but not malformed. |
| 8690 ASSERT(!type.IsMalformed()); | 8655 ASSERT(!type.IsMalformed()); |
| 8691 array = new(I) TypeNode(primary_pos, type); | 8656 array = new(I) TypeNode(primary_pos, type); |
| 8692 } else if (primary_node->primary().IsTypeParameter()) { | 8657 } else if (primary_node->primary().IsTypeParameter()) { |
| 8693 if (current_function().is_static()) { | 8658 if (current_function().is_static()) { |
| 8694 const String& name = String::ZoneHandle(I, | 8659 const String& name = String::ZoneHandle(I, |
| 8695 TypeParameter::Cast(primary_node->primary()).name()); | 8660 TypeParameter::Cast(primary_node->primary()).name()); |
| 8696 ErrorMsg(primary_pos, | 8661 ReportError(primary_pos, |
| 8697 "cannot access type parameter '%s' from static function", | 8662 "cannot access type parameter '%s' " |
| 8698 name.ToCString()); | 8663 "from static function", |
| 8664 name.ToCString()); |
| 8699 } | 8665 } |
| 8700 if (current_block_->scope->function_level() > 0) { | 8666 if (current_block_->scope->function_level() > 0) { |
| 8701 // Make sure that the instantiator is captured. | 8667 // Make sure that the instantiator is captured. |
| 8702 CaptureInstantiator(); | 8668 CaptureInstantiator(); |
| 8703 } | 8669 } |
| 8704 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 8670 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); |
| 8705 type_parameter ^= ClassFinalizer::FinalizeType( | 8671 type_parameter ^= ClassFinalizer::FinalizeType( |
| 8706 current_class(), | 8672 current_class(), |
| 8707 TypeParameter::Cast(primary_node->primary()), | 8673 TypeParameter::Cast(primary_node->primary()), |
| 8708 ClassFinalizer::kCanonicalize); | 8674 ClassFinalizer::kCanonicalize); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8721 if (primary_node->primary().IsFunction()) { | 8687 if (primary_node->primary().IsFunction()) { |
| 8722 const Function& func = Function::Cast(primary_node->primary()); | 8688 const Function& func = Function::Cast(primary_node->primary()); |
| 8723 const String& func_name = String::ZoneHandle(I, func.name()); | 8689 const String& func_name = String::ZoneHandle(I, func.name()); |
| 8724 if (func.is_static()) { | 8690 if (func.is_static()) { |
| 8725 // Parse static function call. | 8691 // Parse static function call. |
| 8726 Class& cls = Class::Handle(I, func.Owner()); | 8692 Class& cls = Class::Handle(I, func.Owner()); |
| 8727 selector = ParseStaticCall(cls, func_name, primary_pos); | 8693 selector = ParseStaticCall(cls, func_name, primary_pos); |
| 8728 } else { | 8694 } else { |
| 8729 // Dynamic function call on implicit "this" parameter. | 8695 // Dynamic function call on implicit "this" parameter. |
| 8730 if (current_function().is_static()) { | 8696 if (current_function().is_static()) { |
| 8731 ErrorMsg(primary_pos, | 8697 ReportError(primary_pos, |
| 8732 "cannot access instance method '%s' " | 8698 "cannot access instance method '%s' " |
| 8733 "from static function", | 8699 "from static function", |
| 8734 func_name.ToCString()); | 8700 func_name.ToCString()); |
| 8735 } | 8701 } |
| 8736 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); | 8702 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); |
| 8737 } | 8703 } |
| 8738 } else if (primary_node->primary().IsString()) { | 8704 } else if (primary_node->primary().IsString()) { |
| 8739 // Primary is an unresolved name. | 8705 // Primary is an unresolved name. |
| 8740 if (primary_node->IsSuper()) { | 8706 if (primary_node->IsSuper()) { |
| 8741 ErrorMsg(primary_pos, "illegal use of super"); | 8707 ReportError(primary_pos, "illegal use of super"); |
| 8742 } | 8708 } |
| 8743 String& name = String::CheckedZoneHandle( | 8709 String& name = String::CheckedZoneHandle( |
| 8744 primary_node->primary().raw()); | 8710 primary_node->primary().raw()); |
| 8745 if (current_function().is_static()) { | 8711 if (current_function().is_static()) { |
| 8746 selector = ThrowNoSuchMethodError(primary_pos, | 8712 selector = ThrowNoSuchMethodError(primary_pos, |
| 8747 current_class(), | 8713 current_class(), |
| 8748 name, | 8714 name, |
| 8749 NULL, // No arguments. | 8715 NULL, // No arguments. |
| 8750 InvocationMirror::kStatic, | 8716 InvocationMirror::kStatic, |
| 8751 InvocationMirror::kMethod, | 8717 InvocationMirror::kMethod, |
| 8752 NULL); // No existing function. | 8718 NULL); // No existing function. |
| 8753 } else { | 8719 } else { |
| 8754 // Treat as call to unresolved (instance) method. | 8720 // Treat as call to unresolved (instance) method. |
| 8755 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); | 8721 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); |
| 8756 } | 8722 } |
| 8757 } else if (primary_node->primary().IsTypeParameter()) { | 8723 } else if (primary_node->primary().IsTypeParameter()) { |
| 8758 const String& name = String::ZoneHandle(I, | 8724 const String& name = String::ZoneHandle(I, |
| 8759 TypeParameter::Cast(primary_node->primary()).name()); | 8725 TypeParameter::Cast(primary_node->primary()).name()); |
| 8760 if (current_function().is_static()) { | 8726 if (current_function().is_static()) { |
| 8761 // Treat as this.T(), because T is in scope. | 8727 // Treat as this.T(), because T is in scope. |
| 8762 ErrorMsg(primary_pos, | 8728 ReportError(primary_pos, |
| 8763 "cannot access type parameter '%s' from static function", | 8729 "cannot access type parameter '%s' " |
| 8764 name.ToCString()); | 8730 "from static function", |
| 8731 name.ToCString()); |
| 8765 } else { | 8732 } else { |
| 8766 // Treat as call to unresolved (instance) method. | 8733 // Treat as call to unresolved (instance) method. |
| 8767 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); | 8734 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); |
| 8768 } | 8735 } |
| 8769 } else if (primary_node->primary().IsClass()) { | 8736 } else if (primary_node->primary().IsClass()) { |
| 8770 const Class& type_class = Class::Cast(primary_node->primary()); | 8737 const Class& type_class = Class::Cast(primary_node->primary()); |
| 8771 AbstractType& type = Type::ZoneHandle(I, Type::New( | 8738 AbstractType& type = Type::ZoneHandle(I, Type::New( |
| 8772 type_class, TypeArguments::Handle(I), primary_pos)); | 8739 type_class, TypeArguments::Handle(I), primary_pos)); |
| 8773 type ^= ClassFinalizer::FinalizeType( | 8740 type ^= ClassFinalizer::FinalizeType( |
| 8774 current_class(), type, ClassFinalizer::kCanonicalize); | 8741 current_class(), type, ClassFinalizer::kCanonicalize); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 8798 type_class, TypeArguments::Handle(I), primary_pos)); | 8765 type_class, TypeArguments::Handle(I), primary_pos)); |
| 8799 type = ClassFinalizer::FinalizeType( | 8766 type = ClassFinalizer::FinalizeType( |
| 8800 current_class(), type, ClassFinalizer::kCanonicalize); | 8767 current_class(), type, ClassFinalizer::kCanonicalize); |
| 8801 // Type may be malbounded, but not malformed. | 8768 // Type may be malbounded, but not malformed. |
| 8802 ASSERT(!type.IsMalformed()); | 8769 ASSERT(!type.IsMalformed()); |
| 8803 left = new(I) TypeNode(primary_pos, type); | 8770 left = new(I) TypeNode(primary_pos, type); |
| 8804 } else if (primary_node->primary().IsTypeParameter()) { | 8771 } else if (primary_node->primary().IsTypeParameter()) { |
| 8805 if (current_function().is_static()) { | 8772 if (current_function().is_static()) { |
| 8806 const String& name = String::ZoneHandle(I, | 8773 const String& name = String::ZoneHandle(I, |
| 8807 TypeParameter::Cast(primary_node->primary()).name()); | 8774 TypeParameter::Cast(primary_node->primary()).name()); |
| 8808 ErrorMsg(primary_pos, | 8775 ReportError(primary_pos, |
| 8809 "cannot access type parameter '%s' from static function", | 8776 "cannot access type parameter '%s' " |
| 8810 name.ToCString()); | 8777 "from static function", |
| 8778 name.ToCString()); |
| 8811 } | 8779 } |
| 8812 if (current_block_->scope->function_level() > 0) { | 8780 if (current_block_->scope->function_level() > 0) { |
| 8813 // Make sure that the instantiator is captured. | 8781 // Make sure that the instantiator is captured. |
| 8814 CaptureInstantiator(); | 8782 CaptureInstantiator(); |
| 8815 } | 8783 } |
| 8816 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 8784 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); |
| 8817 type_parameter ^= ClassFinalizer::FinalizeType( | 8785 type_parameter ^= ClassFinalizer::FinalizeType( |
| 8818 current_class(), | 8786 current_class(), |
| 8819 TypeParameter::Cast(primary_node->primary()), | 8787 TypeParameter::Cast(primary_node->primary()), |
| 8820 ClassFinalizer::kCanonicalize); | 8788 ClassFinalizer::kCanonicalize); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 8840 AstNode* Parser::ParsePostfixExpr() { | 8808 AstNode* Parser::ParsePostfixExpr() { |
| 8841 TRACE_PARSER("ParsePostfixExpr"); | 8809 TRACE_PARSER("ParsePostfixExpr"); |
| 8842 String* expr_ident = | 8810 String* expr_ident = |
| 8843 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 8811 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 8844 const intptr_t expr_pos = TokenPos(); | 8812 const intptr_t expr_pos = TokenPos(); |
| 8845 AstNode* expr = ParsePrimary(); | 8813 AstNode* expr = ParsePrimary(); |
| 8846 expr = ParseSelectors(expr, false); | 8814 expr = ParseSelectors(expr, false); |
| 8847 if (IsIncrementOperator(CurrentToken())) { | 8815 if (IsIncrementOperator(CurrentToken())) { |
| 8848 TRACE_PARSER("IncrementOperator"); | 8816 TRACE_PARSER("IncrementOperator"); |
| 8849 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 8817 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 8850 ErrorMsg(expr_pos, "expression is not assignable"); | 8818 ReportError(expr_pos, "expression is not assignable"); |
| 8851 } | 8819 } |
| 8852 Token::Kind incr_op = CurrentToken(); | 8820 Token::Kind incr_op = CurrentToken(); |
| 8853 ConsumeToken(); | 8821 ConsumeToken(); |
| 8854 // Not prefix. | 8822 // Not prefix. |
| 8855 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 8823 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 8856 LocalVariable* temp = let_expr->AddInitializer(expr); | 8824 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 8857 Token::Kind binary_op = | 8825 Token::Kind binary_op = |
| 8858 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 8826 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 8859 BinaryOpNode* add = new(I) BinaryOpNode( | 8827 BinaryOpNode* add = new(I) BinaryOpNode( |
| 8860 expr_pos, | 8828 expr_pos, |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8981 const bool kTestOnly = false; | 8949 const bool kTestOnly = false; |
| 8982 return current_block_->scope->LookupVariable(ident, kTestOnly); | 8950 return current_block_->scope->LookupVariable(ident, kTestOnly); |
| 8983 } | 8951 } |
| 8984 | 8952 |
| 8985 | 8953 |
| 8986 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 8954 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, |
| 8987 const String& field_name) { | 8955 const String& field_name) { |
| 8988 // Fields are not accessible from a static function, except from a | 8956 // Fields are not accessible from a static function, except from a |
| 8989 // constructor, which is considered as non-static by the compiler. | 8957 // constructor, which is considered as non-static by the compiler. |
| 8990 if (current_function().is_static()) { | 8958 if (current_function().is_static()) { |
| 8991 ErrorMsg(field_pos, | 8959 ReportError(field_pos, |
| 8992 "cannot access instance field '%s' from a static function", | 8960 "cannot access instance field '%s' from a static function", |
| 8993 field_name.ToCString()); | 8961 field_name.ToCString()); |
| 8994 } | 8962 } |
| 8995 } | 8963 } |
| 8996 | 8964 |
| 8997 | 8965 |
| 8998 bool Parser::ParsingStaticMember() const { | 8966 bool Parser::ParsingStaticMember() const { |
| 8999 if (is_top_level_) { | 8967 if (is_top_level_) { |
| 9000 return (current_member_ != NULL) && | 8968 return (current_member_ != NULL) && |
| 9001 current_member_->has_static && !current_member_->has_factory; | 8969 current_member_->has_static && !current_member_->has_factory; |
| 9002 } | 8970 } |
| 9003 ASSERT(!current_function().IsNull()); | 8971 ASSERT(!current_function().IsNull()); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9035 | 9003 |
| 9036 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 9004 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
| 9037 intptr_t token_pos) { | 9005 intptr_t token_pos) { |
| 9038 if (instance.IsNull()) { | 9006 if (instance.IsNull()) { |
| 9039 return instance.raw(); | 9007 return instance.raw(); |
| 9040 } | 9008 } |
| 9041 const char* error_str = NULL; | 9009 const char* error_str = NULL; |
| 9042 Instance& result = | 9010 Instance& result = |
| 9043 Instance::Handle(I, instance.CheckAndCanonicalize(&error_str)); | 9011 Instance::Handle(I, instance.CheckAndCanonicalize(&error_str)); |
| 9044 if (result.IsNull()) { | 9012 if (result.IsNull()) { |
| 9045 ErrorMsg(token_pos, "Invalid const object %s", error_str); | 9013 ReportError(token_pos, "Invalid const object %s", error_str); |
| 9046 } | 9014 } |
| 9047 return result.raw(); | 9015 return result.raw(); |
| 9048 } | 9016 } |
| 9049 | 9017 |
| 9050 | 9018 |
| 9051 // If the field is already initialized, return no ast (NULL). | 9019 // If the field is already initialized, return no ast (NULL). |
| 9052 // Otherwise, if the field is constant, initialize the field and return no ast. | 9020 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 9053 // If the field is not initialized and not const, return the ast for the getter. | 9021 // If the field is not initialized and not const, return the ast for the getter. |
| 9054 AstNode* Parser::RunStaticFieldInitializer(const Field& field, | 9022 AstNode* Parser::RunStaticFieldInitializer(const Field& field, |
| 9055 intptr_t field_ref_pos) { | 9023 intptr_t field_ref_pos) { |
| 9056 ASSERT(field.is_static()); | 9024 ASSERT(field.is_static()); |
| 9057 const Class& field_owner = Class::ZoneHandle(I, field.owner()); | 9025 const Class& field_owner = Class::ZoneHandle(I, field.owner()); |
| 9058 const String& field_name = String::ZoneHandle(I, field.name()); | 9026 const String& field_name = String::ZoneHandle(I, field.name()); |
| 9059 const String& getter_name = String::Handle(I, Field::GetterName(field_name)); | 9027 const String& getter_name = String::Handle(I, Field::GetterName(field_name)); |
| 9060 const Function& getter = Function::Handle(I, | 9028 const Function& getter = Function::Handle(I, |
| 9061 field_owner.LookupStaticFunction(getter_name)); | 9029 field_owner.LookupStaticFunction(getter_name)); |
| 9062 const Instance& value = Instance::Handle(I, field.value()); | 9030 const Instance& value = Instance::Handle(I, field.value()); |
| 9063 if (value.raw() == Object::transition_sentinel().raw()) { | 9031 if (value.raw() == Object::transition_sentinel().raw()) { |
| 9064 if (field.is_const()) { | 9032 if (field.is_const()) { |
| 9065 ErrorMsg("circular dependency while initializing static field '%s'", | 9033 ReportError("circular dependency while initializing static field '%s'", |
| 9066 field_name.ToCString()); | 9034 field_name.ToCString()); |
| 9067 } else { | 9035 } else { |
| 9068 // The implicit static getter will throw the exception if necessary. | 9036 // The implicit static getter will throw the exception if necessary. |
| 9069 return new(I) StaticGetterNode( | 9037 return new(I) StaticGetterNode( |
| 9070 field_ref_pos, NULL, false, field_owner, field_name); | 9038 field_ref_pos, NULL, false, field_owner, field_name); |
| 9071 } | 9039 } |
| 9072 } else if (value.raw() == Object::sentinel().raw()) { | 9040 } else if (value.raw() == Object::sentinel().raw()) { |
| 9073 // This field has not been referenced yet and thus the value has | 9041 // This field has not been referenced yet and thus the value has |
| 9074 // not been evaluated. If the field is const, call the static getter method | 9042 // not been evaluated. If the field is const, call the static getter method |
| 9075 // to evaluate the expression and canonicalize the value. | 9043 // to evaluate the expression and canonicalize the value. |
| 9076 if (field.is_const()) { | 9044 if (field.is_const()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 9091 if (const_value.IsError()) { | 9059 if (const_value.IsError()) { |
| 9092 const Error& error = Error::Cast(const_value); | 9060 const Error& error = Error::Cast(const_value); |
| 9093 if (error.IsUnhandledException()) { | 9061 if (error.IsUnhandledException()) { |
| 9094 // An exception may not occur in every parse attempt, i.e., the | 9062 // An exception may not occur in every parse attempt, i.e., the |
| 9095 // generated AST is not deterministic. Therefore mark the function as | 9063 // generated AST is not deterministic. Therefore mark the function as |
| 9096 // not optimizable. | 9064 // not optimizable. |
| 9097 current_function().SetIsOptimizable(false); | 9065 current_function().SetIsOptimizable(false); |
| 9098 field.set_value(Object::null_instance()); | 9066 field.set_value(Object::null_instance()); |
| 9099 // It is a compile-time error if evaluation of a compile-time constant | 9067 // It is a compile-time error if evaluation of a compile-time constant |
| 9100 // would raise an exception. | 9068 // would raise an exception. |
| 9101 AppendErrorMsg(error, field_ref_pos, | 9069 const String& field_name = String::Handle(I, field.name()); |
| 9102 "error initializing const field '%s'", | 9070 ReportErrors(error, |
| 9103 String::Handle(I, field.name()).ToCString()); | 9071 script_, field_ref_pos, |
| 9072 "error initializing const field '%s'", |
| 9073 field_name.ToCString()); |
| 9104 } else { | 9074 } else { |
| 9105 I->long_jump_base()->Jump(1, error); | 9075 ReportError(error); |
| 9106 UNREACHABLE(); | |
| 9107 } | 9076 } |
| 9077 UNREACHABLE(); |
| 9108 } | 9078 } |
| 9109 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 9079 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 9110 Instance& instance = Instance::Handle(I); | 9080 Instance& instance = Instance::Handle(I); |
| 9111 instance ^= const_value.raw(); | 9081 instance ^= const_value.raw(); |
| 9112 instance = TryCanonicalize(instance, field_ref_pos); | 9082 instance = TryCanonicalize(instance, field_ref_pos); |
| 9113 field.set_value(instance); | 9083 field.set_value(instance); |
| 9114 return NULL; // Constant | 9084 return NULL; // Constant |
| 9115 } else { | 9085 } else { |
| 9116 return new(I) StaticGetterNode( | 9086 return new(I) StaticGetterNode( |
| 9117 field_ref_pos, NULL, false, field_owner, field_name); | 9087 field_ref_pos, NULL, false, field_owner, field_name); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 9135 // Factories have one extra argument: the type arguments. | 9105 // Factories have one extra argument: the type arguments. |
| 9136 // Constructors have 2 extra arguments: rcvr and construction phase. | 9106 // Constructors have 2 extra arguments: rcvr and construction phase. |
| 9137 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; | 9107 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; |
| 9138 const int num_arguments = arguments->length() + kNumExtraArgs; | 9108 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 9139 const Array& arg_values = Array::Handle(I, Array::New(num_arguments)); | 9109 const Array& arg_values = Array::Handle(I, Array::New(num_arguments)); |
| 9140 Instance& instance = Instance::Handle(I); | 9110 Instance& instance = Instance::Handle(I); |
| 9141 if (!constructor.IsFactory()) { | 9111 if (!constructor.IsFactory()) { |
| 9142 instance = Instance::New(type_class, Heap::kOld); | 9112 instance = Instance::New(type_class, Heap::kOld); |
| 9143 if (!type_arguments.IsNull()) { | 9113 if (!type_arguments.IsNull()) { |
| 9144 if (!type_arguments.IsInstantiated()) { | 9114 if (!type_arguments.IsInstantiated()) { |
| 9145 ErrorMsg("type must be constant in const constructor"); | 9115 ReportError("type must be constant in const constructor"); |
| 9146 } | 9116 } |
| 9147 instance.SetTypeArguments( | 9117 instance.SetTypeArguments( |
| 9148 TypeArguments::Handle(I, type_arguments.Canonicalize())); | 9118 TypeArguments::Handle(I, type_arguments.Canonicalize())); |
| 9149 } | 9119 } |
| 9150 arg_values.SetAt(0, instance); | 9120 arg_values.SetAt(0, instance); |
| 9151 arg_values.SetAt(1, Smi::Handle(I, Smi::New(Function::kCtorPhaseAll))); | 9121 arg_values.SetAt(1, Smi::Handle(I, Smi::New(Function::kCtorPhaseAll))); |
| 9152 } else { | 9122 } else { |
| 9153 // Prepend type_arguments to list of arguments to factory. | 9123 // Prepend type_arguments to list of arguments to factory. |
| 9154 ASSERT(type_arguments.IsZoneHandle()); | 9124 ASSERT(type_arguments.IsZoneHandle()); |
| 9155 arg_values.SetAt(0, type_arguments); | 9125 arg_values.SetAt(0, type_arguments); |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9494 InvocationMirror::kField, | 9464 InvocationMirror::kField, |
| 9495 NULL); // No existing function. | 9465 NULL); // No existing function. |
| 9496 } else { | 9466 } else { |
| 9497 // Treat as call to unresolved instance field. | 9467 // Treat as call to unresolved instance field. |
| 9498 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 9468 resolved = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 9499 } | 9469 } |
| 9500 } else if (primary->primary().IsFunction()) { | 9470 } else if (primary->primary().IsFunction()) { |
| 9501 if (allow_closure_names) { | 9471 if (allow_closure_names) { |
| 9502 resolved = LoadClosure(primary); | 9472 resolved = LoadClosure(primary); |
| 9503 } else { | 9473 } else { |
| 9504 ErrorMsg(ident_pos, "illegal reference to method '%s'", | 9474 ReportError(ident_pos, "illegal reference to method '%s'", |
| 9505 ident.ToCString()); | 9475 ident.ToCString()); |
| 9506 } | 9476 } |
| 9507 } else if (primary->primary().IsClass()) { | 9477 } else if (primary->primary().IsClass()) { |
| 9508 const Class& type_class = Class::Cast(primary->primary()); | 9478 const Class& type_class = Class::Cast(primary->primary()); |
| 9509 AbstractType& type = Type::ZoneHandle(I, | 9479 AbstractType& type = Type::ZoneHandle(I, |
| 9510 Type::New(type_class, TypeArguments::Handle(I), primary_pos)); | 9480 Type::New(type_class, TypeArguments::Handle(I), primary_pos)); |
| 9511 type ^= ClassFinalizer::FinalizeType( | 9481 type ^= ClassFinalizer::FinalizeType( |
| 9512 current_class(), type, ClassFinalizer::kCanonicalize); | 9482 current_class(), type, ClassFinalizer::kCanonicalize); |
| 9513 // Type may be malbounded, but not malformed. | 9483 // Type may be malbounded, but not malformed. |
| 9514 ASSERT(!type.IsMalformed()); | 9484 ASSERT(!type.IsMalformed()); |
| 9515 resolved = new(I) TypeNode(primary_pos, type); | 9485 resolved = new(I) TypeNode(primary_pos, type); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9594 intptr_t pos, const Function& constructor, | 9564 intptr_t pos, const Function& constructor, |
| 9595 const TypeArguments& type_arguments) { | 9565 const TypeArguments& type_arguments) { |
| 9596 if (!type_arguments.IsNull()) { | 9566 if (!type_arguments.IsNull()) { |
| 9597 const Class& constructor_class = Class::Handle(I, constructor.Owner()); | 9567 const Class& constructor_class = Class::Handle(I, constructor.Owner()); |
| 9598 ASSERT(!constructor_class.IsNull()); | 9568 ASSERT(!constructor_class.IsNull()); |
| 9599 ASSERT(constructor_class.is_finalized()); | 9569 ASSERT(constructor_class.is_finalized()); |
| 9600 ASSERT(type_arguments.IsCanonical()); | 9570 ASSERT(type_arguments.IsCanonical()); |
| 9601 // Do not report the expected vs. actual number of type arguments, because | 9571 // Do not report the expected vs. actual number of type arguments, because |
| 9602 // the type argument vector is flattened and raw types are allowed. | 9572 // the type argument vector is flattened and raw types are allowed. |
| 9603 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 9573 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
| 9604 ErrorMsg(pos, "wrong number of type arguments passed to constructor"); | 9574 ReportError(pos, "wrong number of type arguments passed to constructor"); |
| 9605 } | 9575 } |
| 9606 } | 9576 } |
| 9607 } | 9577 } |
| 9608 | 9578 |
| 9609 | 9579 |
| 9610 // Parse "[" [ expr { "," expr } ["," ] "]". | 9580 // Parse "[" [ expr { "," expr } ["," ] "]". |
| 9611 // Note: if the list literal is empty and the brackets have no whitespace | 9581 // Note: if the list literal is empty and the brackets have no whitespace |
| 9612 // between them, the scanner recognizes the opening and closing bracket | 9582 // between them, the scanner recognizes the opening and closing bracket |
| 9613 // as one token of type Token::kINDEX. | 9583 // as one token of type Token::kINDEX. |
| 9614 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 9584 AstNode* Parser::ParseListLiteral(intptr_t type_pos, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 9629 if (!list_type_arguments.IsNull()) { | 9599 if (!list_type_arguments.IsNull()) { |
| 9630 ASSERT(list_type_arguments.Length() > 0); | 9600 ASSERT(list_type_arguments.Length() > 0); |
| 9631 // List literals take a single type argument. | 9601 // List literals take a single type argument. |
| 9632 if (list_type_arguments.Length() == 1) { | 9602 if (list_type_arguments.Length() == 1) { |
| 9633 element_type = list_type_arguments.TypeAt(0); | 9603 element_type = list_type_arguments.TypeAt(0); |
| 9634 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. | 9604 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. |
| 9635 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. | 9605 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. |
| 9636 if (element_type.IsDynamicType()) { | 9606 if (element_type.IsDynamicType()) { |
| 9637 list_type_arguments = TypeArguments::null(); | 9607 list_type_arguments = TypeArguments::null(); |
| 9638 } else if (is_const && !element_type.IsInstantiated()) { | 9608 } else if (is_const && !element_type.IsInstantiated()) { |
| 9639 ErrorMsg(type_pos, | 9609 ReportError(type_pos, |
| 9640 "the type argument of a constant list literal cannot include " | 9610 "the type argument of a constant list literal cannot " |
| 9641 "a type variable"); | 9611 "include a type variable"); |
| 9642 } | 9612 } |
| 9643 } else { | 9613 } else { |
| 9644 if (FLAG_error_on_bad_type) { | 9614 if (FLAG_error_on_bad_type) { |
| 9645 ErrorMsg(type_pos, | 9615 ReportError(type_pos, |
| 9646 "a list literal takes one type argument specifying " | 9616 "a list literal takes one type argument specifying " |
| 9647 "the element type"); | 9617 "the element type"); |
| 9648 } | 9618 } |
| 9649 // Ignore type arguments. | 9619 // Ignore type arguments. |
| 9650 list_type_arguments = TypeArguments::null(); | 9620 list_type_arguments = TypeArguments::null(); |
| 9651 } | 9621 } |
| 9652 } | 9622 } |
| 9653 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); | 9623 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
| 9654 const Class& array_class = Class::Handle(I, I->object_store()->array_class()); | 9624 const Class& array_class = Class::Handle(I, I->object_store()->array_class()); |
| 9655 Type& type = Type::ZoneHandle(I, | 9625 Type& type = Type::ZoneHandle(I, |
| 9656 Type::New(array_class, list_type_arguments, type_pos)); | 9626 Type::New(array_class, list_type_arguments, type_pos)); |
| 9657 type ^= ClassFinalizer::FinalizeType( | 9627 type ^= ClassFinalizer::FinalizeType( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 9669 !element_type.IsDynamicType()) { | 9639 !element_type.IsDynamicType()) { |
| 9670 element = new(I) AssignableNode(element_pos, | 9640 element = new(I) AssignableNode(element_pos, |
| 9671 element, | 9641 element, |
| 9672 element_type, | 9642 element_type, |
| 9673 Symbols::ListLiteralElement()); | 9643 Symbols::ListLiteralElement()); |
| 9674 } | 9644 } |
| 9675 element_list.Add(element); | 9645 element_list.Add(element); |
| 9676 if (CurrentToken() == Token::kCOMMA) { | 9646 if (CurrentToken() == Token::kCOMMA) { |
| 9677 ConsumeToken(); | 9647 ConsumeToken(); |
| 9678 } else if (CurrentToken() != Token::kRBRACK) { | 9648 } else if (CurrentToken() != Token::kRBRACK) { |
| 9679 ErrorMsg("comma or ']' expected"); | 9649 ReportError("comma or ']' expected"); |
| 9680 } | 9650 } |
| 9681 } | 9651 } |
| 9682 ExpectToken(Token::kRBRACK); | 9652 ExpectToken(Token::kRBRACK); |
| 9683 SetAllowFunctionLiterals(saved_mode); | 9653 SetAllowFunctionLiterals(saved_mode); |
| 9684 } | 9654 } |
| 9685 | 9655 |
| 9686 if (is_const) { | 9656 if (is_const) { |
| 9687 // Allocate and initialize the const list at compile time. | 9657 // Allocate and initialize the const list at compile time. |
| 9688 Array& const_list = | 9658 Array& const_list = |
| 9689 Array::ZoneHandle(I, Array::New(element_list.length(), Heap::kOld)); | 9659 Array::ZoneHandle(I, Array::New(element_list.length(), Heap::kOld)); |
| 9690 const_list.SetTypeArguments( | 9660 const_list.SetTypeArguments( |
| 9691 TypeArguments::Handle(I, list_type_arguments.Canonicalize())); | 9661 TypeArguments::Handle(I, list_type_arguments.Canonicalize())); |
| 9692 Error& malformed_error = Error::Handle(I); | 9662 Error& malformed_error = Error::Handle(I); |
| 9693 for (int i = 0; i < element_list.length(); i++) { | 9663 for (int i = 0; i < element_list.length(); i++) { |
| 9694 AstNode* elem = element_list[i]; | 9664 AstNode* elem = element_list[i]; |
| 9695 // Arguments have been evaluated to a literal value already. | 9665 // Arguments have been evaluated to a literal value already. |
| 9696 ASSERT(elem->IsLiteralNode()); | 9666 ASSERT(elem->IsLiteralNode()); |
| 9697 ASSERT(!is_top_level_); // We cannot check unresolved types. | 9667 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 9698 if (FLAG_enable_type_checks && | 9668 if (FLAG_enable_type_checks && |
| 9699 !element_type.IsDynamicType() && | 9669 !element_type.IsDynamicType() && |
| 9700 (!elem->AsLiteralNode()->literal().IsNull() && | 9670 (!elem->AsLiteralNode()->literal().IsNull() && |
| 9701 !elem->AsLiteralNode()->literal().IsInstanceOf( | 9671 !elem->AsLiteralNode()->literal().IsInstanceOf( |
| 9702 element_type, | 9672 element_type, |
| 9703 TypeArguments::Handle(I), | 9673 TypeArguments::Handle(I), |
| 9704 &malformed_error))) { | 9674 &malformed_error))) { |
| 9705 // If the failure is due to a malformed type error, display it instead. | 9675 // If the failure is due to a malformed type error, display it instead. |
| 9706 if (!malformed_error.IsNull()) { | 9676 if (!malformed_error.IsNull()) { |
| 9707 ErrorMsg(malformed_error); | 9677 ReportError(malformed_error); |
| 9708 } else { | 9678 } else { |
| 9709 ErrorMsg(elem->AsLiteralNode()->token_pos(), | 9679 ReportError(elem->AsLiteralNode()->token_pos(), |
| 9710 "list literal element at index %d must be " | 9680 "list literal element at index %d must be " |
| 9711 "a constant of type '%s'", | 9681 "a constant of type '%s'", |
| 9712 i, | 9682 i, |
| 9713 String::Handle(I, | 9683 String::Handle(I, |
| 9714 element_type.UserVisibleName()).ToCString()); | 9684 element_type.UserVisibleName()).ToCString()); |
| 9715 } | 9685 } |
| 9716 } | 9686 } |
| 9717 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 9687 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 9718 } | 9688 } |
| 9719 const_list ^= TryCanonicalize(const_list, literal_pos); | 9689 const_list ^= TryCanonicalize(const_list, literal_pos); |
| 9720 const_list.MakeImmutable(); | 9690 const_list.MakeImmutable(); |
| 9721 return new(I) LiteralNode(literal_pos, const_list); | 9691 return new(I) LiteralNode(literal_pos, const_list); |
| 9722 } else { | 9692 } else { |
| 9723 // Factory call at runtime. | 9693 // Factory call at runtime. |
| 9724 const Class& factory_class = | 9694 const Class& factory_class = |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9828 if (map_type_arguments.Length() == 2) { | 9798 if (map_type_arguments.Length() == 2) { |
| 9829 key_type = map_type_arguments.TypeAt(0); | 9799 key_type = map_type_arguments.TypeAt(0); |
| 9830 value_type = map_type_arguments.TypeAt(1); | 9800 value_type = map_type_arguments.TypeAt(1); |
| 9831 // Malformed type arguments are mapped to dynamic. | 9801 // Malformed type arguments are mapped to dynamic. |
| 9832 ASSERT(!key_type.IsMalformed() && !value_type.IsMalformed()); | 9802 ASSERT(!key_type.IsMalformed() && !value_type.IsMalformed()); |
| 9833 // No declared bounds in Map. | 9803 // No declared bounds in Map. |
| 9834 ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); | 9804 ASSERT(!key_type.IsMalbounded() && !value_type.IsMalbounded()); |
| 9835 if (key_type.IsDynamicType() && value_type.IsDynamicType()) { | 9805 if (key_type.IsDynamicType() && value_type.IsDynamicType()) { |
| 9836 map_type_arguments = TypeArguments::null(); | 9806 map_type_arguments = TypeArguments::null(); |
| 9837 } else if (is_const && !type_arguments.IsInstantiated()) { | 9807 } else if (is_const && !type_arguments.IsInstantiated()) { |
| 9838 ErrorMsg(type_pos, | 9808 ReportError(type_pos, |
| 9839 "the type arguments of a constant map literal cannot include " | 9809 "the type arguments of a constant map literal cannot " |
| 9840 "a type variable"); | 9810 "include a type variable"); |
| 9841 } | 9811 } |
| 9842 } else { | 9812 } else { |
| 9843 if (FLAG_error_on_bad_type) { | 9813 if (FLAG_error_on_bad_type) { |
| 9844 ErrorMsg(type_pos, | 9814 ReportError(type_pos, |
| 9845 "a map literal takes two type arguments specifying " | 9815 "a map literal takes two type arguments specifying " |
| 9846 "the key type and the value type"); | 9816 "the key type and the value type"); |
| 9847 } | 9817 } |
| 9848 // Ignore type arguments. | 9818 // Ignore type arguments. |
| 9849 map_type_arguments = TypeArguments::null(); | 9819 map_type_arguments = TypeArguments::null(); |
| 9850 } | 9820 } |
| 9851 } | 9821 } |
| 9852 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 9822 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 9853 map_type_arguments ^= map_type_arguments.Canonicalize(); | 9823 map_type_arguments ^= map_type_arguments.Canonicalize(); |
| 9854 | 9824 |
| 9855 GrowableArray<AstNode*> kv_pairs_list; | 9825 GrowableArray<AstNode*> kv_pairs_list; |
| 9856 // Parse the map entries. Note: there may be an optional extra | 9826 // Parse the map entries. Note: there may be an optional extra |
| 9857 // comma after the last entry. | 9827 // comma after the last entry. |
| 9858 while (CurrentToken() != Token::kRBRACE) { | 9828 while (CurrentToken() != Token::kRBRACE) { |
| 9859 const bool saved_mode = SetAllowFunctionLiterals(true); | 9829 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 9860 const intptr_t key_pos = TokenPos(); | 9830 const intptr_t key_pos = TokenPos(); |
| 9861 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 9831 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
| 9862 if (FLAG_enable_type_checks && | 9832 if (FLAG_enable_type_checks && |
| 9863 !is_const && | 9833 !is_const && |
| 9864 !key_type.IsDynamicType()) { | 9834 !key_type.IsDynamicType()) { |
| 9865 key = new(I) AssignableNode( | 9835 key = new(I) AssignableNode( |
| 9866 key_pos, key, key_type, Symbols::ListLiteralElement()); | 9836 key_pos, key, key_type, Symbols::ListLiteralElement()); |
| 9867 } | 9837 } |
| 9868 if (is_const) { | 9838 if (is_const) { |
| 9869 ASSERT(key->IsLiteralNode()); | 9839 ASSERT(key->IsLiteralNode()); |
| 9870 const Instance& key_value = key->AsLiteralNode()->literal(); | 9840 const Instance& key_value = key->AsLiteralNode()->literal(); |
| 9871 if (key_value.IsDouble()) { | 9841 if (key_value.IsDouble()) { |
| 9872 ErrorMsg(key_pos, "key value must not be of type double"); | 9842 ReportError(key_pos, "key value must not be of type double"); |
| 9873 } | 9843 } |
| 9874 if (!key_value.IsInteger() && | 9844 if (!key_value.IsInteger() && |
| 9875 !key_value.IsString() && | 9845 !key_value.IsString() && |
| 9876 ImplementsEqualOperator(key_value)) { | 9846 ImplementsEqualOperator(key_value)) { |
| 9877 ErrorMsg(key_pos, "key value must not implement operator =="); | 9847 ReportError(key_pos, "key value must not implement operator =="); |
| 9878 } | 9848 } |
| 9879 } | 9849 } |
| 9880 ExpectToken(Token::kCOLON); | 9850 ExpectToken(Token::kCOLON); |
| 9881 const intptr_t value_pos = TokenPos(); | 9851 const intptr_t value_pos = TokenPos(); |
| 9882 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 9852 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
| 9883 SetAllowFunctionLiterals(saved_mode); | 9853 SetAllowFunctionLiterals(saved_mode); |
| 9884 if (FLAG_enable_type_checks && | 9854 if (FLAG_enable_type_checks && |
| 9885 !is_const && | 9855 !is_const && |
| 9886 !value_type.IsDynamicType()) { | 9856 !value_type.IsDynamicType()) { |
| 9887 value = new(I) AssignableNode( | 9857 value = new(I) AssignableNode( |
| 9888 value_pos, value, value_type, Symbols::ListLiteralElement()); | 9858 value_pos, value, value_type, Symbols::ListLiteralElement()); |
| 9889 } | 9859 } |
| 9890 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 9860 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
| 9891 | 9861 |
| 9892 if (CurrentToken() == Token::kCOMMA) { | 9862 if (CurrentToken() == Token::kCOMMA) { |
| 9893 ConsumeToken(); | 9863 ConsumeToken(); |
| 9894 } else if (CurrentToken() != Token::kRBRACE) { | 9864 } else if (CurrentToken() != Token::kRBRACE) { |
| 9895 ErrorMsg("comma or '}' expected"); | 9865 ReportError("comma or '}' expected"); |
| 9896 } | 9866 } |
| 9897 } | 9867 } |
| 9898 ASSERT(kv_pairs_list.length() % 2 == 0); | 9868 ASSERT(kv_pairs_list.length() % 2 == 0); |
| 9899 ExpectToken(Token::kRBRACE); | 9869 ExpectToken(Token::kRBRACE); |
| 9900 | 9870 |
| 9901 if (is_const) { | 9871 if (is_const) { |
| 9902 // Create the key-value pair array, canonicalize it and then create | 9872 // Create the key-value pair array, canonicalize it and then create |
| 9903 // the immutable map object with it. This all happens at compile time. | 9873 // the immutable map object with it. This all happens at compile time. |
| 9904 // The resulting immutable map object is returned as a literal. | 9874 // The resulting immutable map object is returned as a literal. |
| 9905 | 9875 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 9922 arg_type = value_type.raw(); | 9892 arg_type = value_type.raw(); |
| 9923 } | 9893 } |
| 9924 if (!arg_type.IsDynamicType() && | 9894 if (!arg_type.IsDynamicType() && |
| 9925 (!arg->AsLiteralNode()->literal().IsNull() && | 9895 (!arg->AsLiteralNode()->literal().IsNull() && |
| 9926 !arg->AsLiteralNode()->literal().IsInstanceOf( | 9896 !arg->AsLiteralNode()->literal().IsInstanceOf( |
| 9927 arg_type, | 9897 arg_type, |
| 9928 Object::null_type_arguments(), | 9898 Object::null_type_arguments(), |
| 9929 &malformed_error))) { | 9899 &malformed_error))) { |
| 9930 // If the failure is due to a malformed type error, display it. | 9900 // If the failure is due to a malformed type error, display it. |
| 9931 if (!malformed_error.IsNull()) { | 9901 if (!malformed_error.IsNull()) { |
| 9932 ErrorMsg(malformed_error); | 9902 ReportError(malformed_error); |
| 9933 } else { | 9903 } else { |
| 9934 ErrorMsg(arg->AsLiteralNode()->token_pos(), | 9904 ReportError(arg->AsLiteralNode()->token_pos(), |
| 9935 "map literal %s at index %d must be " | 9905 "map literal %s at index %d must be " |
| 9936 "a constant of type '%s'", | 9906 "a constant of type '%s'", |
| 9937 ((i % 2) == 0) ? "key" : "value", | 9907 ((i % 2) == 0) ? "key" : "value", |
| 9938 i >> 1, | 9908 i >> 1, |
| 9939 String::Handle(I, | 9909 String::Handle(I, |
| 9940 arg_type.UserVisibleName()).ToCString()); | 9910 arg_type.UserVisibleName()).ToCString()); |
| 9941 } | 9911 } |
| 9942 } | 9912 } |
| 9943 } | 9913 } |
| 9944 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 9914 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 9945 } | 9915 } |
| 9946 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); | 9916 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); |
| 9947 key_value_array.MakeImmutable(); | 9917 key_value_array.MakeImmutable(); |
| 9948 | 9918 |
| 9949 // Construct the map object. | 9919 // Construct the map object. |
| 9950 const Class& immutable_map_class = Class::Handle(I, | 9920 const Class& immutable_map_class = Class::Handle(I, |
| 9951 Library::LookupCoreClass(Symbols::ImmutableMap())); | 9921 Library::LookupCoreClass(Symbols::ImmutableMap())); |
| 9952 ASSERT(!immutable_map_class.IsNull()); | 9922 ASSERT(!immutable_map_class.IsNull()); |
| 9953 // If the immutable map class extends other parameterized classes, we need | 9923 // If the immutable map class extends other parameterized classes, we need |
| 9954 // to adjust the type argument vector. This is currently not the case. | 9924 // to adjust the type argument vector. This is currently not the case. |
| 9955 ASSERT(immutable_map_class.NumTypeArguments() == 2); | 9925 ASSERT(immutable_map_class.NumTypeArguments() == 2); |
| 9956 ArgumentListNode* constr_args = new(I) ArgumentListNode(TokenPos()); | 9926 ArgumentListNode* constr_args = new(I) ArgumentListNode(TokenPos()); |
| 9957 constr_args->Add(new(I) LiteralNode(literal_pos, key_value_array)); | 9927 constr_args->Add(new(I) LiteralNode(literal_pos, key_value_array)); |
| 9958 const Function& map_constr = | 9928 const Function& map_constr = |
| 9959 Function::ZoneHandle(I, immutable_map_class.LookupConstructor( | 9929 Function::ZoneHandle(I, immutable_map_class.LookupConstructor( |
| 9960 Library::PrivateCoreLibName(Symbols::ImmutableMapConstructor()))); | 9930 Library::PrivateCoreLibName(Symbols::ImmutableMapConstructor()))); |
| 9961 ASSERT(!map_constr.IsNull()); | 9931 ASSERT(!map_constr.IsNull()); |
| 9962 const Object& constructor_result = Object::Handle(I, | 9932 const Object& constructor_result = Object::Handle(I, |
| 9963 EvaluateConstConstructorCall(immutable_map_class, | 9933 EvaluateConstConstructorCall(immutable_map_class, |
| 9964 map_type_arguments, | 9934 map_type_arguments, |
| 9965 map_constr, | 9935 map_constr, |
| 9966 constr_args)); | 9936 constr_args)); |
| 9967 if (constructor_result.IsUnhandledException()) { | 9937 if (constructor_result.IsUnhandledException()) { |
| 9968 AppendErrorMsg(Error::Cast(constructor_result), | 9938 ReportErrors(Error::Cast(constructor_result), |
| 9969 literal_pos, | 9939 script_, literal_pos, |
| 9970 "error executing const Map constructor"); | 9940 "error executing const Map constructor"); |
| 9971 } else { | 9941 } else { |
| 9972 const Instance& const_instance = Instance::Cast(constructor_result); | 9942 const Instance& const_instance = Instance::Cast(constructor_result); |
| 9973 return new(I) LiteralNode( | 9943 return new(I) LiteralNode( |
| 9974 literal_pos, Instance::ZoneHandle(I, const_instance.raw())); | 9944 literal_pos, Instance::ZoneHandle(I, const_instance.raw())); |
| 9975 } | 9945 } |
| 9976 } else { | 9946 } else { |
| 9977 // Factory call at runtime. | 9947 // Factory call at runtime. |
| 9978 const Class& factory_class = | 9948 const Class& factory_class = |
| 9979 Class::Handle(I, Library::LookupCoreClass(Symbols::Map())); | 9949 Class::Handle(I, Library::LookupCoreClass(Symbols::Map())); |
| 9980 ASSERT(!factory_class.IsNull()); | 9950 ASSERT(!factory_class.IsNull()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10034 // them here. | 10004 // them here. |
| 10035 // Map and List interfaces do not declare bounds on their type parameters, so | 10005 // Map and List interfaces do not declare bounds on their type parameters, so |
| 10036 // we will not see malbounded type arguments here. | 10006 // we will not see malbounded type arguments here. |
| 10037 AstNode* primary = NULL; | 10007 AstNode* primary = NULL; |
| 10038 if ((CurrentToken() == Token::kLBRACK) || | 10008 if ((CurrentToken() == Token::kLBRACK) || |
| 10039 (CurrentToken() == Token::kINDEX)) { | 10009 (CurrentToken() == Token::kINDEX)) { |
| 10040 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 10010 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 10041 } else if (CurrentToken() == Token::kLBRACE) { | 10011 } else if (CurrentToken() == Token::kLBRACE) { |
| 10042 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 10012 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 10043 } else { | 10013 } else { |
| 10044 ErrorMsg("unexpected token %s", Token::Str(CurrentToken())); | 10014 ReportError("unexpected token %s", Token::Str(CurrentToken())); |
| 10045 } | 10015 } |
| 10046 return primary; | 10016 return primary; |
| 10047 } | 10017 } |
| 10048 | 10018 |
| 10049 | 10019 |
| 10050 AstNode* Parser::ParseSymbolLiteral() { | 10020 AstNode* Parser::ParseSymbolLiteral() { |
| 10051 ASSERT(CurrentToken() == Token::kHASH); | 10021 ASSERT(CurrentToken() == Token::kHASH); |
| 10052 ConsumeToken(); | 10022 ConsumeToken(); |
| 10053 intptr_t symbol_pos = TokenPos(); | 10023 intptr_t symbol_pos = TokenPos(); |
| 10054 String& symbol = String::Handle(I); | 10024 String& symbol = String::Handle(I); |
| 10055 if (IsIdentifier()) { | 10025 if (IsIdentifier()) { |
| 10056 symbol = CurrentLiteral()->raw(); | 10026 symbol = CurrentLiteral()->raw(); |
| 10057 ConsumeToken(); | 10027 ConsumeToken(); |
| 10058 while (CurrentToken() == Token::kPERIOD) { | 10028 while (CurrentToken() == Token::kPERIOD) { |
| 10059 symbol = String::Concat(symbol, Symbols::Dot()); | 10029 symbol = String::Concat(symbol, Symbols::Dot()); |
| 10060 ConsumeToken(); | 10030 ConsumeToken(); |
| 10061 symbol = String::Concat(symbol, | 10031 symbol = String::Concat(symbol, |
| 10062 *ExpectIdentifier("identifier expected")); | 10032 *ExpectIdentifier("identifier expected")); |
| 10063 } | 10033 } |
| 10064 } else if (Token::CanBeOverloaded(CurrentToken())) { | 10034 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 10065 symbol = String::New(Token::Str(CurrentToken())); | 10035 symbol = String::New(Token::Str(CurrentToken())); |
| 10066 ConsumeToken(); | 10036 ConsumeToken(); |
| 10067 } else { | 10037 } else { |
| 10068 ErrorMsg("illegal symbol literal"); | 10038 ReportError("illegal symbol literal"); |
| 10069 } | 10039 } |
| 10070 // Lookup class Symbol from internal library and call the | 10040 // Lookup class Symbol from internal library and call the |
| 10071 // constructor to create a symbol instance. | 10041 // constructor to create a symbol instance. |
| 10072 const Library& lib = Library::Handle(I, Library::InternalLibrary()); | 10042 const Library& lib = Library::Handle(I, Library::InternalLibrary()); |
| 10073 const Class& symbol_class = Class::Handle(I, | 10043 const Class& symbol_class = Class::Handle(I, |
| 10074 lib.LookupClass(Symbols::Symbol())); | 10044 lib.LookupClass(Symbols::Symbol())); |
| 10075 ASSERT(!symbol_class.IsNull()); | 10045 ASSERT(!symbol_class.IsNull()); |
| 10076 ArgumentListNode* constr_args = new(I) ArgumentListNode(symbol_pos); | 10046 ArgumentListNode* constr_args = new(I) ArgumentListNode(symbol_pos); |
| 10077 constr_args->Add(new(I) LiteralNode( | 10047 constr_args->Add(new(I) LiteralNode( |
| 10078 symbol_pos, String::ZoneHandle(I, Symbols::New(symbol)))); | 10048 symbol_pos, String::ZoneHandle(I, Symbols::New(symbol)))); |
| 10079 const Function& constr = Function::ZoneHandle(I, | 10049 const Function& constr = Function::ZoneHandle(I, |
| 10080 symbol_class.LookupConstructor(Symbols::SymbolCtor())); | 10050 symbol_class.LookupConstructor(Symbols::SymbolCtor())); |
| 10081 ASSERT(!constr.IsNull()); | 10051 ASSERT(!constr.IsNull()); |
| 10082 const Object& result = Object::Handle(I, | 10052 const Object& result = Object::Handle(I, |
| 10083 EvaluateConstConstructorCall(symbol_class, | 10053 EvaluateConstConstructorCall(symbol_class, |
| 10084 TypeArguments::Handle(I), | 10054 TypeArguments::Handle(I), |
| 10085 constr, | 10055 constr, |
| 10086 constr_args)); | 10056 constr_args)); |
| 10087 if (result.IsUnhandledException()) { | 10057 if (result.IsUnhandledException()) { |
| 10088 AppendErrorMsg(Error::Cast(result), | 10058 ReportErrors(Error::Cast(result), |
| 10089 symbol_pos, | 10059 script_, symbol_pos, |
| 10090 "error executing const Symbol constructor"); | 10060 "error executing const Symbol constructor"); |
| 10091 } | 10061 } |
| 10092 const Instance& instance = Instance::Cast(result); | 10062 const Instance& instance = Instance::Cast(result); |
| 10093 return new(I) LiteralNode(symbol_pos, | 10063 return new(I) LiteralNode(symbol_pos, |
| 10094 Instance::ZoneHandle(I, instance.raw())); | 10064 Instance::ZoneHandle(I, instance.raw())); |
| 10095 } | 10065 } |
| 10096 | 10066 |
| 10097 | 10067 |
| 10098 static String& BuildConstructorName(const String& type_class_name, | 10068 static String& BuildConstructorName(const String& type_class_name, |
| 10099 const String* named_constructor) { | 10069 const String* named_constructor) { |
| 10100 // By convention, the static function implementing a named constructor 'C' | 10070 // By convention, the static function implementing a named constructor 'C' |
| 10101 // for class 'A' is labeled 'A.C', and the static function implementing the | 10071 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 10102 // unnamed constructor for class 'A' is labeled 'A.'. | 10072 // unnamed constructor for class 'A' is labeled 'A.'. |
| 10103 // This convention prevents users from explicitly calling constructors. | 10073 // This convention prevents users from explicitly calling constructors. |
| 10104 String& constructor_name = | 10074 String& constructor_name = |
| 10105 String::Handle(String::Concat(type_class_name, Symbols::Dot())); | 10075 String::Handle(String::Concat(type_class_name, Symbols::Dot())); |
| 10106 if (named_constructor != NULL) { | 10076 if (named_constructor != NULL) { |
| 10107 constructor_name = String::Concat(constructor_name, *named_constructor); | 10077 constructor_name = String::Concat(constructor_name, *named_constructor); |
| 10108 } | 10078 } |
| 10109 return constructor_name; | 10079 return constructor_name; |
| 10110 } | 10080 } |
| 10111 | 10081 |
| 10112 | 10082 |
| 10113 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 10083 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
| 10114 TRACE_PARSER("ParseNewOperator"); | 10084 TRACE_PARSER("ParseNewOperator"); |
| 10115 const intptr_t new_pos = TokenPos(); | 10085 const intptr_t new_pos = TokenPos(); |
| 10116 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 10086 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
| 10117 bool is_const = (op_kind == Token::kCONST); | 10087 bool is_const = (op_kind == Token::kCONST); |
| 10118 if (!IsIdentifier()) { | 10088 if (!IsIdentifier()) { |
| 10119 ErrorMsg("type name expected"); | 10089 ReportError("type name expected"); |
| 10120 } | 10090 } |
| 10121 intptr_t type_pos = TokenPos(); | 10091 intptr_t type_pos = TokenPos(); |
| 10122 // Can't allocate const objects of a deferred type. | 10092 // Can't allocate const objects of a deferred type. |
| 10123 const bool allow_deferred_type = !is_const; | 10093 const bool allow_deferred_type = !is_const; |
| 10124 AbstractType& type = AbstractType::Handle(I, | 10094 AbstractType& type = AbstractType::Handle(I, |
| 10125 ParseType(ClassFinalizer::kCanonicalizeWellFormed, allow_deferred_type)); | 10095 ParseType(ClassFinalizer::kCanonicalizeWellFormed, allow_deferred_type)); |
| 10126 // In case the type is malformed, throw a dynamic type error after finishing | 10096 // In case the type is malformed, throw a dynamic type error after finishing |
| 10127 // parsing the instance creation expression. | 10097 // parsing the instance creation expression. |
| 10128 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 10098 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
| 10129 // Replace the type with a malformed type. | 10099 // Replace the type with a malformed type. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 10151 // Parse constructor parameters. | 10121 // Parse constructor parameters. |
| 10152 CheckToken(Token::kLPAREN); | 10122 CheckToken(Token::kLPAREN); |
| 10153 intptr_t call_pos = TokenPos(); | 10123 intptr_t call_pos = TokenPos(); |
| 10154 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 10124 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
| 10155 | 10125 |
| 10156 // Parsing is complete, so we can return a throw in case of a malformed or | 10126 // Parsing is complete, so we can return a throw in case of a malformed or |
| 10157 // malbounded type or report a compile-time error if the constructor is const. | 10127 // malbounded type or report a compile-time error if the constructor is const. |
| 10158 if (type.IsMalformedOrMalbounded()) { | 10128 if (type.IsMalformedOrMalbounded()) { |
| 10159 if (is_const) { | 10129 if (is_const) { |
| 10160 const Error& error = Error::Handle(I, type.error()); | 10130 const Error& error = Error::Handle(I, type.error()); |
| 10161 ErrorMsg(error); | 10131 ReportError(error); |
| 10162 } | 10132 } |
| 10163 return ThrowTypeError(type_pos, type); | 10133 return ThrowTypeError(type_pos, type); |
| 10164 } | 10134 } |
| 10165 | 10135 |
| 10166 // Resolve the type and optional identifier to a constructor or factory. | 10136 // Resolve the type and optional identifier to a constructor or factory. |
| 10167 Class& type_class = Class::Handle(I, type.type_class()); | 10137 Class& type_class = Class::Handle(I, type.type_class()); |
| 10168 String& type_class_name = String::Handle(I, type_class.Name()); | 10138 String& type_class_name = String::Handle(I, type_class.Name()); |
| 10169 TypeArguments& type_arguments = | 10139 TypeArguments& type_arguments = |
| 10170 TypeArguments::ZoneHandle(I, type.arguments()); | 10140 TypeArguments::ZoneHandle(I, type.arguments()); |
| 10171 | 10141 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 10191 // Replace the type with a malformed type and compile a throw or report a | 10161 // Replace the type with a malformed type and compile a throw or report a |
| 10192 // compile-time error if the constructor is const. | 10162 // compile-time error if the constructor is const. |
| 10193 if (is_const) { | 10163 if (is_const) { |
| 10194 type = ClassFinalizer::NewFinalizedMalformedType( | 10164 type = ClassFinalizer::NewFinalizedMalformedType( |
| 10195 Error::Handle(I), // No previous error. | 10165 Error::Handle(I), // No previous error. |
| 10196 script_, | 10166 script_, |
| 10197 call_pos, | 10167 call_pos, |
| 10198 "class '%s' has no constructor or factory named '%s'", | 10168 "class '%s' has no constructor or factory named '%s'", |
| 10199 String::Handle(I, type_class.Name()).ToCString(), | 10169 String::Handle(I, type_class.Name()).ToCString(), |
| 10200 external_constructor_name.ToCString()); | 10170 external_constructor_name.ToCString()); |
| 10201 ErrorMsg(Error::Handle(I, type.error())); | 10171 ReportError(Error::Handle(I, type.error())); |
| 10202 } | 10172 } |
| 10203 return ThrowNoSuchMethodError(call_pos, | 10173 return ThrowNoSuchMethodError(call_pos, |
| 10204 type_class, | 10174 type_class, |
| 10205 external_constructor_name, | 10175 external_constructor_name, |
| 10206 arguments, | 10176 arguments, |
| 10207 InvocationMirror::kConstructor, | 10177 InvocationMirror::kConstructor, |
| 10208 InvocationMirror::kMethod, | 10178 InvocationMirror::kMethod, |
| 10209 NULL); // No existing function. | 10179 NULL); // No existing function. |
| 10210 } else if (constructor.IsRedirectingFactory()) { | 10180 } else if (constructor.IsRedirectingFactory()) { |
| 10211 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); | 10181 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); |
| 10212 Type& redirect_type = Type::Handle(I, constructor.RedirectionType()); | 10182 Type& redirect_type = Type::Handle(I, constructor.RedirectionType()); |
| 10213 if (!redirect_type.IsMalformedOrMalbounded() && | 10183 if (!redirect_type.IsMalformedOrMalbounded() && |
| 10214 !redirect_type.IsInstantiated()) { | 10184 !redirect_type.IsInstantiated()) { |
| 10215 // The type arguments of the redirection type are instantiated from the | 10185 // The type arguments of the redirection type are instantiated from the |
| 10216 // type arguments of the parsed type of the 'new' or 'const' expression. | 10186 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 10217 Error& error = Error::Handle(I); | 10187 Error& error = Error::Handle(I); |
| 10218 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); | 10188 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); |
| 10219 if (!error.IsNull()) { | 10189 if (!error.IsNull()) { |
| 10220 redirect_type = ClassFinalizer::NewFinalizedMalformedType( | 10190 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
| 10221 error, | 10191 error, |
| 10222 script_, | 10192 script_, |
| 10223 call_pos, | 10193 call_pos, |
| 10224 "redirecting factory type '%s' cannot be instantiated", | 10194 "redirecting factory type '%s' cannot be instantiated", |
| 10225 String::Handle(I, redirect_type.UserVisibleName()).ToCString()); | 10195 String::Handle(I, redirect_type.UserVisibleName()).ToCString()); |
| 10226 } | 10196 } |
| 10227 } | 10197 } |
| 10228 if (redirect_type.IsMalformedOrMalbounded()) { | 10198 if (redirect_type.IsMalformedOrMalbounded()) { |
| 10229 if (is_const) { | 10199 if (is_const) { |
| 10230 ErrorMsg(Error::Handle(I, redirect_type.error())); | 10200 ReportError(Error::Handle(I, redirect_type.error())); |
| 10231 } | 10201 } |
| 10232 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 10202 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
| 10233 } | 10203 } |
| 10234 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { | 10204 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { |
| 10235 // Additional type checking of the result is necessary. | 10205 // Additional type checking of the result is necessary. |
| 10236 type_bound = type.raw(); | 10206 type_bound = type.raw(); |
| 10237 } | 10207 } |
| 10238 type = redirect_type.raw(); | 10208 type = redirect_type.raw(); |
| 10239 type_class = type.type_class(); | 10209 type_class = type.type_class(); |
| 10240 type_class_name = type_class.Name(); | 10210 type_class_name = type_class.Name(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 10269 error_arguments)); | 10239 error_arguments)); |
| 10270 return result; | 10240 return result; |
| 10271 } | 10241 } |
| 10272 String& error_message = String::Handle(I); | 10242 String& error_message = String::Handle(I); |
| 10273 if (!constructor.AreValidArguments(arguments_length, | 10243 if (!constructor.AreValidArguments(arguments_length, |
| 10274 arguments->names(), | 10244 arguments->names(), |
| 10275 &error_message)) { | 10245 &error_message)) { |
| 10276 const String& external_constructor_name = | 10246 const String& external_constructor_name = |
| 10277 (named_constructor ? constructor_name : type_class_name); | 10247 (named_constructor ? constructor_name : type_class_name); |
| 10278 if (is_const) { | 10248 if (is_const) { |
| 10279 ErrorMsg(call_pos, | 10249 ReportError(call_pos, |
| 10280 "invalid arguments passed to constructor '%s' " | 10250 "invalid arguments passed to constructor '%s' " |
| 10281 "for class '%s': %s", | 10251 "for class '%s': %s", |
| 10282 external_constructor_name.ToCString(), | 10252 external_constructor_name.ToCString(), |
| 10283 String::Handle(I, type_class.Name()).ToCString(), | 10253 String::Handle(I, type_class.Name()).ToCString(), |
| 10284 error_message.ToCString()); | 10254 error_message.ToCString()); |
| 10285 } | 10255 } |
| 10286 return ThrowNoSuchMethodError(call_pos, | 10256 return ThrowNoSuchMethodError(call_pos, |
| 10287 type_class, | 10257 type_class, |
| 10288 external_constructor_name, | 10258 external_constructor_name, |
| 10289 arguments, | 10259 arguments, |
| 10290 InvocationMirror::kConstructor, | 10260 InvocationMirror::kConstructor, |
| 10291 InvocationMirror::kMethod, | 10261 InvocationMirror::kMethod, |
| 10292 &constructor); | 10262 &constructor); |
| 10293 } | 10263 } |
| 10294 | 10264 |
| 10295 // Return a throw in case of a malformed or malbounded type or report a | 10265 // Return a throw in case of a malformed or malbounded type or report a |
| 10296 // compile-time error if the constructor is const. | 10266 // compile-time error if the constructor is const. |
| 10297 if (type.IsMalformedOrMalbounded()) { | 10267 if (type.IsMalformedOrMalbounded()) { |
| 10298 if (is_const) { | 10268 if (is_const) { |
| 10299 ErrorMsg(Error::Handle(I, type.error())); | 10269 ReportError(Error::Handle(I, type.error())); |
| 10300 } | 10270 } |
| 10301 return ThrowTypeError(type_pos, type); | 10271 return ThrowTypeError(type_pos, type); |
| 10302 } | 10272 } |
| 10303 type_arguments ^= type_arguments.Canonicalize(); | 10273 type_arguments ^= type_arguments.Canonicalize(); |
| 10304 // Make the constructor call. | 10274 // Make the constructor call. |
| 10305 AstNode* new_object = NULL; | 10275 AstNode* new_object = NULL; |
| 10306 if (is_const) { | 10276 if (is_const) { |
| 10307 if (!constructor.is_const()) { | 10277 if (!constructor.is_const()) { |
| 10308 const String& external_constructor_name = | 10278 const String& external_constructor_name = |
| 10309 (named_constructor ? constructor_name : type_class_name); | 10279 (named_constructor ? constructor_name : type_class_name); |
| 10310 ErrorMsg("non-const constructor '%s' cannot be used in " | 10280 ReportError("non-const constructor '%s' cannot be used in " |
| 10311 "const object creation", | 10281 "const object creation", |
| 10312 external_constructor_name.ToCString()); | 10282 external_constructor_name.ToCString()); |
| 10313 } | 10283 } |
| 10314 const Object& constructor_result = Object::Handle(I, | 10284 const Object& constructor_result = Object::Handle(I, |
| 10315 EvaluateConstConstructorCall(type_class, | 10285 EvaluateConstConstructorCall(type_class, |
| 10316 type_arguments, | 10286 type_arguments, |
| 10317 constructor, | 10287 constructor, |
| 10318 arguments)); | 10288 arguments)); |
| 10319 if (constructor_result.IsUnhandledException()) { | 10289 if (constructor_result.IsUnhandledException()) { |
| 10320 // It's a compile-time error if invocation of a const constructor | 10290 // It's a compile-time error if invocation of a const constructor |
| 10321 // call fails. | 10291 // call fails. |
| 10322 AppendErrorMsg(Error::Cast(constructor_result), | 10292 ReportErrors(Error::Cast(constructor_result), |
| 10323 new_pos, | 10293 script_, new_pos, |
| 10324 "error while evaluating const constructor"); | 10294 "error while evaluating const constructor"); |
| 10325 } else { | 10295 } else { |
| 10326 // Const constructors can return null in the case where a const native | 10296 // Const constructors can return null in the case where a const native |
| 10327 // factory returns a null value. Thus we cannot use a Instance::Cast here. | 10297 // factory returns a null value. Thus we cannot use a Instance::Cast here. |
| 10328 Instance& const_instance = Instance::Handle(I); | 10298 Instance& const_instance = Instance::Handle(I); |
| 10329 const_instance ^= constructor_result.raw(); | 10299 const_instance ^= constructor_result.raw(); |
| 10330 new_object = new(I) LiteralNode( | 10300 new_object = new(I) LiteralNode( |
| 10331 new_pos, Instance::ZoneHandle(I, const_instance.raw())); | 10301 new_pos, Instance::ZoneHandle(I, const_instance.raw())); |
| 10332 if (!type_bound.IsNull()) { | 10302 if (!type_bound.IsNull()) { |
| 10333 ASSERT(!type_bound.IsMalformed()); | 10303 ASSERT(!type_bound.IsMalformed()); |
| 10334 Error& malformed_error = Error::Handle(I); | 10304 Error& malformed_error = Error::Handle(I); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10387 const Array& interpolate_arg = Array::Handle(I, Array::New(1)); | 10357 const Array& interpolate_arg = Array::Handle(I, Array::New(1)); |
| 10388 interpolate_arg.SetAt(0, value_arr); | 10358 interpolate_arg.SetAt(0, value_arr); |
| 10389 | 10359 |
| 10390 // Call interpolation function. | 10360 // Call interpolation function. |
| 10391 Object& result = Object::Handle(I); | 10361 Object& result = Object::Handle(I); |
| 10392 { | 10362 { |
| 10393 PAUSETIMERSCOPE(I, time_compilation); | 10363 PAUSETIMERSCOPE(I, time_compilation); |
| 10394 result = DartEntry::InvokeFunction(func, interpolate_arg); | 10364 result = DartEntry::InvokeFunction(func, interpolate_arg); |
| 10395 } | 10365 } |
| 10396 if (result.IsUnhandledException()) { | 10366 if (result.IsUnhandledException()) { |
| 10397 ErrorMsg("%s", Error::Cast(result).ToErrorCString()); | 10367 ReportError("%s", Error::Cast(result).ToErrorCString()); |
| 10398 } | 10368 } |
| 10399 String& concatenated = String::ZoneHandle(I); | 10369 String& concatenated = String::ZoneHandle(I); |
| 10400 concatenated ^= result.raw(); | 10370 concatenated ^= result.raw(); |
| 10401 concatenated = Symbols::New(concatenated); | 10371 concatenated = Symbols::New(concatenated); |
| 10402 return concatenated; | 10372 return concatenated; |
| 10403 } | 10373 } |
| 10404 | 10374 |
| 10405 | 10375 |
| 10406 // A string literal consists of the concatenation of the next n tokens | 10376 // A string literal consists of the concatenation of the next n tokens |
| 10407 // that satisfy the EBNF grammar: | 10377 // that satisfy the EBNF grammar: |
| (...skipping 22 matching lines...) Expand all Loading... |
| 10430 while (CurrentToken() == Token::kSTRING) { | 10400 while (CurrentToken() == Token::kSTRING) { |
| 10431 if (CurrentLiteral()->Length() > 0) { | 10401 if (CurrentLiteral()->Length() > 0) { |
| 10432 // Only add non-empty string sections to the values list | 10402 // Only add non-empty string sections to the values list |
| 10433 // that will be concatenated. | 10403 // that will be concatenated. |
| 10434 values_list.Add(new(I) LiteralNode(TokenPos(), *CurrentLiteral())); | 10404 values_list.Add(new(I) LiteralNode(TokenPos(), *CurrentLiteral())); |
| 10435 } | 10405 } |
| 10436 ConsumeToken(); | 10406 ConsumeToken(); |
| 10437 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 10407 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 10438 (CurrentToken() == Token::kINTERPOL_START)) { | 10408 (CurrentToken() == Token::kINTERPOL_START)) { |
| 10439 if (!allow_interpolation) { | 10409 if (!allow_interpolation) { |
| 10440 ErrorMsg("string interpolation not allowed in this context"); | 10410 ReportError("string interpolation not allowed in this context"); |
| 10441 } | 10411 } |
| 10442 has_interpolation = true; | 10412 has_interpolation = true; |
| 10443 AstNode* expr = NULL; | 10413 AstNode* expr = NULL; |
| 10444 const intptr_t expr_pos = TokenPos(); | 10414 const intptr_t expr_pos = TokenPos(); |
| 10445 if (CurrentToken() == Token::kINTERPOL_VAR) { | 10415 if (CurrentToken() == Token::kINTERPOL_VAR) { |
| 10446 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); | 10416 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); |
| 10447 ConsumeToken(); | 10417 ConsumeToken(); |
| 10448 } else { | 10418 } else { |
| 10449 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 10419 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
| 10450 ConsumeToken(); | 10420 ConsumeToken(); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10579 InvocationMirror::kTopLevel, | 10549 InvocationMirror::kTopLevel, |
| 10580 call_type, | 10550 call_type, |
| 10581 NULL); // No existing function. | 10551 NULL); // No existing function. |
| 10582 } | 10552 } |
| 10583 } | 10553 } |
| 10584 } | 10554 } |
| 10585 ASSERT(primary != NULL); | 10555 ASSERT(primary != NULL); |
| 10586 } else if (token == Token::kTHIS) { | 10556 } else if (token == Token::kTHIS) { |
| 10587 LocalVariable* local = LookupLocalScope(Symbols::This()); | 10557 LocalVariable* local = LookupLocalScope(Symbols::This()); |
| 10588 if (local == NULL) { | 10558 if (local == NULL) { |
| 10589 ErrorMsg("receiver 'this' is not in scope"); | 10559 ReportError("receiver 'this' is not in scope"); |
| 10590 } | 10560 } |
| 10591 primary = new(I) LoadLocalNode(TokenPos(), local); | 10561 primary = new(I) LoadLocalNode(TokenPos(), local); |
| 10592 ConsumeToken(); | 10562 ConsumeToken(); |
| 10593 } else if (token == Token::kINTEGER) { | 10563 } else if (token == Token::kINTEGER) { |
| 10594 const Integer& literal = Integer::ZoneHandle(I, CurrentIntegerLiteral()); | 10564 const Integer& literal = Integer::ZoneHandle(I, CurrentIntegerLiteral()); |
| 10595 primary = new(I) LiteralNode(TokenPos(), literal); | 10565 primary = new(I) LiteralNode(TokenPos(), literal); |
| 10596 ConsumeToken(); | 10566 ConsumeToken(); |
| 10597 } else if (token == Token::kTRUE) { | 10567 } else if (token == Token::kTRUE) { |
| 10598 primary = new(I) LiteralNode(TokenPos(), Bool::True()); | 10568 primary = new(I) LiteralNode(TokenPos(), Bool::True()); |
| 10599 ConsumeToken(); | 10569 ConsumeToken(); |
| 10600 } else if (token == Token::kFALSE) { | 10570 } else if (token == Token::kFALSE) { |
| 10601 primary = new(I) LiteralNode(TokenPos(), Bool::False()); | 10571 primary = new(I) LiteralNode(TokenPos(), Bool::False()); |
| 10602 ConsumeToken(); | 10572 ConsumeToken(); |
| 10603 } else if (token == Token::kNULL) { | 10573 } else if (token == Token::kNULL) { |
| 10604 primary = new(I) LiteralNode(TokenPos(), Instance::ZoneHandle(I)); | 10574 primary = new(I) LiteralNode(TokenPos(), Instance::ZoneHandle(I)); |
| 10605 ConsumeToken(); | 10575 ConsumeToken(); |
| 10606 } else if (token == Token::kLPAREN) { | 10576 } else if (token == Token::kLPAREN) { |
| 10607 ConsumeToken(); | 10577 ConsumeToken(); |
| 10608 const bool saved_mode = SetAllowFunctionLiterals(true); | 10578 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 10609 primary = ParseExpr(kAllowConst, kConsumeCascades); | 10579 primary = ParseExpr(kAllowConst, kConsumeCascades); |
| 10610 SetAllowFunctionLiterals(saved_mode); | 10580 SetAllowFunctionLiterals(saved_mode); |
| 10611 ExpectToken(Token::kRPAREN); | 10581 ExpectToken(Token::kRPAREN); |
| 10612 } else if (token == Token::kDOUBLE) { | 10582 } else if (token == Token::kDOUBLE) { |
| 10613 Double& double_value = Double::ZoneHandle(I, CurrentDoubleLiteral()); | 10583 Double& double_value = Double::ZoneHandle(I, CurrentDoubleLiteral()); |
| 10614 if (double_value.IsNull()) { | 10584 if (double_value.IsNull()) { |
| 10615 ErrorMsg("invalid double literal"); | 10585 ReportError("invalid double literal"); |
| 10616 } | 10586 } |
| 10617 primary = new(I) LiteralNode(TokenPos(), double_value); | 10587 primary = new(I) LiteralNode(TokenPos(), double_value); |
| 10618 ConsumeToken(); | 10588 ConsumeToken(); |
| 10619 } else if (token == Token::kSTRING) { | 10589 } else if (token == Token::kSTRING) { |
| 10620 primary = ParseStringLiteral(true); | 10590 primary = ParseStringLiteral(true); |
| 10621 } else if (token == Token::kNEW) { | 10591 } else if (token == Token::kNEW) { |
| 10622 ConsumeToken(); | 10592 ConsumeToken(); |
| 10623 primary = ParseNewOperator(Token::kNEW); | 10593 primary = ParseNewOperator(Token::kNEW); |
| 10624 } else if (token == Token::kCONST) { | 10594 } else if (token == Token::kCONST) { |
| 10625 if ((LookaheadToken(1) == Token::kLT) || | 10595 if ((LookaheadToken(1) == Token::kLT) || |
| 10626 (LookaheadToken(1) == Token::kLBRACK) || | 10596 (LookaheadToken(1) == Token::kLBRACK) || |
| 10627 (LookaheadToken(1) == Token::kINDEX) || | 10597 (LookaheadToken(1) == Token::kINDEX) || |
| 10628 (LookaheadToken(1) == Token::kLBRACE)) { | 10598 (LookaheadToken(1) == Token::kLBRACE)) { |
| 10629 primary = ParseCompoundLiteral(); | 10599 primary = ParseCompoundLiteral(); |
| 10630 } else { | 10600 } else { |
| 10631 ConsumeToken(); | 10601 ConsumeToken(); |
| 10632 primary = ParseNewOperator(Token::kCONST); | 10602 primary = ParseNewOperator(Token::kCONST); |
| 10633 } | 10603 } |
| 10634 } else if (token == Token::kLT || | 10604 } else if (token == Token::kLT || |
| 10635 token == Token::kLBRACK || | 10605 token == Token::kLBRACK || |
| 10636 token == Token::kINDEX || | 10606 token == Token::kINDEX || |
| 10637 token == Token::kLBRACE) { | 10607 token == Token::kLBRACE) { |
| 10638 primary = ParseCompoundLiteral(); | 10608 primary = ParseCompoundLiteral(); |
| 10639 } else if (token == Token::kHASH) { | 10609 } else if (token == Token::kHASH) { |
| 10640 primary = ParseSymbolLiteral(); | 10610 primary = ParseSymbolLiteral(); |
| 10641 } else if (token == Token::kSUPER) { | 10611 } else if (token == Token::kSUPER) { |
| 10642 if (current_function().is_static()) { | 10612 if (current_function().is_static()) { |
| 10643 ErrorMsg("cannot access superclass from static method"); | 10613 ReportError("cannot access superclass from static method"); |
| 10644 } | 10614 } |
| 10645 if (current_class().SuperClass() == Class::null()) { | 10615 if (current_class().SuperClass() == Class::null()) { |
| 10646 ErrorMsg("class '%s' does not have a superclass", | 10616 ReportError("class '%s' does not have a superclass", |
| 10647 String::Handle(I, current_class().Name()).ToCString()); | 10617 String::Handle(I, current_class().Name()).ToCString()); |
| 10648 } | 10618 } |
| 10649 if (current_class().IsMixinApplication()) { | 10619 if (current_class().IsMixinApplication()) { |
| 10650 const Type& mixin_type = Type::Handle(I, current_class().mixin()); | 10620 const Type& mixin_type = Type::Handle(I, current_class().mixin()); |
| 10651 if (mixin_type.type_class() == current_function().origin()) { | 10621 if (mixin_type.type_class() == current_function().origin()) { |
| 10652 ErrorMsg("method of mixin class '%s' may not refer to 'super'", | 10622 ReportError("method of mixin class '%s' may not refer to 'super'", |
| 10653 String::Handle(I, Class::Handle(I, | 10623 String::Handle(I, Class::Handle(I, |
| 10654 current_function().origin()).Name()).ToCString()); | 10624 current_function().origin()).Name()).ToCString()); |
| 10655 } | 10625 } |
| 10656 } | 10626 } |
| 10657 const intptr_t super_pos = TokenPos(); | 10627 const intptr_t super_pos = TokenPos(); |
| 10658 ConsumeToken(); | 10628 ConsumeToken(); |
| 10659 if (CurrentToken() == Token::kPERIOD) { | 10629 if (CurrentToken() == Token::kPERIOD) { |
| 10660 ConsumeToken(); | 10630 ConsumeToken(); |
| 10661 const intptr_t ident_pos = TokenPos(); | 10631 const intptr_t ident_pos = TokenPos(); |
| 10662 const String& ident = *ExpectIdentifier("identifier expected"); | 10632 const String& ident = *ExpectIdentifier("identifier expected"); |
| 10663 if (CurrentToken() == Token::kLPAREN) { | 10633 if (CurrentToken() == Token::kLPAREN) { |
| 10664 primary = ParseSuperCall(ident); | 10634 primary = ParseSuperCall(ident); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10700 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); | 10670 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); |
| 10701 // Compile time constant expressions cannot reference anything from a | 10671 // Compile time constant expressions cannot reference anything from a |
| 10702 // local scope. | 10672 // local scope. |
| 10703 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); | 10673 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); |
| 10704 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), | 10674 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), |
| 10705 empty_scope); | 10675 empty_scope); |
| 10706 seq->Add(ret); | 10676 seq->Add(ret); |
| 10707 | 10677 |
| 10708 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); | 10678 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); |
| 10709 if (result.IsError()) { | 10679 if (result.IsError()) { |
| 10710 AppendErrorMsg(Error::Cast(result), | 10680 ReportErrors(Error::Cast(result), |
| 10711 expr_pos, | 10681 script_, expr_pos, |
| 10712 "error evaluating constant expression"); | 10682 "error evaluating constant expression"); |
| 10713 } | 10683 } |
| 10714 ASSERT(result.IsInstance()); | 10684 ASSERT(result.IsInstance()); |
| 10715 Instance& value = Instance::ZoneHandle(I); | 10685 Instance& value = Instance::ZoneHandle(I); |
| 10716 value ^= result.raw(); | 10686 value ^= result.raw(); |
| 10717 value = TryCanonicalize(value, TokenPos()); | 10687 value = TryCanonicalize(value, TokenPos()); |
| 10718 return value; | 10688 return value; |
| 10719 } | 10689 } |
| 10720 } | 10690 } |
| 10721 | 10691 |
| 10722 | 10692 |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11046 void Parser::SkipQualIdent() { | 11016 void Parser::SkipQualIdent() { |
| 11047 ASSERT(IsIdentifier()); | 11017 ASSERT(IsIdentifier()); |
| 11048 ConsumeToken(); | 11018 ConsumeToken(); |
| 11049 if (CurrentToken() == Token::kPERIOD) { | 11019 if (CurrentToken() == Token::kPERIOD) { |
| 11050 ConsumeToken(); // Consume the kPERIOD token. | 11020 ConsumeToken(); // Consume the kPERIOD token. |
| 11051 ExpectIdentifier("identifier expected after '.'"); | 11021 ExpectIdentifier("identifier expected after '.'"); |
| 11052 } | 11022 } |
| 11053 } | 11023 } |
| 11054 | 11024 |
| 11055 } // namespace dart | 11025 } // namespace dart |
| OLD | NEW |