From 4ef7fd14c1de301fd08f6fe24cca07531bb924a3 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Fri, 4 Aug 2017 12:02:23 -0700 Subject: [PATCH] Record Typedef reference into Kernel FunctionType and resynthesyze typedefs in Analyzer. R=ahe@google.com, paulberry@google.com, sigmund@google.com BUG= Review-Url: https://codereview.chromium.org/2986393002 . --- pkg/analyzer/lib/src/kernel/resynthesize.dart | 8 ++ .../test/src/summary/resynthesize_common.dart | 2 +- .../src/summary/resynthesize_kernel_test.dart | 85 ------------------- .../kernel_function_type_alias_builder.dart | 17 ++-- .../kernel/kernel_function_type_builder.dart | 2 +- pkg/kernel/lib/ast.dart | 9 +- pkg/kernel/lib/binary/ast_from_binary.dart | 6 +- pkg/kernel/lib/binary/ast_to_binary.dart | 4 +- runtime/vm/kernel_binary_flowgraph.cc | 14 +++ 9 files changed, 50 insertions(+), 97 deletions(-) diff --git a/pkg/analyzer/lib/src/kernel/resynthesize.dart b/pkg/analyzer/lib/src/kernel/resynthesize.dart index d3d0286bb32..189128029e9 100644 --- a/pkg/analyzer/lib/src/kernel/resynthesize.dart +++ b/pkg/analyzer/lib/src/kernel/resynthesize.dart @@ -106,6 +106,8 @@ class KernelResynthesizer { } else if (parentName.name == '@methods') { isMethod = true; parentName = parentName.parent; + } else if (parentName.name == '@typedefs') { + parentName = parentName.parent; } ElementImpl parentElement = _getElement(parentName); @@ -734,6 +736,12 @@ class _KernelUnitResynthesizerContextImpl } if (kernelType is kernel.FunctionType) { + if (kernelType.typedef != null) { + FunctionTypeAliasElementImpl element = libraryContext.resynthesizer + ._getElement(kernelType.typedef.canonicalName); + return element.type; + } + var functionElement = new FunctionElementImpl.synthetic([], null); functionElement.enclosingElement = context; diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart index 3dd04d41b91..970b20cce11 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_common.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart @@ -9226,7 +9226,7 @@ E e; } test_type_reference_to_import() async { - addLibrarySource('/a.dart', 'class C {} enum E { v }; typedef F();'); + addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();'); var library = await checkLibrary('import "a.dart"; C c; E e; F f;'); checkElementText(library, r''' import 'a.dart'; diff --git a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart index 13d0932116f..f4fd23deff3 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart @@ -220,21 +220,11 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest { await super.test_const_invokeConstructor_unnamed_unresolved3(); } - @failingTest - test_const_reference_type() async { - await super.test_const_reference_type(); - } - @failingTest test_const_reference_type_functionType() async { await super.test_const_reference_type_functionType(); } - @failingTest - test_const_reference_type_imported() async { - await super.test_const_reference_type_imported(); - } - @failingTest test_const_reference_type_imported_withPrefix() async { await super.test_const_reference_type_imported_withPrefix(); @@ -521,11 +511,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest { await super.test_import_self(); } - @failingTest - test_inferred_type_is_typedef() async { - await super.test_inferred_type_is_typedef(); - } - @failingTest test_inferred_type_refers_to_function_typed_param_of_typedef() async { await super.test_inferred_type_refers_to_function_typed_param_of_typedef(); @@ -778,76 +763,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest { await super.test_type_invalid_typeParameter_asPrefix(); } - @failingTest - test_type_reference_lib_to_lib() async { - await super.test_type_reference_lib_to_lib(); - } - - @failingTest - test_type_reference_lib_to_part() async { - await super.test_type_reference_lib_to_part(); - } - - @failingTest - test_type_reference_part_to_lib() async { - await super.test_type_reference_part_to_lib(); - } - - @failingTest - test_type_reference_part_to_other_part() async { - await super.test_type_reference_part_to_other_part(); - } - - @failingTest - test_type_reference_part_to_part() async { - await super.test_type_reference_part_to_part(); - } - - @failingTest - test_type_reference_to_import() async { - await super.test_type_reference_to_import(); - } - - @failingTest - test_type_reference_to_import_export() async { - await super.test_type_reference_to_import_export(); - } - - @failingTest - test_type_reference_to_import_export_export() async { - await super.test_type_reference_to_import_export_export(); - } - - @failingTest - test_type_reference_to_import_export_export_in_subdirs() async { - await super.test_type_reference_to_import_export_export_in_subdirs(); - } - - @failingTest - test_type_reference_to_import_export_in_subdirs() async { - await super.test_type_reference_to_import_export_in_subdirs(); - } - - @failingTest - test_type_reference_to_import_part() async { - await super.test_type_reference_to_import_part(); - } - - @failingTest - test_type_reference_to_import_part_in_subdir() async { - await super.test_type_reference_to_import_part_in_subdir(); - } - - @failingTest - test_type_reference_to_import_relative() async { - await super.test_type_reference_to_import_relative(); - } - - @failingTest - test_type_reference_to_typedef() async { - await super.test_type_reference_to_typedef(); - } - @failingTest test_type_reference_to_typedef_with_type_arguments() async { await super.test_type_reference_to_typedef_with_type_arguments(); diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart index f8c928d71fc..eeb4bad231c 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart @@ -61,14 +61,19 @@ class KernelFunctionTypeAliasBuilder return thisType; } thisType = const InvalidType(); - DartType builtType = type?.build(library) ?? const DynamicType(); - if (typeVariables != null) { - for (KernelTypeVariableBuilder tv in typeVariables) { - tv.parameter.bound = tv?.bound?.build(library); - target.typeParameters.add(tv.parameter..parent = target); + FunctionType builtType = type?.build(library); + if (builtType != null) { + builtType.typedefReference = target.reference; + if (typeVariables != null) { + for (KernelTypeVariableBuilder tv in typeVariables) { + tv.parameter.bound = tv?.bound?.build(library); + target.typeParameters.add(tv.parameter..parent = target); + } } + return thisType = builtType; + } else { + return thisType = const DynamicType(); } - return thisType = builtType; } /// [arguments] have already been built. diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart index 3dc642ead97..528521e0a4f 100644 --- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_builder.dart @@ -37,7 +37,7 @@ class KernelFunctionTypeBuilder extends FunctionTypeBuilder List formals) : super(charOffset, fileUri, returnType, typeVariables, formals); - DartType build(LibraryBuilder library) { + FunctionType build(LibraryBuilder library) { DartType builtReturnType = returnType?.build(library) ?? const DynamicType(); List positionalParameters = []; diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart index 76c28cd75e0..be31d44683f 100644 --- a/pkg/kernel/lib/ast.dart +++ b/pkg/kernel/lib/ast.dart @@ -4143,6 +4143,9 @@ class FunctionType extends DartType { @informative final List positionalParameterNames; + /// The [Typedef] this function type is created for. + Reference typedefReference; + final DartType returnType; int _hashCode; @@ -4150,11 +4153,15 @@ class FunctionType extends DartType { {this.namedParameters: const [], this.typeParameters: const [], int requiredParameterCount, - this.positionalParameterNames: const []}) + this.positionalParameterNames: const [], + this.typedefReference}) : this.positionalParameters = positionalParameters, this.requiredParameterCount = requiredParameterCount ?? positionalParameters.length; + /// The [Typedef] this function type is created for. + Typedef get typedef => typedefReference?.asTypedef; + accept(DartTypeVisitor v) => v.visitFunctionType(this); visitChildren(Visitor v) { diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 1c5814732cf..b7a71136937 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -343,7 +343,7 @@ class BinaryBuilder { } Reference readTypedefReference() { - return readCanonicalNameReference().getReference(); + return readCanonicalNameReference()?.getReference(); } Name readName() { @@ -1176,6 +1176,7 @@ class BinaryBuilder { var positional = readDartTypeList(); var named = readNamedTypeList(); var positionalNames = readStringReferenceList(); + var typedefReference = readTypedefReference(); assert(positional.length + named.length == totalParameterCount); var returnType = readDartType(); typeParameterStack.length = typeParameterStackHeight; @@ -1183,7 +1184,8 @@ class BinaryBuilder { typeParameters: typeParameters, requiredParameterCount: requiredParameterCount, namedParameters: named, - positionalParameterNames: positionalNames); + positionalParameterNames: positionalNames, + typedefReference: typedefReference); case Tag.SimpleFunctionType: var positional = readDartTypeList(); var positionalNames = readStringReferenceList(); diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 291908feef1..7b57e7bbcce 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -1130,7 +1130,8 @@ class BinaryPrinter extends Visitor { visitFunctionType(FunctionType node) { if (node.requiredParameterCount == node.positionalParameters.length && node.typeParameters.isEmpty && - node.namedParameters.isEmpty) { + node.namedParameters.isEmpty && + node.typedefReference == null) { writeByte(Tag.SimpleFunctionType); writeNodeList(node.positionalParameters); writeStringReferenceList(node.positionalParameterNames); @@ -1145,6 +1146,7 @@ class BinaryPrinter extends Visitor { writeNodeList(node.positionalParameters); writeNodeList(node.namedParameters); writeStringReferenceList(node.positionalParameterNames); + writeReference(node.typedefReference); writeNode(node.returnType); _typeParameterIndexer.exit(node.typeParameters); } diff --git a/runtime/vm/kernel_binary_flowgraph.cc b/runtime/vm/kernel_binary_flowgraph.cc index 34963a7c561..5c8115e943c 100644 --- a/runtime/vm/kernel_binary_flowgraph.cc +++ b/runtime/vm/kernel_binary_flowgraph.cc @@ -1097,6 +1097,11 @@ void StreamingScopeBuilder::VisitFunctionType(bool simple) { } builder_->SkipListOfStrings(); // read positional parameter names. + + if (!simple) { + builder_->SkipCanonicalNameReference(); // read typedef reference. + } + VisitDartType(); // read return type. } @@ -1574,6 +1579,10 @@ void StreamingDartTypeTranslator::BuildFunctionType(bool simple) { builder_->SkipListOfStrings(); // read positional parameter names. + if (!simple) { + builder_->SkipCanonicalNameReference(); // read typedef reference. + } + BuildTypeInternal(); // read return type. if (result_.IsMalformed()) { result_ = AbstractType::dynamic_type().raw(); @@ -3812,6 +3821,11 @@ void StreamingFlowGraphBuilder::SkipFunctionType(bool simple) { } SkipListOfStrings(); // read positional parameter names. + + if (!simple) { + SkipCanonicalNameReference(); // read typedef reference. + } + SkipDartType(); // read return type. }