Chromium Code Reviews| Index: runtime/vm/parser.cc |
| diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc |
| index 802c47286985e867def3e2d4918026af78562dec..78706adc60b0c70f83efd0055da61322fb72d751 100644 |
| --- a/runtime/vm/parser.cc |
| +++ b/runtime/vm/parser.cc |
| @@ -2055,7 +2055,7 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
| // signature functions (except typedef signature functions), therefore |
| // we do not need to keep the correct script via a patch class. Use the |
| // actual current class as owner of the signature function. |
| - const Function& signature_function = |
| + Function& signature_function = |
| Function::Handle(Z, Function::NewSignatureFunction( |
| current_class(), TokenPosition::kNoSource)); |
| signature_function.set_parent_function(innermost_function()); |
| @@ -2095,7 +2095,11 @@ void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
| if (!is_top_level_) { |
| signature_type ^= ClassFinalizer::FinalizeType( |
| current_class(), signature_type, ClassFinalizer::kCanonicalize); |
| - signature_function.SetSignatureType(signature_type); |
| +// Do not refer to signature_function anymore, since it may have been |
| +// replaced during canonicalization. |
| +#ifdef DEBUG |
| + signature_function = Function::null(); |
| +#endif |
|
siva
2016/12/27 18:08:28
Why is this done only under the DEBUG flag?
regis
2016/12/27 18:28:48
This variable is not used anymore and the assignme
|
| } |
| ASSERT(is_top_level_ || signature_type.IsFinalized()); |
| // A signature type itself cannot be malformed or malbounded, only its |
| @@ -11893,6 +11897,8 @@ AstNode* Parser::ParsePostfixExpr() { |
| // Not all involved type classes may get resolved yet, but at least type |
| // parameters will get resolved, thereby relieving the class |
| // finalizer from resolving type parameters out of context. |
| +// TODO(regis): Refactor this code which is partially duplicated in the class |
| +// finalizer, paying attention to type parameter resolution and mixin library. |
| void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, |
| AbstractType* type) { |
| ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); |
| @@ -11970,6 +11976,12 @@ void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, |
| if (!resolved_type_class.IsNull()) { |
| // Replace unresolved class with resolved type class. |
| parameterized_type.set_type_class(resolved_type_class); |
| + // Promote type to a function type in case its type class is a typedef. |
| + if (resolved_type_class.IsTypedefClass()) { |
| + ASSERT(!parameterized_type.IsFunctionType()); |
| + parameterized_type.set_signature( |
| + Function::Handle(Z, resolved_type_class.signature_function())); |
| + } |
| } else if (finalization >= ClassFinalizer::kCanonicalize) { |
| ClassFinalizer::FinalizeMalformedType( |
| Error::Handle(Z), // No previous error. |
| @@ -11978,6 +11990,9 @@ void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, |
| return; |
| } |
| } |
| + if (finalization > ClassFinalizer::kResolveTypeParameters) { |
| + type->SetIsResolved(); |
| + } |
| // Resolve type arguments, if any. |
| if (type->arguments() != TypeArguments::null()) { |
| const TypeArguments& arguments = |
| @@ -11990,6 +12005,32 @@ void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, |
| arguments.SetTypeAt(i, type_argument); |
| } |
| } |
| + if (type->IsFunctionType()) { |
| + const Function& signature = |
| + Function::Handle(Z, Type::Cast(*type).signature()); |
| + Type& signature_type = Type::Handle(Z, signature.SignatureType()); |
| + if (signature_type.raw() != type->raw()) { |
| + ResolveType(finalization, &signature_type); |
| + } else { |
| + AbstractType& type = AbstractType::Handle(signature.result_type()); |
| + ResolveType(finalization, &type); |
| + signature.set_result_type(type); |
| + const intptr_t num_parameters = signature.NumParameters(); |
| + for (intptr_t i = 0; i < num_parameters; i++) { |
| + type = signature.ParameterTypeAt(i); |
| + ResolveType(finalization, &type); |
| + signature.SetParameterTypeAt(i, type); |
| + } |
| + if (signature.IsSignatureFunction()) { |
| + // Drop fields that are not necessary anymore after resolution. |
| + // TODO(regis): Setting the owner to null is breaking mirrors. |
| + // signature.set_owner(Object::Handle(Z)); |
| + signature.set_parent_function(Function::Handle(Z)); |
| + // TODO(regis): As long as we support metadata in typedef signatures, |
| + // we cannot reset the token position to TokenPosition::kNoSource. |
|
siva
2016/12/27 18:08:28
Ditto comment about dropping non parent_function f
regis
2016/12/27 18:28:48
I'll add a comment explaining why the owner and to
|
| + } |
| + } |
| + } |
| } |