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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 isolate->object_store()->clear_sticky_error(); | 854 isolate->object_store()->clear_sticky_error(); |
855 isolate->set_long_jump_base(base); | 855 isolate->set_long_jump_base(base); |
856 return error.raw(); | 856 return error.raw(); |
857 } | 857 } |
858 UNREACHABLE(); | 858 UNREACHABLE(); |
859 return Object::null(); | 859 return Object::null(); |
860 } | 860 } |
861 | 861 |
862 | 862 |
863 RawArray* Parser::EvaluateMetadata() { | 863 RawArray* Parser::EvaluateMetadata() { |
864 if (CurrentToken() != Token::kAT) { | 864 CheckToken(Token::kAT, "Metadata character '@' expected"); |
865 ErrorMsg("Metadata character '@' expected"); | |
866 } | |
867 GrowableObjectArray& meta_values = | 865 GrowableObjectArray& meta_values = |
868 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 866 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
869 while (CurrentToken() == Token::kAT) { | 867 while (CurrentToken() == Token::kAT) { |
870 ConsumeToken(); | 868 ConsumeToken(); |
871 intptr_t expr_pos = TokenPos(); | 869 intptr_t expr_pos = TokenPos(); |
872 if (!IsIdentifier()) { | 870 if (!IsIdentifier()) { |
873 ExpectIdentifier("identifier expected"); | 871 ExpectIdentifier("identifier expected"); |
874 } | 872 } |
875 AstNode* expr = NULL; | 873 AstNode* expr = NULL; |
876 if ((LookaheadToken(1) == Token::kLPAREN) || | 874 if ((LookaheadToken(1) == Token::kLPAREN) || |
(...skipping 806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1683 ParseFormalParameters(allow_explicit_default_values, | 1681 ParseFormalParameters(allow_explicit_default_values, |
1684 evaluate_metadata, | 1682 evaluate_metadata, |
1685 params); | 1683 params); |
1686 if (params->has_optional_positional_parameters || | 1684 if (params->has_optional_positional_parameters || |
1687 params->has_optional_named_parameters) { | 1685 params->has_optional_named_parameters) { |
1688 // Parse optional parameters. | 1686 // Parse optional parameters. |
1689 ParseFormalParameters(allow_explicit_default_values, | 1687 ParseFormalParameters(allow_explicit_default_values, |
1690 evaluate_metadata, | 1688 evaluate_metadata, |
1691 params); | 1689 params); |
1692 if (params->has_optional_positional_parameters) { | 1690 if (params->has_optional_positional_parameters) { |
1693 if (CurrentToken() != Token::kRBRACK) { | 1691 CheckToken(Token::kRBRACK, "',' or ']' expected"); |
1694 ErrorMsg("',' or ']' expected"); | |
1695 } | |
1696 } else { | 1692 } else { |
1697 if (CurrentToken() != Token::kRBRACE) { | 1693 CheckToken(Token::kRBRACE, "',' or '}' expected"); |
1698 ErrorMsg("',' or '}' expected"); | |
1699 } | |
1700 } | 1694 } |
1701 ConsumeToken(); // ']' or '}'. | 1695 ConsumeToken(); // ']' or '}'. |
1702 } | 1696 } |
1703 if ((CurrentToken() != Token::kRPAREN) && | 1697 if ((CurrentToken() != Token::kRPAREN) && |
1704 !params->has_optional_positional_parameters && | 1698 !params->has_optional_positional_parameters && |
1705 !params->has_optional_named_parameters) { | 1699 !params->has_optional_named_parameters) { |
1706 ErrorMsg("',' or ')' expected"); | 1700 ErrorMsg("',' or ')' expected"); |
1707 } | 1701 } |
1708 } else { | 1702 } else { |
1709 ConsumeToken(); | 1703 ConsumeToken(); |
1710 } | 1704 } |
1711 ExpectToken(Token::kRPAREN); | 1705 ExpectToken(Token::kRPAREN); |
1712 } | 1706 } |
1713 | 1707 |
1714 | 1708 |
1715 String& Parser::ParseNativeDeclaration() { | 1709 String& Parser::ParseNativeDeclaration() { |
1716 TRACE_PARSER("ParseNativeDeclaration"); | 1710 TRACE_PARSER("ParseNativeDeclaration"); |
1717 ASSERT(IsLiteral("native")); | 1711 ASSERT(IsLiteral("native")); |
1718 ConsumeToken(); | 1712 ConsumeToken(); |
1719 if (CurrentToken() != Token::kSTRING) { | 1713 CheckToken(Token::kSTRING, "string literal expected"); |
1720 ErrorMsg("string literal expected"); | |
1721 } | |
1722 String& native_name = *CurrentLiteral(); | 1714 String& native_name = *CurrentLiteral(); |
1723 ConsumeToken(); | 1715 ConsumeToken(); |
1724 return native_name; | 1716 return native_name; |
1725 } | 1717 } |
1726 | 1718 |
1727 | 1719 |
1728 // Resolve and return the dynamic function of the given name in the superclass. | 1720 // Resolve and return the dynamic function of the given name in the superclass. |
1729 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1721 // If it is not found, and resolve_getter is true, try to resolve a getter of |
1730 // the same name. If it is still not found, return noSuchMethod and | 1722 // the same name. If it is still not found, return noSuchMethod and |
1731 // set is_no_such_method to true.. | 1723 // set is_no_such_method to true.. |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2112 ConsumeToken(); | 2104 ConsumeToken(); |
2113 const Class& super_class = Class::Handle(cls.SuperClass()); | 2105 const Class& super_class = Class::Handle(cls.SuperClass()); |
2114 ASSERT(!super_class.IsNull()); | 2106 ASSERT(!super_class.IsNull()); |
2115 String& ctor_name = String::Handle(super_class.Name()); | 2107 String& ctor_name = String::Handle(super_class.Name()); |
2116 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 2108 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
2117 if (CurrentToken() == Token::kPERIOD) { | 2109 if (CurrentToken() == Token::kPERIOD) { |
2118 ConsumeToken(); | 2110 ConsumeToken(); |
2119 ctor_name = String::Concat(ctor_name, | 2111 ctor_name = String::Concat(ctor_name, |
2120 *ExpectIdentifier("constructor name expected")); | 2112 *ExpectIdentifier("constructor name expected")); |
2121 } | 2113 } |
2122 if (CurrentToken() != Token::kLPAREN) { | 2114 CheckToken(Token::kLPAREN, "parameter list expected"); |
2123 ErrorMsg("parameter list expected"); | |
2124 } | |
2125 | 2115 |
2126 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2116 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
2127 // 'this' parameter is the first argument to super class constructor. | 2117 // 'this' parameter is the first argument to super class constructor. |
2128 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2118 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
2129 arguments->Add(implicit_argument); | 2119 arguments->Add(implicit_argument); |
2130 // Second implicit parameter is the construction phase. We optimistically | 2120 // Second implicit parameter is the construction phase. We optimistically |
2131 // assume that we can execute both the super initializer and the super | 2121 // assume that we can execute both the super initializer and the super |
2132 // constructor body. We may later change this to only execute the | 2122 // constructor body. We may later change this to only execute the |
2133 // super initializer. | 2123 // super initializer. |
2134 AstNode* phase_parameter = | 2124 AstNode* phase_parameter = |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2373 const intptr_t call_pos = TokenPos(); | 2363 const intptr_t call_pos = TokenPos(); |
2374 ConsumeToken(); | 2364 ConsumeToken(); |
2375 String& ctor_name = String::Handle(cls.Name()); | 2365 String& ctor_name = String::Handle(cls.Name()); |
2376 | 2366 |
2377 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 2367 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
2378 if (CurrentToken() == Token::kPERIOD) { | 2368 if (CurrentToken() == Token::kPERIOD) { |
2379 ConsumeToken(); | 2369 ConsumeToken(); |
2380 ctor_name = String::Concat(ctor_name, | 2370 ctor_name = String::Concat(ctor_name, |
2381 *ExpectIdentifier("constructor name expected")); | 2371 *ExpectIdentifier("constructor name expected")); |
2382 } | 2372 } |
2383 if (CurrentToken() != Token::kLPAREN) { | 2373 CheckToken(Token::kLPAREN, "parameter list expected"); |
2384 ErrorMsg("parameter list expected"); | |
2385 } | |
2386 | 2374 |
2387 ArgumentListNode* arguments = new ArgumentListNode(call_pos); | 2375 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
2388 // 'this' parameter is the first argument to constructor. | 2376 // 'this' parameter is the first argument to constructor. |
2389 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); | 2377 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); |
2390 arguments->Add(implicit_argument); | 2378 arguments->Add(implicit_argument); |
2391 // Construction phase parameter is second argument. | 2379 // Construction phase parameter is second argument. |
2392 LocalVariable* phase_param = LookupPhaseParameter(); | 2380 LocalVariable* phase_param = LookupPhaseParameter(); |
2393 ASSERT(phase_param != NULL); | 2381 ASSERT(phase_param != NULL); |
2394 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); | 2382 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); |
2395 arguments->Add(phase_argument); | 2383 arguments->Add(phase_argument); |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2995 void Parser::SkipInitializers() { | 2983 void Parser::SkipInitializers() { |
2996 ASSERT(CurrentToken() == Token::kCOLON); | 2984 ASSERT(CurrentToken() == Token::kCOLON); |
2997 do { | 2985 do { |
2998 ConsumeToken(); // Colon or comma. | 2986 ConsumeToken(); // Colon or comma. |
2999 if (CurrentToken() == Token::kSUPER) { | 2987 if (CurrentToken() == Token::kSUPER) { |
3000 ConsumeToken(); | 2988 ConsumeToken(); |
3001 if (CurrentToken() == Token::kPERIOD) { | 2989 if (CurrentToken() == Token::kPERIOD) { |
3002 ConsumeToken(); | 2990 ConsumeToken(); |
3003 ExpectIdentifier("identifier expected"); | 2991 ExpectIdentifier("identifier expected"); |
3004 } | 2992 } |
3005 if (CurrentToken() != Token::kLPAREN) { | 2993 CheckToken(Token::kLPAREN); |
3006 ErrorMsg("'(' expected"); | |
3007 } | |
3008 SkipToMatchingParenthesis(); | 2994 SkipToMatchingParenthesis(); |
3009 } else { | 2995 } else { |
3010 SkipIf(Token::kTHIS); | 2996 SkipIf(Token::kTHIS); |
3011 SkipIf(Token::kPERIOD); | 2997 SkipIf(Token::kPERIOD); |
3012 ExpectIdentifier("identifier expected"); | 2998 ExpectIdentifier("identifier expected"); |
3013 ExpectToken(Token::kASSIGN); | 2999 ExpectToken(Token::kASSIGN); |
3014 SetAllowFunctionLiterals(false); | 3000 SetAllowFunctionLiterals(false); |
3015 SkipExpr(); | 3001 SkipExpr(); |
3016 SetAllowFunctionLiterals(true); | 3002 SetAllowFunctionLiterals(true); |
3017 } | 3003 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3208 ConsumeToken(); // Colon. | 3194 ConsumeToken(); // Colon. |
3209 ExpectToken(Token::kTHIS); | 3195 ExpectToken(Token::kTHIS); |
3210 String& redir_name = String::ZoneHandle( | 3196 String& redir_name = String::ZoneHandle( |
3211 String::Concat(members->class_name(), Symbols::Dot())); | 3197 String::Concat(members->class_name(), Symbols::Dot())); |
3212 if (CurrentToken() == Token::kPERIOD) { | 3198 if (CurrentToken() == Token::kPERIOD) { |
3213 ConsumeToken(); | 3199 ConsumeToken(); |
3214 redir_name = String::Concat(redir_name, | 3200 redir_name = String::Concat(redir_name, |
3215 *ExpectIdentifier("constructor name expected")); | 3201 *ExpectIdentifier("constructor name expected")); |
3216 } | 3202 } |
3217 method->redirect_name = &redir_name; | 3203 method->redirect_name = &redir_name; |
3218 if (CurrentToken() != Token::kLPAREN) { | 3204 CheckToken(Token::kLPAREN); |
3219 ErrorMsg("'(' expected"); | |
3220 } | |
3221 SkipToMatchingParenthesis(); | 3205 SkipToMatchingParenthesis(); |
3222 } else { | 3206 } else { |
3223 SkipInitializers(); | 3207 SkipInitializers(); |
3224 } | 3208 } |
3225 } | 3209 } |
3226 | 3210 |
3227 // Only constructors can redirect to another method. | 3211 // Only constructors can redirect to another method. |
3228 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3212 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
3229 | 3213 |
3230 intptr_t method_end_pos = TokenPos(); | 3214 intptr_t method_end_pos = TokenPos(); |
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3677 *member.name = String::Concat(*member.name, Symbols::Dot()); | 3661 *member.name = String::Concat(*member.name, Symbols::Dot()); |
3678 if (CurrentToken() == Token::kPERIOD) { | 3662 if (CurrentToken() == Token::kPERIOD) { |
3679 // Named constructor. | 3663 // Named constructor. |
3680 ConsumeToken(); | 3664 ConsumeToken(); |
3681 member.dict_name = ExpectIdentifier("identifier expected"); | 3665 member.dict_name = ExpectIdentifier("identifier expected"); |
3682 *member.name = String::Concat(*member.name, *member.dict_name); | 3666 *member.name = String::Concat(*member.name, *member.dict_name); |
3683 } | 3667 } |
3684 // Ensure that names are symbols. | 3668 // Ensure that names are symbols. |
3685 *member.name = Symbols::New(*member.name); | 3669 *member.name = Symbols::New(*member.name); |
3686 | 3670 |
3687 if (CurrentToken() != Token::kLPAREN) { | 3671 CheckToken(Token::kLPAREN); |
3688 ErrorMsg("left parenthesis expected"); | |
3689 } | |
3690 } else if ((CurrentToken() == Token::kGET) && !member.has_var && | 3672 } else if ((CurrentToken() == Token::kGET) && !member.has_var && |
3691 (LookaheadToken(1) != Token::kLPAREN) && | 3673 (LookaheadToken(1) != Token::kLPAREN) && |
3692 (LookaheadToken(1) != Token::kASSIGN) && | 3674 (LookaheadToken(1) != Token::kASSIGN) && |
3693 (LookaheadToken(1) != Token::kCOMMA) && | 3675 (LookaheadToken(1) != Token::kCOMMA) && |
3694 (LookaheadToken(1) != Token::kSEMICOLON)) { | 3676 (LookaheadToken(1) != Token::kSEMICOLON)) { |
3695 ConsumeToken(); | 3677 ConsumeToken(); |
3696 member.kind = RawFunction::kGetterFunction; | 3678 member.kind = RawFunction::kGetterFunction; |
3697 member.name_pos = this->TokenPos(); | 3679 member.name_pos = this->TokenPos(); |
3698 member.name = ExpectIdentifier("identifier expected"); | 3680 member.name = ExpectIdentifier("identifier expected"); |
3699 // If the result type was not specified, it will be set to DynamicType. | 3681 // If the result type was not specified, it will be set to DynamicType. |
3700 } else if ((CurrentToken() == Token::kSET) && !member.has_var && | 3682 } else if ((CurrentToken() == Token::kSET) && !member.has_var && |
3701 (LookaheadToken(1) != Token::kLPAREN) && | 3683 (LookaheadToken(1) != Token::kLPAREN) && |
3702 (LookaheadToken(1) != Token::kASSIGN) && | 3684 (LookaheadToken(1) != Token::kASSIGN) && |
3703 (LookaheadToken(1) != Token::kCOMMA) && | 3685 (LookaheadToken(1) != Token::kCOMMA) && |
3704 (LookaheadToken(1) != Token::kSEMICOLON)) { | 3686 (LookaheadToken(1) != Token::kSEMICOLON)) { |
3705 ConsumeToken(); | 3687 ConsumeToken(); |
3706 member.kind = RawFunction::kSetterFunction; | 3688 member.kind = RawFunction::kSetterFunction; |
3707 member.name_pos = this->TokenPos(); | 3689 member.name_pos = this->TokenPos(); |
3708 member.name = ExpectIdentifier("identifier expected"); | 3690 member.name = ExpectIdentifier("identifier expected"); |
3709 if (CurrentToken() != Token::kLPAREN) { | 3691 CheckToken(Token::kLPAREN); |
3710 ErrorMsg("'(' expected"); | |
3711 } | |
3712 // The grammar allows a return type, so member.type is not always NULL here. | 3692 // The grammar allows a return type, so member.type is not always NULL here. |
3713 // If no return type is specified, the return type of the setter is dynamic. | 3693 // If no return type is specified, the return type of the setter is dynamic. |
3714 if (member.type == NULL) { | 3694 if (member.type == NULL) { |
3715 member.type = &Type::ZoneHandle(Type::DynamicType()); | 3695 member.type = &Type::ZoneHandle(Type::DynamicType()); |
3716 } | 3696 } |
3717 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && | 3697 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && |
3718 (LookaheadToken(1) != Token::kLPAREN) && | 3698 (LookaheadToken(1) != Token::kLPAREN) && |
3719 (LookaheadToken(1) != Token::kASSIGN) && | 3699 (LookaheadToken(1) != Token::kASSIGN) && |
3720 (LookaheadToken(1) != Token::kCOMMA) && | 3700 (LookaheadToken(1) != Token::kCOMMA) && |
3721 (LookaheadToken(1) != Token::kSEMICOLON)) { | 3701 (LookaheadToken(1) != Token::kSEMICOLON)) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3934 const Class& orig_class = Class::Cast(obj); | 3914 const Class& orig_class = Class::Cast(obj); |
3935 ASSERT(!orig_class.is_finalized()); | 3915 ASSERT(!orig_class.is_finalized()); |
3936 orig_class.set_patch_class(cls); | 3916 orig_class.set_patch_class(cls); |
3937 cls.set_is_patch(); | 3917 cls.set_is_patch(); |
3938 } | 3918 } |
3939 pending_classes.Add(cls, Heap::kOld); | 3919 pending_classes.Add(cls, Heap::kOld); |
3940 | 3920 |
3941 if (is_mixin_declaration) { | 3921 if (is_mixin_declaration) { |
3942 ExpectSemicolon(); | 3922 ExpectSemicolon(); |
3943 } else { | 3923 } else { |
3944 if (CurrentToken() != Token::kLBRACE) { | 3924 CheckToken(Token::kLBRACE); |
3945 ErrorMsg("{ expected"); | |
3946 } | |
3947 SkipBlock(); | 3925 SkipBlock(); |
3948 ExpectToken(Token::kRBRACE); | 3926 ExpectToken(Token::kRBRACE); |
3949 } | 3927 } |
3950 } | 3928 } |
3951 | 3929 |
3952 | 3930 |
3953 void Parser::ParseClassDefinition(const Class& cls) { | 3931 void Parser::ParseClassDefinition(const Class& cls) { |
3954 TRACE_PARSER("ParseClassDefinition"); | 3932 TRACE_PARSER("ParseClassDefinition"); |
3955 set_current_class(cls); | 3933 set_current_class(cls); |
3956 is_top_level_ = true; | 3934 is_top_level_ = true; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4100 const intptr_t type_pos = TokenPos(); | 4078 const intptr_t type_pos = TokenPos(); |
4101 AbstractType& type = | 4079 AbstractType& type = |
4102 AbstractType::Handle(ParseType(ClassFinalizer::kResolveTypeParameters)); | 4080 AbstractType::Handle(ParseType(ClassFinalizer::kResolveTypeParameters)); |
4103 if (type.IsTypeParameter()) { | 4081 if (type.IsTypeParameter()) { |
4104 ErrorMsg(type_pos, | 4082 ErrorMsg(type_pos, |
4105 "class '%s' may not extend type parameter '%s'", | 4083 "class '%s' may not extend type parameter '%s'", |
4106 class_name.ToCString(), | 4084 class_name.ToCString(), |
4107 String::Handle(type.UserVisibleName()).ToCString()); | 4085 String::Handle(type.UserVisibleName()).ToCString()); |
4108 } | 4086 } |
4109 | 4087 |
4110 if (CurrentToken() != Token::kWITH) { | 4088 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
4111 ErrorMsg("mixin application 'with Type' expected"); | |
4112 } | |
4113 type = ParseMixins(type); | 4089 type = ParseMixins(type); |
4114 | 4090 |
4115 mixin_application.set_super_type(type); | 4091 mixin_application.set_super_type(type); |
4116 mixin_application.set_is_synthesized_class(); | 4092 mixin_application.set_is_synthesized_class(); |
4117 | 4093 |
4118 // This mixin application typedef needs an implicit constructor, but it is | 4094 // This mixin application typedef needs an implicit constructor, but it is |
4119 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4095 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
4120 // because this class should be lazily compiled. | 4096 // because this class should be lazily compiled. |
4121 if (CurrentToken() == Token::kIMPLEMENTS) { | 4097 if (CurrentToken() == Token::kIMPLEMENTS) { |
4122 ParseInterfaceList(mixin_application); | 4098 ParseInterfaceList(mixin_application); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4219 // Parse the type parameters of the function type. | 4195 // Parse the type parameters of the function type. |
4220 ParseTypeParameters(function_type_alias); | 4196 ParseTypeParameters(function_type_alias); |
4221 // At this point, the type parameters have been parsed, so we can resolve the | 4197 // At this point, the type parameters have been parsed, so we can resolve the |
4222 // result type. | 4198 // result type. |
4223 if (!result_type.IsNull()) { | 4199 if (!result_type.IsNull()) { |
4224 ResolveTypeFromClass(function_type_alias, | 4200 ResolveTypeFromClass(function_type_alias, |
4225 ClassFinalizer::kResolveTypeParameters, | 4201 ClassFinalizer::kResolveTypeParameters, |
4226 &result_type); | 4202 &result_type); |
4227 } | 4203 } |
4228 // Parse the formal parameters of the function type. | 4204 // Parse the formal parameters of the function type. |
4229 if (CurrentToken() != Token::kLPAREN) { | 4205 CheckToken(Token::kLPAREN, "formal parameter list expected"); |
4230 ErrorMsg("formal parameter list expected"); | |
4231 } | |
4232 ParamList func_params; | 4206 ParamList func_params; |
4233 | 4207 |
4234 // Add implicit closure object parameter. | 4208 // Add implicit closure object parameter. |
4235 func_params.AddFinalParameter( | 4209 func_params.AddFinalParameter( |
4236 TokenPos(), | 4210 TokenPos(), |
4237 &Symbols::ClosureParameter(), | 4211 &Symbols::ClosureParameter(), |
4238 &Type::ZoneHandle(Type::DynamicType())); | 4212 &Type::ZoneHandle(Type::DynamicType())); |
4239 | 4213 |
4240 const bool no_explicit_default_values = false; | 4214 const bool no_explicit_default_values = false; |
4241 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 4215 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4647 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); | 4621 ErrorMsg(name_pos, "missing '%s' cannot be patched", func_name.ToCString()); |
4648 } | 4622 } |
4649 String& accessor_name = String::Handle(Field::GetterName(func_name)); | 4623 String& accessor_name = String::Handle(Field::GetterName(func_name)); |
4650 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 4624 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
4651 ErrorMsg(name_pos, "'%s' is already defined as getter", | 4625 ErrorMsg(name_pos, "'%s' is already defined as getter", |
4652 func_name.ToCString()); | 4626 func_name.ToCString()); |
4653 } | 4627 } |
4654 // A setter named x= may co-exist with a function named x, thus we do | 4628 // A setter named x= may co-exist with a function named x, thus we do |
4655 // not need to check setters. | 4629 // not need to check setters. |
4656 | 4630 |
4657 if (CurrentToken() != Token::kLPAREN) { | 4631 CheckToken(Token::kLPAREN); |
4658 ErrorMsg("'(' expected"); | |
4659 } | |
4660 const intptr_t function_pos = TokenPos(); | 4632 const intptr_t function_pos = TokenPos(); |
4661 ParamList params; | 4633 ParamList params; |
4662 const bool allow_explicit_default_values = true; | 4634 const bool allow_explicit_default_values = true; |
4663 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 4635 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
4664 | 4636 |
4665 intptr_t function_end_pos = function_pos; | 4637 intptr_t function_end_pos = function_pos; |
4666 if (is_external) { | 4638 if (is_external) { |
4667 function_end_pos = TokenPos(); | 4639 function_end_pos = TokenPos(); |
4668 ExpectSemicolon(); | 4640 ExpectSemicolon(); |
4669 } else if (CurrentToken() == Token::kLBRACE) { | 4641 } else if (CurrentToken() == Token::kLBRACE) { |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4906 } | 4878 } |
4907 } | 4879 } |
4908 | 4880 |
4909 | 4881 |
4910 void Parser::ParseLibraryImportExport() { | 4882 void Parser::ParseLibraryImportExport() { |
4911 bool is_import = (CurrentToken() == Token::kIMPORT); | 4883 bool is_import = (CurrentToken() == Token::kIMPORT); |
4912 bool is_export = (CurrentToken() == Token::kEXPORT); | 4884 bool is_export = (CurrentToken() == Token::kEXPORT); |
4913 ASSERT(is_import || is_export); | 4885 ASSERT(is_import || is_export); |
4914 const intptr_t import_pos = TokenPos(); | 4886 const intptr_t import_pos = TokenPos(); |
4915 ConsumeToken(); | 4887 ConsumeToken(); |
4916 if (CurrentToken() != Token::kSTRING) { | 4888 CheckToken(Token::kSTRING, "library url expected"); |
4917 ErrorMsg("library url expected"); | |
4918 } | |
4919 AstNode* url_literal = ParseStringLiteral(false); | 4889 AstNode* url_literal = ParseStringLiteral(false); |
4920 ASSERT(url_literal->IsLiteralNode()); | 4890 ASSERT(url_literal->IsLiteralNode()); |
4921 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 4891 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
4922 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 4892 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
4923 if (url.Length() == 0) { | 4893 if (url.Length() == 0) { |
4924 ErrorMsg("library url expected"); | 4894 ErrorMsg("library url expected"); |
4925 } | 4895 } |
4926 String& prefix = String::Handle(); | 4896 String& prefix = String::Handle(); |
4927 if (is_import && (CurrentToken() == Token::kAS)) { | 4897 if (is_import && (CurrentToken() == Token::kAS)) { |
4928 ConsumeToken(); | 4898 ConsumeToken(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4997 } else { | 4967 } else { |
4998 ASSERT(is_export); | 4968 ASSERT(is_export); |
4999 library_.AddExport(ns); | 4969 library_.AddExport(ns); |
5000 } | 4970 } |
5001 } | 4971 } |
5002 | 4972 |
5003 | 4973 |
5004 void Parser::ParseLibraryPart() { | 4974 void Parser::ParseLibraryPart() { |
5005 const intptr_t source_pos = TokenPos(); | 4975 const intptr_t source_pos = TokenPos(); |
5006 ConsumeToken(); // Consume "part". | 4976 ConsumeToken(); // Consume "part". |
5007 if (CurrentToken() != Token::kSTRING) { | 4977 CheckToken(Token::kSTRING, "url expected"); |
5008 ErrorMsg("url expected"); | |
5009 } | |
5010 AstNode* url_literal = ParseStringLiteral(false); | 4978 AstNode* url_literal = ParseStringLiteral(false); |
5011 ASSERT(url_literal->IsLiteralNode()); | 4979 ASSERT(url_literal->IsLiteralNode()); |
5012 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 4980 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
5013 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 4981 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
5014 ExpectSemicolon(); | 4982 ExpectSemicolon(); |
5015 const String& canon_url = String::CheckedHandle( | 4983 const String& canon_url = String::CheckedHandle( |
5016 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); | 4984 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); |
5017 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); | 4985 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); |
5018 } | 4986 } |
5019 | 4987 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5065 ParseLibraryPart(); | 5033 ParseLibraryPart(); |
5066 rewind_pos = TokenPos(); | 5034 rewind_pos = TokenPos(); |
5067 metadata_pos = SkipMetadata(); | 5035 metadata_pos = SkipMetadata(); |
5068 } | 5036 } |
5069 SetPosition(rewind_pos); | 5037 SetPosition(rewind_pos); |
5070 } | 5038 } |
5071 | 5039 |
5072 | 5040 |
5073 void Parser::ParsePartHeader() { | 5041 void Parser::ParsePartHeader() { |
5074 SkipMetadata(); | 5042 SkipMetadata(); |
5075 if (CurrentToken() != Token::kPART) { | 5043 CheckToken(Token::kPART, "'part of' expected"); |
5076 ErrorMsg("'part of' expected"); | |
5077 } | |
5078 ConsumeToken(); | 5044 ConsumeToken(); |
5079 if (!IsLiteral("of")) { | 5045 if (!IsLiteral("of")) { |
5080 ErrorMsg("'part of' expected"); | 5046 ErrorMsg("'part of' expected"); |
5081 } | 5047 } |
5082 ConsumeToken(); | 5048 ConsumeToken(); |
5083 // The VM is not required to check that the library name matches the | 5049 // The VM is not required to check that the library name matches the |
5084 // name of the current library, so we ignore it. | 5050 // name of the current library, so we ignore it. |
5085 ExpectIdentifier("library name expected"); | 5051 ExpectIdentifier("library name expected"); |
5086 while (CurrentToken() == Token::kPERIOD) { | 5052 while (CurrentToken() == Token::kPERIOD) { |
5087 ConsumeToken(); | 5053 ConsumeToken(); |
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5577 if (previous_pos >= 0) { | 5543 if (previous_pos >= 0) { |
5578 ASSERT(!script_.IsNull()); | 5544 ASSERT(!script_.IsNull()); |
5579 intptr_t line_number; | 5545 intptr_t line_number; |
5580 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 5546 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
5581 ErrorMsg(name_pos, | 5547 ErrorMsg(name_pos, |
5582 "identifier '%s' previously used in line %" Pd "", | 5548 "identifier '%s' previously used in line %" Pd "", |
5583 function_name->ToCString(), | 5549 function_name->ToCString(), |
5584 line_number); | 5550 line_number); |
5585 } | 5551 } |
5586 } | 5552 } |
5587 | 5553 CheckToken(Token::kLPAREN); |
5588 if (CurrentToken() != Token::kLPAREN) { | |
5589 ErrorMsg("'(' expected"); | |
5590 } | |
5591 | 5554 |
5592 // Check whether we have parsed this closure function before, in a previous | 5555 // Check whether we have parsed this closure function before, in a previous |
5593 // compilation. If so, reuse the function object, else create a new one | 5556 // compilation. If so, reuse the function object, else create a new one |
5594 // and register it in the current class. | 5557 // and register it in the current class. |
5595 // Note that we cannot share the same closure function between the closurized | 5558 // Note that we cannot share the same closure function between the closurized |
5596 // and non-closurized versions of the same parent function. | 5559 // and non-closurized versions of the same parent function. |
5597 Function& function = Function::ZoneHandle(); | 5560 Function& function = Function::ZoneHandle(); |
5598 bool is_new_closure = false; | 5561 bool is_new_closure = false; |
5599 // TODO(hausner): There could be two different closures at the given | 5562 // TODO(hausner): There could be two different closures at the given |
5600 // function_pos, one enclosed in a closurized function and one enclosed in the | 5563 // function_pos, one enclosed in a closurized function and one enclosed in the |
(...skipping 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6828 | 6791 |
6829 SourceLabel* try_label = NULL; | 6792 SourceLabel* try_label = NULL; |
6830 if (label_name != NULL) { | 6793 if (label_name != NULL) { |
6831 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 6794 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
6832 OpenBlock(); | 6795 OpenBlock(); |
6833 current_block_->scope->AddLabel(try_label); | 6796 current_block_->scope->AddLabel(try_label); |
6834 } | 6797 } |
6835 | 6798 |
6836 // Now parse the 'try' block. | 6799 // Now parse the 'try' block. |
6837 OpenBlock(); | 6800 OpenBlock(); |
6838 Block* current_try_block = current_block_; | 6801 PushTryBlock(current_block_); |
6839 PushTryBlock(current_try_block); | |
6840 ExpectToken(Token::kLBRACE); | 6802 ExpectToken(Token::kLBRACE); |
6841 ParseStatementSequence(); | 6803 ParseStatementSequence(); |
6842 ExpectToken(Token::kRBRACE); | 6804 ExpectToken(Token::kRBRACE); |
6843 SequenceNode* try_block = CloseBlock(); | 6805 SequenceNode* try_block = CloseBlock(); |
6844 | 6806 |
6845 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && | 6807 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && |
6846 (CurrentToken() != Token::kFINALLY)) { | 6808 (CurrentToken() != Token::kFINALLY)) { |
6847 ErrorMsg("catch or finally clause expected"); | 6809 ErrorMsg("catch or finally clause expected"); |
6848 } | 6810 } |
6849 | 6811 |
(...skipping 14 matching lines...) Expand all Loading... |
6864 bool needs_stacktrace = false; | 6826 bool needs_stacktrace = false; |
6865 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 6827 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
6866 const intptr_t catch_pos = TokenPos(); | 6828 const intptr_t catch_pos = TokenPos(); |
6867 CatchParamDesc exception_param; | 6829 CatchParamDesc exception_param; |
6868 CatchParamDesc stack_trace_param; | 6830 CatchParamDesc stack_trace_param; |
6869 if (IsLiteral("on")) { | 6831 if (IsLiteral("on")) { |
6870 ConsumeToken(); | 6832 ConsumeToken(); |
6871 exception_param.type = &AbstractType::ZoneHandle( | 6833 exception_param.type = &AbstractType::ZoneHandle( |
6872 ParseType(ClassFinalizer::kCanonicalize)); | 6834 ParseType(ClassFinalizer::kCanonicalize)); |
6873 } else { | 6835 } else { |
6874 exception_param.type = | 6836 exception_param.type = &AbstractType::ZoneHandle(Type::DynamicType()); |
6875 &AbstractType::ZoneHandle(Type::DynamicType()); | |
6876 } | 6837 } |
6877 if (CurrentToken() == Token::kCATCH) { | 6838 if (CurrentToken() == Token::kCATCH) { |
6878 ConsumeToken(); // Consume the 'catch'. | 6839 ConsumeToken(); // Consume the 'catch'. |
6879 ExpectToken(Token::kLPAREN); | 6840 ExpectToken(Token::kLPAREN); |
6880 exception_param.token_pos = TokenPos(); | 6841 exception_param.token_pos = TokenPos(); |
6881 exception_param.var = ExpectIdentifier("identifier expected"); | 6842 exception_param.var = ExpectIdentifier("identifier expected"); |
6882 if (CurrentToken() == Token::kCOMMA) { | 6843 if (CurrentToken() == Token::kCOMMA) { |
6883 ConsumeToken(); | 6844 ConsumeToken(); |
6884 // TODO(hausner): Make implicit type be StackTrace, not dynamic. | 6845 // TODO(hausner): Make implicit type be StackTrace, not dynamic. |
6885 stack_trace_param.type = | 6846 stack_trace_param.type = |
6886 &AbstractType::ZoneHandle(Type::DynamicType()); | 6847 &AbstractType::ZoneHandle(Type::DynamicType()); |
6887 stack_trace_param.token_pos = TokenPos(); | 6848 stack_trace_param.token_pos = TokenPos(); |
6888 stack_trace_param.var = ExpectIdentifier("identifier expected"); | 6849 stack_trace_param.var = ExpectIdentifier("identifier expected"); |
6889 } | 6850 } |
6890 ExpectToken(Token::kRPAREN); | 6851 ExpectToken(Token::kRPAREN); |
6891 } | 6852 } |
6892 | 6853 |
6893 // Parse the individual catch handler code and add an unconditional | 6854 // Create a block containing the catch clause parameters and |
6894 // JUMP to the end of the try block. | 6855 // the following code: |
6895 ExpectToken(Token::kLBRACE); | 6856 // 1) Store exception object and stack trace object into user-defined |
| 6857 // variables (as needed). |
| 6858 // 2) Nested block with source code from catch clause block. |
| 6859 // 3) Unconditional JUMP to the end of the try block. |
6896 OpenBlock(); | 6860 OpenBlock(); |
6897 AddCatchParamsToScope(exception_param, | 6861 AddCatchParamsToScope(exception_param, |
6898 stack_trace_param, | 6862 stack_trace_param, |
6899 current_block_->scope); | 6863 current_block_->scope); |
6900 | 6864 |
6901 if (exception_param.var != NULL) { | 6865 if (exception_param.var != NULL) { |
6902 // Generate code to load the exception object (:exception_var) into | 6866 // Generate code to load the exception object (:exception_var) into |
6903 // the exception variable specified in this block. | 6867 // the exception variable specified in this block. |
6904 LocalVariable* var = LookupLocalScope(*exception_param.var); | 6868 LocalVariable* var = LookupLocalScope(*exception_param.var); |
6905 ASSERT(var != NULL); | 6869 ASSERT(var != NULL); |
(...skipping 14 matching lines...) Expand all Loading... |
6920 new StoreLocalNode(catch_pos, trace, | 6884 new StoreLocalNode(catch_pos, trace, |
6921 new LoadLocalNode(catch_pos, catch_trace_var))); | 6885 new LoadLocalNode(catch_pos, catch_trace_var))); |
6922 current_block_->statements->Add( | 6886 current_block_->statements->Add( |
6923 new InstanceCallNode( | 6887 new InstanceCallNode( |
6924 catch_pos, | 6888 catch_pos, |
6925 new LoadLocalNode(catch_pos, trace), | 6889 new LoadLocalNode(catch_pos, trace), |
6926 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 6890 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
6927 no_args)); | 6891 no_args)); |
6928 } | 6892 } |
6929 | 6893 |
6930 ParseStatementSequence(); // Parse the catch handler code. | 6894 // Add nested block with user-defined code. |
| 6895 CheckToken(Token::kLBRACE); |
| 6896 current_block_->statements->Add(ParseNestedStatement(false, NULL)); |
| 6897 |
| 6898 // Add unconditional jump to end of catch clause list. |
6931 current_block_->statements->Add( | 6899 current_block_->statements->Add( |
6932 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); | 6900 new JumpNode(catch_pos, Token::kCONTINUE, end_catch_label)); |
6933 SequenceNode* catch_handler = CloseBlock(); | 6901 |
6934 ExpectToken(Token::kRBRACE); | 6902 SequenceNode* catch_clause = CloseBlock(); |
6935 | 6903 |
6936 const bool is_bad_type = exception_param.type->IsMalformed() || | 6904 const bool is_bad_type = exception_param.type->IsMalformed() || |
6937 exception_param.type->IsMalbounded(); | 6905 exception_param.type->IsMalbounded(); |
6938 if (!is_bad_type && !exception_param.type->IsDynamicType()) { | 6906 if (!is_bad_type && !exception_param.type->IsDynamicType()) { |
6939 // Has a type specification that is not malformed or malbounded. | 6907 // Has a type specification that is not malformed or malbounded. |
6940 // Now form an 'if type check' as an exception type exists in the | 6908 // Now form an 'if type check' to guard the catch handler code. |
6941 // catch specifier. | |
6942 if (!exception_param.type->IsInstantiated() && | 6909 if (!exception_param.type->IsInstantiated() && |
6943 (current_block_->scope->function_level() > 0)) { | 6910 (current_block_->scope->function_level() > 0)) { |
6944 // Make sure that the instantiator is captured. | 6911 // Make sure that the instantiator is captured. |
6945 CaptureInstantiator(); | 6912 CaptureInstantiator(); |
6946 } | 6913 } |
6947 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); | 6914 TypeNode* exception_type = new TypeNode(catch_pos, *exception_param.type); |
6948 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var); | 6915 AstNode* exception_var = new LoadLocalNode(catch_pos, catch_excp_var); |
6949 if (!exception_type->type().IsInstantiated()) { | 6916 if (!exception_type->type().IsInstantiated()) { |
6950 EnsureExpressionTemp(); | 6917 EnsureExpressionTemp(); |
6951 } | 6918 } |
6952 AstNode* type_cond_expr = new ComparisonNode( | 6919 AstNode* type_cond_expr = new ComparisonNode( |
6953 catch_pos, Token::kIS, exception_var, exception_type); | 6920 catch_pos, Token::kIS, exception_var, exception_type); |
6954 current_block_->statements->Add( | 6921 current_block_->statements->Add( |
6955 new IfNode(catch_pos, type_cond_expr, catch_handler, NULL)); | 6922 new IfNode(catch_pos, type_cond_expr, catch_clause, NULL)); |
6956 | 6923 |
6957 // Do not add uninstantiated types (e.g. type parameter T or | 6924 // Do not add uninstantiated types (e.g. type parameter T or |
6958 // generic type List<T>), since the debugger won't be able to | 6925 // generic type List<T>), since the debugger won't be able to |
6959 // instantiate it when walking the stack. | 6926 // instantiate it when walking the stack. |
6960 // This means that the debugger is not able to determine whether | 6927 // This means that the debugger is not able to determine whether |
6961 // an exception is caught if the catch clause uses generic types. | 6928 // an exception is caught if the catch clause uses generic types. |
6962 // It will report the exception as uncaught when in fact it might | 6929 // It will report the exception as uncaught when in fact it might |
6963 // be caught and handled when we unwind the stack. | 6930 // be caught and handled when we unwind the stack. |
6964 if (exception_param.type->IsInstantiated()) { | 6931 if (exception_param.type->IsInstantiated()) { |
6965 handler_types.Add(*exception_param.type); | 6932 handler_types.Add(*exception_param.type); |
6966 } | 6933 } |
6967 } else { | 6934 } else { |
6968 if (is_bad_type) { | 6935 if (is_bad_type) { |
6969 current_block_->statements->Add(ThrowTypeError(catch_pos, | 6936 current_block_->statements->Add(ThrowTypeError(catch_pos, |
6970 *exception_param.type)); | 6937 *exception_param.type)); |
6971 // We still add the dead code below to satisfy the code generator. | 6938 // We still add the dead code below to satisfy the code generator. |
6972 } | 6939 } |
6973 // No exception type exists in the catch specifier so execute the | 6940 // No exception type exists in the catch clause so execute the |
6974 // catch handler code unconditionally. | 6941 // catch handler code unconditionally. |
6975 current_block_->statements->Add(catch_handler); | 6942 current_block_->statements->Add(catch_clause); |
6976 generic_catch_seen = true; | 6943 generic_catch_seen = true; |
6977 // This catch clause will handle all exceptions. We can safely forget | 6944 // This catch clause will handle all exceptions. We can safely forget |
6978 // all previous catch clause types. | 6945 // all previous catch clause types. |
6979 handler_types.SetLength(0); | 6946 handler_types.SetLength(0); |
6980 handler_types.Add(*exception_param.type); | 6947 handler_types.Add(*exception_param.type); |
6981 } | 6948 } |
6982 } | 6949 } |
| 6950 |
6983 SequenceNode* catch_handler_list = CloseBlock(); | 6951 SequenceNode* catch_handler_list = CloseBlock(); |
6984 TryBlocks* inner_try_block = PopTryBlock(); | 6952 TryBlocks* inner_try_block = PopTryBlock(); |
6985 const intptr_t try_index = inner_try_block->try_index(); | 6953 const intptr_t try_index = inner_try_block->try_index(); |
6986 TryBlocks* outer_try_block = try_blocks_list_; | 6954 TryBlocks* outer_try_block = try_blocks_list_; |
6987 const intptr_t outer_try_index = (outer_try_block != NULL) | 6955 const intptr_t outer_try_index = (outer_try_block != NULL) |
6988 ? outer_try_block->try_index() | 6956 ? outer_try_block->try_index() |
6989 : CatchClauseNode::kInvalidTryIndex; | 6957 : CatchClauseNode::kInvalidTryIndex; |
6990 | 6958 |
6991 // Finally parse the 'finally' block. | 6959 // Finally parse the 'finally' block. |
6992 SequenceNode* finally_block = NULL; | 6960 SequenceNode* finally_block = NULL; |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7394 OS::Print("%s", error.ToErrorCString()); | 7362 OS::Print("%s", error.ToErrorCString()); |
7395 } | 7363 } |
7396 } | 7364 } |
7397 | 7365 |
7398 | 7366 |
7399 void Parser::Unimplemented(const char* msg) { | 7367 void Parser::Unimplemented(const char* msg) { |
7400 ErrorMsg(TokenPos(), "%s", msg); | 7368 ErrorMsg(TokenPos(), "%s", msg); |
7401 } | 7369 } |
7402 | 7370 |
7403 | 7371 |
| 7372 void Parser::CheckToken(Token::Kind token_expected, const char* msg) { |
| 7373 if (CurrentToken() != token_expected) { |
| 7374 if (msg != NULL) { |
| 7375 ErrorMsg("%s", msg); |
| 7376 } else { |
| 7377 ErrorMsg("'%s' expected", Token::Str(token_expected)); |
| 7378 } |
| 7379 } |
| 7380 } |
| 7381 |
| 7382 |
7404 void Parser::ExpectToken(Token::Kind token_expected) { | 7383 void Parser::ExpectToken(Token::Kind token_expected) { |
7405 if (CurrentToken() != token_expected) { | 7384 if (CurrentToken() != token_expected) { |
7406 ErrorMsg("'%s' expected", Token::Str(token_expected)); | 7385 ErrorMsg("'%s' expected", Token::Str(token_expected)); |
7407 } | 7386 } |
7408 ConsumeToken(); | 7387 ConsumeToken(); |
7409 } | 7388 } |
7410 | 7389 |
7411 | 7390 |
7412 void Parser::ExpectSemicolon() { | 7391 void Parser::ExpectSemicolon() { |
7413 if (CurrentToken() != Token::kSEMICOLON) { | 7392 if (CurrentToken() != Token::kSEMICOLON) { |
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8195 arguments->NodeAt(0), | 8174 arguments->NodeAt(0), |
8196 arguments->NodeAt(1)); | 8175 arguments->NodeAt(1)); |
8197 } | 8176 } |
8198 return new StaticCallNode(call_pos, func, arguments); | 8177 return new StaticCallNode(call_pos, func, arguments); |
8199 } | 8178 } |
8200 | 8179 |
8201 | 8180 |
8202 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { | 8181 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { |
8203 TRACE_PARSER("ParseInstanceCall"); | 8182 TRACE_PARSER("ParseInstanceCall"); |
8204 const intptr_t call_pos = TokenPos(); | 8183 const intptr_t call_pos = TokenPos(); |
8205 if (CurrentToken() != Token::kLPAREN) { | 8184 CheckToken(Token::kLPAREN); |
8206 ErrorMsg(call_pos, "left parenthesis expected"); | |
8207 } | |
8208 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 8185 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
8209 return new InstanceCallNode(call_pos, receiver, func_name, arguments); | 8186 return new InstanceCallNode(call_pos, receiver, func_name, arguments); |
8210 } | 8187 } |
8211 | 8188 |
8212 | 8189 |
8213 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 8190 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
8214 TRACE_PARSER("ParseClosureCall"); | 8191 TRACE_PARSER("ParseClosureCall"); |
8215 const intptr_t call_pos = TokenPos(); | 8192 const intptr_t call_pos = TokenPos(); |
8216 ASSERT(CurrentToken() == Token::kLPAREN); | 8193 ASSERT(CurrentToken() == Token::kLPAREN); |
8217 EnsureSavedCurrentContext(); | 8194 EnsureSavedCurrentContext(); |
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9271 } | 9248 } |
9272 return resolved; | 9249 return resolved; |
9273 } | 9250 } |
9274 | 9251 |
9275 | 9252 |
9276 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 9253 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
9277 // finalize it according to the given type finalization mode. | 9254 // finalize it according to the given type finalization mode. |
9278 RawAbstractType* Parser::ParseType( | 9255 RawAbstractType* Parser::ParseType( |
9279 ClassFinalizer::FinalizationKind finalization) { | 9256 ClassFinalizer::FinalizationKind finalization) { |
9280 TRACE_PARSER("ParseType"); | 9257 TRACE_PARSER("ParseType"); |
9281 if (CurrentToken() != Token::kIDENT) { | 9258 CheckToken(Token::kIDENT, "type name expected"); |
9282 ErrorMsg("type name expected"); | |
9283 } | |
9284 QualIdent type_name; | 9259 QualIdent type_name; |
9285 if (finalization == ClassFinalizer::kIgnore) { | 9260 if (finalization == ClassFinalizer::kIgnore) { |
9286 if (!is_top_level_ && (current_block_ != NULL)) { | 9261 if (!is_top_level_ && (current_block_ != NULL)) { |
9287 // Add the library prefix or type class name to the list of referenced | 9262 // Add the library prefix or type class name to the list of referenced |
9288 // names of this scope, even if the type is ignored. | 9263 // names of this scope, even if the type is ignored. |
9289 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 9264 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
9290 } | 9265 } |
9291 SkipQualIdent(); | 9266 SkipQualIdent(); |
9292 } else { | 9267 } else { |
9293 ParseQualIdent(&type_name); | 9268 ParseQualIdent(&type_name); |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9890 // is a named constructor. Note that ParseType() above will not consume it as | 9865 // is a named constructor. Note that ParseType() above will not consume it as |
9891 // part of a misinterpreted qualified identifier, because only a valid library | 9866 // part of a misinterpreted qualified identifier, because only a valid library |
9892 // prefix is accepted as qualifier. | 9867 // prefix is accepted as qualifier. |
9893 String* named_constructor = NULL; | 9868 String* named_constructor = NULL; |
9894 if (CurrentToken() == Token::kPERIOD) { | 9869 if (CurrentToken() == Token::kPERIOD) { |
9895 ConsumeToken(); | 9870 ConsumeToken(); |
9896 named_constructor = ExpectIdentifier("name of constructor expected"); | 9871 named_constructor = ExpectIdentifier("name of constructor expected"); |
9897 } | 9872 } |
9898 | 9873 |
9899 // Parse constructor parameters. | 9874 // Parse constructor parameters. |
9900 if (CurrentToken() != Token::kLPAREN) { | 9875 CheckToken(Token::kLPAREN); |
9901 ErrorMsg("'(' expected"); | |
9902 } | |
9903 intptr_t call_pos = TokenPos(); | 9876 intptr_t call_pos = TokenPos(); |
9904 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 9877 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
9905 | 9878 |
9906 // Parsing is complete, so we can return a throw in case of a malformed type | 9879 // Parsing is complete, so we can return a throw in case of a malformed type |
9907 // or report a compile-time error if the constructor is const. | 9880 // or report a compile-time error if the constructor is const. |
9908 if (type.IsMalformed()) { | 9881 if (type.IsMalformed()) { |
9909 if (is_const) { | 9882 if (is_const) { |
9910 const Error& error = Error::Handle(type.malformed_error()); | 9883 const Error& error = Error::Handle(type.malformed_error()); |
9911 ErrorMsg(error); | 9884 ErrorMsg(error); |
9912 } | 9885 } |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10759 void Parser::SkipQualIdent() { | 10732 void Parser::SkipQualIdent() { |
10760 ASSERT(IsIdentifier()); | 10733 ASSERT(IsIdentifier()); |
10761 ConsumeToken(); | 10734 ConsumeToken(); |
10762 if (CurrentToken() == Token::kPERIOD) { | 10735 if (CurrentToken() == Token::kPERIOD) { |
10763 ConsumeToken(); // Consume the kPERIOD token. | 10736 ConsumeToken(); // Consume the kPERIOD token. |
10764 ExpectIdentifier("identifier expected after '.'"); | 10737 ExpectIdentifier("identifier expected after '.'"); |
10765 } | 10738 } |
10766 } | 10739 } |
10767 | 10740 |
10768 } // namespace dart | 10741 } // namespace dart |
OLD | NEW |