Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 2955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2966 ConsumeToken(); | 2966 ConsumeToken(); |
| 2967 AbstractType& type = AbstractType::ZoneHandle(ParseType(type_resolution)); | 2967 AbstractType& type = AbstractType::ZoneHandle(ParseType(type_resolution)); |
| 2968 types.Add(&type); | 2968 types.Add(&type); |
| 2969 } while (CurrentToken() == Token::kCOMMA); | 2969 } while (CurrentToken() == Token::kCOMMA); |
| 2970 Token::Kind token = CurrentToken(); | 2970 Token::Kind token = CurrentToken(); |
| 2971 if ((token == Token::kGT) || (token == Token::kSHR)) { | 2971 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 2972 ConsumeRightAngleBracket(); | 2972 ConsumeRightAngleBracket(); |
| 2973 } else { | 2973 } else { |
| 2974 ErrorMsg("right angle bracket expected"); | 2974 ErrorMsg("right angle bracket expected"); |
| 2975 } | 2975 } |
| 2976 return NewTypeArguments(types); | 2976 if (type_resolution != kIgnore) { |
| 2977 return NewTypeArguments(types); | |
| 2978 } | |
| 2977 } | 2979 } |
| 2978 return TypeArguments::null(); | 2980 return TypeArguments::null(); |
| 2979 } | 2981 } |
| 2980 | 2982 |
| 2981 | 2983 |
| 2982 // Parse and return an array of interface types. | 2984 // Parse and return an array of interface types. |
| 2983 RawArray* Parser::ParseInterfaceList() { | 2985 RawArray* Parser::ParseInterfaceList() { |
| 2984 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || | 2986 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || |
| 2985 (CurrentToken() == Token::kEXTENDS)); | 2987 (CurrentToken() == Token::kEXTENDS)); |
| 2986 GrowableArray<AbstractType*> interfaces; | 2988 GrowableArray<AbstractType*> interfaces; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3033 } | 3035 } |
| 3034 } | 3036 } |
| 3035 cls_interfaces = NewArray<AbstractType>(all_interfaces); | 3037 cls_interfaces = NewArray<AbstractType>(all_interfaces); |
| 3036 cls.set_interfaces(cls_interfaces); | 3038 cls.set_interfaces(cls_interfaces); |
| 3037 } | 3039 } |
| 3038 | 3040 |
| 3039 | 3041 |
| 3040 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3042 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
| 3041 const bool is_final = (CurrentToken() == Token::kFINAL); | 3043 const bool is_final = (CurrentToken() == Token::kFINAL); |
| 3042 const bool is_static = true; | 3044 const bool is_static = true; |
| 3043 const AbstractType& type = AbstractType::ZoneHandle( | 3045 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 3044 ParseFinalVarOrType(kIsMandatory, kCanResolve)); | 3046 FLAG_enable_type_checks ? kCanResolve : kIgnore)); |
| 3045 | 3047 |
| 3046 while (true) { | 3048 while (true) { |
| 3047 const intptr_t name_pos = token_index_; | 3049 const intptr_t name_pos = token_index_; |
| 3048 String& var_name = *ExpectIdentifier("variable name expected"); | 3050 String& var_name = *ExpectIdentifier("variable name expected"); |
| 3049 | 3051 |
| 3050 if (library_.LookupObject(var_name) != Object::null()) { | 3052 if (library_.LookupObject(var_name) != Object::null()) { |
| 3051 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 3053 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 3052 } | 3054 } |
| 3053 String& accessor_name = String::Handle(Field::GetterName(var_name)); | 3055 String& accessor_name = String::Handle(Field::GetterName(var_name)); |
| 3054 if (library_.LookupObject(accessor_name) != Object::null()) { | 3056 if (library_.LookupObject(accessor_name) != Object::null()) { |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3650 } | 3652 } |
| 3651 if (is_final) { | 3653 if (is_final) { |
| 3652 variable->set_is_final(); | 3654 variable->set_is_final(); |
| 3653 } | 3655 } |
| 3654 return initialization; | 3656 return initialization; |
| 3655 } | 3657 } |
| 3656 | 3658 |
| 3657 | 3659 |
| 3658 // Parses ('var' | 'final' [type] | type). | 3660 // Parses ('var' | 'final' [type] | type). |
| 3659 // The presence of 'final' must be detected and remembered before the call. | 3661 // The presence of 'final' must be detected and remembered before the call. |
| 3660 // If type_specification is kIsOptional, and no type can be parsed, then return | |
| 3661 // the DynamicType. | |
| 3662 // If a type is parsed, it is resolved (or not) according to type_resolution. | 3662 // If a type is parsed, it is resolved (or not) according to type_resolution. |
| 3663 RawAbstractType* Parser::ParseFinalVarOrType( | 3663 RawAbstractType* Parser::ParseFinalVarOrType(TypeResolution type_resolution) { |
| 3664 TypeSpecification type_specification, TypeResolution type_resolution) { | |
| 3665 if (CurrentToken() == Token::kVAR) { | 3664 if (CurrentToken() == Token::kVAR) { |
| 3666 ConsumeToken(); | 3665 ConsumeToken(); |
| 3667 return Type::DynamicType(); | 3666 return Type::DynamicType(); |
| 3668 } | 3667 } |
| 3668 bool type_is_optional = false; | |
| 3669 if (CurrentToken() == Token::kFINAL) { | 3669 if (CurrentToken() == Token::kFINAL) { |
| 3670 ConsumeToken(); | 3670 ConsumeToken(); |
| 3671 type_specification = kIsOptional; | 3671 type_is_optional = true; |
| 3672 } | 3672 } |
| 3673 if (CurrentToken() != Token::kIDENT) { | 3673 if (CurrentToken() != Token::kIDENT) { |
| 3674 if (type_specification == kIsOptional) { | 3674 if (type_is_optional) { |
| 3675 return Type::DynamicType(); | 3675 return Type::DynamicType(); |
| 3676 } else { | 3676 } else { |
| 3677 ErrorMsg("type name expected"); | 3677 ErrorMsg("type name expected"); |
| 3678 } | 3678 } |
| 3679 } | 3679 } |
| 3680 if (type_specification == kIsOptional) { | 3680 if (type_is_optional) { |
| 3681 Token::Kind follower = LookaheadToken(1); | 3681 Token::Kind follower = LookaheadToken(1); |
| 3682 // We have an identifier followed by a 'follower' token. | 3682 // We have an identifier followed by a 'follower' token. |
| 3683 // We either parse a type or return now. | 3683 // We either parse a type or return now. |
| 3684 if ((follower != Token::kLT) && // Parameterized type. | 3684 if ((follower != Token::kLT) && // Parameterized type. |
| 3685 (follower != Token::kPERIOD) && // Qualified class name of type. | 3685 (follower != Token::kPERIOD) && // Qualified class name of type. |
| 3686 !Token::IsIdentifier(follower) && // Variable name following a type. | 3686 !Token::IsIdentifier(follower) && // Variable name following a type. |
| 3687 (follower != Token::kTHIS)) { // Field parameter following a type. | 3687 (follower != Token::kTHIS)) { // Field parameter following a type. |
| 3688 return Type::DynamicType(); | 3688 return Type::DynamicType(); |
| 3689 } | 3689 } |
| 3690 } | 3690 } |
| 3691 return ParseType(type_resolution); | 3691 return ParseType(type_resolution); |
| 3692 } | 3692 } |
| 3693 | 3693 |
| 3694 | 3694 |
| 3695 // Returns ast nodes of the variable initialization. Variables without an | 3695 // Returns ast nodes of the variable initialization. Variables without an |
| 3696 // explicit initializer are initialized to null. If several variables are | 3696 // explicit initializer are initialized to null. If several variables are |
| 3697 // declared, the individual initializers are collected in a sequence node. | 3697 // declared, the individual initializers are collected in a sequence node. |
| 3698 AstNode* Parser::ParseVariableDeclarationList() { | 3698 AstNode* Parser::ParseVariableDeclarationList() { |
| 3699 TRACE_PARSER("ParseVariableDeclarationList"); | 3699 TRACE_PARSER("ParseVariableDeclarationList"); |
| 3700 bool is_final = (CurrentToken() == Token::kFINAL); | 3700 bool is_final = (CurrentToken() == Token::kFINAL); |
| 3701 const AbstractType& type = AbstractType::ZoneHandle( | 3701 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 3702 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 3702 FLAG_enable_type_checks ? kMustResolve : kIgnore)); |
| 3703 if (!IsIdentifier()) { | 3703 if (!IsIdentifier()) { |
| 3704 ErrorMsg("identifier expected"); | 3704 ErrorMsg("identifier expected"); |
| 3705 } | 3705 } |
| 3706 | 3706 |
| 3707 AstNode* initializers = ParseVariableDeclaration(type, is_final); | 3707 AstNode* initializers = ParseVariableDeclaration(type, is_final); |
| 3708 ASSERT(initializers != NULL); | 3708 ASSERT(initializers != NULL); |
| 3709 while (CurrentToken() == Token::kCOMMA) { | 3709 while (CurrentToken() == Token::kCOMMA) { |
| 3710 ConsumeToken(); | 3710 ConsumeToken(); |
| 3711 if (!IsIdentifier()) { | 3711 if (!IsIdentifier()) { |
| 3712 ErrorMsg("identifier expected after comma"); | 3712 ErrorMsg("identifier expected after comma"); |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4384 SourceLabel* label) { | 4384 SourceLabel* label) { |
| 4385 bool is_final = (CurrentToken() == Token::kFINAL); | 4385 bool is_final = (CurrentToken() == Token::kFINAL); |
| 4386 const String* loop_var_name = NULL; | 4386 const String* loop_var_name = NULL; |
| 4387 LocalVariable* loop_var = NULL; | 4387 LocalVariable* loop_var = NULL; |
| 4388 intptr_t loop_var_pos = 0; | 4388 intptr_t loop_var_pos = 0; |
| 4389 if (LookaheadToken(1) == Token::kIN) { | 4389 if (LookaheadToken(1) == Token::kIN) { |
| 4390 loop_var_pos = token_index_; | 4390 loop_var_pos = token_index_; |
| 4391 loop_var_name = ExpectIdentifier("variable name expected"); | 4391 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4392 } else { | 4392 } else { |
| 4393 // The case without a type is handled above, so require a type here. | 4393 // The case without a type is handled above, so require a type here. |
| 4394 const AbstractType& type = AbstractType::ZoneHandle( | 4394 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 4395 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 4395 FLAG_enable_type_checks ? kMustResolve : kIgnore)); |
| 4396 loop_var_pos = token_index_; | 4396 loop_var_pos = token_index_; |
| 4397 loop_var_name = ExpectIdentifier("variable name expected"); | 4397 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4398 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); | 4398 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); |
| 4399 if (is_final) { | 4399 if (is_final) { |
| 4400 loop_var->set_is_final(); | 4400 loop_var->set_is_final(); |
| 4401 } | 4401 } |
| 4402 } | 4402 } |
| 4403 ExpectToken(Token::kIN); | 4403 ExpectToken(Token::kIN); |
| 4404 const intptr_t collection_pos = token_index_; | 4404 const intptr_t collection_pos = token_index_; |
| 4405 AstNode* collection_expr = ParseExpr(kAllowConst); | 4405 AstNode* collection_expr = ParseExpr(kAllowConst); |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4646 bool is_final; | 4646 bool is_final; |
| 4647 }; | 4647 }; |
| 4648 | 4648 |
| 4649 | 4649 |
| 4650 // Parse the parameter specified in the catch clause. | 4650 // Parse the parameter specified in the catch clause. |
| 4651 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { | 4651 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { |
| 4652 TRACE_PARSER("ParseCatchParameter"); | 4652 TRACE_PARSER("ParseCatchParameter"); |
| 4653 ASSERT(catch_param != NULL); | 4653 ASSERT(catch_param != NULL); |
| 4654 catch_param->is_final = (CurrentToken() == Token::kFINAL); | 4654 catch_param->is_final = (CurrentToken() == Token::kFINAL); |
| 4655 catch_param->type = &AbstractType::ZoneHandle( | 4655 catch_param->type = &AbstractType::ZoneHandle( |
| 4656 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 4656 ParseFinalVarOrType(kMustResolve)); |
|
hausner
2012/01/18 17:50:57
We may want to check with Gilad to make sure this
regis
2012/01/18 18:09:18
I have added a comment stating that the type must
| |
| 4657 catch_param->token_index = token_index_; | 4657 catch_param->token_index = token_index_; |
| 4658 catch_param->var = ExpectIdentifier("identifier expected"); | 4658 catch_param->var = ExpectIdentifier("identifier expected"); |
| 4659 } | 4659 } |
| 4660 | 4660 |
| 4661 | 4661 |
| 4662 // Populate local scope of the catch block with the catch parameters. | 4662 // Populate local scope of the catch block with the catch parameters. |
| 4663 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, | 4663 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, |
| 4664 const CatchParamDesc& stack_trace_param, | 4664 const CatchParamDesc& stack_trace_param, |
| 4665 LocalScope* scope) { | 4665 LocalScope* scope) { |
| 4666 ASSERT(exception_param.var != NULL); | 4666 ASSERT(exception_param.var != NULL); |
| (...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6651 } | 6651 } |
| 6652 QualIdent type_name; | 6652 QualIdent type_name; |
| 6653 const intptr_t type_pos = token_index_; | 6653 const intptr_t type_pos = token_index_; |
| 6654 ParseQualIdent(&type_name); | 6654 ParseQualIdent(&type_name); |
| 6655 if (type_name.is_local_scope_ident) { | 6655 if (type_name.is_local_scope_ident) { |
| 6656 ErrorMsg(type_pos, "using '%s' in this context is invalid", | 6656 ErrorMsg(type_pos, "using '%s' in this context is invalid", |
| 6657 type_name.ident->ToCString()); | 6657 type_name.ident->ToCString()); |
| 6658 } | 6658 } |
| 6659 Class& scope_class = Class::Handle(); | 6659 Class& scope_class = Class::Handle(); |
| 6660 Object& type_class = Object::Handle(); | 6660 Object& type_class = Object::Handle(); |
| 6661 if (type_resolution == kDoNotResolve) { | 6661 if (type_resolution == kIgnore) { |
| 6662 // Leave type_class as null. | |
| 6663 } else if (type_resolution == kDoNotResolve) { | |
| 6662 String& qualifier = String::Handle(); | 6664 String& qualifier = String::Handle(); |
| 6663 if (type_name.qualifier != NULL) { | 6665 if (type_name.qualifier != NULL) { |
| 6664 qualifier ^= type_name.qualifier->raw(); | 6666 qualifier ^= type_name.qualifier->raw(); |
| 6665 } | 6667 } |
| 6666 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); | 6668 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); |
| 6667 } else { | 6669 } else { |
| 6668 scope_class = TypeParametersScopeClass(); | 6670 scope_class = TypeParametersScopeClass(); |
| 6669 if (!scope_class.IsNull()) { | 6671 if (!scope_class.IsNull()) { |
| 6670 TypeParameter& type_parameter = TypeParameter::Handle(); | 6672 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 6671 // Check if qualifier is a type parameter in scope. | 6673 // Check if qualifier is a type parameter in scope. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 6696 } | 6698 } |
| 6697 return type_parameter.raw(); | 6699 return type_parameter.raw(); |
| 6698 } | 6700 } |
| 6699 } | 6701 } |
| 6700 } | 6702 } |
| 6701 // Try to resolve the type class. | 6703 // Try to resolve the type class. |
| 6702 type_class = LookupTypeClass(type_name, type_resolution); | 6704 type_class = LookupTypeClass(type_name, type_resolution); |
| 6703 } | 6705 } |
| 6704 AbstractTypeArguments& type_arguments = | 6706 AbstractTypeArguments& type_arguments = |
| 6705 AbstractTypeArguments::Handle(ParseTypeArguments(type_resolution)); | 6707 AbstractTypeArguments::Handle(ParseTypeArguments(type_resolution)); |
| 6708 if (type_resolution == kIgnore) { | |
| 6709 return Type::DynamicType(); | |
| 6710 } | |
| 6706 Type& type = Type::Handle( | 6711 Type& type = Type::Handle( |
| 6707 Type::NewParameterizedType(type_class, type_arguments)); | 6712 Type::NewParameterizedType(type_class, type_arguments)); |
| 6708 if (type_resolution == kMustResolve) { | 6713 if (type_resolution == kMustResolve) { |
| 6709 ASSERT(type_class.IsClass()); // Must be resolved. | 6714 ASSERT(type_class.IsClass()); // Must be resolved. |
| 6710 Error& error = Error::Handle(); | 6715 Error& error = Error::Handle(); |
| 6711 type ^= ClassFinalizer::FinalizeAndCanonicalizeType(scope_class, | 6716 type ^= ClassFinalizer::FinalizeAndCanonicalizeType(scope_class, |
| 6712 type, | 6717 type, |
| 6713 &error); | 6718 &error); |
| 6714 if (!error.IsNull()) { | 6719 if (!error.IsNull()) { |
| 6715 ErrorMsg(error.ToErrorCString()); | 6720 ErrorMsg(error.ToErrorCString()); |
| (...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7743 } | 7748 } |
| 7744 | 7749 |
| 7745 | 7750 |
| 7746 void Parser::SkipNestedExpr() { | 7751 void Parser::SkipNestedExpr() { |
| 7747 const bool saved_mode = SetAllowFunctionLiterals(true); | 7752 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7748 SkipExpr(); | 7753 SkipExpr(); |
| 7749 SetAllowFunctionLiterals(saved_mode); | 7754 SetAllowFunctionLiterals(saved_mode); |
| 7750 } | 7755 } |
| 7751 | 7756 |
| 7752 } // namespace dart | 7757 } // namespace dart |
| OLD | NEW |