mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:44:27 +00:00
Type inference of set literals
Change-Id: Icb0f839defa96de186707a8cdc1046281d96fa6c Reviewed-on: https://dart-review.googlesource.com/c/86931 Reviewed-by: Peter von der Ahé <ahe@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
451fdc41e6
commit
60f6ccf3e4
1 changed files with 87 additions and 3 deletions
|
@ -731,6 +731,30 @@ class InferenceVistor extends BodyVisitor1<void, DartType> {
|
|||
assert((node.keyType is ImplicitTypeArgument) ==
|
||||
(node.valueType is ImplicitTypeArgument));
|
||||
bool inferenceNeeded = node.keyType is ImplicitTypeArgument;
|
||||
KernelLibraryBuilder library = inferrer.library;
|
||||
if (library != null &&
|
||||
library.loader.target.enableSetLiterals &&
|
||||
inferenceNeeded &&
|
||||
node.entries.isEmpty) {
|
||||
// Ambiguous set/map literal
|
||||
DartType context =
|
||||
inferrer.typeSchemaEnvironment.unfutureType(typeContext);
|
||||
if (context is InterfaceType) {
|
||||
if (inferrer.classHierarchy
|
||||
.isSubclassOf(inferrer.coreTypes.setClass, context.classNode) &&
|
||||
!inferrer.classHierarchy
|
||||
.isSubclassOf(inferrer.coreTypes.mapClass, context.classNode)) {
|
||||
// Set literal
|
||||
SetLiteralJudgment setLiteral = new SetLiteralJudgment([],
|
||||
typeArgument: const ImplicitTypeArgument(),
|
||||
isConst: node.isConst);
|
||||
node.replaceWith(setLiteral);
|
||||
visitSetLiteralJudgment(setLiteral, typeContext);
|
||||
node.inferredType = setLiteral.inferredType;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool typeChecksNeeded = !inferrer.isTopLevel;
|
||||
if (inferenceNeeded || typeChecksNeeded) {
|
||||
formalTypes = [];
|
||||
|
@ -810,7 +834,6 @@ class InferenceVistor extends BodyVisitor1<void, DartType> {
|
|||
node, inferrer.typeSchemaEnvironment,
|
||||
inferred: true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
void visitMethodInvocationJudgment(
|
||||
|
@ -1028,8 +1051,69 @@ class InferenceVistor extends BodyVisitor1<void, DartType> {
|
|||
}
|
||||
|
||||
void visitSetLiteralJudgment(SetLiteralJudgment node, DartType typeContext) {
|
||||
// Not implemented
|
||||
defaultExpression(node, typeContext);
|
||||
var setClass = inferrer.coreTypes.setClass;
|
||||
var setType = setClass.thisType;
|
||||
List<DartType> inferredTypes;
|
||||
DartType inferredTypeArgument;
|
||||
List<DartType> formalTypes;
|
||||
List<DartType> actualTypes;
|
||||
bool inferenceNeeded = node.typeArgument is ImplicitTypeArgument;
|
||||
bool typeChecksNeeded = !inferrer.isTopLevel;
|
||||
if (inferenceNeeded || typeChecksNeeded) {
|
||||
formalTypes = [];
|
||||
actualTypes = [];
|
||||
}
|
||||
if (inferenceNeeded) {
|
||||
inferredTypes = [const UnknownType()];
|
||||
inferrer.typeSchemaEnvironment.inferGenericFunctionOrType(setType,
|
||||
setClass.typeParameters, null, null, typeContext, inferredTypes,
|
||||
isConst: node.isConst);
|
||||
inferredTypeArgument = inferredTypes[0];
|
||||
} else {
|
||||
inferredTypeArgument = node.typeArgument;
|
||||
}
|
||||
if (inferenceNeeded || typeChecksNeeded) {
|
||||
for (int i = 0; i < node.expressions.length; ++i) {
|
||||
Expression judgment = node.expressions[i];
|
||||
inferrer.inferExpression(
|
||||
judgment, inferredTypeArgument, inferenceNeeded || typeChecksNeeded,
|
||||
isVoidAllowed: true);
|
||||
if (inferenceNeeded) {
|
||||
formalTypes.add(setType.typeArguments[0]);
|
||||
}
|
||||
actualTypes.add(getInferredType(judgment, inferrer));
|
||||
}
|
||||
}
|
||||
if (inferenceNeeded) {
|
||||
inferrer.typeSchemaEnvironment.inferGenericFunctionOrType(
|
||||
setType,
|
||||
setClass.typeParameters,
|
||||
formalTypes,
|
||||
actualTypes,
|
||||
typeContext,
|
||||
inferredTypes);
|
||||
inferredTypeArgument = inferredTypes[0];
|
||||
inferrer.instrumentation?.record(
|
||||
inferrer.uri,
|
||||
node.fileOffset,
|
||||
'typeArgs',
|
||||
new InstrumentationValueForTypeArgs([inferredTypeArgument]));
|
||||
node.typeArgument = inferredTypeArgument;
|
||||
}
|
||||
if (typeChecksNeeded) {
|
||||
for (int i = 0; i < node.expressions.length; i++) {
|
||||
inferrer.ensureAssignable(node.typeArgument, actualTypes[i],
|
||||
node.expressions[i], node.expressions[i].fileOffset,
|
||||
isVoidAllowed: node.typeArgument is VoidType);
|
||||
}
|
||||
}
|
||||
node.inferredType = new InterfaceType(setClass, [inferredTypeArgument]);
|
||||
KernelLibraryBuilder inferrerLibrary = inferrer.library;
|
||||
if (inferenceNeeded && inferrerLibrary is KernelLibraryBuilder) {
|
||||
inferrerLibrary.checkBoundsInSetLiteral(
|
||||
node, inferrer.typeSchemaEnvironment,
|
||||
inferred: true);
|
||||
}
|
||||
}
|
||||
|
||||
void visitStaticAssignmentJudgment(
|
||||
|
|
Loading…
Reference in a new issue