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