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 #include "vm/flags.h" | 6 #include "vm/flags.h" |
7 | 7 |
8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
9 | 9 |
10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
(...skipping 2031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2042 if (IsIdentifier() || (CurrentToken() == Token::kTHIS)) { | 2042 if (IsIdentifier() || (CurrentToken() == Token::kTHIS)) { |
2043 found_type = true; | 2043 found_type = true; |
2044 } | 2044 } |
2045 } | 2045 } |
2046 } | 2046 } |
2047 if (found_type) { | 2047 if (found_type) { |
2048 // The types of formal parameters are never ignored, even in unchecked | 2048 // The types of formal parameters are never ignored, even in unchecked |
2049 // mode, because they are part of the function type of closurized | 2049 // mode, because they are part of the function type of closurized |
2050 // functions appearing in type tests with typedefs. | 2050 // functions appearing in type tests with typedefs. |
2051 parameter.has_explicit_type = true; | 2051 parameter.has_explicit_type = true; |
2052 // It is too early to resolve the type here, since it can be a result type | |
2053 // referring to a not yet declared function type parameter. | |
2052 parameter.type = &AbstractType::ZoneHandle(Z, | 2054 parameter.type = &AbstractType::ZoneHandle(Z, |
2053 ParseType(is_top_level_ ? ClassFinalizer::kResolveTypeParameters : | 2055 ParseType(ClassFinalizer::kDoNotResolve)); |
2054 ClassFinalizer::kCanonicalize)); | |
2055 } else { | 2056 } else { |
2056 // If this is an initializing formal, its type will be set to the type of | 2057 // If this is an initializing formal, its type will be set to the type of |
2057 // the respective field when the constructor is fully parsed. | 2058 // the respective field when the constructor is fully parsed. |
2058 parameter.type = &Object::dynamic_type(); | 2059 parameter.type = &Object::dynamic_type(); |
2059 } | 2060 } |
2060 } | 2061 } |
2061 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 2062 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
2062 ConsumeToken(); | 2063 ConsumeToken(); |
2063 ExpectToken(Token::kPERIOD); | 2064 ExpectToken(Token::kPERIOD); |
2064 this_seen = true; | 2065 this_seen = true; |
(...skipping 29 matching lines...) Expand all Loading... | |
2094 if (IsParameterPart()) { | 2095 if (IsParameterPart()) { |
2095 // This parameter is probably a closure. If we saw the keyword 'var' | 2096 // This parameter is probably a closure. If we saw the keyword 'var' |
2096 // or 'final', a closure is not legal here and we ignore the | 2097 // or 'final', a closure is not legal here and we ignore the |
2097 // opening parens. | 2098 // opening parens. |
2098 // TODO(hausner): The language spec appears to allow var and final | 2099 // TODO(hausner): The language spec appears to allow var and final |
2099 // in signature types when used with initializing formals: | 2100 // in signature types when used with initializing formals: |
2100 // fieldFormalParameter: | 2101 // fieldFormalParameter: |
2101 // metadata finalConstVarOrType? this ‘.’ identifier formalParameterList? ; | 2102 // metadata finalConstVarOrType? this ‘.’ identifier formalParameterList? ; |
2102 if (!var_seen && !final_seen) { | 2103 if (!var_seen && !final_seen) { |
2103 // The parsed parameter type is actually the function result type. | 2104 // The parsed parameter type is actually the function result type. |
2104 const AbstractType& result_type = | 2105 AbstractType& result_type = |
2105 AbstractType::Handle(Z, parameter.type->raw()); | 2106 AbstractType::Handle(Z, parameter.type->raw()); |
2106 | 2107 |
2108 // In top-level and mixin functions, the source may be in a different | |
2109 // script than the script of the current class. However, we never reparse | |
2110 // signature functions (except typedef signature functions), therefore | |
2111 // we do not need to keep the correct script via a patch class. Use the | |
2112 // actual current class as owner of the signature function. | |
2113 const Function& signature_function = Function::Handle(Z, | |
2114 Function::NewSignatureFunction(current_class(), | |
2115 TokenPosition::kNoSource)); | |
2116 signature_function.set_parent_function(innermost_function()); | |
2117 innermost_function_ = signature_function.raw(); | |
2118 | |
2107 // Finish parsing the function type parameter. | 2119 // Finish parsing the function type parameter. |
2108 if (CurrentToken() == Token::kLT) { | 2120 if (CurrentToken() == Token::kLT) { |
2109 // TODO(hausner): handle generic function types. | |
2110 if (!FLAG_generic_method_syntax) { | 2121 if (!FLAG_generic_method_syntax) { |
2111 ReportError("generic function types not supported"); | 2122 ReportError("generic function types not supported"); |
2112 } | 2123 } |
2113 TokenPosition type_param_pos = TokenPos(); | 2124 ParseTypeParameters(false); |
2114 if (!TryParseTypeParameters()) { | |
2115 ReportError(type_param_pos, "error in type parameters"); | |
2116 } | |
2117 } | 2125 } |
2118 | 2126 |
2127 // Now that type parameters are declared, the result type can be resolved. | |
2128 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); | |
2129 | |
2119 ASSERT(CurrentToken() == Token::kLPAREN); | 2130 ASSERT(CurrentToken() == Token::kLPAREN); |
2120 ParamList func_params; | 2131 ParamList func_params; |
2121 | 2132 |
2122 // Add implicit closure object parameter. | 2133 // Add implicit closure object parameter. |
2123 func_params.AddFinalParameter( | 2134 func_params.AddFinalParameter( |
2124 TokenPos(), | 2135 TokenPos(), |
2125 &Symbols::ClosureParameter(), | 2136 &Symbols::ClosureParameter(), |
2126 &Object::dynamic_type()); | 2137 &Object::dynamic_type()); |
2127 | 2138 |
2128 const bool no_explicit_default_values = false; | 2139 const bool no_explicit_default_values = false; |
2129 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 2140 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
2130 | 2141 |
2131 // In top-level and mixin functions, the source may be in a different | |
2132 // script than the script of the current class. However, we never reparse | |
2133 // signature functions (except typedef signature functions), therefore | |
2134 // we do not need to keep the correct script via a patch class. Use the | |
2135 // actual current class as owner of the signature function. | |
2136 const Function& signature_function = Function::Handle(Z, | |
2137 Function::NewSignatureFunction(current_class(), | |
2138 TokenPosition::kNoSource)); | |
2139 signature_function.set_result_type(result_type); | 2142 signature_function.set_result_type(result_type); |
2140 AddFormalParamsToFunction(&func_params, signature_function); | 2143 AddFormalParamsToFunction(&func_params, signature_function); |
2144 | |
2145 ASSERT(innermost_function().raw() == signature_function.raw()); | |
2146 innermost_function_ = signature_function.parent_function(); | |
2147 signature_function.set_data(Object::Handle()); | |
2148 | |
2141 Type& signature_type = | 2149 Type& signature_type = |
2142 Type::ZoneHandle(Z, signature_function.SignatureType()); | 2150 Type::ZoneHandle(Z, signature_function.SignatureType()); |
2143 if (!is_top_level_) { | 2151 if (!is_top_level_) { |
2144 signature_type ^= ClassFinalizer::FinalizeType( | 2152 signature_type ^= ClassFinalizer::FinalizeType( |
2145 current_class(), signature_type, ClassFinalizer::kCanonicalize); | 2153 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
2146 signature_function.SetSignatureType(signature_type); | 2154 signature_function.SetSignatureType(signature_type); |
2147 } | 2155 } |
2148 ASSERT(is_top_level_ || signature_type.IsFinalized()); | 2156 ASSERT(is_top_level_ || signature_type.IsFinalized()); |
2149 // A signature type itself cannot be malformed or malbounded, only its | 2157 // A signature type itself cannot be malformed or malbounded, only its |
2150 // signature function's result type or parameter types may be. | 2158 // signature function's result type or parameter types may be. |
2151 ASSERT(!signature_type.IsMalformed()); | 2159 ASSERT(!signature_type.IsMalformed()); |
2152 ASSERT(!signature_type.IsMalbounded()); | 2160 ASSERT(!signature_type.IsMalbounded()); |
2153 // The type of the parameter is now the signature type. | 2161 // The type of the parameter is now the signature type. |
2154 parameter.type = &signature_type; | 2162 parameter.type = &signature_type; |
2155 } | 2163 } |
2164 } else { | |
2165 if (!parameter.type->IsFinalized()) { | |
2166 AbstractType& type = AbstractType::ZoneHandle(Z, parameter.type->raw()); | |
2167 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); | |
2168 if (!is_top_level_) { | |
2169 type = ClassFinalizer::FinalizeType( | |
2170 current_class(), type, ClassFinalizer::kCanonicalize); | |
2171 } | |
2172 parameter.type = &type; | |
2173 } | |
2156 } | 2174 } |
2157 | 2175 |
2158 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) { | 2176 if ((CurrentToken() == Token::kASSIGN) || (CurrentToken() == Token::kCOLON)) { |
2159 if ((!params->has_optional_positional_parameters && | 2177 if ((!params->has_optional_positional_parameters && |
2160 !params->has_optional_named_parameters) || | 2178 !params->has_optional_named_parameters) || |
2161 !allow_explicit_default_value) { | 2179 !allow_explicit_default_value) { |
2162 ReportError("parameter must not specify a default value"); | 2180 ReportError("parameter must not specify a default value"); |
2163 } | 2181 } |
2164 if (params->has_optional_positional_parameters) { | 2182 if (params->has_optional_positional_parameters) { |
2165 ExpectToken(Token::kASSIGN); | 2183 ExpectToken(Token::kASSIGN); |
(...skipping 1224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3390 SequenceNode* statements = CloseBlock(); | 3408 SequenceNode* statements = CloseBlock(); |
3391 return statements; | 3409 return statements; |
3392 } | 3410 } |
3393 | 3411 |
3394 | 3412 |
3395 // Parser is at the opening parenthesis of the formal parameter | 3413 // Parser is at the opening parenthesis of the formal parameter |
3396 // declaration of the function or constructor. | 3414 // declaration of the function or constructor. |
3397 // Parse the formal parameters and code. | 3415 // Parse the formal parameters and code. |
3398 SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) { | 3416 SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) { |
3399 TRACE_PARSER("ParseFunc"); | 3417 TRACE_PARSER("ParseFunc"); |
3400 Function& saved_innermost_function = | 3418 ASSERT(innermost_function().raw() == func.raw()); |
3401 Function::Handle(Z, innermost_function().raw()); | |
3402 innermost_function_ = func.raw(); | |
3403 | 3419 |
3404 // Save current try index. Try index starts at zero for each function. | 3420 // Save current try index. Try index starts at zero for each function. |
3405 intptr_t saved_try_index = last_used_try_index_; | 3421 intptr_t saved_try_index = last_used_try_index_; |
3406 last_used_try_index_ = 0; | 3422 last_used_try_index_ = 0; |
3407 | 3423 |
3408 // In case of nested async functions we also need to save the scope where | 3424 // In case of nested async functions we also need to save the scope where |
3409 // temporaries are added. | 3425 // temporaries are added. |
3410 LocalScope* saved_async_temp_scope = async_temp_scope_; | 3426 LocalScope* saved_async_temp_scope = async_temp_scope_; |
3411 | 3427 |
3412 if (func.IsGenerativeConstructor()) { | 3428 if (func.IsGenerativeConstructor()) { |
3413 SequenceNode* statements = ParseConstructor(func); | 3429 SequenceNode* statements = ParseConstructor(func); |
3414 innermost_function_ = saved_innermost_function.raw(); | |
3415 last_used_try_index_ = saved_try_index; | 3430 last_used_try_index_ = saved_try_index; |
3416 return statements; | 3431 return statements; |
3417 } | 3432 } |
3418 | 3433 |
3419 ASSERT(!func.IsGenerativeConstructor()); | 3434 ASSERT(!func.IsGenerativeConstructor()); |
3420 OpenFunctionBlock(func); // Build local scope for function. | 3435 OpenFunctionBlock(func); // Build local scope for function. |
3421 | 3436 |
3422 ParamList params; | 3437 ParamList params; |
3423 // An instance closure function may capture and access the receiver, but via | 3438 // An instance closure function may capture and access the receiver, but via |
3424 // the context and not via the first formal parameter. | 3439 // the context and not via the first formal parameter. |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3640 } else if (func.IsSyncGenClosure()) { | 3655 } else if (func.IsSyncGenClosure()) { |
3641 // body is unchanged. | 3656 // body is unchanged. |
3642 } else if (func.IsAsyncGenerator()) { | 3657 } else if (func.IsAsyncGenerator()) { |
3643 body = CloseAsyncGeneratorFunction(generated_body_closure, body); | 3658 body = CloseAsyncGeneratorFunction(generated_body_closure, body); |
3644 generated_body_closure.set_end_token_pos(end_token_pos); | 3659 generated_body_closure.set_end_token_pos(end_token_pos); |
3645 } else if (func.IsAsyncGenClosure()) { | 3660 } else if (func.IsAsyncGenClosure()) { |
3646 body = CloseAsyncGeneratorClosure(body); | 3661 body = CloseAsyncGeneratorClosure(body); |
3647 } | 3662 } |
3648 EnsureHasReturnStatement(body, end_token_pos); | 3663 EnsureHasReturnStatement(body, end_token_pos); |
3649 current_block_->statements->Add(body); | 3664 current_block_->statements->Add(body); |
3650 innermost_function_ = saved_innermost_function.raw(); | |
3651 last_used_try_index_ = saved_try_index; | 3665 last_used_try_index_ = saved_try_index; |
3652 async_temp_scope_ = saved_async_temp_scope; | 3666 async_temp_scope_ = saved_async_temp_scope; |
3653 return CloseBlock(); | 3667 return CloseBlock(); |
3654 } | 3668 } |
3655 | 3669 |
3656 | 3670 |
3657 void Parser::AddEqualityNullCheck() { | 3671 void Parser::AddEqualityNullCheck() { |
3658 AstNode* argument = | 3672 AstNode* argument = |
3659 new LoadLocalNode(TokenPosition::kNoSource, | 3673 new LoadLocalNode(TokenPosition::kNoSource, |
3660 current_block_->scope->parent()->VariableAt(1)); | 3674 current_block_->scope->parent()->VariableAt(1)); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3736 // not a library prefix. | 3750 // not a library prefix. |
3737 LibraryPrefix& prefix = | 3751 LibraryPrefix& prefix = |
3738 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); | 3752 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); |
3739 if (prefix.IsNull()) { | 3753 if (prefix.IsNull()) { |
3740 return LibraryPrefix::null(); | 3754 return LibraryPrefix::null(); |
3741 } | 3755 } |
3742 | 3756 |
3743 // A library prefix with the name exists. Now check whether it is | 3757 // A library prefix with the name exists. Now check whether it is |
3744 // shadowed by a local definition. | 3758 // shadowed by a local definition. |
3745 if (!is_top_level_ && | 3759 if (!is_top_level_ && |
3746 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { | 3760 ResolveIdentInLocalScope(TokenPos(), ident, NULL, NULL)) { |
3747 return LibraryPrefix::null(); | 3761 return LibraryPrefix::null(); |
3748 } | 3762 } |
3749 // Check whether the identifier is shadowed by a type parameter. | 3763 // Check whether the identifier is shadowed by a function type parameter. |
3764 // TODO(regis): Shortcut this lookup if no generic functions in scope. | |
3765 if (!innermost_function().IsNull() && | |
3766 (innermost_function().LookupTypeParameter(ident, NULL) != | |
3767 TypeParameter::null())) { | |
3768 return LibraryPrefix::null(); | |
3769 } | |
3770 // Check whether the identifier is shadowed by a class type parameter. | |
3750 ASSERT(!current_class().IsNull()); | 3771 ASSERT(!current_class().IsNull()); |
3751 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { | 3772 if (current_class().LookupTypeParameter(ident) != TypeParameter::null()) { |
3752 return LibraryPrefix::null(); | 3773 return LibraryPrefix::null(); |
3753 } | 3774 } |
3754 | 3775 |
3755 // We have a name that is not shadowed, followed by a period or #. | 3776 // We have a name that is not shadowed, followed by a period or #. |
3756 // Consume the identifier, let the caller consume the . or #. | 3777 // Consume the identifier, let the caller consume the . or #. |
3757 ConsumeToken(); | 3778 ConsumeToken(); |
3758 return prefix.raw(); | 3779 return prefix.raw(); |
3759 } | 3780 } |
3760 | 3781 |
3761 | 3782 |
3762 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { | 3783 void Parser::ParseMethodOrConstructor(ClassDesc* members, MemberDesc* method) { |
3763 TRACE_PARSER("ParseMethodOrConstructor"); | 3784 TRACE_PARSER("ParseMethodOrConstructor"); |
3764 // We are at the beginning of the formal parameters list. | 3785 // We are at the beginning of the formal parameters list. |
3765 ASSERT(CurrentToken() == Token::kLPAREN || | 3786 ASSERT(CurrentToken() == Token::kLPAREN || |
3766 CurrentToken() == Token::kLT || | 3787 CurrentToken() == Token::kLT || |
3767 method->IsGetter()); | 3788 method->IsGetter()); |
3768 ASSERT(method->type != NULL); | 3789 ASSERT(method->type != NULL); // May still be unresolved. |
3769 ASSERT(current_member_ == method); | 3790 ASSERT(current_member_ == method); |
3770 | 3791 |
3771 if (method->has_var) { | 3792 if (method->has_var) { |
3772 ReportError(method->name_pos, "keyword var not allowed for methods"); | 3793 ReportError(method->name_pos, "keyword var not allowed for methods"); |
3773 } | 3794 } |
3774 if (method->has_final) { | 3795 if (method->has_final) { |
3775 ReportError(method->name_pos, "'final' not allowed for methods"); | 3796 ReportError(method->name_pos, "'final' not allowed for methods"); |
3776 } | 3797 } |
3777 if (method->has_abstract && method->has_static) { | 3798 if (method->has_abstract && method->has_static) { |
3778 ReportError(method->name_pos, | 3799 ReportError(method->name_pos, |
3779 "static method '%s' cannot be abstract", | 3800 "static method '%s' cannot be abstract", |
3780 method->name->ToCString()); | 3801 method->name->ToCString()); |
3781 } | 3802 } |
3782 if (method->has_const && !method->IsFactoryOrConstructor()) { | 3803 if (method->has_const && !method->IsFactoryOrConstructor()) { |
3783 ReportError(method->name_pos, "'const' not allowed for methods"); | 3804 ReportError(method->name_pos, "'const' not allowed for methods"); |
3784 } | 3805 } |
3785 if (method->has_abstract && method->IsFactoryOrConstructor()) { | 3806 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
3786 ReportError(method->name_pos, "constructor cannot be abstract"); | 3807 ReportError(method->name_pos, "constructor cannot be abstract"); |
3787 } | 3808 } |
3788 if (method->has_const && method->IsConstructor()) { | 3809 if (method->has_const && method->IsConstructor()) { |
3789 current_class().set_is_const(); | 3810 current_class().set_is_const(); |
3790 } | 3811 } |
3791 | 3812 |
3813 Function& func = Function::Handle(Z, | |
3814 Function::New(*method->name, // May change. | |
3815 method->kind, | |
3816 method->has_static, | |
3817 method->has_const, | |
3818 method->has_abstract, // May change. | |
3819 method->has_external, | |
3820 method->has_native, // May change. | |
3821 current_class(), | |
3822 method->decl_begin_pos)); | |
3823 | |
3824 ASSERT(innermost_function().IsNull()); | |
3825 innermost_function_ = func.raw(); | |
3826 | |
3792 if (CurrentToken() == Token::kLT) { | 3827 if (CurrentToken() == Token::kLT) { |
3793 // Parse type parameters, but ignore them. | |
3794 // TODO(hausner): handle type parameters. | |
3795 if (!FLAG_generic_method_syntax) { | 3828 if (!FLAG_generic_method_syntax) { |
3796 ReportError("generic type arguments not supported."); | 3829 ReportError("generic type arguments not supported."); |
3797 } | 3830 } |
3798 TokenPosition type_param_pos = TokenPos(); | 3831 TokenPosition type_param_pos = TokenPos(); |
3799 if (method->IsFactoryOrConstructor()) { | 3832 if (method->IsFactoryOrConstructor()) { |
3800 ReportError(method->name_pos, "constructor cannot be generic"); | 3833 ReportError(method->name_pos, "constructor cannot be generic"); |
3801 } | 3834 } |
3802 if (method->IsGetter() || method->IsSetter()) { | 3835 if (method->IsGetter() || method->IsSetter()) { |
3803 ReportError(type_param_pos, "%s cannot be generic", | 3836 ReportError(type_param_pos, "%s cannot be generic", |
3804 method->IsGetter() ? "getter" : "setter"); | 3837 method->IsGetter() ? "getter" : "setter"); |
3805 } | 3838 } |
3806 if (!TryParseTypeParameters()) { | 3839 ParseTypeParameters(false); |
3807 ReportError(type_param_pos, "error in type parameters"); | 3840 } |
3808 } | 3841 |
3842 // Now that type parameters are declared, the result type can be resolved. | |
3843 if (!method->type->IsResolved()) { | |
3844 AbstractType& type = AbstractType::ZoneHandle(Z, method->type->raw()); | |
3845 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); | |
3846 method->type = &type; | |
3809 } | 3847 } |
3810 | 3848 |
3811 // Parse the formal parameters. | 3849 // Parse the formal parameters. |
3812 const bool are_implicitly_final = method->has_const; | 3850 const bool are_implicitly_final = method->has_const; |
3813 const bool allow_explicit_default_values = true; | 3851 const bool allow_explicit_default_values = true; |
3814 const TokenPosition formal_param_pos = TokenPos(); | 3852 const TokenPosition formal_param_pos = TokenPos(); |
3815 method->params.Clear(); | 3853 method->params.Clear(); |
3816 // Static functions do not have a receiver. | 3854 // Static functions do not have a receiver. |
3817 // The first parameter of a factory is the TypeArguments vector of | 3855 // The first parameter of a factory is the TypeArguments vector of |
3818 // the type of the instance to be allocated. | 3856 // the type of the instance to be allocated. |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4072 } | 4110 } |
4073 } | 4111 } |
4074 } | 4112 } |
4075 | 4113 |
4076 if (method->has_abstract && (async_modifier != RawFunction::kNoModifier)) { | 4114 if (method->has_abstract && (async_modifier != RawFunction::kNoModifier)) { |
4077 ReportError(modifier_pos, | 4115 ReportError(modifier_pos, |
4078 "abstract function '%s' may not be async, async* or sync*", | 4116 "abstract function '%s' may not be async, async* or sync*", |
4079 method->name->ToCString()); | 4117 method->name->ToCString()); |
4080 } | 4118 } |
4081 | 4119 |
4082 RawFunction::Kind function_kind; | 4120 // Update function object. |
4083 if (method->IsFactoryOrConstructor()) { | 4121 func.set_name(*method->name); |
4084 function_kind = RawFunction::kConstructor; | 4122 func.set_is_abstract(method->has_abstract); |
4085 } else if (method->IsGetter()) { | 4123 func.set_is_native(method->has_native); |
4086 function_kind = RawFunction::kGetterFunction; | |
4087 } else if (method->IsSetter()) { | |
4088 function_kind = RawFunction::kSetterFunction; | |
4089 } else { | |
4090 function_kind = RawFunction::kRegularFunction; | |
4091 } | |
4092 Function& func = Function::Handle(Z, | |
4093 Function::New(*method->name, | |
4094 function_kind, | |
4095 method->has_static, | |
4096 method->has_const, | |
4097 method->has_abstract, | |
4098 method->has_external, | |
4099 method->has_native, | |
4100 current_class(), | |
4101 method->decl_begin_pos)); | |
4102 func.set_result_type(*method->type); | 4124 func.set_result_type(*method->type); |
4103 func.set_end_token_pos(method_end_pos); | 4125 func.set_end_token_pos(method_end_pos); |
4104 func.set_is_redirecting(is_redirecting); | 4126 func.set_is_redirecting(is_redirecting); |
4105 func.set_modifier(async_modifier); | 4127 func.set_modifier(async_modifier); |
4106 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { | 4128 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { |
4107 func.set_is_reflectable(false); | 4129 func.set_is_reflectable(false); |
4108 } | 4130 } |
4109 if (is_patch_source() && IsPatchAnnotation(method->metadata_pos)) { | 4131 if (is_patch_source() && IsPatchAnnotation(method->metadata_pos)) { |
4110 // Currently, we just ignore the patch annotation. If the function | 4132 // Currently, we just ignore the patch annotation. If the function |
4111 // name already exists in the patched class, this function will replace | 4133 // name already exists in the patched class, this function will replace |
(...skipping 12 matching lines...) Expand all Loading... | |
4124 ASSERT(func.IsFactory()); | 4146 ASSERT(func.IsFactory()); |
4125 func.SetRedirectionType(redirection_type); | 4147 func.SetRedirectionType(redirection_type); |
4126 if (!redirection_identifier.IsNull()) { | 4148 if (!redirection_identifier.IsNull()) { |
4127 func.SetRedirectionIdentifier(redirection_identifier); | 4149 func.SetRedirectionIdentifier(redirection_identifier); |
4128 } | 4150 } |
4129 } | 4151 } |
4130 | 4152 |
4131 // No need to resolve parameter types yet, or add parameters to local scope. | 4153 // No need to resolve parameter types yet, or add parameters to local scope. |
4132 ASSERT(is_top_level_); | 4154 ASSERT(is_top_level_); |
4133 AddFormalParamsToFunction(&method->params, func); | 4155 AddFormalParamsToFunction(&method->params, func); |
4156 ASSERT(innermost_function().raw() == func.raw()); | |
4157 innermost_function_ = Function::null(); | |
4134 members->AddFunction(func); | 4158 members->AddFunction(func); |
4135 } | 4159 } |
4136 | 4160 |
4137 | 4161 |
4138 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 4162 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
4139 TRACE_PARSER("ParseFieldDefinition"); | 4163 TRACE_PARSER("ParseFieldDefinition"); |
4140 // The parser has read the first field name and is now at the token | 4164 // The parser has read the first field name and is now at the token |
4141 // after the field name. | 4165 // after the field name. |
4142 ASSERT(CurrentToken() == Token::kSEMICOLON || | 4166 ASSERT(CurrentToken() == Token::kSEMICOLON || |
4143 CurrentToken() == Token::kCOMMA || | 4167 CurrentToken() == Token::kCOMMA || |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4425 if (TryParseReturnType()) { | 4449 if (TryParseReturnType()) { |
4426 if (IsIdentifier() || | 4450 if (IsIdentifier() || |
4427 (CurrentToken() == Token::kGET) || | 4451 (CurrentToken() == Token::kGET) || |
4428 (CurrentToken() == Token::kSET) || | 4452 (CurrentToken() == Token::kSET) || |
4429 (CurrentToken() == Token::kOPERATOR)) { | 4453 (CurrentToken() == Token::kOPERATOR)) { |
4430 found_type = true; | 4454 found_type = true; |
4431 } | 4455 } |
4432 } | 4456 } |
4433 } | 4457 } |
4434 if (found_type) { | 4458 if (found_type) { |
4459 // It is too early to resolve the type here, since it can be a result type | |
4460 // referring to a not yet declared function type parameter. | |
4435 member.type = &AbstractType::ZoneHandle(Z, | 4461 member.type = &AbstractType::ZoneHandle(Z, |
4436 ParseType(ClassFinalizer::kResolveTypeParameters)); | 4462 ParseType(ClassFinalizer::kDoNotResolve)); |
4437 } | 4463 } |
4438 } | 4464 } |
4439 | 4465 |
4440 // Optionally parse a (possibly named) constructor name or factory. | 4466 // Optionally parse a (possibly named) constructor name or factory. |
4441 if (IsIdentifier() && | 4467 if (IsIdentifier() && |
4442 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 4468 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
4443 member.name_pos = TokenPos(); | 4469 member.name_pos = TokenPos(); |
4444 member.name = CurrentLiteral(); // Unqualified identifier. | 4470 member.name = CurrentLiteral(); // Unqualified identifier. |
4445 ConsumeToken(); | 4471 ConsumeToken(); |
4446 if (member.has_factory) { | 4472 if (member.has_factory) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4539 ReportError("identifier expected"); | 4565 ReportError("identifier expected"); |
4540 } | 4566 } |
4541 | 4567 |
4542 ASSERT(member.name != NULL); | 4568 ASSERT(member.name != NULL); |
4543 if (IsParameterPart() || member.IsGetter()) { | 4569 if (IsParameterPart() || member.IsGetter()) { |
4544 // Constructor or method. | 4570 // Constructor or method. |
4545 if (member.type == NULL) { | 4571 if (member.type == NULL) { |
4546 member.type = &Object::dynamic_type(); | 4572 member.type = &Object::dynamic_type(); |
4547 } | 4573 } |
4548 ASSERT(member.IsFactory() == member.has_factory); | 4574 ASSERT(member.IsFactory() == member.has_factory); |
4575 // Note that member.type may still be unresolved. | |
4549 ParseMethodOrConstructor(members, &member); | 4576 ParseMethodOrConstructor(members, &member); |
4550 } else if (CurrentToken() == Token::kSEMICOLON || | 4577 } else if (CurrentToken() == Token::kSEMICOLON || |
4551 CurrentToken() == Token::kCOMMA || | 4578 CurrentToken() == Token::kCOMMA || |
4552 CurrentToken() == Token::kASSIGN) { | 4579 CurrentToken() == Token::kASSIGN) { |
4553 // Field definition. | 4580 // Field definition. |
4554 if (member.has_const) { | 4581 if (member.has_const) { |
4555 // const fields are implicitly final. | 4582 // const fields are implicitly final. |
4556 member.has_final = true; | 4583 member.has_final = true; |
4557 } | 4584 } |
4558 if (member.type == NULL) { | 4585 if (member.type == NULL) { |
4559 if (member.has_final) { | 4586 if (member.has_final) { |
4560 member.type = &Object::dynamic_type(); | 4587 member.type = &Object::dynamic_type(); |
4561 } else { | 4588 } else { |
4562 ReportError("missing 'var', 'final', 'const' or type" | 4589 ReportError("missing 'var', 'final', 'const' or type" |
4563 " in field declaration"); | 4590 " in field declaration"); |
4564 } | 4591 } |
4565 } else if (member.type->IsVoidType()) { | 4592 } else if (member.type->IsVoidType()) { |
4566 ReportError(member.name_pos, "field may not be 'void'"); | 4593 ReportError(member.name_pos, "field may not be 'void'"); |
4567 } | 4594 } |
4595 if (!member.type->IsResolved()) { | |
4596 AbstractType& type = AbstractType::ZoneHandle(Z, member.type->raw()); | |
4597 ResolveType(ClassFinalizer::kResolveTypeParameters, &type); | |
4598 member.type = &type; | |
4599 } | |
4568 ParseFieldDefinition(members, &member); | 4600 ParseFieldDefinition(members, &member); |
4569 } else { | 4601 } else { |
4570 UnexpectedToken(); | 4602 UnexpectedToken(); |
4571 } | 4603 } |
4572 current_member_ = NULL; | 4604 current_member_ = NULL; |
4573 CheckMemberNameConflict(members, &member); | 4605 CheckMemberNameConflict(members, &member); |
4574 members->AddMember(member); | 4606 members->AddMember(member); |
4575 } | 4607 } |
4576 | 4608 |
4577 | 4609 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4676 class_name.ToCString()); | 4708 class_name.ToCString()); |
4677 } | 4709 } |
4678 // Pre-registered classes need their scripts connected at this time. | 4710 // Pre-registered classes need their scripts connected at this time. |
4679 cls.set_script(script_); | 4711 cls.set_script(script_); |
4680 cls.set_token_pos(declaration_pos); | 4712 cls.set_token_pos(declaration_pos); |
4681 } | 4713 } |
4682 } | 4714 } |
4683 ASSERT(!cls.IsNull()); | 4715 ASSERT(!cls.IsNull()); |
4684 ASSERT(cls.functions() == Object::empty_array().raw()); | 4716 ASSERT(cls.functions() == Object::empty_array().raw()); |
4685 set_current_class(cls); | 4717 set_current_class(cls); |
4686 ParseTypeParameters(cls); | 4718 ParseTypeParameters(true); |
4687 if (is_patch) { | 4719 if (is_patch) { |
4688 // Check that the new type parameters are identical to the original ones. | 4720 // Check that the new type parameters are identical to the original ones. |
4689 const TypeArguments& new_type_parameters = | 4721 const TypeArguments& new_type_parameters = |
4690 TypeArguments::Handle(Z, cls.type_parameters()); | 4722 TypeArguments::Handle(Z, cls.type_parameters()); |
4691 const int new_type_params_count = | 4723 const int new_type_params_count = |
4692 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); | 4724 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); |
4693 const int orig_type_params_count = | 4725 const int orig_type_params_count = |
4694 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); | 4726 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); |
4695 if (new_type_params_count != orig_type_params_count) { | 4727 if (new_type_params_count != orig_type_params_count) { |
4696 ReportError(classname_pos, | 4728 ReportError(classname_pos, |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5140 if (!obj.IsNull()) { | 5172 if (!obj.IsNull()) { |
5141 ReportError(classname_pos, "'%s' is already defined", | 5173 ReportError(classname_pos, "'%s' is already defined", |
5142 class_name.ToCString()); | 5174 class_name.ToCString()); |
5143 } | 5175 } |
5144 const Class& mixin_application = | 5176 const Class& mixin_application = |
5145 Class::Handle(Z, Class::New(library_, class_name, | 5177 Class::Handle(Z, Class::New(library_, class_name, |
5146 script_, classname_pos)); | 5178 script_, classname_pos)); |
5147 mixin_application.set_is_mixin_app_alias(); | 5179 mixin_application.set_is_mixin_app_alias(); |
5148 library_.AddClass(mixin_application); | 5180 library_.AddClass(mixin_application); |
5149 set_current_class(mixin_application); | 5181 set_current_class(mixin_application); |
5150 ParseTypeParameters(mixin_application); | 5182 ParseTypeParameters(true); |
5151 | 5183 |
5152 ExpectToken(Token::kASSIGN); | 5184 ExpectToken(Token::kASSIGN); |
5153 | 5185 |
5154 if (CurrentToken() == Token::kABSTRACT) { | 5186 if (CurrentToken() == Token::kABSTRACT) { |
5155 mixin_application.set_is_abstract(); | 5187 mixin_application.set_is_abstract(); |
5156 ConsumeToken(); | 5188 ConsumeToken(); |
5157 } | 5189 } |
5158 | 5190 |
5159 const TokenPosition type_pos = TokenPos(); | 5191 const TokenPosition type_pos = TokenPos(); |
5160 AbstractType& type = | 5192 AbstractType& type = |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5268 // to be properly finalized, need to be associated to this scope class as | 5300 // to be properly finalized, need to be associated to this scope class as |
5269 // they are parsed. | 5301 // they are parsed. |
5270 const Class& function_type_alias = | 5302 const Class& function_type_alias = |
5271 Class::Handle(Z, Class::New( | 5303 Class::Handle(Z, Class::New( |
5272 library_, *alias_name, script_, declaration_pos)); | 5304 library_, *alias_name, script_, declaration_pos)); |
5273 function_type_alias.set_is_synthesized_class(); | 5305 function_type_alias.set_is_synthesized_class(); |
5274 function_type_alias.set_is_abstract(); | 5306 function_type_alias.set_is_abstract(); |
5275 function_type_alias.set_is_prefinalized(); | 5307 function_type_alias.set_is_prefinalized(); |
5276 library_.AddClass(function_type_alias); | 5308 library_.AddClass(function_type_alias); |
5277 set_current_class(function_type_alias); | 5309 set_current_class(function_type_alias); |
5278 // Parse the type parameters of the function type. | 5310 // Parse the type parameters of the typedef class. |
5279 ParseTypeParameters(function_type_alias); | 5311 ParseTypeParameters(true); |
5280 // At this point, the type parameters have been parsed, so we can resolve the | 5312 // At this point, the type parameters have been parsed, so we can resolve the |
5281 // result type. | 5313 // result type. |
5282 if (!result_type.IsNull()) { | 5314 if (!result_type.IsNull()) { |
5283 ResolveTypeFromClass(function_type_alias, | 5315 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); |
5284 ClassFinalizer::kResolveTypeParameters, | |
5285 &result_type); | |
5286 } | 5316 } |
5287 // Parse the formal parameters of the function type. | 5317 // Parse the formal parameters of the function type. |
5288 CheckToken(Token::kLPAREN, "formal parameter list expected"); | 5318 CheckToken(Token::kLPAREN, "formal parameter list expected"); |
5289 ParamList func_params; | 5319 ParamList func_params; |
5290 | 5320 |
5291 // Add implicit closure object parameter. | 5321 // Add implicit closure object parameter. |
5292 func_params.AddFinalParameter( | 5322 func_params.AddFinalParameter( |
5293 TokenPos(), | 5323 TokenPos(), |
5294 &Symbols::ClosureParameter(), | 5324 &Symbols::ClosureParameter(), |
5295 &Object::dynamic_type()); | 5325 &Object::dynamic_type()); |
5296 | 5326 |
5297 // Mark the current class as a typedef class (by setting its signature | 5327 // Mark the current class as a typedef class (by setting its signature |
5298 // function field to a non-null function) before parsing its formal parameters | 5328 // function field to a non-null function) before parsing its formal parameters |
5299 // so that parsed function types are aware that their owner class is a | 5329 // so that parsed function types are aware that their owner class is a |
5300 // typedef class. | 5330 // typedef class. |
5301 Function& signature_function = | 5331 Function& signature_function = |
5302 Function::Handle(Z, Function::NewSignatureFunction(function_type_alias, | 5332 Function::Handle(Z, Function::NewSignatureFunction(function_type_alias, |
5303 alias_name_pos)); | 5333 alias_name_pos)); |
5334 ASSERT(innermost_function().IsNull()); | |
5335 innermost_function_ = signature_function.raw(); | |
5304 // Set the signature function in the function type alias class. | 5336 // Set the signature function in the function type alias class. |
5305 function_type_alias.set_signature_function(signature_function); | 5337 function_type_alias.set_signature_function(signature_function); |
5306 | 5338 |
5307 const bool no_explicit_default_values = false; | 5339 const bool no_explicit_default_values = false; |
5308 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 5340 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
5309 ExpectSemicolon(); | 5341 ExpectSemicolon(); |
5310 signature_function.set_result_type(result_type); | 5342 signature_function.set_result_type(result_type); |
5311 AddFormalParamsToFunction(&func_params, signature_function); | 5343 AddFormalParamsToFunction(&func_params, signature_function); |
5312 | 5344 |
5345 ASSERT(innermost_function().raw() == signature_function.raw()); | |
5346 innermost_function_ = Function::null(); | |
5347 | |
5313 if (FLAG_trace_parser) { | 5348 if (FLAG_trace_parser) { |
5314 OS::Print("TopLevel parsing function type alias '%s'\n", | 5349 OS::Print("TopLevel parsing function type alias '%s'\n", |
5315 String::Handle(Z, signature_function.Signature()).ToCString()); | 5350 String::Handle(Z, signature_function.Signature()).ToCString()); |
5316 } | 5351 } |
5317 // The alias should not be marked as finalized yet, since it needs to be | 5352 // The alias should not be marked as finalized yet, since it needs to be |
5318 // checked in the class finalizer for illegal self references. | 5353 // checked in the class finalizer for illegal self references. |
5319 ASSERT(!function_type_alias.is_finalized()); | 5354 ASSERT(!function_type_alias.is_finalized()); |
5320 pending_classes.Add(function_type_alias, Heap::kOld); | 5355 pending_classes.Add(function_type_alias, Heap::kOld); |
5321 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5356 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5322 library_.AddClassMetadata(function_type_alias, | 5357 library_.AddClassMetadata(function_type_alias, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5402 ExpectIdentifier("type name expected"); | 5437 ExpectIdentifier("type name expected"); |
5403 if (CurrentToken() == Token::kPERIOD) { | 5438 if (CurrentToken() == Token::kPERIOD) { |
5404 ConsumeToken(); | 5439 ConsumeToken(); |
5405 ExpectIdentifier("name expected"); | 5440 ExpectIdentifier("name expected"); |
5406 } | 5441 } |
5407 SkipTypeArguments(); | 5442 SkipTypeArguments(); |
5408 } | 5443 } |
5409 } | 5444 } |
5410 | 5445 |
5411 | 5446 |
5412 void Parser::ParseTypeParameters(const Class& cls) { | 5447 void Parser::ParseTypeParameters(bool parameterizing_class) { |
hausner
2016/09/19 20:28:48
Would it make sense to pass the class or function
regis
2016/09/19 22:02:30
Actually, I tried, but realized that other calls i
| |
5413 TRACE_PARSER("ParseTypeParameters"); | 5448 TRACE_PARSER("ParseTypeParameters"); |
5414 if (CurrentToken() == Token::kLT) { | 5449 if (CurrentToken() == Token::kLT) { |
5415 GrowableArray<AbstractType*> type_parameters_array(Z, 2); | 5450 GrowableArray<AbstractType*> type_parameters_array(Z, 2); |
5416 intptr_t index = 0; | 5451 intptr_t index = 0; |
5417 TypeParameter& type_parameter = TypeParameter::Handle(Z); | 5452 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
5418 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); | 5453 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
5419 String& existing_type_parameter_name = String::Handle(Z); | 5454 String& existing_type_parameter_name = String::Handle(Z); |
5420 AbstractType& type_parameter_bound = Type::Handle(Z); | 5455 AbstractType& type_parameter_bound = Type::Handle(Z); |
5421 do { | 5456 do { |
5422 ConsumeToken(); | 5457 ConsumeToken(); |
5423 const TokenPosition metadata_pos = SkipMetadata(); | 5458 const TokenPosition metadata_pos = SkipMetadata(); |
5424 const TokenPosition type_parameter_pos = TokenPos(); | 5459 const TokenPosition type_parameter_pos = TokenPos(); |
5425 const TokenPosition declaration_pos = | 5460 const TokenPosition declaration_pos = |
5426 metadata_pos.IsReal() ? metadata_pos : type_parameter_pos; | 5461 metadata_pos.IsReal() ? metadata_pos : type_parameter_pos; |
5427 String& type_parameter_name = | 5462 String& type_parameter_name = |
5428 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 5463 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
5429 // Check for duplicate type parameters. | 5464 // Check for duplicate type parameters. |
5430 for (intptr_t i = 0; i < index; i++) { | 5465 for (intptr_t i = 0; i < index; i++) { |
5431 existing_type_parameter ^= type_parameters_array.At(i)->raw(); | 5466 existing_type_parameter ^= type_parameters_array.At(i)->raw(); |
5432 existing_type_parameter_name = existing_type_parameter.name(); | 5467 existing_type_parameter_name = existing_type_parameter.name(); |
5433 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 5468 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
5434 ReportError(type_parameter_pos, "duplicate type parameter '%s'", | 5469 ReportError(type_parameter_pos, "duplicate type parameter '%s'", |
5435 type_parameter_name.ToCString()); | 5470 type_parameter_name.ToCString()); |
5436 } | 5471 } |
5437 } | 5472 } |
5438 if (CurrentToken() == Token::kEXTENDS) { | 5473 if ((CurrentToken() == Token::kEXTENDS) || |
5474 (!parameterizing_class && (CurrentToken() == Token::kSUPER))) { | |
5439 ConsumeToken(); | 5475 ConsumeToken(); |
5476 // TODO(regis): Handle 'super' differently than 'extends'. | |
5440 // A bound may refer to the owner of the type parameter it applies to, | 5477 // A bound may refer to the owner of the type parameter it applies to, |
5441 // i.e. to the class or interface currently being parsed. | 5478 // i.e. to the class or function currently being parsed. |
5442 // Postpone resolution in order to avoid resolving the class and its | 5479 // Postpone resolution in order to avoid resolving the owner and its |
5443 // type parameters, as they are not fully parsed yet. | 5480 // type parameters, as they are not fully parsed yet. |
5444 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 5481 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
5445 } else { | 5482 } else { |
5446 type_parameter_bound = I->object_store()->object_type(); | 5483 type_parameter_bound = I->object_store()->object_type(); |
5447 } | 5484 } |
5448 type_parameter = TypeParameter::New(cls, | 5485 type_parameter = TypeParameter::New( |
5449 index, | 5486 parameterizing_class ? current_class() : Class::Handle(Z), |
5450 type_parameter_name, | 5487 parameterizing_class ? Function::Handle(Z) : innermost_function(), |
5451 type_parameter_bound, | 5488 index, |
5452 declaration_pos); | 5489 type_parameter_name, |
5490 type_parameter_bound, | |
5491 declaration_pos); | |
5453 type_parameters_array.Add( | 5492 type_parameters_array.Add( |
5454 &AbstractType::ZoneHandle(Z, type_parameter.raw())); | 5493 &AbstractType::ZoneHandle(Z, type_parameter.raw())); |
5455 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 5494 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
5456 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 5495 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
5457 } | 5496 } |
5458 index++; | 5497 index++; |
5459 } while (CurrentToken() == Token::kCOMMA); | 5498 } while (CurrentToken() == Token::kCOMMA); |
5460 Token::Kind token = CurrentToken(); | 5499 Token::Kind token = CurrentToken(); |
5461 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5500 if ((token == Token::kGT) || (token == Token::kSHR)) { |
5462 ConsumeRightAngleBracket(); | 5501 ConsumeRightAngleBracket(); |
5463 } else { | 5502 } else { |
5464 ReportError("right angle bracket expected"); | 5503 ReportError("right angle bracket expected"); |
5465 } | 5504 } |
5466 const TypeArguments& type_parameters = | 5505 const TypeArguments& type_parameters = |
5467 TypeArguments::Handle(Z, | 5506 TypeArguments::Handle(Z, NewTypeArguments(type_parameters_array)); |
5468 NewTypeArguments(type_parameters_array)); | 5507 if (parameterizing_class) { |
5469 cls.set_type_parameters(type_parameters); | 5508 current_class().set_type_parameters(type_parameters); |
5509 } else { | |
5510 innermost_function().set_type_parameters(type_parameters); | |
5511 } | |
5470 // Try to resolve the upper bounds, which will at least resolve the | 5512 // Try to resolve the upper bounds, which will at least resolve the |
5471 // referenced type parameters. | 5513 // referenced type parameters. |
5472 const intptr_t num_types = type_parameters.Length(); | 5514 const intptr_t num_types = type_parameters.Length(); |
5473 for (intptr_t i = 0; i < num_types; i++) { | 5515 for (intptr_t i = 0; i < num_types; i++) { |
5474 type_parameter ^= type_parameters.TypeAt(i); | 5516 type_parameter ^= type_parameters.TypeAt(i); |
5475 type_parameter_bound = type_parameter.bound(); | 5517 type_parameter_bound = type_parameter.bound(); |
5476 ResolveTypeFromClass(cls, | 5518 ResolveType(ClassFinalizer::kResolveTypeParameters, |
5477 ClassFinalizer::kResolveTypeParameters, | 5519 &type_parameter_bound); |
5478 &type_parameter_bound); | |
5479 type_parameter.set_bound(type_parameter_bound); | 5520 type_parameter.set_bound(type_parameter_bound); |
5480 } | 5521 } |
5481 } | 5522 } |
5482 } | 5523 } |
5483 | 5524 |
5484 | 5525 |
5485 RawTypeArguments* Parser::ParseTypeArguments( | 5526 RawTypeArguments* Parser::ParseTypeArguments( |
5486 ClassFinalizer::FinalizationKind finalization) { | 5527 ClassFinalizer::FinalizationKind finalization) { |
5487 TRACE_PARSER("ParseTypeArguments"); | 5528 TRACE_PARSER("ParseTypeArguments"); |
5488 if (CurrentToken() == Token::kLT) { | 5529 if (CurrentToken() == Token::kLT) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5684 return RawFunction::kNoModifier; | 5725 return RawFunction::kNoModifier; |
5685 } | 5726 } |
5686 | 5727 |
5687 | 5728 |
5688 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5729 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
5689 const Object& owner, | 5730 const Object& owner, |
5690 TokenPosition metadata_pos) { | 5731 TokenPosition metadata_pos) { |
5691 TRACE_PARSER("ParseTopLevelFunction"); | 5732 TRACE_PARSER("ParseTopLevelFunction"); |
5692 const TokenPosition decl_begin_pos = TokenPos(); | 5733 const TokenPosition decl_begin_pos = TokenPos(); |
5693 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 5734 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
5694 const bool is_static = true; | |
5695 bool is_external = false; | 5735 bool is_external = false; |
5696 bool is_patch = false; | 5736 bool is_patch = false; |
5697 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { | 5737 if (is_patch_source() && IsPatchAnnotation(metadata_pos)) { |
5698 is_patch = true; | 5738 is_patch = true; |
5699 metadata_pos = TokenPosition::kNoSource; | 5739 metadata_pos = TokenPosition::kNoSource; |
5700 } else if (CurrentToken() == Token::kEXTERNAL) { | 5740 } else if (CurrentToken() == Token::kEXTERNAL) { |
5701 ConsumeToken(); | 5741 ConsumeToken(); |
5702 is_external = true; | 5742 is_external = true; |
5703 } | 5743 } |
5704 if (CurrentToken() == Token::kVOID) { | 5744 if (CurrentToken() == Token::kVOID) { |
5705 ConsumeToken(); | 5745 ConsumeToken(); |
5706 result_type = Type::VoidType(); | 5746 result_type = Type::VoidType(); |
5707 } else { | 5747 } else { |
5708 // Parse optional type. | 5748 // Parse optional type. |
5709 if (IsFunctionReturnType()) { | 5749 if (IsFunctionReturnType()) { |
5710 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5750 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
hausner
2016/09/19 20:28:48
In other places you added a comment that explains
regis
2016/09/19 22:02:30
Done.
| |
5711 } | 5751 } |
5712 } | 5752 } |
5713 const TokenPosition name_pos = TokenPos(); | 5753 const TokenPosition name_pos = TokenPos(); |
5714 const String& func_name = *ExpectIdentifier("function name expected"); | 5754 const String& func_name = *ExpectIdentifier("function name expected"); |
5715 | 5755 |
5716 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 5756 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
5717 if (found && !is_patch) { | 5757 if (found && !is_patch) { |
5718 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); | 5758 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); |
5719 } else if (!found && is_patch) { | 5759 } else if (!found && is_patch) { |
5720 ReportError(name_pos, "missing '%s' cannot be patched", | 5760 ReportError(name_pos, "missing '%s' cannot be patched", |
5721 func_name.ToCString()); | 5761 func_name.ToCString()); |
5722 } | 5762 } |
5723 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); | 5763 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); |
5724 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5764 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
5725 ReportError(name_pos, "'%s' is already defined as getter", | 5765 ReportError(name_pos, "'%s' is already defined as getter", |
5726 func_name.ToCString()); | 5766 func_name.ToCString()); |
5727 } | 5767 } |
5728 // A setter named x= may co-exist with a function named x, thus we do | 5768 // A setter named x= may co-exist with a function named x, thus we do |
5729 // not need to check setters. | 5769 // not need to check setters. |
5730 | 5770 |
5771 Function& func = Function::Handle(Z, | |
5772 Function::New(func_name, | |
5773 RawFunction::kRegularFunction, | |
5774 /* is_static = */ true, | |
5775 /* is_const = */ false, | |
5776 /* is_abstract = */ false, | |
5777 is_external, | |
5778 /* is_native = */ false, // May change. | |
5779 owner, | |
5780 decl_begin_pos)); | |
5781 | |
5782 ASSERT(innermost_function().IsNull()); | |
5783 innermost_function_ = func.raw(); | |
5784 | |
5731 if (CurrentToken() == Token::kLT) { | 5785 if (CurrentToken() == Token::kLT) { |
5732 // Type parameters of generic function. | |
5733 // TODO(hausner): handle type parameters. | |
5734 if (!FLAG_generic_method_syntax) { | 5786 if (!FLAG_generic_method_syntax) { |
5735 ReportError("generic functions not supported"); | 5787 ReportError("generic functions not supported"); |
5736 } | 5788 } |
5737 TokenPosition type_arg_pos = TokenPos(); | 5789 ParseTypeParameters(false); |
5738 if (!TryParseTypeParameters()) { | 5790 } |
5739 ReportError(type_arg_pos, "error in type parameters"); | 5791 // At this point, the type parameters have been parsed, so we can resolve the |
5740 } | 5792 // result type. |
5793 if (!result_type.IsNull()) { | |
5794 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); | |
5741 } | 5795 } |
5742 | 5796 |
5743 CheckToken(Token::kLPAREN); | 5797 CheckToken(Token::kLPAREN); |
5744 const TokenPosition function_pos = TokenPos(); | 5798 const TokenPosition function_pos = TokenPos(); |
5745 ParamList params; | 5799 ParamList params; |
5746 const bool allow_explicit_default_values = true; | 5800 const bool allow_explicit_default_values = true; |
5747 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5801 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
5748 | 5802 |
5749 const TokenPosition modifier_pos = TokenPos(); | 5803 const TokenPosition modifier_pos = TokenPos(); |
5750 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5804 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
(...skipping 17 matching lines...) Expand all Loading... | |
5768 BoolScope allow_await(&this->await_is_keyword_, | 5822 BoolScope allow_await(&this->await_is_keyword_, |
5769 func_modifier != RawFunction::kNoModifier); | 5823 func_modifier != RawFunction::kNoModifier); |
5770 SkipExpr(); | 5824 SkipExpr(); |
5771 function_end_pos = TokenPos(); | 5825 function_end_pos = TokenPos(); |
5772 ExpectSemicolon(); | 5826 ExpectSemicolon(); |
5773 } else if (IsSymbol(Symbols::Native())) { | 5827 } else if (IsSymbol(Symbols::Native())) { |
5774 native_name = &ParseNativeDeclaration(); | 5828 native_name = &ParseNativeDeclaration(); |
5775 function_end_pos = TokenPos(); | 5829 function_end_pos = TokenPos(); |
5776 ExpectSemicolon(); | 5830 ExpectSemicolon(); |
5777 is_native = true; | 5831 is_native = true; |
5832 func.set_is_native(true); | |
5778 } else { | 5833 } else { |
5779 ReportError("function block expected"); | 5834 ReportError("function block expected"); |
5780 } | 5835 } |
5781 Function& func = Function::Handle(Z, | |
5782 Function::New(func_name, | |
5783 RawFunction::kRegularFunction, | |
5784 is_static, | |
5785 /* is_const = */ false, | |
5786 /* is_abstract = */ false, | |
5787 is_external, | |
5788 is_native, | |
5789 owner, | |
5790 decl_begin_pos)); | |
5791 func.set_result_type(result_type); | 5836 func.set_result_type(result_type); |
5792 func.set_end_token_pos(function_end_pos); | 5837 func.set_end_token_pos(function_end_pos); |
5793 func.set_modifier(func_modifier); | 5838 func.set_modifier(func_modifier); |
5794 if (library_.is_dart_scheme() && library_.IsPrivate(func_name)) { | 5839 if (library_.is_dart_scheme() && library_.IsPrivate(func_name)) { |
5795 func.set_is_reflectable(false); | 5840 func.set_is_reflectable(false); |
5796 } | 5841 } |
5797 if (is_native) { | 5842 if (is_native) { |
5798 func.set_native_name(*native_name); | 5843 func.set_native_name(*native_name); |
5799 } | 5844 } |
5800 AddFormalParamsToFunction(¶ms, func); | 5845 AddFormalParamsToFunction(¶ms, func); |
5846 ASSERT(innermost_function().raw() == func.raw()); | |
5847 innermost_function_ = Function::null(); | |
5801 top_level->AddFunction(func); | 5848 top_level->AddFunction(func); |
5802 if (!is_patch) { | 5849 if (!is_patch) { |
5803 library_.AddObject(func, func_name); | 5850 library_.AddObject(func, func_name); |
5804 } else { | 5851 } else { |
5805 // Need to remove the previously added function that is being patched. | 5852 // Need to remove the previously added function that is being patched. |
5806 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); | 5853 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); |
5807 const Function& replaced_func = | 5854 const Function& replaced_func = |
5808 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); | 5855 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); |
5809 ASSERT(!replaced_func.IsNull()); | 5856 ASSERT(!replaced_func.IsNull()); |
5810 toplevel_cls.RemoveFunction(replaced_func); | 5857 toplevel_cls.RemoveFunction(replaced_func); |
(...skipping 1823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7634 | 7681 |
7635 void Parser::CaptureInstantiator() { | 7682 void Parser::CaptureInstantiator() { |
7636 ASSERT(FunctionLevel() > 0); | 7683 ASSERT(FunctionLevel() > 0); |
7637 const String* variable_name = current_function().IsInFactoryScope() ? | 7684 const String* variable_name = current_function().IsInFactoryScope() ? |
7638 &Symbols::TypeArgumentsParameter() : &Symbols::This(); | 7685 &Symbols::TypeArgumentsParameter() : &Symbols::This(); |
7639 current_block_->scope->CaptureVariable( | 7686 current_block_->scope->CaptureVariable( |
7640 current_block_->scope->LookupVariable(*variable_name, true)); | 7687 current_block_->scope->LookupVariable(*variable_name, true)); |
7641 } | 7688 } |
7642 | 7689 |
7643 | 7690 |
7691 void Parser::CaptureFunctionInstantiator() { | |
7692 ASSERT(FunctionLevel() > 0); | |
7693 const String* variable_name = &Symbols::FunctionInstantiatorVar(); | |
7694 current_block_->scope->CaptureVariable( | |
7695 current_block_->scope->LookupVariable(*variable_name, true)); | |
7696 } | |
7697 | |
7698 | |
7644 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { | 7699 AstNode* Parser::LoadReceiver(TokenPosition token_pos) { |
7645 // A nested function may access 'this', referring to the receiver of the | 7700 // A nested function may access 'this', referring to the receiver of the |
7646 // outermost enclosing function. | 7701 // outermost enclosing function. |
7647 const bool kTestOnly = false; | 7702 const bool kTestOnly = false; |
7648 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7703 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
7649 if (receiver == NULL) { | 7704 if (receiver == NULL) { |
7650 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7705 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
7651 } | 7706 } |
7652 return new(Z) LoadLocalNode(TokenPos(), receiver); | 7707 return new(Z) LoadLocalNode(TokenPos(), receiver); |
7653 } | 7708 } |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7833 TokenPosition metadata_pos = TokenPosition::kNoSource; | 7888 TokenPosition metadata_pos = TokenPosition::kNoSource; |
7834 if (is_literal) { | 7889 if (is_literal) { |
7835 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT); | 7890 ASSERT(CurrentToken() == Token::kLPAREN || CurrentToken() == Token::kLT); |
7836 function_name = &Symbols::AnonymousClosure(); | 7891 function_name = &Symbols::AnonymousClosure(); |
7837 } else { | 7892 } else { |
7838 metadata_pos = SkipMetadata(); | 7893 metadata_pos = SkipMetadata(); |
7839 if (CurrentToken() == Token::kVOID) { | 7894 if (CurrentToken() == Token::kVOID) { |
7840 ConsumeToken(); | 7895 ConsumeToken(); |
7841 result_type = Type::VoidType(); | 7896 result_type = Type::VoidType(); |
7842 } else if (IsFunctionReturnType()) { | 7897 } else if (IsFunctionReturnType()) { |
7843 result_type = ParseType(ClassFinalizer::kCanonicalize); | 7898 // It is too early to resolve the type here, since it can be a result type |
7899 // referring to a not yet declared function type parameter. | |
7900 result_type = ParseType(ClassFinalizer::kDoNotResolve); | |
7844 } | 7901 } |
7845 const TokenPosition name_pos = TokenPos(); | 7902 const TokenPosition name_pos = TokenPos(); |
7846 variable_name = ExpectIdentifier("function name expected"); | 7903 variable_name = ExpectIdentifier("function name expected"); |
7847 function_name = variable_name; | 7904 function_name = variable_name; |
7848 | 7905 |
7849 // Check that the function name has not been referenced | 7906 // Check that the function name has not been referenced |
7850 // before this declaration. | 7907 // before this declaration. |
7851 ASSERT(current_block_ != NULL); | 7908 ASSERT(current_block_ != NULL); |
7852 const TokenPosition previous_pos = | 7909 const TokenPosition previous_pos = |
7853 current_block_->scope->PreviousReferencePos(*function_name); | 7910 current_block_->scope->PreviousReferencePos(*function_name); |
7854 if (previous_pos.IsReal()) { | 7911 if (previous_pos.IsReal()) { |
7855 ASSERT(!script_.IsNull()); | 7912 ASSERT(!script_.IsNull()); |
7856 intptr_t line_number; | 7913 intptr_t line_number; |
7857 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7914 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
7858 ReportError(name_pos, | 7915 ReportError(name_pos, |
7859 "identifier '%s' previously used in line %" Pd "", | 7916 "identifier '%s' previously used in line %" Pd "", |
7860 function_name->ToCString(), | 7917 function_name->ToCString(), |
7861 line_number); | 7918 line_number); |
7862 } | 7919 } |
7863 } | 7920 } |
7864 | 7921 |
7865 if (CurrentToken() == Token::kLT) { | |
7866 if (!FLAG_generic_method_syntax) { | |
7867 ReportError("generic functions not supported"); | |
7868 } | |
7869 TokenPosition type_arg_pos = TokenPos(); | |
7870 // TODO(hausner): handle type parameters of generic function. | |
7871 if (!TryParseTypeParameters()) { | |
7872 ReportError(type_arg_pos, "error in type parameters"); | |
7873 } | |
7874 } | |
7875 | |
7876 CheckToken(Token::kLPAREN); | |
7877 | |
7878 // Check whether we have parsed this closure function before, in a previous | 7922 // Check whether we have parsed this closure function before, in a previous |
7879 // compilation. If so, reuse the function object, else create a new one | 7923 // compilation. If so, reuse the function object, else create a new one |
7880 // and register it in the current class. | 7924 // and register it in the current class. |
7881 // Note that we cannot share the same closure function between the closurized | 7925 // Note that we cannot share the same closure function between the closurized |
7882 // and non-closurized versions of the same parent function. | 7926 // and non-closurized versions of the same parent function. |
7883 Function& function = Function::ZoneHandle(Z); | 7927 Function& function = Function::ZoneHandle(Z); |
7884 bool found_func = true; | 7928 bool found_func = true; |
7885 // TODO(hausner): There could be two different closures at the given | 7929 // TODO(hausner): There could be two different closures at the given |
7886 // function_pos, one enclosed in a closurized function and one enclosed in the | 7930 // function_pos, one enclosed in a closurized function and one enclosed in the |
7887 // non-closurized version of this same function. | 7931 // non-closurized version of this same function. |
7888 function = I->LookupClosureFunction(innermost_function(), function_pos); | 7932 function = I->LookupClosureFunction(innermost_function(), function_pos); |
7889 if (function.IsNull()) { | 7933 if (function.IsNull()) { |
7890 // The function will be registered in the lookup table by the | 7934 // The function will be registered in the lookup table by the |
7891 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 7935 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
7892 // function has been properly setup. | 7936 // function has been properly setup. |
7893 found_func = false; | 7937 found_func = false; |
7894 function = Function::NewClosureFunction(*function_name, | 7938 function = Function::NewClosureFunction(*function_name, |
7895 innermost_function(), | 7939 innermost_function(), |
7896 function_pos); | 7940 function_pos); |
7897 function.set_result_type(result_type); | 7941 function.set_result_type(result_type); |
7898 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { | 7942 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
7899 library_.AddFunctionMetadata(function, metadata_pos); | 7943 library_.AddFunctionMetadata(function, metadata_pos); |
7900 } | 7944 } |
7901 } | 7945 } |
7902 | 7946 |
7947 ASSERT(function.parent_function() == innermost_function_.raw()); | |
7948 innermost_function_ = function.raw(); | |
7949 | |
7950 if (CurrentToken() == Token::kLT) { | |
7951 if (!FLAG_generic_method_syntax) { | |
7952 ReportError("generic functions not supported"); | |
7953 } | |
7954 if (!found_func) { | |
7955 ParseTypeParameters(false); | |
7956 } else { | |
7957 TryParseTypeParameters(); | |
7958 } | |
7959 } | |
7960 | |
7961 if (!found_func && !result_type.IsFinalized()) { | |
7962 // Now that type parameters are declared, the result type can be resolved | |
7963 // and finalized. | |
7964 ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type); | |
7965 result_type = ClassFinalizer::FinalizeType( | |
7966 current_class(), result_type, ClassFinalizer::kCanonicalize); | |
7967 function.set_result_type(result_type); | |
7968 } | |
7969 | |
7970 CheckToken(Token::kLPAREN); | |
7971 | |
7903 // The function type needs to be finalized at compile time, since the closure | 7972 // The function type needs to be finalized at compile time, since the closure |
7904 // may be type checked at run time when assigned to a function variable, | 7973 // may be type checked at run time when assigned to a function variable, |
7905 // passed as a function argument, or returned as a function result. | 7974 // passed as a function argument, or returned as a function result. |
7906 | 7975 |
7907 LocalVariable* function_variable = NULL; | 7976 LocalVariable* function_variable = NULL; |
7908 Type& function_type = Type::ZoneHandle(Z); | 7977 Type& function_type = Type::ZoneHandle(Z); |
7909 if (variable_name != NULL) { | 7978 if (variable_name != NULL) { |
7910 // Since the function type depends on the signature of the closure function, | 7979 // Since the function type depends on the signature of the closure function, |
7911 // it cannot be determined before the formal parameter list of the closure | 7980 // it cannot be determined before the formal parameter list of the closure |
7912 // function is parsed. Therefore, we set the function type to a new | 7981 // function is parsed. Therefore, we set the function type to a new |
(...skipping 27 matching lines...) Expand all Loading... | |
7940 } | 8009 } |
7941 } | 8010 } |
7942 | 8011 |
7943 Type& signature_type = Type::ZoneHandle(Z); | 8012 Type& signature_type = Type::ZoneHandle(Z); |
7944 SequenceNode* statements = NULL; | 8013 SequenceNode* statements = NULL; |
7945 if (!found_func) { | 8014 if (!found_func) { |
7946 // Parse the local function. As a side effect of the parsing, the | 8015 // Parse the local function. As a side effect of the parsing, the |
7947 // variables of this function's scope that are referenced by the local | 8016 // variables of this function's scope that are referenced by the local |
7948 // function (and its inner nested functions) will be marked as captured. | 8017 // function (and its inner nested functions) will be marked as captured. |
7949 | 8018 |
8019 ASSERT(AbstractType::Handle(Z, function.result_type()).IsResolved()); | |
7950 statements = Parser::ParseFunc(function, !is_literal); | 8020 statements = Parser::ParseFunc(function, !is_literal); |
7951 INC_STAT(thread(), num_functions_parsed, 1); | 8021 INC_STAT(thread(), num_functions_parsed, 1); |
7952 | 8022 |
7953 // Now that the local function has formal parameters, lookup the signature | 8023 // Now that the local function has formal parameters, lookup the signature |
7954 signature_type = function.SignatureType(); | 8024 signature_type = function.SignatureType(); |
7955 signature_type ^= ClassFinalizer::FinalizeType( | 8025 signature_type ^= ClassFinalizer::FinalizeType( |
7956 current_class(), signature_type, ClassFinalizer::kCanonicalize); | 8026 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
7957 function.SetSignatureType(signature_type); | 8027 function.SetSignatureType(signature_type); |
7958 } else { | 8028 } else { |
7959 // The local function was parsed before. The captured variables are | 8029 // The local function was parsed before. The captured variables are |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8025 // since further closure functions may capture more variables. | 8095 // since further closure functions may capture more variables. |
8026 // This Scope object is constructed after all variables have been allocated. | 8096 // This Scope object is constructed after all variables have been allocated. |
8027 // The local scope of the parsed function can be pruned, since contained | 8097 // The local scope of the parsed function can be pruned, since contained |
8028 // variables are not relevant for the compilation of the enclosing function. | 8098 // variables are not relevant for the compilation of the enclosing function. |
8029 // This pruning is done by omitting to hook the local scope in its parent | 8099 // This pruning is done by omitting to hook the local scope in its parent |
8030 // scope in the constructor of LocalScope. | 8100 // scope in the constructor of LocalScope. |
8031 AstNode* closure = | 8101 AstNode* closure = |
8032 new(Z) ClosureNode(function_pos, function, NULL, | 8102 new(Z) ClosureNode(function_pos, function, NULL, |
8033 statements != NULL ? statements->scope() : NULL); | 8103 statements != NULL ? statements->scope() : NULL); |
8034 | 8104 |
8105 ASSERT(innermost_function_.raw() == function.raw()); | |
8106 innermost_function_ = function.parent_function(); | |
8107 | |
8035 if (function_variable == NULL) { | 8108 if (function_variable == NULL) { |
8036 ASSERT(is_literal); | 8109 ASSERT(is_literal); |
8037 return closure; | 8110 return closure; |
8038 } else { | 8111 } else { |
8039 AstNode* initialization = new(Z) StoreLocalNode( | 8112 AstNode* initialization = new(Z) StoreLocalNode( |
8040 function_pos, function_variable, closure); | 8113 function_pos, function_variable, closure); |
8041 return initialization; | 8114 return initialization; |
8042 } | 8115 } |
8043 } | 8116 } |
8044 | 8117 |
(...skipping 3747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11792 funcname.ToCString()); | 11865 funcname.ToCString()); |
11793 } | 11866 } |
11794 AstNode* receiver = LoadReceiver(primary->token_pos()); | 11867 AstNode* receiver = LoadReceiver(primary->token_pos()); |
11795 return CallGetter(primary->token_pos(), receiver, funcname); | 11868 return CallGetter(primary->token_pos(), receiver, funcname); |
11796 } | 11869 } |
11797 UNREACHABLE(); | 11870 UNREACHABLE(); |
11798 return NULL; | 11871 return NULL; |
11799 } | 11872 } |
11800 | 11873 |
11801 | 11874 |
11875 AstNode* Parser::LoadTypeParameter(PrimaryNode* primary) { | |
11876 const TokenPosition primary_pos = primary->token_pos(); | |
11877 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | |
11878 type_parameter = TypeParameter::Cast(primary->primary()).raw(); | |
11879 if (type_parameter.IsClassTypeParameter()) { | |
11880 if (ParsingStaticMember()) { | |
11881 const String& name = String::Handle(Z, type_parameter.name()); | |
11882 ReportError(primary_pos, | |
11883 "cannot access type parameter '%s' " | |
11884 "from static function", | |
11885 name.ToCString()); | |
11886 } | |
11887 // TODO(regis): Verify that CaptureInstantiator() was already called | |
11888 // and remove call below. | |
11889 if (FunctionLevel() > 0) { | |
11890 // Make sure that the class instantiator is captured. | |
11891 CaptureInstantiator(); | |
11892 } | |
11893 type_parameter ^= ClassFinalizer::FinalizeType( | |
11894 current_class(), type_parameter, ClassFinalizer::kCanonicalize); | |
11895 ASSERT(!type_parameter.IsMalformed()); | |
11896 return new(Z) TypeNode(primary_pos, type_parameter); | |
11897 } else { | |
11898 ASSERT(type_parameter.IsFunctionTypeParameter()); | |
11899 // TODO(regis): Verify that CaptureFunctionInstantiator() was already | |
11900 // called if necessary. | |
11901 // TODO(regis): Finalize type parameter and return as type node. | |
11902 // For now, throw a type error. | |
11903 Type& malformed_type = Type::ZoneHandle(Z); | |
11904 malformed_type = ClassFinalizer::NewFinalizedMalformedType( | |
11905 Error::Handle(Z), // No previous error. | |
11906 script_, | |
11907 primary_pos, | |
11908 "function type parameter '%s' not yet supported", | |
11909 String::Handle(Z, type_parameter.name()).ToCString()); | |
11910 return ThrowTypeError(primary_pos, malformed_type); | |
11911 } | |
11912 } | |
11913 | |
11914 | |
11802 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { | 11915 AstNode* Parser::ParseSelectors(AstNode* primary, bool is_cascade) { |
11803 AstNode* left = primary; | 11916 AstNode* left = primary; |
11804 while (true) { | 11917 while (true) { |
11805 AstNode* selector = NULL; | 11918 AstNode* selector = NULL; |
11806 if ((CurrentToken() == Token::kPERIOD) || | 11919 if ((CurrentToken() == Token::kPERIOD) || |
11807 (CurrentToken() == Token::kQM_PERIOD)) { | 11920 (CurrentToken() == Token::kQM_PERIOD)) { |
11808 // Unconditional or conditional property extraction or method call. | 11921 // Unconditional or conditional property extraction or method call. |
11809 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; | 11922 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; |
11810 ConsumeToken(); | 11923 ConsumeToken(); |
11811 if (left->IsPrimaryNode()) { | 11924 if (left->IsPrimaryNode()) { |
11812 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11925 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11813 const TokenPosition primary_pos = primary_node->token_pos(); | |
11814 if (primary_node->primary().IsFunction()) { | 11926 if (primary_node->primary().IsFunction()) { |
11815 left = LoadClosure(primary_node); | 11927 left = LoadClosure(primary_node); |
11816 } else if (primary_node->primary().IsTypeParameter()) { | 11928 } else if (primary_node->primary().IsTypeParameter()) { |
11817 if (ParsingStaticMember()) { | 11929 left = LoadTypeParameter(primary_node); |
11818 const String& name = String::Handle(Z, | |
11819 TypeParameter::Cast(primary_node->primary()).name()); | |
11820 ReportError(primary_pos, | |
11821 "cannot access type parameter '%s' " | |
11822 "from static function", | |
11823 name.ToCString()); | |
11824 } | |
11825 if (FunctionLevel() > 0) { | |
11826 // Make sure that the instantiator is captured. | |
11827 CaptureInstantiator(); | |
11828 } | |
11829 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | |
11830 type_parameter ^= ClassFinalizer::FinalizeType( | |
11831 current_class(), | |
11832 TypeParameter::Cast(primary_node->primary()), | |
11833 ClassFinalizer::kCanonicalize); | |
11834 ASSERT(!type_parameter.IsMalformed()); | |
11835 left = new(Z) TypeNode(primary->token_pos(), type_parameter); | |
11836 } else { | 11930 } else { |
11837 // Super field access handled in ParseSuperFieldAccess(), | 11931 // Super field access handled in ParseSuperFieldAccess(), |
11838 // super calls handled in ParseSuperCall(). | 11932 // super calls handled in ParseSuperCall(). |
11839 ASSERT(!primary_node->IsSuper()); | 11933 ASSERT(!primary_node->IsSuper()); |
11840 left = LoadFieldIfUnresolved(left); | 11934 left = LoadFieldIfUnresolved(left); |
11841 } | 11935 } |
11842 } | 11936 } |
11843 const TokenPosition ident_pos = TokenPos(); | 11937 const TokenPosition ident_pos = TokenPos(); |
11844 String* ident = ExpectIdentifier("identifier expected"); | 11938 String* ident = ExpectIdentifier("identifier expected"); |
11845 if (IsArgumentPart()) { | 11939 if (IsArgumentPart()) { |
11846 // Identifier followed by optional type arguments and opening paren: | 11940 // Identifier followed by optional type arguments and opening paren: |
11847 // method call. | 11941 // method call. |
11848 if (CurrentToken() == Token::kLT) { | 11942 if (CurrentToken() == Token::kLT) { |
11849 // Type arguments. | 11943 // Type arguments. |
11850 if (!FLAG_generic_method_syntax) { | 11944 if (!FLAG_generic_method_syntax) { |
11851 ReportError("generic type arguments not supported."); | 11945 ReportError("generic type arguments not supported."); |
11852 } | 11946 } |
11853 // TODO(hausner): handle type arguments. | 11947 // TODO(regis): Pass type arguments in generic call. |
11854 ParseTypeArguments(ClassFinalizer::kIgnore); | 11948 // For now, resolve type arguments and ignore. |
11949 ParseTypeArguments(ClassFinalizer::kCanonicalize); | |
11855 } | 11950 } |
11856 if (left->IsPrimaryNode() && | 11951 if (left->IsPrimaryNode() && |
11857 left->AsPrimaryNode()->primary().IsClass()) { | 11952 left->AsPrimaryNode()->primary().IsClass()) { |
11858 // Static method call prefixed with class name. | 11953 // Static method call prefixed with class name. |
11859 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | 11954 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); |
11860 selector = ParseStaticCall(cls, *ident, ident_pos); | 11955 selector = ParseStaticCall(cls, *ident, ident_pos); |
11861 } else { | 11956 } else { |
11862 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); | 11957 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); |
11863 } | 11958 } |
11864 } else { | 11959 } else { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11912 const Class& type_class = Class::Cast(primary_node->primary()); | 12007 const Class& type_class = Class::Cast(primary_node->primary()); |
11913 AbstractType& type = Type::ZoneHandle(Z, | 12008 AbstractType& type = Type::ZoneHandle(Z, |
11914 Type::New(type_class, TypeArguments::Handle(Z), | 12009 Type::New(type_class, TypeArguments::Handle(Z), |
11915 primary_pos, Heap::kOld)); | 12010 primary_pos, Heap::kOld)); |
11916 type ^= ClassFinalizer::FinalizeType( | 12011 type ^= ClassFinalizer::FinalizeType( |
11917 current_class(), type, ClassFinalizer::kCanonicalize); | 12012 current_class(), type, ClassFinalizer::kCanonicalize); |
11918 // Type may be malbounded, but not malformed. | 12013 // Type may be malbounded, but not malformed. |
11919 ASSERT(!type.IsMalformed()); | 12014 ASSERT(!type.IsMalformed()); |
11920 array = new(Z) TypeNode(primary_pos, type); | 12015 array = new(Z) TypeNode(primary_pos, type); |
11921 } else if (primary_node->primary().IsTypeParameter()) { | 12016 } else if (primary_node->primary().IsTypeParameter()) { |
11922 if (ParsingStaticMember()) { | 12017 array = LoadTypeParameter(primary_node); |
11923 const String& name = String::ZoneHandle(Z, | |
11924 TypeParameter::Cast(primary_node->primary()).name()); | |
11925 ReportError(primary_pos, | |
11926 "cannot access type parameter '%s' " | |
11927 "from static function", | |
11928 name.ToCString()); | |
11929 } | |
11930 if (FunctionLevel() > 0) { | |
11931 // Make sure that the instantiator is captured. | |
11932 CaptureInstantiator(); | |
11933 } | |
11934 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | |
11935 type_parameter ^= ClassFinalizer::FinalizeType( | |
11936 current_class(), | |
11937 TypeParameter::Cast(primary_node->primary()), | |
11938 ClassFinalizer::kCanonicalize); | |
11939 ASSERT(!type_parameter.IsMalformed()); | |
11940 array = new(Z) TypeNode(primary_pos, type_parameter); | |
11941 } else { | 12018 } else { |
11942 UNREACHABLE(); // Internal parser error. | 12019 UNREACHABLE(); // Internal parser error. |
11943 } | 12020 } |
11944 } | 12021 } |
11945 selector = new(Z) LoadIndexedNode( | 12022 selector = new(Z) LoadIndexedNode( |
11946 bracket_pos, array, index, Class::ZoneHandle(Z)); | 12023 bracket_pos, array, index, Class::ZoneHandle(Z)); |
11947 } else if (IsArgumentPart()) { | 12024 } else if (IsArgumentPart()) { |
11948 if (CurrentToken() == Token::kLT) { | 12025 if (CurrentToken() == Token::kLT) { |
11949 // Type arguments. | 12026 // Type arguments. |
11950 if (!FLAG_generic_method_syntax) { | 12027 if (!FLAG_generic_method_syntax) { |
11951 ReportError("generic type arguments not supported."); | 12028 ReportError("generic type arguments not supported."); |
11952 } | 12029 } |
11953 // TODO(hausner): handle type arguments. | 12030 // TODO(regis): Pass type arguments in generic call. |
11954 ParseTypeArguments(ClassFinalizer::kIgnore); | 12031 // For now, resolve type arguments and ignore. |
12032 ParseTypeArguments(ClassFinalizer::kCanonicalize); | |
11955 } | 12033 } |
11956 if (left->IsPrimaryNode()) { | 12034 if (left->IsPrimaryNode()) { |
11957 PrimaryNode* primary_node = left->AsPrimaryNode(); | 12035 PrimaryNode* primary_node = left->AsPrimaryNode(); |
11958 const TokenPosition primary_pos = primary_node->token_pos(); | 12036 const TokenPosition primary_pos = primary_node->token_pos(); |
11959 if (primary_node->primary().IsFunction()) { | 12037 if (primary_node->primary().IsFunction()) { |
11960 const Function& func = Function::Cast(primary_node->primary()); | 12038 const Function& func = Function::Cast(primary_node->primary()); |
11961 const String& func_name = String::ZoneHandle(Z, func.name()); | 12039 const String& func_name = String::ZoneHandle(Z, func.name()); |
11962 if (func.is_static()) { | 12040 if (func.is_static()) { |
11963 // Parse static function call. | 12041 // Parse static function call. |
11964 Class& cls = Class::Handle(Z, func.Owner()); | 12042 Class& cls = Class::Handle(Z, func.Owner()); |
(...skipping 22 matching lines...) Expand all Loading... | |
11987 // The static call will be converted to throwing a NSM error. | 12065 // The static call will be converted to throwing a NSM error. |
11988 selector = ParseStaticCall(current_class(), name, primary_pos); | 12066 selector = ParseStaticCall(current_class(), name, primary_pos); |
11989 } else { | 12067 } else { |
11990 // Treat as call to unresolved (instance) method. | 12068 // Treat as call to unresolved (instance) method. |
11991 selector = ParseInstanceCall(LoadReceiver(primary_pos), | 12069 selector = ParseInstanceCall(LoadReceiver(primary_pos), |
11992 name, | 12070 name, |
11993 primary_pos, | 12071 primary_pos, |
11994 false /* is_conditional */); | 12072 false /* is_conditional */); |
11995 } | 12073 } |
11996 } else if (primary_node->primary().IsTypeParameter()) { | 12074 } else if (primary_node->primary().IsTypeParameter()) { |
11997 const String& name = String::ZoneHandle(Z, | 12075 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
11998 TypeParameter::Cast(primary_node->primary()).name()); | 12076 type_parameter = TypeParameter::Cast(primary_node->primary()).raw(); |
11999 if (ParsingStaticMember()) { | 12077 const String& name = String::ZoneHandle(Z, type_parameter.name()); |
12000 // Treat as this.T(), because T is in scope. | 12078 if (type_parameter.IsClassTypeParameter()) { |
12079 if (ParsingStaticMember()) { | |
12080 // Treat as this.T(), because T is in scope. | |
12081 ReportError(primary_pos, | |
12082 "cannot access type parameter '%s' " | |
12083 "from static function", | |
12084 name.ToCString()); | |
12085 } else { | |
12086 // Treat as call to unresolved (instance) method. | |
12087 selector = ParseInstanceCall(LoadReceiver(primary_pos), | |
12088 name, | |
12089 primary_pos, | |
12090 false /* is_conditional */); | |
12091 } | |
12092 } else { | |
12093 ASSERT(type_parameter.IsFunctionTypeParameter()); | |
12094 // TODO(regis): Should we throw a type error instead? | |
12001 ReportError(primary_pos, | 12095 ReportError(primary_pos, |
12002 "cannot access type parameter '%s' " | 12096 "illegal use of function type parameter '%s'", |
12003 "from static function", | |
12004 name.ToCString()); | 12097 name.ToCString()); |
12005 } else { | |
12006 // Treat as call to unresolved (instance) method. | |
12007 selector = ParseInstanceCall(LoadReceiver(primary_pos), | |
12008 name, | |
12009 primary_pos, | |
12010 false /* is_conditional */); | |
12011 } | 12098 } |
12012 } else if (primary_node->primary().IsClass()) { | 12099 } else if (primary_node->primary().IsClass()) { |
12013 const Class& type_class = Class::Cast(primary_node->primary()); | 12100 const Class& type_class = Class::Cast(primary_node->primary()); |
12014 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 12101 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
12015 type_class, TypeArguments::Handle(Z), primary_pos, Heap::kOld)); | 12102 type_class, TypeArguments::Handle(Z), primary_pos, Heap::kOld)); |
12016 type ^= ClassFinalizer::FinalizeType( | 12103 type ^= ClassFinalizer::FinalizeType( |
12017 current_class(), type, ClassFinalizer::kCanonicalize); | 12104 current_class(), type, ClassFinalizer::kCanonicalize); |
12018 // Type may be malbounded, but not malformed. | 12105 // Type may be malbounded, but not malformed. |
12019 ASSERT(!type.IsMalformed()); | 12106 ASSERT(!type.IsMalformed()); |
12020 selector = new(Z) TypeNode(primary_pos, type); | 12107 selector = new(Z) TypeNode(primary_pos, type); |
(...skipping 17 matching lines...) Expand all Loading... | |
12038 } else if (primary_node->primary().IsClass()) { | 12125 } else if (primary_node->primary().IsClass()) { |
12039 const Class& type_class = Class::Cast(primary_node->primary()); | 12126 const Class& type_class = Class::Cast(primary_node->primary()); |
12040 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 12127 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
12041 type_class, TypeArguments::Handle(Z), primary_pos, Heap::kOld)); | 12128 type_class, TypeArguments::Handle(Z), primary_pos, Heap::kOld)); |
12042 type = ClassFinalizer::FinalizeType( | 12129 type = ClassFinalizer::FinalizeType( |
12043 current_class(), type, ClassFinalizer::kCanonicalize); | 12130 current_class(), type, ClassFinalizer::kCanonicalize); |
12044 // Type may be malbounded, but not malformed. | 12131 // Type may be malbounded, but not malformed. |
12045 ASSERT(!type.IsMalformed()); | 12132 ASSERT(!type.IsMalformed()); |
12046 left = new(Z) TypeNode(primary_pos, type); | 12133 left = new(Z) TypeNode(primary_pos, type); |
12047 } else if (primary_node->primary().IsTypeParameter()) { | 12134 } else if (primary_node->primary().IsTypeParameter()) { |
12048 if (ParsingStaticMember()) { | 12135 left = LoadTypeParameter(primary_node); |
12049 const String& name = String::ZoneHandle(Z, | |
12050 TypeParameter::Cast(primary_node->primary()).name()); | |
12051 ReportError(primary_pos, | |
12052 "cannot access type parameter '%s' " | |
12053 "from static function", | |
12054 name.ToCString()); | |
12055 } | |
12056 if (FunctionLevel() > 0) { | |
12057 // Make sure that the instantiator is captured. | |
12058 CaptureInstantiator(); | |
12059 } | |
12060 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | |
12061 type_parameter ^= ClassFinalizer::FinalizeType( | |
12062 current_class(), | |
12063 TypeParameter::Cast(primary_node->primary()), | |
12064 ClassFinalizer::kCanonicalize); | |
12065 ASSERT(!type_parameter.IsMalformed()); | |
12066 left = new(Z) TypeNode(primary_pos, type_parameter); | |
12067 } else if (primary_node->IsSuper()) { | 12136 } else if (primary_node->IsSuper()) { |
12068 // Return "super" to handle unary super operator calls, | 12137 // Return "super" to handle unary super operator calls, |
12069 // or to report illegal use of "super" otherwise. | 12138 // or to report illegal use of "super" otherwise. |
12070 left = primary_node; | 12139 left = primary_node; |
12071 } else { | 12140 } else { |
12072 UNREACHABLE(); // Internal parser error. | 12141 UNREACHABLE(); // Internal parser error. |
12073 } | 12142 } |
12074 } | 12143 } |
12075 // Done parsing selectors. | 12144 // Done parsing selectors. |
12076 return left; | 12145 return left; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12264 // The result is a pair of the (side effects of the) store followed by | 12333 // The result is a pair of the (side effects of the) store followed by |
12265 // the (value of the) initial value temp variable load. | 12334 // the (value of the) initial value temp variable load. |
12266 let_expr->AddNode(store); | 12335 let_expr->AddNode(store); |
12267 let_expr->AddNode(new(Z) LoadLocalNode(op_pos, temp)); | 12336 let_expr->AddNode(new(Z) LoadLocalNode(op_pos, temp)); |
12268 return let_expr; | 12337 return let_expr; |
12269 } | 12338 } |
12270 return expr; | 12339 return expr; |
12271 } | 12340 } |
12272 | 12341 |
12273 | 12342 |
12274 // Resolve the given type and its type arguments from the given scope class | 12343 // Resolve the given type and its type arguments from the current function and |
12275 // according to the given type finalization mode. | 12344 // current class according to the given type finalization mode. |
12276 // If the given scope class is null, use the current library, but do not try to | 12345 // Not all involved type classes may get resolved yet, but at least type |
12277 // resolve type parameters. | 12346 // parameters will get resolved, thereby relieving the class |
12278 // Not all involved type classes may get resolved yet, but at least the type | |
12279 // parameters of the given class will get resolved, thereby relieving the class | |
12280 // finalizer from resolving type parameters out of context. | 12347 // finalizer from resolving type parameters out of context. |
12281 void Parser::ResolveTypeFromClass(const Class& scope_class, | 12348 void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, |
12282 ClassFinalizer::FinalizationKind finalization, | 12349 AbstractType* type) { |
12283 AbstractType* type) { | |
12284 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); | 12350 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); |
12285 ASSERT(type != NULL); | 12351 ASSERT(type != NULL); |
12286 if (type->IsResolved()) { | 12352 if (type->IsResolved()) { |
12287 return; | 12353 return; |
12288 } | 12354 } |
12289 // Resolve class. | 12355 // Resolve class. |
12290 if (!type->HasResolvedTypeClass()) { | 12356 if (!type->HasResolvedTypeClass()) { |
12291 const UnresolvedClass& unresolved_class = | 12357 const UnresolvedClass& unresolved_class = |
12292 UnresolvedClass::Handle(Z, type->unresolved_class()); | 12358 UnresolvedClass::Handle(Z, type->unresolved_class()); |
12293 const String& unresolved_class_name = | 12359 const String& unresolved_class_name = |
12294 String::Handle(Z, unresolved_class.ident()); | 12360 String::Handle(Z, unresolved_class.ident()); |
12295 Class& resolved_type_class = Class::Handle(Z); | 12361 Class& resolved_type_class = Class::Handle(Z); |
12296 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 12362 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
12297 if (!scope_class.IsNull()) { | 12363 // First check if the type is a function type parameter. |
12298 // First check if the type is a type parameter of the given scope class. | 12364 if (!innermost_function().IsNull()) { |
12299 const TypeParameter& type_parameter = TypeParameter::Handle(Z, | 12365 // TODO(regis): Shortcut this lookup if no generic functions in scope. |
12300 scope_class.LookupTypeParameter(unresolved_class_name)); | 12366 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, |
12367 innermost_function().LookupTypeParameter(unresolved_class_name, | |
12368 NULL)); | |
12301 if (!type_parameter.IsNull()) { | 12369 if (!type_parameter.IsNull()) { |
12302 // A type parameter is considered to be a malformed type when | 12370 // TODO(regis): Check for absence of type arguments. |
12303 // referenced by a static member. | 12371 // For now, return as malformed type. |
12304 if (ParsingStaticMember()) { | 12372 Type& malformed_type = Type::ZoneHandle(Z); |
12305 ASSERT(scope_class.raw() == current_class().raw()); | 12373 malformed_type = ClassFinalizer::NewFinalizedMalformedType( |
12306 *type = ClassFinalizer::NewFinalizedMalformedType( | 12374 Error::Handle(Z), // No previous error. |
12307 Error::Handle(Z), // No previous error. | 12375 script_, |
12308 script_, | 12376 type->token_pos(), |
12309 type->token_pos(), | 12377 "function type parameter '%s' not yet supported", |
12310 "type parameter '%s' cannot be referenced " | 12378 String::Handle(Z, type_parameter.name()).ToCString()); |
12311 "from static member", | 12379 *type = malformed_type.raw(); |
12312 String::Handle(Z, type_parameter.name()).ToCString()); | |
12313 return; | |
12314 } | |
12315 // A type parameter cannot be parameterized, so make the type | |
12316 // malformed if type arguments have previously been parsed. | |
12317 if (type->arguments() != TypeArguments::null()) { | |
12318 *type = ClassFinalizer::NewFinalizedMalformedType( | |
12319 Error::Handle(Z), // No previous error. | |
12320 script_, | |
12321 type_parameter.token_pos(), | |
12322 "type parameter '%s' cannot be parameterized", | |
12323 String::Handle(Z, type_parameter.name()).ToCString()); | |
12324 return; | |
12325 } | |
12326 *type = type_parameter.raw(); | |
12327 return; | 12380 return; |
12328 } | 12381 } |
12329 } | 12382 } |
12383 // Then check if the type is a class type parameter. | |
12384 const TypeParameter& type_parameter = TypeParameter::Handle(Z, | |
12385 current_class().LookupTypeParameter(unresolved_class_name)); | |
12386 if (!type_parameter.IsNull()) { | |
12387 // A type parameter is considered to be a malformed type when | |
12388 // referenced by a static member. | |
12389 if (ParsingStaticMember()) { | |
12390 *type = ClassFinalizer::NewFinalizedMalformedType( | |
12391 Error::Handle(Z), // No previous error. | |
12392 script_, | |
12393 type->token_pos(), | |
12394 "type parameter '%s' cannot be referenced " | |
12395 "from static member", | |
12396 String::Handle(Z, type_parameter.name()).ToCString()); | |
12397 return; | |
12398 } | |
12399 // A type parameter cannot be parameterized, so make the type | |
12400 // malformed if type arguments have previously been parsed. | |
12401 if (type->arguments() != TypeArguments::null()) { | |
12402 *type = ClassFinalizer::NewFinalizedMalformedType( | |
12403 Error::Handle(Z), // No previous error. | |
12404 script_, | |
12405 type_parameter.token_pos(), | |
12406 "type parameter '%s' cannot be parameterized", | |
12407 String::Handle(Z, type_parameter.name()).ToCString()); | |
12408 return; | |
12409 } | |
12410 *type = type_parameter.raw(); | |
12411 return; | |
12412 } | |
12330 // The referenced class may not have been parsed yet. It would be wrong | 12413 // The referenced class may not have been parsed yet. It would be wrong |
12331 // to resolve it too early to an imported class of the same name. Only | 12414 // to resolve it too early to an imported class of the same name. Only |
12332 // resolve the class when a finalized type is requested. | 12415 // resolve the class when a finalized type is requested. |
12333 if (finalization > ClassFinalizer::kResolveTypeParameters) { | 12416 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
12334 resolved_type_class = library_.LookupClass(unresolved_class_name); | 12417 resolved_type_class = library_.LookupClass(unresolved_class_name); |
12335 } | 12418 } |
12336 } else { | 12419 } else { |
12337 // Resolve class name in the scope of the library prefix. | 12420 // Resolve class name in the scope of the library prefix. |
12338 const LibraryPrefix& lib_prefix = | 12421 const LibraryPrefix& lib_prefix = |
12339 LibraryPrefix::Handle(Z, unresolved_class.library_prefix()); | 12422 LibraryPrefix::Handle(Z, unresolved_class.library_prefix()); |
(...skipping 15 matching lines...) Expand all Loading... | |
12355 } | 12438 } |
12356 } | 12439 } |
12357 // Resolve type arguments, if any. | 12440 // Resolve type arguments, if any. |
12358 if (type->arguments() != TypeArguments::null()) { | 12441 if (type->arguments() != TypeArguments::null()) { |
12359 const TypeArguments& arguments = | 12442 const TypeArguments& arguments = |
12360 TypeArguments::Handle(Z, type->arguments()); | 12443 TypeArguments::Handle(Z, type->arguments()); |
12361 const intptr_t num_arguments = arguments.Length(); | 12444 const intptr_t num_arguments = arguments.Length(); |
12362 AbstractType& type_argument = AbstractType::Handle(Z); | 12445 AbstractType& type_argument = AbstractType::Handle(Z); |
12363 for (intptr_t i = 0; i < num_arguments; i++) { | 12446 for (intptr_t i = 0; i < num_arguments; i++) { |
12364 type_argument ^= arguments.TypeAt(i); | 12447 type_argument ^= arguments.TypeAt(i); |
12365 ResolveTypeFromClass(scope_class, finalization, &type_argument); | 12448 ResolveType(finalization, &type_argument); |
12366 arguments.SetTypeAt(i, type_argument); | 12449 arguments.SetTypeAt(i, type_argument); |
12367 } | 12450 } |
12368 } | 12451 } |
12369 } | 12452 } |
12370 | 12453 |
12371 | 12454 |
12372 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 12455 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
12373 if (current_block_ == NULL) { | 12456 if (current_block_ == NULL) { |
12374 return NULL; | 12457 return NULL; |
12375 } | 12458 } |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12637 return TryCanonicalize(instance, TokenPos()); | 12720 return TryCanonicalize(instance, TokenPos()); |
12638 } | 12721 } |
12639 } | 12722 } |
12640 | 12723 |
12641 | 12724 |
12642 // Do a lookup for the identifier in the block scope and the class scope | 12725 // Do a lookup for the identifier in the block scope and the class scope |
12643 // return true if the identifier is found, false otherwise. | 12726 // return true if the identifier is found, false otherwise. |
12644 // If node is non NULL return an AST node corresponding to the identifier. | 12727 // If node is non NULL return an AST node corresponding to the identifier. |
12645 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, | 12728 bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos, |
12646 const String &ident, | 12729 const String &ident, |
12647 AstNode** node) { | 12730 AstNode** node, |
12731 intptr_t* function_level) { | |
12648 TRACE_PARSER("ResolveIdentInLocalScope"); | 12732 TRACE_PARSER("ResolveIdentInLocalScope"); |
12649 // First try to find the identifier in the nested local scopes. | 12733 // First try to find the identifier in the nested local scopes. |
12650 LocalVariable* local = LookupLocalScope(ident); | 12734 LocalVariable* local = LookupLocalScope(ident); |
12651 if (current_block_ != NULL) { | 12735 if (current_block_ != NULL) { |
12652 current_block_->scope->AddReferencedName(ident_pos, ident); | 12736 current_block_->scope->AddReferencedName(ident_pos, ident); |
12653 } | 12737 } |
12654 if (local != NULL) { | 12738 if (local != NULL) { |
12655 if (node != NULL) { | 12739 if (node != NULL) { |
12656 *node = new(Z) LoadLocalNode(ident_pos, local); | 12740 *node = new(Z) LoadLocalNode(ident_pos, local); |
12657 } | 12741 } |
12742 if (function_level != NULL) { | |
12743 *function_level = local->owner()->function_level(); | |
12744 } | |
12658 return true; | 12745 return true; |
12659 } | 12746 } |
12660 | 12747 |
12661 // If we are compiling top-level code, we don't need to look for | 12748 // If we are compiling top-level code, we don't need to look for |
12662 // the identifier in the current (top-level) class. The class scope | 12749 // the identifier in the current (top-level) class. The class scope |
12663 // of the top-level class is part of the library scope. | 12750 // of the top-level class is part of the library scope. |
12664 if (current_class().IsTopLevel()) { | 12751 if (current_class().IsTopLevel()) { |
12665 if (node != NULL) { | 12752 if (node != NULL) { |
12666 *node = NULL; | 12753 *node = NULL; |
12667 } | 12754 } |
(...skipping 16 matching lines...) Expand all Loading... | |
12684 field = cls.LookupField(ident); | 12771 field = cls.LookupField(ident); |
12685 if (!field.IsNull()) { | 12772 if (!field.IsNull()) { |
12686 if (node != NULL) { | 12773 if (node != NULL) { |
12687 if (!field.is_static()) { | 12774 if (!field.is_static()) { |
12688 CheckInstanceFieldAccess(ident_pos, ident); | 12775 CheckInstanceFieldAccess(ident_pos, ident); |
12689 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 12776 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
12690 } else { | 12777 } else { |
12691 *node = GenerateStaticFieldLookup(field, ident_pos); | 12778 *node = GenerateStaticFieldLookup(field, ident_pos); |
12692 } | 12779 } |
12693 } | 12780 } |
12781 if (function_level != NULL) { | |
12782 *function_level = 0; | |
12783 } | |
12694 return true; | 12784 return true; |
12695 } | 12785 } |
12696 | 12786 |
12697 // Check if an instance/static function exists. | 12787 // Check if an instance/static function exists. |
12698 func = cls.LookupFunction(ident); | 12788 func = cls.LookupFunction(ident); |
12699 if (!func.IsNull() && | 12789 if (!func.IsNull() && |
12700 (func.IsDynamicFunction() || | 12790 (func.IsDynamicFunction() || |
12701 func.IsStaticFunction() || | 12791 func.IsStaticFunction() || |
12702 func.is_abstract())) { | 12792 func.is_abstract())) { |
12703 if (node != NULL) { | 12793 if (node != NULL) { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12872 // If the name cannot be resolved, turn it into an instance field access | 12962 // If the name cannot be resolved, turn it into an instance field access |
12873 // if we're compiling an instance method, or generate | 12963 // if we're compiling an instance method, or generate |
12874 // throw NoSuchMethodError if we're compiling a static method. | 12964 // throw NoSuchMethodError if we're compiling a static method. |
12875 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, | 12965 AstNode* Parser::ResolveIdent(TokenPosition ident_pos, |
12876 const String& ident, | 12966 const String& ident, |
12877 bool allow_closure_names) { | 12967 bool allow_closure_names) { |
12878 TRACE_PARSER("ResolveIdent"); | 12968 TRACE_PARSER("ResolveIdent"); |
12879 // First try to find the variable in the local scope (block scope or | 12969 // First try to find the variable in the local scope (block scope or |
12880 // class scope). | 12970 // class scope). |
12881 AstNode* resolved = NULL; | 12971 AstNode* resolved = NULL; |
12882 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 12972 intptr_t resolved_func_level = 0; |
12973 ResolveIdentInLocalScope(ident_pos, ident, &resolved, &resolved_func_level); | |
12974 if (!innermost_function().IsNull()) { | |
12975 // TODO(regis): Shortcut this lookup if no generic functions in scope. | |
12976 intptr_t type_param_func_level = FunctionLevel(); | |
12977 const TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, | |
12978 innermost_function().LookupTypeParameter(ident, | |
12979 &type_param_func_level)); | |
12980 if (!type_parameter.IsNull()) { | |
12981 if ((resolved == NULL) || (resolved_func_level < type_param_func_level)) { | |
12982 // The identifier is a function type parameter, possibly shadowing | |
12983 // 'resolved'. | |
12984 if (type_param_func_level < FunctionLevel()) { | |
12985 // Make sure that the function instantiator is captured. | |
12986 CaptureFunctionInstantiator(); | |
12987 } | |
12988 // TODO(regis): Finalize type parameter and return as type node. | |
12989 // For now, return as malformed type. | |
12990 Type& malformed_type = Type::ZoneHandle(Z); | |
12991 malformed_type = ClassFinalizer::NewFinalizedMalformedType( | |
12992 Error::Handle(Z), // No previous error. | |
12993 script_, | |
12994 ident_pos, | |
12995 "function type parameter '%s' not yet supported", | |
12996 ident.ToCString()); | |
12997 return new(Z) TypeNode(ident_pos, malformed_type); | |
12998 } | |
12999 } | |
13000 } | |
12883 if (resolved == NULL) { | 13001 if (resolved == NULL) { |
12884 // Check whether the identifier is a type parameter. | 13002 // Check whether the identifier is a class type parameter. |
12885 if (!current_class().IsNull()) { | 13003 if (!current_class().IsNull()) { |
12886 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, | 13004 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, |
12887 current_class().LookupTypeParameter(ident)); | 13005 current_class().LookupTypeParameter(ident)); |
12888 if (!type_parameter.IsNull()) { | 13006 if (!type_parameter.IsNull()) { |
12889 if (FunctionLevel() > 0) { | 13007 if (FunctionLevel() > 0) { |
12890 // Make sure that the instantiator is captured. | 13008 // Make sure that the class instantiator is captured. |
12891 CaptureInstantiator(); | 13009 CaptureInstantiator(); |
12892 } | 13010 } |
12893 type_parameter ^= ClassFinalizer::FinalizeType( | 13011 type_parameter ^= ClassFinalizer::FinalizeType( |
12894 current_class(), type_parameter, ClassFinalizer::kCanonicalize); | 13012 current_class(), type_parameter, ClassFinalizer::kCanonicalize); |
12895 ASSERT(!type_parameter.IsMalformed()); | 13013 ASSERT(!type_parameter.IsMalformed()); |
12896 return new(Z) TypeNode(ident_pos, type_parameter); | 13014 return new(Z) TypeNode(ident_pos, type_parameter); |
12897 } | 13015 } |
12898 } | 13016 } |
12899 // Not found in the local scope, and the name is not a type parameter. | 13017 // Not found in the local scope, and the name is not a type parameter. |
12900 // Try finding the variable in the library scope (current library | 13018 // Try finding the variable in the library scope (current library |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
13008 script_, | 13126 script_, |
13009 ident_pos, | 13127 ident_pos, |
13010 "qualified name '%s' does not refer to a type", | 13128 "qualified name '%s' does not refer to a type", |
13011 qualified_name.ToCString()); | 13129 qualified_name.ToCString()); |
13012 } | 13130 } |
13013 | 13131 |
13014 // If parsing inside a local scope, check whether the type name | 13132 // If parsing inside a local scope, check whether the type name |
13015 // is shadowed by a local declaration. | 13133 // is shadowed by a local declaration. |
13016 if (!is_top_level_ && | 13134 if (!is_top_level_ && |
13017 (prefix->IsNull()) && | 13135 (prefix->IsNull()) && |
13018 ResolveIdentInLocalScope(ident_pos, type_name, NULL)) { | 13136 ResolveIdentInLocalScope(ident_pos, type_name, NULL, NULL)) { |
13019 // The type is malformed. Skip over its type arguments. | 13137 // The type is malformed. Skip over its type arguments. |
13020 ParseTypeArguments(ClassFinalizer::kIgnore); | 13138 ParseTypeArguments(ClassFinalizer::kIgnore); |
13021 return ClassFinalizer::NewFinalizedMalformedType( | 13139 return ClassFinalizer::NewFinalizedMalformedType( |
13022 Error::Handle(Z), // No previous error. | 13140 Error::Handle(Z), // No previous error. |
13023 script_, | 13141 script_, |
13024 ident_pos, | 13142 ident_pos, |
13025 "using '%s' in this context is invalid", | 13143 "using '%s' in this context is invalid", |
13026 type_name.ToCString()); | 13144 type_name.ToCString()); |
13027 } | 13145 } |
13028 if ((!FLAG_load_deferred_eagerly || !allow_deferred_type) && | 13146 if ((!FLAG_load_deferred_eagerly || !allow_deferred_type) && |
(...skipping 30 matching lines...) Expand all Loading... | |
13059 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); | 13177 type_class = UnresolvedClass::New(*prefix, type_name, ident_pos); |
13060 } | 13178 } |
13061 TypeArguments& type_arguments = TypeArguments::Handle( | 13179 TypeArguments& type_arguments = TypeArguments::Handle( |
13062 Z, ParseTypeArguments(finalization)); | 13180 Z, ParseTypeArguments(finalization)); |
13063 if (finalization == ClassFinalizer::kIgnore) { | 13181 if (finalization == ClassFinalizer::kIgnore) { |
13064 return Type::DynamicType(); | 13182 return Type::DynamicType(); |
13065 } | 13183 } |
13066 AbstractType& type = AbstractType::Handle( | 13184 AbstractType& type = AbstractType::Handle( |
13067 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); | 13185 Z, Type::New(type_class, type_arguments, ident_pos, Heap::kOld)); |
13068 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 13186 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
13069 ResolveTypeFromClass(current_class(), finalization, &type); | 13187 ResolveType(finalization, &type); |
13070 if (finalization >= ClassFinalizer::kCanonicalize) { | 13188 if (finalization >= ClassFinalizer::kCanonicalize) { |
13071 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 13189 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
13072 } | 13190 } |
13073 } | 13191 } |
13074 return type.raw(); | 13192 return type.raw(); |
13075 } | 13193 } |
13076 | 13194 |
13077 | 13195 |
13078 void Parser::CheckConstructorCallTypeArguments( | 13196 void Parser::CheckConstructorCallTypeArguments( |
13079 TokenPosition pos, const Function& constructor, | 13197 TokenPosition pos, const Function& constructor, |
(...skipping 1181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14261 if (CurrentToken() == Token::kHASH) { | 14379 if (CurrentToken() == Token::kHASH) { |
14262 // Closurization of top-level entity in prefix scope. | 14380 // Closurization of top-level entity in prefix scope. |
14263 return new(Z) LiteralNode(qual_ident_pos, prefix); | 14381 return new(Z) LiteralNode(qual_ident_pos, prefix); |
14264 } else { | 14382 } else { |
14265 ExpectToken(Token::kPERIOD); | 14383 ExpectToken(Token::kPERIOD); |
14266 } | 14384 } |
14267 } | 14385 } |
14268 String& ident = *CurrentLiteral(); | 14386 String& ident = *CurrentLiteral(); |
14269 ConsumeToken(); | 14387 ConsumeToken(); |
14270 if (prefix.IsNull()) { | 14388 if (prefix.IsNull()) { |
14271 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { | 14389 intptr_t primary_func_level = 0; |
14390 ResolveIdentInLocalScope( | |
14391 qual_ident_pos, ident, &primary, &primary_func_level); | |
14392 // Check whether the identifier is shadowed by a function type parameter. | |
14393 if (!innermost_function().IsNull()) { | |
14394 // TODO(regis): Shortcut this lookup if no generic functions in scope. | |
14395 intptr_t type_param_func_level = FunctionLevel(); | |
14396 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, | |
14397 innermost_function().LookupTypeParameter(ident, | |
14398 &type_param_func_level)); | |
14399 if (!type_param.IsNull()) { | |
14400 if ((primary == NULL) || | |
14401 (primary_func_level < type_param_func_level)) { | |
14402 // The identifier is a function type parameter, possibly shadowing | |
14403 // already resolved 'primary'. | |
14404 if (type_param_func_level < FunctionLevel()) { | |
14405 // Make sure that the function instantiator is captured. | |
14406 CaptureFunctionInstantiator(); | |
14407 } | |
14408 return new(Z) PrimaryNode(qual_ident_pos, type_param); | |
14409 } | |
14410 } | |
14411 } | |
14412 if (primary == NULL) { | |
14272 // Check whether the identifier is a type parameter. | 14413 // Check whether the identifier is a type parameter. |
14273 if (!current_class().IsNull()) { | 14414 if (!current_class().IsNull()) { |
14274 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, | 14415 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, |
14275 current_class().LookupTypeParameter(ident)); | 14416 current_class().LookupTypeParameter(ident)); |
14276 if (!type_param.IsNull()) { | 14417 if (!type_param.IsNull()) { |
14277 return new(Z) PrimaryNode(qual_ident_pos, type_param); | 14418 return new(Z) PrimaryNode(qual_ident_pos, type_param); |
14278 } | 14419 } |
14279 } | 14420 } |
14280 // This is a non-local unqualified identifier so resolve the | 14421 // This is a non-local unqualified identifier so resolve the |
14281 // identifier locally in the main app library and all libraries | 14422 // identifier locally in the main app library and all libraries |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14957 const ArgumentListNode& function_args, | 15098 const ArgumentListNode& function_args, |
14958 const LocalVariable* temp_for_last_arg, | 15099 const LocalVariable* temp_for_last_arg, |
14959 bool is_super_invocation) { | 15100 bool is_super_invocation) { |
14960 UNREACHABLE(); | 15101 UNREACHABLE(); |
14961 return NULL; | 15102 return NULL; |
14962 } | 15103 } |
14963 | 15104 |
14964 } // namespace dart | 15105 } // namespace dart |
14965 | 15106 |
14966 #endif // DART_PRECOMPILED_RUNTIME | 15107 #endif // DART_PRECOMPILED_RUNTIME |
OLD | NEW |