Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "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. | |
|
regis
2013/11/06 21:59:55
Upper-case u.
hausner
2013/11/06 22:07:11
Done.
| |
| 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 |