[kernel] Add VariableDeclarations to represent formals of Typedefs

Change-Id: Ic1575dadb4fcf644dfdeb436612e2bed72d41a03
Reviewed-on: https://dart-review.googlesource.com/68083
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
Dmitry Stefantsov 2018-08-03 12:28:11 +00:00 committed by commit-bot@chromium.org
parent 4c455e7876
commit 637e55d4be
14 changed files with 107 additions and 70 deletions

View file

@ -413,9 +413,14 @@ class KernelResynthesizer implements ElementResynthesizer {
int positionalCount = type.positionalParameters.length;
var positionalParameters =
new List<kernel.VariableDeclaration>(positionalCount);
var knownPositionalParameters = const <kernel.VariableDeclaration>[];
if (type.typedefReference != null) {
knownPositionalParameters =
type.typedefReference.asTypedef.positionalParameters;
}
for (int i = 0; i < positionalCount; i++) {
String name = i < type.positionalParameterNames.length
? type.positionalParameterNames[i]
String name = i < knownPositionalParameters.length
? (knownPositionalParameters[i].name ?? '')
: 'arg_$i';
positionalParameters[i] = new kernel.VariableDeclaration(name,
type: type.positionalParameters[i]);

View file

@ -11,9 +11,11 @@ import 'package:kernel/ast.dart'
FunctionType,
InvalidType,
TypeParameter,
Typedef;
Typedef,
VariableDeclaration;
import 'package:kernel/type_algebra.dart' show substitute;
import 'package:kernel/type_algebra.dart'
show FreshTypeParameters, getFreshTypeParameters, substitute;
import '../fasta_codes.dart'
show noLength, templateCyclicTypedef, templateTypeArgumentMismatch;
@ -23,6 +25,7 @@ import '../problems.dart' show unhandled;
import 'kernel_builder.dart'
show
FunctionTypeAliasBuilder,
KernelFormalParameterBuilder,
KernelFunctionTypeBuilder,
KernelTypeBuilder,
KernelTypeVariableBuilder,
@ -51,7 +54,34 @@ class KernelFunctionTypeAliasBuilder
super(metadata, name, typeVariables, type, parent, charOffset);
Typedef build(LibraryBuilder libraryBuilder) {
return target..type ??= buildThisType(libraryBuilder);
target..type ??= buildThisType(libraryBuilder);
if (type != null) {
List<TypeParameter> typeParameters =
new List<TypeParameter>(type.typeVariables?.length ?? 0);
for (int i = 0; i < typeParameters.length; ++i) {
KernelTypeVariableBuilder typeVariable = type.typeVariables[i];
typeParameters[i] = typeVariable.parameter;
}
FreshTypeParameters freshTypeParameters =
getFreshTypeParameters(typeParameters);
target.typeParametersOfFunctionType
.addAll(freshTypeParameters.freshTypeParameters);
if (type.formals != null) {
for (KernelFormalParameterBuilder formal in type.formals) {
VariableDeclaration parameter = formal.build(libraryBuilder);
parameter.type = freshTypeParameters.substitute(parameter.type);
if (formal.isNamed) {
target.namedParameters.add(parameter);
} else {
target.positionalParameters.add(parameter);
}
}
}
}
return target;
}
DartType buildThisType(LibraryBuilder library) {

View file

@ -47,7 +47,6 @@ class KernelFunctionTypeBuilder extends FunctionTypeBuilder
DartType builtReturnType =
returnType?.build(library) ?? const DynamicType();
List<DartType> positionalParameters = <DartType>[];
List<String> positionalParameterNames = <String>[];
List<NamedType> namedParameters;
int requiredParameterCount = 0;
if (formals != null) {
@ -55,7 +54,6 @@ class KernelFunctionTypeBuilder extends FunctionTypeBuilder
DartType type = formal.type?.build(library) ?? const DynamicType();
if (formal.isPositional) {
positionalParameters.add(type);
positionalParameterNames.add(formal.name ?? '');
if (formal.isRequired) requiredParameterCount++;
} else if (formal.isNamed) {
namedParameters ??= <NamedType>[];
@ -76,8 +74,7 @@ class KernelFunctionTypeBuilder extends FunctionTypeBuilder
var type = new FunctionType(positionalParameters, builtReturnType,
namedParameters: namedParameters ?? const <NamedType>[],
typeParameters: typeParameters ?? const <TypeParameter>[],
requiredParameterCount: requiredParameterCount,
positionalParameterNames: positionalParameterNames);
requiredParameterCount: requiredParameterCount);
outlineListener?.store(charOffset, false, type: type);
return type;
}

View file

@ -131,7 +131,7 @@ type CanonicalName {
type ComponentFile {
UInt32 magic = 0x90ABCDEF;
UInt32 formatVersion = 9;
UInt32 formatVersion = 10;
Library[] libraries;
UriSource sourceMap;
List<CanonicalName> canonicalNames;
@ -253,6 +253,9 @@ type Typedef {
List<Expression> annotations;
List<TypeParameter> typeParameters;
DartType type;
List<TypeParameter> typeParametersOfFunctionType;
List<VariableDeclaration> positionalParameters;
List<VariableDeclaration> namedParameters;
}
type Combinator {
@ -1167,7 +1170,6 @@ type FunctionType extends DartType {
UInt totalParameterCount;
List<DartType> positionalParameters;
List<NamedDartType> namedParameters;
List<StringReference> positionalParameterNames;
CanonicalNameReference typedefReference;
DartType returnType;
}

View file

@ -581,9 +581,25 @@ class Typedef extends NamedNode implements FileUriNode {
final List<TypeParameter> typeParameters;
DartType type;
// The following two fields describe parameters of the underlying function
// type. They are needed to keep such attributes as names and annotations.
final List<TypeParameter> typeParametersOfFunctionType;
final List<VariableDeclaration> positionalParameters;
final List<VariableDeclaration> namedParameters;
Typedef(this.name, this.type,
{Reference reference, this.fileUri, List<TypeParameter> typeParameters})
{Reference reference,
this.fileUri,
List<TypeParameter> typeParameters,
List<TypeParameter> typeParametersOfFunctionType,
List<VariableDeclaration> positionalParameters,
List<VariableDeclaration> namedParameters})
: this.typeParameters = typeParameters ?? <TypeParameter>[],
this.typeParametersOfFunctionType =
typeParametersOfFunctionType ?? <TypeParameter>[],
this.positionalParameters =
positionalParameters ?? <VariableDeclaration>[],
this.namedParameters = namedParameters ?? <VariableDeclaration>[],
super(reference) {
setParents(this.typeParameters, this);
}
@ -2224,8 +2240,7 @@ class PropertyGet extends Expression {
if (interfaceTarget != null) {
Class superclass = interfaceTarget.enclosingClass;
var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
return Substitution
.fromInterfaceType(receiverType)
return Substitution.fromInterfaceType(receiverType)
.substituteType(interfaceTarget.getterType);
}
// Treat the properties of Object specially.
@ -2342,8 +2357,7 @@ class DirectPropertyGet extends Expression {
DartType getStaticType(TypeEnvironment types) {
Class superclass = target.enclosingClass;
var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
return Substitution
.fromInterfaceType(receiverType)
return Substitution.fromInterfaceType(receiverType)
.substituteType(target.getterType);
}
}
@ -2446,11 +2460,10 @@ class DirectMethodInvocation extends InvocationExpression {
}
Class superclass = target.enclosingClass;
var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
var returnType = Substitution
.fromInterfaceType(receiverType)
var returnType = Substitution.fromInterfaceType(receiverType)
.substituteType(target.function.returnType);
return Substitution
.fromPairs(target.function.typeParameters, arguments.types)
return Substitution.fromPairs(
target.function.typeParameters, arguments.types)
.substituteType(returnType);
}
}
@ -2481,8 +2494,7 @@ class SuperPropertyGet extends Expression {
}
var receiver =
types.hierarchy.getTypeAsInstanceOf(types.thisType, declaringClass);
return Substitution
.fromInterfaceType(receiver)
return Substitution.fromInterfaceType(receiver)
.substituteType(interfaceTarget.getterType);
}
@ -2727,12 +2739,11 @@ class MethodInvocation extends InvocationExpression {
}
Class superclass = interfaceTarget.enclosingClass;
var receiverType = receiver.getStaticTypeAsInstanceOf(superclass, types);
var getterType = Substitution
.fromInterfaceType(receiverType)
var getterType = Substitution.fromInterfaceType(receiverType)
.substituteType(interfaceTarget.getterType);
if (getterType is FunctionType) {
return Substitution
.fromPairs(getterType.typeParameters, arguments.types)
return Substitution.fromPairs(
getterType.typeParameters, arguments.types)
.substituteType(getterType.returnType);
} else {
return const DynamicType();
@ -2744,8 +2755,8 @@ class MethodInvocation extends InvocationExpression {
if (receiverType.typeParameters.length != arguments.types.length) {
return const BottomType();
}
return Substitution
.fromPairs(receiverType.typeParameters, arguments.types)
return Substitution.fromPairs(
receiverType.typeParameters, arguments.types)
.substituteType(receiverType.returnType);
}
}
@ -2806,11 +2817,10 @@ class SuperMethodInvocation extends InvocationExpression {
Class superclass = interfaceTarget.enclosingClass;
var receiverType =
types.hierarchy.getTypeAsInstanceOf(types.thisType, superclass);
var returnType = Substitution
.fromInterfaceType(receiverType)
var returnType = Substitution.fromInterfaceType(receiverType)
.substituteType(interfaceTarget.function.returnType);
return Substitution
.fromPairs(interfaceTarget.function.typeParameters, arguments.types)
return Substitution.fromPairs(
interfaceTarget.function.typeParameters, arguments.types)
.substituteType(returnType);
}
@ -2859,8 +2869,8 @@ class StaticInvocation extends InvocationExpression {
}
DartType getStaticType(TypeEnvironment types) {
return Substitution
.fromPairs(target.function.typeParameters, arguments.types)
return Substitution.fromPairs(
target.function.typeParameters, arguments.types)
.substituteType(target.function.returnType);
}
@ -2951,8 +2961,7 @@ class Instantiation extends Expression {
DartType getStaticType(TypeEnvironment types) {
FunctionType type = expression.getStaticType(types);
return Substitution
.fromPairs(type.typeParameters, typeArguments)
return Substitution.fromPairs(type.typeParameters, typeArguments)
.substituteType(type.withoutTypeParameters);
}
@ -4804,11 +4813,6 @@ class FunctionType extends DartType {
final List<DartType> positionalParameters;
final List<NamedType> namedParameters; // Must be sorted.
/// The optional names of [positionalParameters], not `null`, but might be
/// empty if information is not available.
@informative
final List<String> positionalParameterNames;
/// The [Typedef] this function type is created for.
@nocoq
Reference typedefReference;
@ -4820,7 +4824,6 @@ class FunctionType extends DartType {
{this.namedParameters: const <NamedType>[],
this.typeParameters: const <TypeParameter>[],
int requiredParameterCount,
this.positionalParameterNames: const <String>[],
this.typedefReference})
: this.positionalParameters = positionalParameters,
this.requiredParameterCount =

View file

@ -867,7 +867,11 @@ class BinaryBuilder {
node.annotations = readAnnotationList(node);
readAndPushTypeParameterList(node.typeParameters, node);
var type = readDartType();
readAndPushTypeParameterList(node.typeParametersOfFunctionType, node);
node.positionalParameters.addAll(readAndPushVariableDeclarationList());
node.namedParameters.addAll(readAndPushVariableDeclarationList());
typeParameterStack.length = 0;
variableStack.length = 0;
if (shouldWriteData) {
node.fileOffset = fileOffset;
node.name = name;
@ -1828,7 +1832,6 @@ class BinaryBuilder {
var totalParameterCount = readUInt();
var positional = readDartTypeList();
var named = readNamedTypeList();
var positionalNames = readStringReferenceList();
var typedefReference = readTypedefReference();
assert(positional.length + named.length == totalParameterCount);
var returnType = readDartType();
@ -1837,14 +1840,11 @@ class BinaryBuilder {
typeParameters: typeParameters,
requiredParameterCount: requiredParameterCount,
namedParameters: named,
positionalParameterNames: positionalNames,
typedefReference: typedefReference);
case Tag.SimpleFunctionType:
var positional = readDartTypeList();
var positionalNames = readStringReferenceList();
var returnType = readDartType();
return new FunctionType(positional, returnType,
positionalParameterNames: positionalNames);
return new FunctionType(positional, returnType);
case Tag.TypeParameterType:
int index = readUInt();
var bound = readDartTypeOption();

View file

@ -689,6 +689,7 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
}
void visitTypedef(Typedef node) {
_variableIndexer ??= new VariableIndexer();
writeCanonicalNameReference(getCanonicalNameOfTypedef(node));
final Uri activeFileUriSaved = _activeFileUri;
@ -697,10 +698,18 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
writeOffset(node.fileOffset);
writeStringReference(node.name);
writeAnnotationList(node.annotations);
enterScope(typeParameters: node.typeParameters);
enterScope(typeParameters: node.typeParameters, variableScope: true);
writeNodeList(node.typeParameters);
writeNode(node.type);
leaveScope(typeParameters: node.typeParameters);
enterScope(typeParameters: node.typeParametersOfFunctionType);
writeNodeList(node.typeParametersOfFunctionType);
writeVariableDeclarationList(node.positionalParameters);
writeVariableDeclarationList(node.namedParameters);
leaveScope(typeParameters: node.typeParametersOfFunctionType);
leaveScope(typeParameters: node.typeParameters, variableScope: true);
_activeFileUri = activeFileUriSaved;
}
@ -1673,7 +1682,6 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
node.typedefReference == null) {
writeByte(Tag.SimpleFunctionType);
writeNodeList(node.positionalParameters);
writeStringReferenceList(node.positionalParameterNames);
writeNode(node.returnType);
} else {
writeByte(Tag.FunctionType);
@ -1684,7 +1692,6 @@ class BinaryPrinter implements Visitor<void>, BinarySink {
node.positionalParameters.length + node.namedParameters.length);
writeNodeList(node.positionalParameters);
writeNodeList(node.namedParameters);
writeStringReferenceList(node.positionalParameterNames);
writeReference(node.typedefReference);
writeNode(node.returnType);
leaveScope(typeParameters: node.typeParameters);

View file

@ -135,7 +135,7 @@ class Tag {
/// Internal version of kernel binary format.
/// Bump it when making incompatible changes in kernel binaries.
/// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
static const int BinaryFormatVersion = 9;
static const int BinaryFormatVersion = 10;
}
abstract class ConstantTag {

View file

@ -248,7 +248,6 @@ class FreshTypeParameters {
namedParameters: type.namedParameters.map(substituteNamed).toList(),
typeParameters: freshTypeParameters,
requiredParameterCount: type.requiredParameterCount,
positionalParameterNames: type.positionalParameterNames,
typedefReference: type.typedefReference);
DartType substitute(DartType type) => substitution.substituteType(type);

View file

@ -204,7 +204,6 @@ class TypeEnvironment extends SubtypeTester {
namedParameters: replacedNamedParameters,
typeParameters: type.typeParameters,
requiredParameterCount: type.requiredParameterCount,
positionalParameterNames: type.positionalParameterNames,
typedefReference: type.typedefReference);
}
return type;

View file

@ -287,8 +287,6 @@ void KernelFingerprintHelper::CalculateFunctionTypeFingerprint(bool simple) {
}
}
CalculateListOfStringsFingerprint(); // read positional parameter names.
if (!simple) {
// TODO(bkonyi): include in hash.
SkipCanonicalNameReference(); // read typedef reference.

View file

@ -1887,8 +1887,6 @@ void KernelReaderHelper::SkipFunctionType(bool simple) {
}
}
SkipListOfStrings(); // read positional parameter names.
if (!simple) {
SkipCanonicalNameReference(); // read typedef reference.
}
@ -2377,13 +2375,16 @@ void KernelReaderHelper::SkipLibraryPart() {
}
void KernelReaderHelper::SkipLibraryTypedef() {
SkipCanonicalNameReference(); // read canonical name.
ReadUInt(); // read source_uri_index.
ReadPosition(); // read position.
SkipStringReference(); // read name index.
SkipListOfExpressions(); // read annotations.
SkipTypeParametersList(); // read type parameters.
SkipDartType(); // read type.
SkipCanonicalNameReference(); // read canonical name.
ReadUInt(); // read source_uri_index.
ReadPosition(); // read position.
SkipStringReference(); // read name index.
SkipListOfExpressions(); // read annotations.
SkipTypeParametersList(); // read type parameters.
SkipDartType(); // read type.
SkipTypeParametersList(); // read type parameters of function type.
SkipListOfVariableDeclarations(); // read positional parameters.
SkipListOfVariableDeclarations(); // read named parameters.
}
TokenPosition KernelReaderHelper::ReadPosition(bool record) {
@ -2763,8 +2764,6 @@ void TypeTranslator::BuildFunctionType(bool simple) {
}
}
helper_->SkipListOfStrings(); // read positional parameter names.
if (!simple) {
helper_->SkipCanonicalNameReference(); // read typedef reference.
}

View file

@ -1291,8 +1291,6 @@ void ScopeBuilder::VisitFunctionType(bool simple) {
}
}
helper_.SkipListOfStrings(); // read positional parameter names.
if (!simple) {
helper_.SkipCanonicalNameReference(); // read typedef reference.
}

View file

@ -17,7 +17,7 @@ namespace kernel {
// package:kernel/binary.md.
static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
static const uint32_t kBinaryFormatVersion = 9;
static const uint32_t kBinaryFormatVersion = 10;
// Keep in sync with package:kernel/lib/binary/tag.dart
#define KERNEL_TAG_LIST(V) \