| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3043 } | 3045 } |
| 3044 } | 3046 } |
| 3045 cls_interfaces = NewArray<AbstractType>(all_interfaces); | 3047 cls_interfaces = NewArray<AbstractType>(all_interfaces); |
| 3046 cls.set_interfaces(cls_interfaces); | 3048 cls.set_interfaces(cls_interfaces); |
| 3047 } | 3049 } |
| 3048 | 3050 |
| 3049 | 3051 |
| 3050 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3052 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
| 3051 const bool is_final = (CurrentToken() == Token::kFINAL); | 3053 const bool is_final = (CurrentToken() == Token::kFINAL); |
| 3052 const bool is_static = true; | 3054 const bool is_static = true; |
| 3053 const AbstractType& type = AbstractType::ZoneHandle( | 3055 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 3054 ParseFinalVarOrType(kIsMandatory, kCanResolve)); | 3056 FLAG_enable_type_checks ? kCanResolve : kIgnore)); |
| 3055 | 3057 |
| 3056 while (true) { | 3058 while (true) { |
| 3057 const intptr_t name_pos = token_index_; | 3059 const intptr_t name_pos = token_index_; |
| 3058 String& var_name = *ExpectIdentifier("variable name expected"); | 3060 String& var_name = *ExpectIdentifier("variable name expected"); |
| 3059 | 3061 |
| 3060 if (library_.LookupObject(var_name) != Object::null()) { | 3062 if (library_.LookupObject(var_name) != Object::null()) { |
| 3061 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); | 3063 ErrorMsg(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 3062 } | 3064 } |
| 3063 String& accessor_name = String::Handle(Field::GetterName(var_name)); | 3065 String& accessor_name = String::Handle(Field::GetterName(var_name)); |
| 3064 if (library_.LookupObject(accessor_name) != Object::null()) { | 3066 if (library_.LookupObject(accessor_name) != Object::null()) { |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3660 } | 3662 } |
| 3661 if (is_final) { | 3663 if (is_final) { |
| 3662 variable->set_is_final(); | 3664 variable->set_is_final(); |
| 3663 } | 3665 } |
| 3664 return initialization; | 3666 return initialization; |
| 3665 } | 3667 } |
| 3666 | 3668 |
| 3667 | 3669 |
| 3668 // Parses ('var' | 'final' [type] | type). | 3670 // Parses ('var' | 'final' [type] | type). |
| 3669 // The presence of 'final' must be detected and remembered before the call. | 3671 // The presence of 'final' must be detected and remembered before the call. |
| 3670 // If type_specification is kIsOptional, and no type can be parsed, then return | |
| 3671 // the DynamicType. | |
| 3672 // If a type is parsed, it is resolved (or not) according to type_resolution. | 3672 // If a type is parsed, it is resolved (or not) according to type_resolution. |
| 3673 RawAbstractType* Parser::ParseFinalVarOrType( | 3673 RawAbstractType* Parser::ParseFinalVarOrType(TypeResolution type_resolution) { |
| 3674 TypeSpecification type_specification, TypeResolution type_resolution) { | |
| 3675 if (CurrentToken() == Token::kVAR) { | 3674 if (CurrentToken() == Token::kVAR) { |
| 3676 ConsumeToken(); | 3675 ConsumeToken(); |
| 3677 return Type::DynamicType(); | 3676 return Type::DynamicType(); |
| 3678 } | 3677 } |
| 3678 bool type_is_optional = false; |
| 3679 if (CurrentToken() == Token::kFINAL) { | 3679 if (CurrentToken() == Token::kFINAL) { |
| 3680 ConsumeToken(); | 3680 ConsumeToken(); |
| 3681 type_specification = kIsOptional; | 3681 type_is_optional = true; |
| 3682 } | 3682 } |
| 3683 if (CurrentToken() != Token::kIDENT) { | 3683 if (CurrentToken() != Token::kIDENT) { |
| 3684 if (type_specification == kIsOptional) { | 3684 if (type_is_optional) { |
| 3685 return Type::DynamicType(); | 3685 return Type::DynamicType(); |
| 3686 } else { | 3686 } else { |
| 3687 ErrorMsg("type name expected"); | 3687 ErrorMsg("type name expected"); |
| 3688 } | 3688 } |
| 3689 } | 3689 } |
| 3690 if (type_specification == kIsOptional) { | 3690 if (type_is_optional) { |
| 3691 Token::Kind follower = LookaheadToken(1); | 3691 Token::Kind follower = LookaheadToken(1); |
| 3692 // We have an identifier followed by a 'follower' token. | 3692 // We have an identifier followed by a 'follower' token. |
| 3693 // We either parse a type or return now. | 3693 // We either parse a type or return now. |
| 3694 if ((follower != Token::kLT) && // Parameterized type. | 3694 if ((follower != Token::kLT) && // Parameterized type. |
| 3695 (follower != Token::kPERIOD) && // Qualified class name of type. | 3695 (follower != Token::kPERIOD) && // Qualified class name of type. |
| 3696 !Token::IsIdentifier(follower) && // Variable name following a type. | 3696 !Token::IsIdentifier(follower) && // Variable name following a type. |
| 3697 (follower != Token::kTHIS)) { // Field parameter following a type. | 3697 (follower != Token::kTHIS)) { // Field parameter following a type. |
| 3698 return Type::DynamicType(); | 3698 return Type::DynamicType(); |
| 3699 } | 3699 } |
| 3700 } | 3700 } |
| 3701 return ParseType(type_resolution); | 3701 return ParseType(type_resolution); |
| 3702 } | 3702 } |
| 3703 | 3703 |
| 3704 | 3704 |
| 3705 // Returns ast nodes of the variable initialization. Variables without an | 3705 // Returns ast nodes of the variable initialization. Variables without an |
| 3706 // explicit initializer are initialized to null. If several variables are | 3706 // explicit initializer are initialized to null. If several variables are |
| 3707 // declared, the individual initializers are collected in a sequence node. | 3707 // declared, the individual initializers are collected in a sequence node. |
| 3708 AstNode* Parser::ParseVariableDeclarationList() { | 3708 AstNode* Parser::ParseVariableDeclarationList() { |
| 3709 TRACE_PARSER("ParseVariableDeclarationList"); | 3709 TRACE_PARSER("ParseVariableDeclarationList"); |
| 3710 bool is_final = (CurrentToken() == Token::kFINAL); | 3710 bool is_final = (CurrentToken() == Token::kFINAL); |
| 3711 const AbstractType& type = AbstractType::ZoneHandle( | 3711 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 3712 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 3712 FLAG_enable_type_checks ? kMustResolve : kIgnore)); |
| 3713 if (!IsIdentifier()) { | 3713 if (!IsIdentifier()) { |
| 3714 ErrorMsg("identifier expected"); | 3714 ErrorMsg("identifier expected"); |
| 3715 } | 3715 } |
| 3716 | 3716 |
| 3717 AstNode* initializers = ParseVariableDeclaration(type, is_final); | 3717 AstNode* initializers = ParseVariableDeclaration(type, is_final); |
| 3718 ASSERT(initializers != NULL); | 3718 ASSERT(initializers != NULL); |
| 3719 while (CurrentToken() == Token::kCOMMA) { | 3719 while (CurrentToken() == Token::kCOMMA) { |
| 3720 ConsumeToken(); | 3720 ConsumeToken(); |
| 3721 if (!IsIdentifier()) { | 3721 if (!IsIdentifier()) { |
| 3722 ErrorMsg("identifier expected after comma"); | 3722 ErrorMsg("identifier expected after comma"); |
| (...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4394 SourceLabel* label) { | 4394 SourceLabel* label) { |
| 4395 bool is_final = (CurrentToken() == Token::kFINAL); | 4395 bool is_final = (CurrentToken() == Token::kFINAL); |
| 4396 const String* loop_var_name = NULL; | 4396 const String* loop_var_name = NULL; |
| 4397 LocalVariable* loop_var = NULL; | 4397 LocalVariable* loop_var = NULL; |
| 4398 intptr_t loop_var_pos = 0; | 4398 intptr_t loop_var_pos = 0; |
| 4399 if (LookaheadToken(1) == Token::kIN) { | 4399 if (LookaheadToken(1) == Token::kIN) { |
| 4400 loop_var_pos = token_index_; | 4400 loop_var_pos = token_index_; |
| 4401 loop_var_name = ExpectIdentifier("variable name expected"); | 4401 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4402 } else { | 4402 } else { |
| 4403 // The case without a type is handled above, so require a type here. | 4403 // The case without a type is handled above, so require a type here. |
| 4404 const AbstractType& type = AbstractType::ZoneHandle( | 4404 const AbstractType& type = AbstractType::ZoneHandle(ParseFinalVarOrType( |
| 4405 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 4405 FLAG_enable_type_checks ? kMustResolve : kIgnore)); |
| 4406 loop_var_pos = token_index_; | 4406 loop_var_pos = token_index_; |
| 4407 loop_var_name = ExpectIdentifier("variable name expected"); | 4407 loop_var_name = ExpectIdentifier("variable name expected"); |
| 4408 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); | 4408 loop_var = new LocalVariable(loop_var_pos, *loop_var_name, type); |
| 4409 if (is_final) { | 4409 if (is_final) { |
| 4410 loop_var->set_is_final(); | 4410 loop_var->set_is_final(); |
| 4411 } | 4411 } |
| 4412 } | 4412 } |
| 4413 ExpectToken(Token::kIN); | 4413 ExpectToken(Token::kIN); |
| 4414 const intptr_t collection_pos = token_index_; | 4414 const intptr_t collection_pos = token_index_; |
| 4415 AstNode* collection_expr = ParseExpr(kAllowConst); | 4415 AstNode* collection_expr = ParseExpr(kAllowConst); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4655 const String* var; | 4655 const String* var; |
| 4656 bool is_final; | 4656 bool is_final; |
| 4657 }; | 4657 }; |
| 4658 | 4658 |
| 4659 | 4659 |
| 4660 // Parse the parameter specified in the catch clause. | 4660 // Parse the parameter specified in the catch clause. |
| 4661 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { | 4661 void Parser::ParseCatchParameter(CatchParamDesc* catch_param) { |
| 4662 TRACE_PARSER("ParseCatchParameter"); | 4662 TRACE_PARSER("ParseCatchParameter"); |
| 4663 ASSERT(catch_param != NULL); | 4663 ASSERT(catch_param != NULL); |
| 4664 catch_param->is_final = (CurrentToken() == Token::kFINAL); | 4664 catch_param->is_final = (CurrentToken() == Token::kFINAL); |
| 4665 // The type of the catch parameter must always be resolved, even in unchecked |
| 4666 // mode. |
| 4665 catch_param->type = &AbstractType::ZoneHandle( | 4667 catch_param->type = &AbstractType::ZoneHandle( |
| 4666 ParseFinalVarOrType(kIsMandatory, kMustResolve)); | 4668 ParseFinalVarOrType(kMustResolve)); |
| 4667 catch_param->token_index = token_index_; | 4669 catch_param->token_index = token_index_; |
| 4668 catch_param->var = ExpectIdentifier("identifier expected"); | 4670 catch_param->var = ExpectIdentifier("identifier expected"); |
| 4669 } | 4671 } |
| 4670 | 4672 |
| 4671 | 4673 |
| 4672 // Populate local scope of the catch block with the catch parameters. | 4674 // Populate local scope of the catch block with the catch parameters. |
| 4673 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, | 4675 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, |
| 4674 const CatchParamDesc& stack_trace_param, | 4676 const CatchParamDesc& stack_trace_param, |
| 4675 LocalScope* scope) { | 4677 LocalScope* scope) { |
| 4676 ASSERT(exception_param.var != NULL); | 4678 ASSERT(exception_param.var != NULL); |
| (...skipping 1984 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6661 } | 6663 } |
| 6662 QualIdent type_name; | 6664 QualIdent type_name; |
| 6663 const intptr_t type_pos = token_index_; | 6665 const intptr_t type_pos = token_index_; |
| 6664 ParseQualIdent(&type_name); | 6666 ParseQualIdent(&type_name); |
| 6665 if (type_name.is_local_scope_ident) { | 6667 if (type_name.is_local_scope_ident) { |
| 6666 ErrorMsg(type_pos, "using '%s' in this context is invalid", | 6668 ErrorMsg(type_pos, "using '%s' in this context is invalid", |
| 6667 type_name.ident->ToCString()); | 6669 type_name.ident->ToCString()); |
| 6668 } | 6670 } |
| 6669 Class& scope_class = Class::Handle(); | 6671 Class& scope_class = Class::Handle(); |
| 6670 Object& type_class = Object::Handle(); | 6672 Object& type_class = Object::Handle(); |
| 6671 if (type_resolution == kDoNotResolve) { | 6673 if (type_resolution == kIgnore) { |
| 6674 // Leave type_class as null. |
| 6675 } else if (type_resolution == kDoNotResolve) { |
| 6672 String& qualifier = String::Handle(); | 6676 String& qualifier = String::Handle(); |
| 6673 if (type_name.qualifier != NULL) { | 6677 if (type_name.qualifier != NULL) { |
| 6674 qualifier ^= type_name.qualifier->raw(); | 6678 qualifier ^= type_name.qualifier->raw(); |
| 6675 } | 6679 } |
| 6676 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); | 6680 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); |
| 6677 } else { | 6681 } else { |
| 6678 scope_class = TypeParametersScopeClass(); | 6682 scope_class = TypeParametersScopeClass(); |
| 6679 if (!scope_class.IsNull()) { | 6683 if (!scope_class.IsNull()) { |
| 6680 TypeParameter& type_parameter = TypeParameter::Handle(); | 6684 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 6681 // Check if qualifier is a type parameter in scope. | 6685 // Check if qualifier is a type parameter in scope. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 6706 } | 6710 } |
| 6707 return type_parameter.raw(); | 6711 return type_parameter.raw(); |
| 6708 } | 6712 } |
| 6709 } | 6713 } |
| 6710 } | 6714 } |
| 6711 // Try to resolve the type class. | 6715 // Try to resolve the type class. |
| 6712 type_class = LookupTypeClass(type_name, type_resolution); | 6716 type_class = LookupTypeClass(type_name, type_resolution); |
| 6713 } | 6717 } |
| 6714 AbstractTypeArguments& type_arguments = | 6718 AbstractTypeArguments& type_arguments = |
| 6715 AbstractTypeArguments::Handle(ParseTypeArguments(type_resolution)); | 6719 AbstractTypeArguments::Handle(ParseTypeArguments(type_resolution)); |
| 6720 if (type_resolution == kIgnore) { |
| 6721 return Type::DynamicType(); |
| 6722 } |
| 6716 Type& type = Type::Handle( | 6723 Type& type = Type::Handle( |
| 6717 Type::NewParameterizedType(type_class, type_arguments)); | 6724 Type::NewParameterizedType(type_class, type_arguments)); |
| 6718 if (type_resolution == kMustResolve) { | 6725 if (type_resolution == kMustResolve) { |
| 6719 ASSERT(type_class.IsClass()); // Must be resolved. | 6726 ASSERT(type_class.IsClass()); // Must be resolved. |
| 6720 Error& error = Error::Handle(); | 6727 Error& error = Error::Handle(); |
| 6721 type ^= ClassFinalizer::FinalizeAndCanonicalizeType(scope_class, | 6728 type ^= ClassFinalizer::FinalizeAndCanonicalizeType(scope_class, |
| 6722 type, | 6729 type, |
| 6723 &error); | 6730 &error); |
| 6724 if (!error.IsNull()) { | 6731 if (!error.IsNull()) { |
| 6725 ErrorMsg(error.ToErrorCString()); | 6732 ErrorMsg(error.ToErrorCString()); |
| (...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7753 } | 7760 } |
| 7754 | 7761 |
| 7755 | 7762 |
| 7756 void Parser::SkipNestedExpr() { | 7763 void Parser::SkipNestedExpr() { |
| 7757 const bool saved_mode = SetAllowFunctionLiterals(true); | 7764 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 7758 SkipExpr(); | 7765 SkipExpr(); |
| 7759 SetAllowFunctionLiterals(saved_mode); | 7766 SetAllowFunctionLiterals(saved_mode); |
| 7760 } | 7767 } |
| 7761 | 7768 |
| 7762 } // namespace dart | 7769 } // namespace dart |
| OLD | NEW |