mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:17:55 +00:00
Serialize typedef parameters (including function typed ones) to Kernel and use it to resynthesize typedefs from Kernel.
R=ahe@google.com, brianwilkerson@google.com, sigmund@google.com BUG= Review-Url: https://codereview.chromium.org/2990783002 .
This commit is contained in:
parent
7d8d0b51c4
commit
afc392b66d
|
@ -1683,6 +1683,11 @@ class CompilationUnitElementImpl extends UriReferencedElementImpl
|
|||
|
||||
@override
|
||||
List<FunctionTypeAliasElement> get functionTypeAliases {
|
||||
if (_kernelContext != null) {
|
||||
_typeAliases ??= _kernelContext.library.typedefs
|
||||
.map((k) => new FunctionTypeAliasElementImpl.forKernel(this, k))
|
||||
.toList(growable: false);
|
||||
}
|
||||
if (_unlinkedUnit != null) {
|
||||
_typeAliases ??= _unlinkedUnit.typedefs.map((t) {
|
||||
if (t.style == TypedefStyle.functionType) {
|
||||
|
@ -4920,6 +4925,11 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
*/
|
||||
final UnlinkedTypedef _unlinkedTypedef;
|
||||
|
||||
/**
|
||||
* The kernel of the element.
|
||||
*/
|
||||
final kernel.Typedef _kernel;
|
||||
|
||||
/**
|
||||
* A list containing all of the parameters defined by this type alias.
|
||||
*/
|
||||
|
@ -4944,13 +4954,23 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
*/
|
||||
FunctionTypeAliasElementImpl(String name, int nameOffset)
|
||||
: _unlinkedTypedef = null,
|
||||
_kernel = null,
|
||||
super(name, nameOffset);
|
||||
|
||||
/**
|
||||
* Initialize using the given kernel.
|
||||
*/
|
||||
FunctionTypeAliasElementImpl.forKernel(
|
||||
CompilationUnitElementImpl enclosingUnit, this._kernel)
|
||||
: _unlinkedTypedef = null,
|
||||
super.forSerialized(enclosingUnit);
|
||||
|
||||
/**
|
||||
* Initialize a newly created type alias element to have the given [name].
|
||||
*/
|
||||
FunctionTypeAliasElementImpl.forNode(Identifier name)
|
||||
: _unlinkedTypedef = null,
|
||||
_kernel = null,
|
||||
super.forNode(name);
|
||||
|
||||
/**
|
||||
|
@ -4958,7 +4978,8 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
*/
|
||||
FunctionTypeAliasElementImpl.forSerialized(
|
||||
this._unlinkedTypedef, CompilationUnitElementImpl enclosingUnit)
|
||||
: super.forSerialized(enclosingUnit);
|
||||
: _kernel = null,
|
||||
super.forSerialized(enclosingUnit);
|
||||
|
||||
@override
|
||||
int get codeLength {
|
||||
|
@ -4999,7 +5020,7 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
_enclosingElement as CompilationUnitElementImpl;
|
||||
|
||||
@override
|
||||
List<kernel.TypeParameter> get kernelTypeParams => null;
|
||||
List<kernel.TypeParameter> get kernelTypeParams => _kernel?.typeParameters;
|
||||
|
||||
@override
|
||||
ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
|
||||
|
@ -5015,6 +5036,9 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
|
||||
@override
|
||||
String get name {
|
||||
if (_kernel != null) {
|
||||
return _kernel.name;
|
||||
}
|
||||
if (_unlinkedTypedef != null) {
|
||||
return _unlinkedTypedef.name;
|
||||
}
|
||||
|
@ -5032,6 +5056,13 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
|
||||
@override
|
||||
List<ParameterElement> get parameters {
|
||||
if (_kernel != null) {
|
||||
_parameters ??= ParameterElementImpl.forKernelParameters(
|
||||
this,
|
||||
_kernel.requiredParameterCount,
|
||||
_kernel.positionalParameters,
|
||||
_kernel.namedParameters);
|
||||
}
|
||||
if (_unlinkedTypedef != null) {
|
||||
_parameters ??= ParameterElementImpl.resynthesizeList(
|
||||
_unlinkedTypedef.parameters, this);
|
||||
|
@ -5054,10 +5085,17 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
|
||||
@override
|
||||
DartType get returnType {
|
||||
if (_unlinkedTypedef != null && _returnType == null) {
|
||||
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
|
||||
this, _unlinkedTypedef.returnType,
|
||||
declaredType: true);
|
||||
if (_returnType == null) {
|
||||
if (_kernel != null) {
|
||||
var type = _kernel.type as kernel.FunctionType;
|
||||
_returnType =
|
||||
enclosingUnit._kernelContext.getType(this, type.returnType);
|
||||
}
|
||||
if (_unlinkedTypedef != null) {
|
||||
_returnType = enclosingUnit.resynthesizerContext.resolveTypeRef(
|
||||
this, _unlinkedTypedef.returnType,
|
||||
declaredType: true);
|
||||
}
|
||||
}
|
||||
return _returnType;
|
||||
}
|
||||
|
@ -5069,8 +5107,10 @@ class FunctionTypeAliasElementImpl extends ElementImpl
|
|||
|
||||
@override
|
||||
FunctionType get type {
|
||||
if (_unlinkedTypedef != null && _type == null) {
|
||||
_type = new FunctionTypeImpl.forTypedef(this);
|
||||
if (_type == null) {
|
||||
if (_kernel != null || _unlinkedTypedef != null) {
|
||||
_type = new FunctionTypeImpl.forTypedef(this);
|
||||
}
|
||||
}
|
||||
return _type;
|
||||
}
|
||||
|
|
|
@ -9435,6 +9435,13 @@ typedef dynamic F(dynamic x, dynamic y);
|
|||
''');
|
||||
}
|
||||
|
||||
test_typedef_parameters_named() async {
|
||||
var library = await checkLibrary('typedef F({y, z, x});');
|
||||
checkElementText(library, r'''
|
||||
typedef dynamic F({dynamic y}, {dynamic z}, {dynamic x});
|
||||
''');
|
||||
}
|
||||
|
||||
test_typedef_return_type() async {
|
||||
var library = await checkLibrary('typedef int F();');
|
||||
checkElementText(library, r'''
|
||||
|
|
|
@ -723,11 +723,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
|
|||
await super.test_library_documented_stars();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_main_typedef() async {
|
||||
await super.test_main_typedef();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_metadata_classTypeAlias() async {
|
||||
await super.test_metadata_classTypeAlias();
|
||||
|
@ -800,11 +795,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
|
|||
await super.test_metadata_simpleFormalParameter_withDefault();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_metadata_typeParameter_ofTypedef() async {
|
||||
await super.test_metadata_typeParameter_ofTypedef();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_method_documented() async {
|
||||
await super.test_method_documented();
|
||||
|
@ -995,61 +985,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
|
|||
await super.test_typedef_generic_asFieldType();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_parameter_parameters() async {
|
||||
await super.test_typedef_parameter_parameters();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_parameter_parameters_in_generic_class() async {
|
||||
await super.test_typedef_parameter_parameters_in_generic_class();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_parameter_return_type() async {
|
||||
await super.test_typedef_parameter_return_type();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_parameter_type() async {
|
||||
await super.test_typedef_parameter_type();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_parameter_type_generic() async {
|
||||
await super.test_typedef_parameter_type_generic();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_parameters() async {
|
||||
await super.test_typedef_parameters();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_return_type() async {
|
||||
await super.test_typedef_return_type();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_return_type_generic() async {
|
||||
await super.test_typedef_return_type_generic();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_return_type_implicit() async {
|
||||
await super.test_typedef_return_type_implicit();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_return_type_void() async {
|
||||
await super.test_typedef_return_type_void();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_type_parameters() async {
|
||||
await super.test_typedef_type_parameters();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_type_parameters_bound() async {
|
||||
await super.test_typedef_type_parameters_bound();
|
||||
|
@ -1065,16 +1000,6 @@ class ResynthesizeKernelStrongTest extends ResynthesizeTest {
|
|||
await super.test_typedef_type_parameters_bound_recursive2();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_type_parameters_f_bound_complex() async {
|
||||
await super.test_typedef_type_parameters_f_bound_complex();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
test_typedef_type_parameters_f_bound_simple() async {
|
||||
await super.test_typedef_type_parameters_f_bound_simple();
|
||||
}
|
||||
|
||||
@failingTest
|
||||
@fastaProblem
|
||||
test_unresolved_annotation_instanceCreation_argument_super() async {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
library fasta.kernel_function_type_alias_builder;
|
||||
|
||||
import 'package:front_end/src/fasta/kernel/kernel_function_type_builder.dart';
|
||||
import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
|
||||
import 'package:kernel/ast.dart'
|
||||
show
|
||||
DartType,
|
||||
|
@ -11,15 +13,15 @@ import 'package:kernel/ast.dart'
|
|||
FunctionType,
|
||||
InvalidType,
|
||||
TypeParameter,
|
||||
Typedef;
|
||||
|
||||
Typedef,
|
||||
VariableDeclaration;
|
||||
import 'package:kernel/type_algebra.dart' show substitute;
|
||||
|
||||
import '../fasta_codes.dart' show templateCyclicTypedef;
|
||||
|
||||
import 'kernel_builder.dart'
|
||||
show
|
||||
FunctionTypeAliasBuilder,
|
||||
KernelFormalParameterBuilder,
|
||||
KernelFunctionTypeBuilder,
|
||||
KernelTypeBuilder,
|
||||
KernelTypeVariableBuilder,
|
||||
|
@ -61,6 +63,7 @@ class KernelFunctionTypeAliasBuilder
|
|||
return thisType;
|
||||
}
|
||||
thisType = const InvalidType();
|
||||
|
||||
DartType builtType = type?.build(library) ?? const DynamicType();
|
||||
if (typeVariables != null) {
|
||||
for (KernelTypeVariableBuilder tv in typeVariables) {
|
||||
|
@ -68,6 +71,9 @@ class KernelFunctionTypeAliasBuilder
|
|||
target.typeParameters.add(tv.parameter..parent = target);
|
||||
}
|
||||
}
|
||||
|
||||
_buildParameters(library);
|
||||
|
||||
return thisType = builtType;
|
||||
}
|
||||
|
||||
|
@ -103,4 +109,23 @@ class KernelFunctionTypeAliasBuilder
|
|||
}
|
||||
return buildTypesWithBuiltArguments(library, builtArguments);
|
||||
}
|
||||
|
||||
/// Build and set formal parameters of this typedef.
|
||||
void _buildParameters(LibraryBuilder library) {
|
||||
int requiredCount = 0;
|
||||
final positional = <VariableDeclaration>[];
|
||||
final named = <VariableDeclaration>[];
|
||||
if (type.formals != null) {
|
||||
for (KernelFormalParameterBuilder formal in type.formals) {
|
||||
KernelVariableDeclaration parameter = formal.build(library);
|
||||
if (formal.isPositional) {
|
||||
positional.add(parameter);
|
||||
if (formal.isRequired) requiredCount++;
|
||||
} else if (formal.isNamed) {
|
||||
named.add(parameter);
|
||||
}
|
||||
}
|
||||
target.setParameters(requiredCount, positional, named);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import 'package:kernel/ast.dart'
|
|||
TypeParameter;
|
||||
|
||||
import '../fasta_codes.dart' show messageSupertypeIsFunction;
|
||||
|
||||
import 'kernel_builder.dart'
|
||||
show
|
||||
FormalParameterBuilder,
|
||||
|
|
|
@ -493,6 +493,16 @@ class Typedef extends NamedNode {
|
|||
List<Expression> annotations = const <Expression>[];
|
||||
String name;
|
||||
final List<TypeParameter> typeParameters;
|
||||
|
||||
@informative
|
||||
int requiredParameterCount = 0;
|
||||
|
||||
@informative
|
||||
List<VariableDeclaration> positionalParameters = <VariableDeclaration>[];
|
||||
|
||||
@informative
|
||||
List<VariableDeclaration> namedParameters = <VariableDeclaration>[];
|
||||
|
||||
DartType type;
|
||||
|
||||
Typedef(this.name, this.type,
|
||||
|
@ -508,9 +518,22 @@ class Typedef extends NamedNode {
|
|||
return v.visitTypedef(this);
|
||||
}
|
||||
|
||||
void setParameters(
|
||||
int requiredParameterCount,
|
||||
List<VariableDeclaration> positionalParameters,
|
||||
List<VariableDeclaration> namedParameters) {
|
||||
this.requiredParameterCount = requiredParameterCount;
|
||||
this.positionalParameters = positionalParameters;
|
||||
this.namedParameters = namedParameters;
|
||||
setParents(this.positionalParameters, this);
|
||||
setParents(this.namedParameters, this);
|
||||
}
|
||||
|
||||
transformChildren(Transformer v) {
|
||||
transformList(annotations, v, this);
|
||||
transformList(typeParameters, v, this);
|
||||
transformList(positionalParameters, v, this);
|
||||
transformList(namedParameters, v, this);
|
||||
if (type != null) {
|
||||
type = v.visitDartType(type);
|
||||
}
|
||||
|
@ -519,6 +542,9 @@ class Typedef extends NamedNode {
|
|||
visitChildren(Visitor v) {
|
||||
visitList(annotations, v);
|
||||
visitList(typeParameters, v);
|
||||
visitList(typeParameters, v);
|
||||
visitList(positionalParameters, v);
|
||||
visitList(namedParameters, v);
|
||||
type?.accept(v);
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,13 @@ class BinaryBuilder {
|
|||
String name = readStringReference();
|
||||
String fileUri = readUriReference();
|
||||
readAndPushTypeParameterList(node.typeParameters, node);
|
||||
|
||||
int requiredParameterCount = readUInt();
|
||||
var positionalParameters = readVariableDeclarationList();
|
||||
var namedParameters = readVariableDeclarationList();
|
||||
node.setParameters(
|
||||
requiredParameterCount, positionalParameters, namedParameters);
|
||||
|
||||
var type = readDartType();
|
||||
typeParameterStack.length = 0;
|
||||
if (shouldWriteData) {
|
||||
|
@ -1221,6 +1228,11 @@ class BinaryBuilder {
|
|||
return new NamedExpression(readStringReference(), readExpression());
|
||||
}
|
||||
|
||||
List<VariableDeclaration> readVariableDeclarationList() {
|
||||
return new List<VariableDeclaration>.generate(
|
||||
readUInt(), (i) => readVariableDeclaration());
|
||||
}
|
||||
|
||||
List<VariableDeclaration> readAndPushVariableDeclarationList() {
|
||||
return new List<VariableDeclaration>.generate(
|
||||
readUInt(), (i) => readAndPushVariableDeclaration());
|
||||
|
|
|
@ -344,14 +344,19 @@ class BinaryPrinter extends Visitor {
|
|||
}
|
||||
|
||||
void visitTypedef(Typedef node) {
|
||||
_variableIndexer = new VariableIndexer();
|
||||
writeCanonicalNameReference(getCanonicalNameOfTypedef(node));
|
||||
writeOffset(node.fileOffset);
|
||||
writeStringReference(node.name);
|
||||
writeUriReference(node.fileUri ?? '');
|
||||
_typeParameterIndexer.enter(node.typeParameters);
|
||||
writeNodeList(node.typeParameters);
|
||||
writeUInt30(node.requiredParameterCount);
|
||||
writeVariableDeclarationList(node.positionalParameters);
|
||||
writeVariableDeclarationList(node.namedParameters);
|
||||
writeNode(node.type);
|
||||
_typeParameterIndexer.exit(node.typeParameters);
|
||||
_variableIndexer = null;
|
||||
}
|
||||
|
||||
void writeAnnotation(Expression annotation) {
|
||||
|
|
|
@ -337,7 +337,8 @@ class VerifyingVisitor extends RecursiveVisitor {
|
|||
!(parent is ForStatement && parent.body != node) &&
|
||||
!(parent is ForInStatement && parent.body != node) &&
|
||||
parent is! Let &&
|
||||
parent is! LocalInitializer) {
|
||||
parent is! LocalInitializer &&
|
||||
parent is! Typedef) {
|
||||
problem(
|
||||
node,
|
||||
"VariableDeclaration must be a direct child of a Block, "
|
||||
|
|
|
@ -4225,6 +4225,18 @@ void StreamingFlowGraphBuilder::SkipLibraryTypedef() {
|
|||
SkipStringReference(); // read name index.
|
||||
ReadUInt(); // read source_uri_index.
|
||||
SkipTypeParametersList(); // read type parameters.
|
||||
ReadUInt(); // read required parameter count
|
||||
|
||||
intptr_t positional_count = ReadListLength();
|
||||
for (intptr_t i = 0; i < positional_count; i++) {
|
||||
SkipVariableDeclaration();
|
||||
}
|
||||
|
||||
intptr_t named_count = ReadListLength();
|
||||
for (intptr_t i = 0; i < named_count; i++) {
|
||||
SkipVariableDeclaration();
|
||||
}
|
||||
|
||||
SkipDartType(); // read type.
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue