[cfe][Contexts][InternalNodes] Add internal nodes for FunctionNode, FunctionExpression and FunctionDeclaration
This adds internal nodes for FunctionNode, FunctionExpression and FunctionDeclaration which require InternalVariable rather than Variable. This is in preparation for using the new variable model by default. Change-Id: I3c29954bcaae555c20b37e6a3ba1e70d959f1559 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506941 Reviewed-by: Slava Egorov <vegorov@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
8c42f67d35
commit
02046380d1
@@ -145,77 +145,21 @@ class FunctionNode extends TreeNode implements ScopeProvider, ContextConsumer {
|
||||
/// is useful in some contexts, especially when reasoning about the function
|
||||
/// type of the enclosing generic function and in combination with
|
||||
/// [FunctionType.withoutTypeParameters].
|
||||
FunctionType computeThisFunctionType(
|
||||
Nullability nullability, {
|
||||
bool reuseTypeParameters = false,
|
||||
}) {
|
||||
FunctionType computeThisFunctionType(Nullability nullability) {
|
||||
TreeNode? parent = this.parent;
|
||||
|
||||
List<StructuralParameter> structuralParameters;
|
||||
List<TypeParameter> typeParametersToCopy = parent is Constructor
|
||||
? parent.enclosingClass.typeParameters
|
||||
: typeParameters;
|
||||
DartType returnType;
|
||||
List<DartType> positionalParameters;
|
||||
List<NamedType> namedParameters;
|
||||
if (typeParametersToCopy.isEmpty || reuseTypeParameters) {
|
||||
structuralParameters = const <StructuralParameter>[];
|
||||
returnType = this.returnType;
|
||||
List<Variable> thisPositionals = this.positionalParameters;
|
||||
positionalParameters = List.generate(
|
||||
thisPositionals.length,
|
||||
(index) => _getTypeOfVariable(thisPositionals[index]),
|
||||
growable: false,
|
||||
);
|
||||
|
||||
List<Variable> thisNamed = this.namedParameters;
|
||||
if (thisNamed.isEmpty) {
|
||||
namedParameters = const <NamedType>[];
|
||||
} else {
|
||||
namedParameters = List.generate(
|
||||
thisNamed.length,
|
||||
(index) => _getNamedTypeOfVariable(thisNamed[index]),
|
||||
growable: false,
|
||||
);
|
||||
namedParameters.sort();
|
||||
}
|
||||
} else {
|
||||
// We need create a copy of the list of type parameters, otherwise
|
||||
// transformations like erasure don't work.
|
||||
FreshStructuralParametersFromTypeParameters freshStructuralParameters =
|
||||
getFreshStructuralParametersFromTypeParameters(typeParametersToCopy);
|
||||
structuralParameters = freshStructuralParameters.freshTypeParameters;
|
||||
Substitution substitution = freshStructuralParameters.substitution;
|
||||
returnType = substitution.substituteType(this.returnType);
|
||||
|
||||
List<Variable> thisPositionals = this.positionalParameters;
|
||||
positionalParameters = List.generate(
|
||||
thisPositionals.length,
|
||||
(index) => substitution.substituteType(
|
||||
_getTypeOfVariable(thisPositionals[index]),
|
||||
),
|
||||
growable: false,
|
||||
);
|
||||
List<Variable> thisNamed = this.namedParameters;
|
||||
if (thisNamed.isEmpty) {
|
||||
namedParameters = const <NamedType>[];
|
||||
} else {
|
||||
namedParameters = List.generate(
|
||||
thisNamed.length,
|
||||
(index) => _getNamedTypeOfVariable(thisNamed[index], substitution),
|
||||
growable: false,
|
||||
);
|
||||
namedParameters.sort();
|
||||
}
|
||||
}
|
||||
// TODO(johnniwinther,cstefantsova): Cache the function type here and use
|
||||
// [DartType.withDeclaredNullability] to handle the variants.
|
||||
return new FunctionType(
|
||||
positionalParameters,
|
||||
returnType,
|
||||
nullability,
|
||||
return computeFunctionTypeFromData(
|
||||
returnType: returnType,
|
||||
typeParameters: typeParametersToCopy,
|
||||
positionalParameters: positionalParameters,
|
||||
namedParameters: namedParameters,
|
||||
typeParameters: structuralParameters,
|
||||
nullability: nullability,
|
||||
requiredParameterCount: requiredParameterCount,
|
||||
);
|
||||
}
|
||||
@@ -233,6 +177,75 @@ class FunctionNode extends TreeNode implements ScopeProvider, ContextConsumer {
|
||||
return computeThisFunctionType(nullability);
|
||||
}
|
||||
|
||||
static FunctionType computeFunctionTypeFromData({
|
||||
required DartType returnType,
|
||||
required List<TypeParameter> typeParameters,
|
||||
required List<Variable> positionalParameters,
|
||||
required List<Variable> namedParameters,
|
||||
required Nullability nullability,
|
||||
required int requiredParameterCount,
|
||||
}) {
|
||||
List<StructuralParameter> structuralParameters;
|
||||
DartType functionReturnType;
|
||||
List<DartType> positionalParameterTypes;
|
||||
List<NamedType> namedParameterTypes;
|
||||
if (typeParameters.isEmpty) {
|
||||
structuralParameters = const <StructuralParameter>[];
|
||||
functionReturnType = returnType;
|
||||
positionalParameterTypes = List.generate(
|
||||
positionalParameters.length,
|
||||
(index) => _getTypeOfVariable(positionalParameters[index]),
|
||||
growable: false,
|
||||
);
|
||||
|
||||
if (namedParameters.isEmpty) {
|
||||
namedParameterTypes = const <NamedType>[];
|
||||
} else {
|
||||
namedParameterTypes = List.generate(
|
||||
namedParameters.length,
|
||||
(index) => _getNamedTypeOfVariable(namedParameters[index]),
|
||||
growable: false,
|
||||
);
|
||||
namedParameterTypes.sort();
|
||||
}
|
||||
} else {
|
||||
// We need create a copy of the list of type parameters, otherwise
|
||||
// transformations like erasure don't work.
|
||||
FreshStructuralParametersFromTypeParameters freshStructuralParameters =
|
||||
getFreshStructuralParametersFromTypeParameters(typeParameters);
|
||||
structuralParameters = freshStructuralParameters.freshTypeParameters;
|
||||
Substitution substitution = freshStructuralParameters.substitution;
|
||||
functionReturnType = substitution.substituteType(returnType);
|
||||
|
||||
positionalParameterTypes = List.generate(
|
||||
positionalParameters.length,
|
||||
(index) => substitution.substituteType(
|
||||
_getTypeOfVariable(positionalParameters[index]),
|
||||
),
|
||||
growable: false,
|
||||
);
|
||||
if (namedParameters.isEmpty) {
|
||||
namedParameterTypes = const <NamedType>[];
|
||||
} else {
|
||||
namedParameterTypes = List.generate(
|
||||
namedParameters.length,
|
||||
(index) =>
|
||||
_getNamedTypeOfVariable(namedParameters[index], substitution),
|
||||
growable: false,
|
||||
);
|
||||
namedParameterTypes.sort();
|
||||
}
|
||||
}
|
||||
return new FunctionType(
|
||||
positionalParameterTypes,
|
||||
functionReturnType,
|
||||
nullability,
|
||||
namedParameters: namedParameterTypes,
|
||||
typeParameters: structuralParameters,
|
||||
requiredParameterCount: requiredParameterCount,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
R accept<R>(TreeVisitor<R> v) => v.visitFunctionNode(this);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user