Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: runtime/vm/parser.cc

Issue 2592263004: Fix resolution and canonicalization of typedefs and function types in (Closed)
Patch Set: work in progress Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 2037 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 if (!var_seen && !final_seen) { 2048 if (!var_seen && !final_seen) {
2049 // The parsed parameter type is actually the function result type. 2049 // The parsed parameter type is actually the function result type.
2050 AbstractType& result_type = 2050 AbstractType& result_type =
2051 AbstractType::Handle(Z, parameter.type->raw()); 2051 AbstractType::Handle(Z, parameter.type->raw());
2052 2052
2053 // In top-level and mixin functions, the source may be in a different 2053 // In top-level and mixin functions, the source may be in a different
2054 // script than the script of the current class. However, we never reparse 2054 // script than the script of the current class. However, we never reparse
2055 // signature functions (except typedef signature functions), therefore 2055 // signature functions (except typedef signature functions), therefore
2056 // we do not need to keep the correct script via a patch class. Use the 2056 // we do not need to keep the correct script via a patch class. Use the
2057 // actual current class as owner of the signature function. 2057 // actual current class as owner of the signature function.
2058 const Function& signature_function = 2058 Function& signature_function =
2059 Function::Handle(Z, Function::NewSignatureFunction( 2059 Function::Handle(Z, Function::NewSignatureFunction(
2060 current_class(), TokenPosition::kNoSource)); 2060 current_class(), TokenPosition::kNoSource));
2061 signature_function.set_parent_function(innermost_function()); 2061 signature_function.set_parent_function(innermost_function());
2062 innermost_function_ = signature_function.raw(); 2062 innermost_function_ = signature_function.raw();
2063 2063
2064 // Finish parsing the function type parameter. 2064 // Finish parsing the function type parameter.
2065 if (CurrentToken() == Token::kLT) { 2065 if (CurrentToken() == Token::kLT) {
2066 if (!FLAG_generic_method_syntax) { 2066 if (!FLAG_generic_method_syntax) {
2067 ReportError("generic function types not supported"); 2067 ReportError("generic function types not supported");
2068 } 2068 }
(...skipping 19 matching lines...) Expand all
2088 AddFormalParamsToFunction(&func_params, signature_function); 2088 AddFormalParamsToFunction(&func_params, signature_function);
2089 2089
2090 ASSERT(innermost_function().raw() == signature_function.raw()); 2090 ASSERT(innermost_function().raw() == signature_function.raw());
2091 innermost_function_ = signature_function.parent_function(); 2091 innermost_function_ = signature_function.parent_function();
2092 2092
2093 Type& signature_type = 2093 Type& signature_type =
2094 Type::ZoneHandle(Z, signature_function.SignatureType()); 2094 Type::ZoneHandle(Z, signature_function.SignatureType());
2095 if (!is_top_level_) { 2095 if (!is_top_level_) {
2096 signature_type ^= ClassFinalizer::FinalizeType( 2096 signature_type ^= ClassFinalizer::FinalizeType(
2097 current_class(), signature_type, ClassFinalizer::kCanonicalize); 2097 current_class(), signature_type, ClassFinalizer::kCanonicalize);
2098 signature_function.SetSignatureType(signature_type); 2098 // Do not refer to signature_function anymore, since it may have been
2099 // replaced during canonicalization.
2100 #ifdef DEBUG
2101 signature_function = Function::null();
2102 #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
2099 } 2103 }
2100 ASSERT(is_top_level_ || signature_type.IsFinalized()); 2104 ASSERT(is_top_level_ || signature_type.IsFinalized());
2101 // A signature type itself cannot be malformed or malbounded, only its 2105 // A signature type itself cannot be malformed or malbounded, only its
2102 // signature function's result type or parameter types may be. 2106 // signature function's result type or parameter types may be.
2103 ASSERT(!signature_type.IsMalformed()); 2107 ASSERT(!signature_type.IsMalformed());
2104 ASSERT(!signature_type.IsMalbounded()); 2108 ASSERT(!signature_type.IsMalbounded());
2105 // The type of the parameter is now the signature type. 2109 // The type of the parameter is now the signature type.
2106 parameter.type = &signature_type; 2110 parameter.type = &signature_type;
2107 } 2111 }
2108 } else { 2112 } else {
(...skipping 9777 matching lines...) Expand 10 before | Expand all | Expand 10 after
11886 } 11890 }
11887 return expr; 11891 return expr;
11888 } 11892 }
11889 11893
11890 11894
11891 // Resolve the given type and its type arguments from the current function and 11895 // Resolve the given type and its type arguments from the current function and
11892 // current class according to the given type finalization mode. 11896 // current class according to the given type finalization mode.
11893 // Not all involved type classes may get resolved yet, but at least type 11897 // Not all involved type classes may get resolved yet, but at least type
11894 // parameters will get resolved, thereby relieving the class 11898 // parameters will get resolved, thereby relieving the class
11895 // finalizer from resolving type parameters out of context. 11899 // finalizer from resolving type parameters out of context.
11900 // TODO(regis): Refactor this code which is partially duplicated in the class
11901 // finalizer, paying attention to type parameter resolution and mixin library.
11896 void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, 11902 void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization,
11897 AbstractType* type) { 11903 AbstractType* type) {
11898 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); 11904 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters);
11899 ASSERT(type != NULL); 11905 ASSERT(type != NULL);
11900 if (type->IsResolved()) { 11906 if (type->IsResolved()) {
11901 return; 11907 return;
11902 } 11908 }
11903 // Resolve class. 11909 // Resolve class.
11904 if (!type->HasResolvedTypeClass()) { 11910 if (!type->HasResolvedTypeClass()) {
11905 const UnresolvedClass& unresolved_class = 11911 const UnresolvedClass& unresolved_class =
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
11963 Object::Handle(Z, unresolved_class.library_or_library_prefix()); 11969 Object::Handle(Z, unresolved_class.library_or_library_prefix());
11964 ASSERT(prefix.IsLibraryPrefix()); 11970 ASSERT(prefix.IsLibraryPrefix());
11965 resolved_type_class = 11971 resolved_type_class =
11966 LibraryPrefix::Cast(prefix).LookupClass(unresolved_class_name); 11972 LibraryPrefix::Cast(prefix).LookupClass(unresolved_class_name);
11967 } 11973 }
11968 // At this point, we can only have a parameterized_type. 11974 // At this point, we can only have a parameterized_type.
11969 const Type& parameterized_type = Type::Cast(*type); 11975 const Type& parameterized_type = Type::Cast(*type);
11970 if (!resolved_type_class.IsNull()) { 11976 if (!resolved_type_class.IsNull()) {
11971 // Replace unresolved class with resolved type class. 11977 // Replace unresolved class with resolved type class.
11972 parameterized_type.set_type_class(resolved_type_class); 11978 parameterized_type.set_type_class(resolved_type_class);
11979 // Promote type to a function type in case its type class is a typedef.
11980 if (resolved_type_class.IsTypedefClass()) {
11981 ASSERT(!parameterized_type.IsFunctionType());
11982 parameterized_type.set_signature(
11983 Function::Handle(Z, resolved_type_class.signature_function()));
11984 }
11973 } else if (finalization >= ClassFinalizer::kCanonicalize) { 11985 } else if (finalization >= ClassFinalizer::kCanonicalize) {
11974 ClassFinalizer::FinalizeMalformedType( 11986 ClassFinalizer::FinalizeMalformedType(
11975 Error::Handle(Z), // No previous error. 11987 Error::Handle(Z), // No previous error.
11976 script_, parameterized_type, "type '%s' is not loaded", 11988 script_, parameterized_type, "type '%s' is not loaded",
11977 String::Handle(Z, parameterized_type.UserVisibleName()).ToCString()); 11989 String::Handle(Z, parameterized_type.UserVisibleName()).ToCString());
11978 return; 11990 return;
11979 } 11991 }
11980 } 11992 }
11993 if (finalization > ClassFinalizer::kResolveTypeParameters) {
11994 type->SetIsResolved();
11995 }
11981 // Resolve type arguments, if any. 11996 // Resolve type arguments, if any.
11982 if (type->arguments() != TypeArguments::null()) { 11997 if (type->arguments() != TypeArguments::null()) {
11983 const TypeArguments& arguments = 11998 const TypeArguments& arguments =
11984 TypeArguments::Handle(Z, type->arguments()); 11999 TypeArguments::Handle(Z, type->arguments());
11985 const intptr_t num_arguments = arguments.Length(); 12000 const intptr_t num_arguments = arguments.Length();
11986 AbstractType& type_argument = AbstractType::Handle(Z); 12001 AbstractType& type_argument = AbstractType::Handle(Z);
11987 for (intptr_t i = 0; i < num_arguments; i++) { 12002 for (intptr_t i = 0; i < num_arguments; i++) {
11988 type_argument ^= arguments.TypeAt(i); 12003 type_argument ^= arguments.TypeAt(i);
11989 ResolveType(finalization, &type_argument); 12004 ResolveType(finalization, &type_argument);
11990 arguments.SetTypeAt(i, type_argument); 12005 arguments.SetTypeAt(i, type_argument);
11991 } 12006 }
11992 } 12007 }
12008 if (type->IsFunctionType()) {
12009 const Function& signature =
12010 Function::Handle(Z, Type::Cast(*type).signature());
12011 Type& signature_type = Type::Handle(Z, signature.SignatureType());
12012 if (signature_type.raw() != type->raw()) {
12013 ResolveType(finalization, &signature_type);
12014 } else {
12015 AbstractType& type = AbstractType::Handle(signature.result_type());
12016 ResolveType(finalization, &type);
12017 signature.set_result_type(type);
12018 const intptr_t num_parameters = signature.NumParameters();
12019 for (intptr_t i = 0; i < num_parameters; i++) {
12020 type = signature.ParameterTypeAt(i);
12021 ResolveType(finalization, &type);
12022 signature.SetParameterTypeAt(i, type);
12023 }
12024 if (signature.IsSignatureFunction()) {
12025 // Drop fields that are not necessary anymore after resolution.
12026 // TODO(regis): Setting the owner to null is breaking mirrors.
12027 // signature.set_owner(Object::Handle(Z));
12028 signature.set_parent_function(Function::Handle(Z));
12029 // TODO(regis): As long as we support metadata in typedef signatures,
12030 // 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
12031 }
12032 }
12033 }
11993 } 12034 }
11994 12035
11995 12036
11996 LocalVariable* Parser::LookupLocalScope(const String& ident) { 12037 LocalVariable* Parser::LookupLocalScope(const String& ident) {
11997 if (current_block_ == NULL) { 12038 if (current_block_ == NULL) {
11998 return NULL; 12039 return NULL;
11999 } 12040 }
12000 // A found name is treated as accessed and possibly marked as captured. 12041 // A found name is treated as accessed and possibly marked as captured.
12001 const bool kTestOnly = false; 12042 const bool kTestOnly = false;
12002 return current_block_->scope->LookupVariable(ident, kTestOnly); 12043 return current_block_->scope->LookupVariable(ident, kTestOnly);
(...skipping 2539 matching lines...) Expand 10 before | Expand all | Expand 10 after
14542 const ArgumentListNode& function_args, 14583 const ArgumentListNode& function_args,
14543 const LocalVariable* temp_for_last_arg, 14584 const LocalVariable* temp_for_last_arg,
14544 bool is_super_invocation) { 14585 bool is_super_invocation) {
14545 UNREACHABLE(); 14586 UNREACHABLE();
14546 return NULL; 14587 return NULL;
14547 } 14588 }
14548 14589
14549 } // namespace dart 14590 } // namespace dart
14550 14591
14551 #endif // DART_PRECOMPILED_RUNTIME 14592 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698