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

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

Issue 2592263004: Fix resolution and canonicalization of typedefs and function types in (Closed)
Patch Set: address comments and todos Created 3 years, 11 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
« no previous file with comments | « runtime/vm/object_service.cc ('k') | tests/corelib/corelib.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 signature_function = Function::null();
2099 } 2101 }
2100 ASSERT(is_top_level_ || signature_type.IsFinalized()); 2102 ASSERT(is_top_level_ || signature_type.IsFinalized());
2101 // A signature type itself cannot be malformed or malbounded, only its 2103 // A signature type itself cannot be malformed or malbounded, only its
2102 // signature function's result type or parameter types may be. 2104 // signature function's result type or parameter types may be.
2103 ASSERT(!signature_type.IsMalformed()); 2105 ASSERT(!signature_type.IsMalformed());
2104 ASSERT(!signature_type.IsMalbounded()); 2106 ASSERT(!signature_type.IsMalbounded());
2105 // The type of the parameter is now the signature type. 2107 // The type of the parameter is now the signature type.
2106 parameter.type = &signature_type; 2108 parameter.type = &signature_type;
2107 } 2109 }
2108 } else { 2110 } else {
(...skipping 9777 matching lines...) Expand 10 before | Expand all | Expand 10 after
11886 } 11888 }
11887 return expr; 11889 return expr;
11888 } 11890 }
11889 11891
11890 11892
11891 // Resolve the given type and its type arguments from the current function and 11893 // Resolve the given type and its type arguments from the current function and
11892 // current class according to the given type finalization mode. 11894 // current class according to the given type finalization mode.
11893 // Not all involved type classes may get resolved yet, but at least type 11895 // Not all involved type classes may get resolved yet, but at least type
11894 // parameters will get resolved, thereby relieving the class 11896 // parameters will get resolved, thereby relieving the class
11895 // finalizer from resolving type parameters out of context. 11897 // finalizer from resolving type parameters out of context.
11898 // TODO(regis): Refactor this code which is partially duplicated in the class
11899 // finalizer, paying attention to type parameter resolution and mixin library.
11896 void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization, 11900 void Parser::ResolveType(ClassFinalizer::FinalizationKind finalization,
11897 AbstractType* type) { 11901 AbstractType* type) {
11898 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); 11902 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters);
11899 ASSERT(type != NULL); 11903 ASSERT(type != NULL);
11900 if (type->IsResolved()) { 11904 if (type->IsResolved()) {
11901 return; 11905 return;
11902 } 11906 }
11903 // Resolve class. 11907 // Resolve class.
11904 if (!type->HasResolvedTypeClass()) { 11908 if (!type->HasResolvedTypeClass()) {
11905 const UnresolvedClass& unresolved_class = 11909 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()); 11967 Object::Handle(Z, unresolved_class.library_or_library_prefix());
11964 ASSERT(prefix.IsLibraryPrefix()); 11968 ASSERT(prefix.IsLibraryPrefix());
11965 resolved_type_class = 11969 resolved_type_class =
11966 LibraryPrefix::Cast(prefix).LookupClass(unresolved_class_name); 11970 LibraryPrefix::Cast(prefix).LookupClass(unresolved_class_name);
11967 } 11971 }
11968 // At this point, we can only have a parameterized_type. 11972 // At this point, we can only have a parameterized_type.
11969 const Type& parameterized_type = Type::Cast(*type); 11973 const Type& parameterized_type = Type::Cast(*type);
11970 if (!resolved_type_class.IsNull()) { 11974 if (!resolved_type_class.IsNull()) {
11971 // Replace unresolved class with resolved type class. 11975 // Replace unresolved class with resolved type class.
11972 parameterized_type.set_type_class(resolved_type_class); 11976 parameterized_type.set_type_class(resolved_type_class);
11977 // Promote type to a function type in case its type class is a typedef.
11978 if (resolved_type_class.IsTypedefClass()) {
11979 ASSERT(!parameterized_type.IsFunctionType());
11980 parameterized_type.set_signature(
11981 Function::Handle(Z, resolved_type_class.signature_function()));
11982 }
11973 } else if (finalization >= ClassFinalizer::kCanonicalize) { 11983 } else if (finalization >= ClassFinalizer::kCanonicalize) {
11974 ClassFinalizer::FinalizeMalformedType( 11984 ClassFinalizer::FinalizeMalformedType(
11975 Error::Handle(Z), // No previous error. 11985 Error::Handle(Z), // No previous error.
11976 script_, parameterized_type, "type '%s' is not loaded", 11986 script_, parameterized_type, "type '%s' is not loaded",
11977 String::Handle(Z, parameterized_type.UserVisibleName()).ToCString()); 11987 String::Handle(Z, parameterized_type.UserVisibleName()).ToCString());
11978 return; 11988 return;
11979 } 11989 }
11980 } 11990 }
11991 if (finalization > ClassFinalizer::kResolveTypeParameters) {
11992 type->SetIsResolved();
11993 }
11981 // Resolve type arguments, if any. 11994 // Resolve type arguments, if any.
11982 if (type->arguments() != TypeArguments::null()) { 11995 if (type->arguments() != TypeArguments::null()) {
11983 const TypeArguments& arguments = 11996 const TypeArguments& arguments =
11984 TypeArguments::Handle(Z, type->arguments()); 11997 TypeArguments::Handle(Z, type->arguments());
11985 const intptr_t num_arguments = arguments.Length(); 11998 const intptr_t num_arguments = arguments.Length();
11986 AbstractType& type_argument = AbstractType::Handle(Z); 11999 AbstractType& type_argument = AbstractType::Handle(Z);
11987 for (intptr_t i = 0; i < num_arguments; i++) { 12000 for (intptr_t i = 0; i < num_arguments; i++) {
11988 type_argument ^= arguments.TypeAt(i); 12001 type_argument ^= arguments.TypeAt(i);
11989 ResolveType(finalization, &type_argument); 12002 ResolveType(finalization, &type_argument);
11990 arguments.SetTypeAt(i, type_argument); 12003 arguments.SetTypeAt(i, type_argument);
11991 } 12004 }
11992 } 12005 }
12006 if (type->IsFunctionType()) {
12007 const Function& signature =
12008 Function::Handle(Z, Type::Cast(*type).signature());
12009 Type& signature_type = Type::Handle(Z, signature.SignatureType());
12010 if (signature_type.raw() != type->raw()) {
12011 ResolveType(finalization, &signature_type);
12012 } else {
12013 AbstractType& type = AbstractType::Handle(signature.result_type());
12014 ResolveType(finalization, &type);
12015 signature.set_result_type(type);
12016 const intptr_t num_parameters = signature.NumParameters();
12017 for (intptr_t i = 0; i < num_parameters; i++) {
12018 type = signature.ParameterTypeAt(i);
12019 ResolveType(finalization, &type);
12020 signature.SetParameterTypeAt(i, type);
12021 }
12022 if (signature.IsSignatureFunction()) {
12023 // Drop fields that are not necessary anymore after resolution.
12024 // The parent function, owner, and token position of a shared
12025 // canonical function type are meaningless, since the canonical
12026 // representent is picked arbitrarily.
12027 signature.set_parent_function(Function::Handle(Z));
12028 // TODO(regis): As long as we support metadata in typedef signatures,
12029 // we cannot reset these fields used to reparse a typedef.
12030 // Note that the scope class of a typedef function type is always
12031 // preserved as the typedef class (not reset to _Closure class), thereby
12032 // preventing sharing of canonical function types between typedefs.
12033 // Not being shared, these fields are therefore always meaningful for
12034 // typedefs.
12035 const Class& scope_class = Class::Handle(Z, type.type_class());
12036 if (!scope_class.IsTypedefClass()) {
12037 signature.set_owner(Object::Handle(Z));
12038 signature.set_token_pos(TokenPosition::kNoSource);
12039 }
12040 }
12041 }
12042 }
11993 } 12043 }
11994 12044
11995 12045
11996 LocalVariable* Parser::LookupLocalScope(const String& ident) { 12046 LocalVariable* Parser::LookupLocalScope(const String& ident) {
11997 if (current_block_ == NULL) { 12047 if (current_block_ == NULL) {
11998 return NULL; 12048 return NULL;
11999 } 12049 }
12000 // A found name is treated as accessed and possibly marked as captured. 12050 // A found name is treated as accessed and possibly marked as captured.
12001 const bool kTestOnly = false; 12051 const bool kTestOnly = false;
12002 return current_block_->scope->LookupVariable(ident, kTestOnly); 12052 return current_block_->scope->LookupVariable(ident, kTestOnly);
(...skipping 2539 matching lines...) Expand 10 before | Expand all | Expand 10 after
14542 const ArgumentListNode& function_args, 14592 const ArgumentListNode& function_args,
14543 const LocalVariable* temp_for_last_arg, 14593 const LocalVariable* temp_for_last_arg,
14544 bool is_super_invocation) { 14594 bool is_super_invocation) {
14545 UNREACHABLE(); 14595 UNREACHABLE();
14546 return NULL; 14596 return NULL;
14547 } 14597 }
14548 14598
14549 } // namespace dart 14599 } // namespace dart
14550 14600
14551 #endif // DART_PRECOMPILED_RUNTIME 14601 #endif // DART_PRECOMPILED_RUNTIME
OLDNEW
« no previous file with comments | « runtime/vm/object_service.cc ('k') | tests/corelib/corelib.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698