Type checking for redirecting factories.
Implements static semantics for redirecting factories (c.f. §10.6.2 of
the specification). This CL does not include inference of actual type
arguments on redirectees, that is it does not handle the case where
type arguments have been omitted on the redirectee as in this
following example program:
class A<T> {
factory A() = B;
}
class B<T> implements A<T> {
B();
}
Closes https://github.com/dart-lang/sdk/issues/32988.
Also resolves the second part of
https://github.com/dart-lang/sdk/issues/30579.
Can possibly also close https://github.com/dart-lang/sdk/issues/11578.
Change-Id: I5f1fb60510ba6cdc917321239819c1f817b5b85d
Reviewed-on: https://dart-review.googlesource.com/74580
Commit-Queue: Daniel Hillerström <hillerstrom@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
4134b95a3d
commit
de984e58cb
@@ -2915,6 +2915,75 @@ const MessageCode messageFactoryNotSync = const MessageCode("FactoryNotSync",
|
||||
analyzerCode: "NON_SYNC_FACTORY",
|
||||
message: r"""Factory bodies can't use 'async', 'async*', or 'sync*'.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(String name, int count)>
|
||||
templateFactoryRedirecteeHasTooFewPositionalParameters =
|
||||
const Template<Message Function(String name, int count)>(
|
||||
messageTemplate:
|
||||
r"""Redirection target '#name' accepts fewer arguments ('#count') than the redirecting factory can provide.""",
|
||||
tipTemplate: r"""Try redirecting to a different constructor.""",
|
||||
withArguments:
|
||||
_withArgumentsFactoryRedirecteeHasTooFewPositionalParameters);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name, int count)>
|
||||
codeFactoryRedirecteeHasTooFewPositionalParameters =
|
||||
const Code<Message Function(String name, int count)>(
|
||||
"FactoryRedirecteeHasTooFewPositionalParameters",
|
||||
templateFactoryRedirecteeHasTooFewPositionalParameters,
|
||||
analyzerCode: "REDIRECT_TO_INVALID_FUNCTION_TYPE");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsFactoryRedirecteeHasTooFewPositionalParameters(
|
||||
String name, int count) {
|
||||
return new Message(codeFactoryRedirecteeHasTooFewPositionalParameters,
|
||||
message:
|
||||
"""Redirection target '${name}' accepts fewer arguments ('${count}') than the redirecting factory can provide.""",
|
||||
tip: """Try redirecting to a different constructor.""",
|
||||
arguments: {'name': name, 'count': count});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
DartType _type,
|
||||
String name,
|
||||
DartType
|
||||
_type2)> templateFactoryRedirecteeInvalidReturnType = const Template<
|
||||
Message Function(DartType _type, String name, DartType _type2)>(
|
||||
messageTemplate:
|
||||
r"""The return type '#type' of the constructor '#name' isn't a subtype of '#type2'.""",
|
||||
tipTemplate: r"""Try redirecting to a different constructor.""",
|
||||
withArguments: _withArgumentsFactoryRedirecteeInvalidReturnType);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(DartType _type, String name, DartType _type2)>
|
||||
codeFactoryRedirecteeInvalidReturnType =
|
||||
const Code<Message Function(DartType _type, String name, DartType _type2)>(
|
||||
"FactoryRedirecteeInvalidReturnType",
|
||||
templateFactoryRedirecteeInvalidReturnType,
|
||||
analyzerCode: "REDIRECT_TO_INVALID_RETURN_TYPE");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsFactoryRedirecteeInvalidReturnType(
|
||||
DartType _type, String name, DartType _type2) {
|
||||
NameSystem nameSystem = new NameSystem();
|
||||
StringBuffer buffer;
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
|
||||
String type = '$buffer';
|
||||
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
|
||||
String type2 = '$buffer';
|
||||
|
||||
return new Message(codeFactoryRedirecteeInvalidReturnType,
|
||||
message:
|
||||
"""The return type '${type}' of the constructor '${name}' isn't a subtype of '${type2}'.""",
|
||||
tip: """Try redirecting to a different constructor.""",
|
||||
arguments: {'type': _type, 'name': name, 'type2': _type2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Null> codeFactoryTopLevelDeclaration =
|
||||
messageFactoryTopLevelDeclaration;
|
||||
@@ -6327,6 +6396,187 @@ const MessageCode messageRedirectingConstructorWithBody = const MessageCode(
|
||||
tip:
|
||||
r"""Try removing the body, or not making this a redirecting constructor.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
String name,
|
||||
DartType _type,
|
||||
DartType
|
||||
_type2)> templateRedirectingFactoryIncompatibleBounds = const Template<
|
||||
Message Function(String name, DartType _type, DartType _type2)>(
|
||||
messageTemplate:
|
||||
r"""The type variable '#name' has bound '#type' but the context expects a type variable with bound '#type2'.""",
|
||||
tipTemplate: r"""Try redirecting to a different constructor.""",
|
||||
withArguments: _withArgumentsRedirectingFactoryIncompatibleBounds);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name, DartType _type, DartType _type2)>
|
||||
codeRedirectingFactoryIncompatibleBounds =
|
||||
const Code<Message Function(String name, DartType _type, DartType _type2)>(
|
||||
"RedirectingFactoryIncompatibleBounds",
|
||||
templateRedirectingFactoryIncompatibleBounds,
|
||||
analyzerCode: "REDIRECT_TO_INVALID_RETURN_TYPE");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsRedirectingFactoryIncompatibleBounds(
|
||||
String name, DartType _type, DartType _type2) {
|
||||
NameSystem nameSystem = new NameSystem();
|
||||
StringBuffer buffer;
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
|
||||
String type = '$buffer';
|
||||
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
|
||||
String type2 = '$buffer';
|
||||
|
||||
return new Message(codeRedirectingFactoryIncompatibleBounds,
|
||||
message:
|
||||
"""The type variable '${name}' has bound '${type}' but the context expects a type variable with bound '${type2}'.""",
|
||||
tip: """Try redirecting to a different constructor.""",
|
||||
arguments: {'name': name, 'type': _type, 'type2': _type2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(String name, DartType _type, DartType _type2)>
|
||||
templateRedirectingFactoryInvalidNamedParameterType = const Template<
|
||||
Message Function(String name, DartType _type, DartType _type2)>(
|
||||
messageTemplate:
|
||||
r"""The type of the named parameter '#name' (#type) is not a subtype of the redirection target's corresponding named parameter type (#type2).""",
|
||||
tipTemplate:
|
||||
r"""Try changing either the type of the parameter or the redirection target.""",
|
||||
withArguments:
|
||||
_withArgumentsRedirectingFactoryInvalidNamedParameterType);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name, DartType _type, DartType _type2)>
|
||||
codeRedirectingFactoryInvalidNamedParameterType =
|
||||
const Code<Message Function(String name, DartType _type, DartType _type2)>(
|
||||
"RedirectingFactoryInvalidNamedParameterType",
|
||||
templateRedirectingFactoryInvalidNamedParameterType,
|
||||
analyzerCode: "REDIRECT_TO_INVALID_FUNCTION_TYPE");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsRedirectingFactoryInvalidNamedParameterType(
|
||||
String name, DartType _type, DartType _type2) {
|
||||
NameSystem nameSystem = new NameSystem();
|
||||
StringBuffer buffer;
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
|
||||
String type = '$buffer';
|
||||
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
|
||||
String type2 = '$buffer';
|
||||
|
||||
return new Message(codeRedirectingFactoryInvalidNamedParameterType,
|
||||
message:
|
||||
"""The type of the named parameter '${name}' (${type}) is not a subtype of the redirection target's corresponding named parameter type (${type2}).""",
|
||||
tip: """Try changing either the type of the parameter or the redirection target.""",
|
||||
arguments: {'name': name, 'type': _type, 'type2': _type2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(String name, DartType _type, DartType _type2)>
|
||||
templateRedirectingFactoryInvalidPositionalParameterType = const Template<
|
||||
Message Function(String name, DartType _type, DartType _type2)>(
|
||||
messageTemplate:
|
||||
r"""The type of parameter '#name' (#type) is not a subtype of the redirection target's corresponding parameter type (#type2).""",
|
||||
tipTemplate:
|
||||
r"""Try changing either the type of the parameter or the redirection target.""",
|
||||
withArguments:
|
||||
_withArgumentsRedirectingFactoryInvalidPositionalParameterType);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name, DartType _type, DartType _type2)>
|
||||
codeRedirectingFactoryInvalidPositionalParameterType =
|
||||
const Code<Message Function(String name, DartType _type, DartType _type2)>(
|
||||
"RedirectingFactoryInvalidPositionalParameterType",
|
||||
templateRedirectingFactoryInvalidPositionalParameterType,
|
||||
analyzerCode: "REDIRECT_TO_INVALID_FUNCTION_TYPE");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsRedirectingFactoryInvalidPositionalParameterType(
|
||||
String name, DartType _type, DartType _type2) {
|
||||
NameSystem nameSystem = new NameSystem();
|
||||
StringBuffer buffer;
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
|
||||
String type = '$buffer';
|
||||
|
||||
buffer = new StringBuffer();
|
||||
new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
|
||||
String type2 = '$buffer';
|
||||
|
||||
return new Message(codeRedirectingFactoryInvalidPositionalParameterType,
|
||||
message:
|
||||
"""The type of parameter '${name}' (${type}) is not a subtype of the redirection target's corresponding parameter type (${type2}).""",
|
||||
tip: """Try changing either the type of the parameter or the redirection target.""",
|
||||
arguments: {'name': name, 'type': _type, 'type2': _type2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<Message Function(String name, String name2)>
|
||||
templateRedirectingFactoryMissingNamedParameter =
|
||||
const Template<Message Function(String name, String name2)>(
|
||||
messageTemplate:
|
||||
r"""The constructor '#name' does not have a named parameter '#name2'.""",
|
||||
tipTemplate:
|
||||
r"""Try adding '#name2' as a named parameter to '#name'.""",
|
||||
withArguments: _withArgumentsRedirectingFactoryMissingNamedParameter);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name, String name2)>
|
||||
codeRedirectingFactoryMissingNamedParameter =
|
||||
const Code<Message Function(String name, String name2)>(
|
||||
"RedirectingFactoryMissingNamedParameter",
|
||||
templateRedirectingFactoryMissingNamedParameter,
|
||||
analyzerCode: "REDIRECT_TO_INVALID_FUNCTION_TYPE");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsRedirectingFactoryMissingNamedParameter(
|
||||
String name, String name2) {
|
||||
return new Message(codeRedirectingFactoryMissingNamedParameter,
|
||||
message:
|
||||
"""The constructor '${name}' does not have a named parameter '${name2}'.""",
|
||||
tip: """Try adding '${name2}' as a named parameter to '${name}'.""",
|
||||
arguments: {'name': name, 'name2': name2});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(String name, int count, String name2, int count2)>
|
||||
templateRedirectingFactoryProvidesTooFewRequiredParameters = const Template<
|
||||
Message Function(String name, int count, String name2, int count2)>(
|
||||
messageTemplate:
|
||||
r"""Redirecting factory '#name' can provide less arguments ('#count') than required by the redirection target '#name2' ('#count2').""",
|
||||
tipTemplate: r"""Try redirecting to a different constructor.""",
|
||||
withArguments:
|
||||
_withArgumentsRedirectingFactoryProvidesTooFewRequiredParameters);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name, int count, String name2, int count2)>
|
||||
codeRedirectingFactoryProvidesTooFewRequiredParameters = const Code<
|
||||
Message Function(String name, int count, String name2, int count2)>(
|
||||
"RedirectingFactoryProvidesTooFewRequiredParameters",
|
||||
templateRedirectingFactoryProvidesTooFewRequiredParameters,
|
||||
analyzerCode: "REDIRECT_TO_INVALID_FUNCTION_TYPE");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsRedirectingFactoryProvidesTooFewRequiredParameters(
|
||||
String name, int count, String name2, int count2) {
|
||||
return new Message(codeRedirectingFactoryProvidesTooFewRequiredParameters,
|
||||
message:
|
||||
"""Redirecting factory '${name}' can provide less arguments ('${count}') than required by the redirection target '${name2}' ('${count2}').""",
|
||||
tip: """Try redirecting to a different constructor.""",
|
||||
arguments: {
|
||||
'name': name,
|
||||
'count': count,
|
||||
'name2': name2,
|
||||
'count2': count2
|
||||
});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Null> codeRedirectionInNonFactory = messageRedirectionInNonFactory;
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ import 'package:kernel/ast.dart'
|
||||
Arguments,
|
||||
VariableDeclaration;
|
||||
|
||||
import 'package:kernel/ast.dart'
|
||||
show FunctionType, NamedType, TypeParameterType;
|
||||
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
|
||||
import 'package:kernel/clone.dart' show CloneWithoutBody;
|
||||
@@ -53,6 +56,8 @@ import '../fasta_codes.dart'
|
||||
messagePatchDeclarationMismatch,
|
||||
messagePatchDeclarationOrigin,
|
||||
noLength,
|
||||
templateFactoryRedirecteeHasTooFewPositionalParameters,
|
||||
templateFactoryRedirecteeInvalidReturnType,
|
||||
templateImplementsRepeated,
|
||||
templateImplementsSuperClass,
|
||||
templateMissingImplementationCause,
|
||||
@@ -65,6 +70,11 @@ import '../fasta_codes.dart'
|
||||
templateOverrideTypeMismatchParameter,
|
||||
templateOverrideTypeMismatchReturnType,
|
||||
templateOverrideTypeVariablesMismatch,
|
||||
templateRedirectingFactoryIncompatibleBounds,
|
||||
templateRedirectingFactoryInvalidNamedParameterType,
|
||||
templateRedirectingFactoryInvalidPositionalParameterType,
|
||||
templateRedirectingFactoryMissingNamedParameter,
|
||||
templateRedirectingFactoryProvidesTooFewRequiredParameters,
|
||||
templateRedirectionTargetNotFound,
|
||||
templateTypeArgumentMismatch;
|
||||
|
||||
@@ -80,6 +90,7 @@ import 'kernel_builder.dart'
|
||||
ConstructorReferenceBuilder,
|
||||
Declaration,
|
||||
KernelLibraryBuilder,
|
||||
KernelFunctionBuilder,
|
||||
KernelProcedureBuilder,
|
||||
KernelRedirectingFactoryBuilder,
|
||||
KernelNamedTypeBuilder,
|
||||
@@ -1176,4 +1187,302 @@ abstract class KernelClassBuilder
|
||||
}
|
||||
return declaration;
|
||||
}
|
||||
|
||||
// Computes the function type of a given redirection target. Returns [null] if
|
||||
// the type of actual target could not be computed.
|
||||
FunctionType computeRedirecteeType(
|
||||
ConstructorReferenceBuilder redirectionTarget,
|
||||
TypeEnvironment typeEnvironment) {
|
||||
FunctionNode target;
|
||||
bool isConstructor = false;
|
||||
Class targetClass; // Used when the redirection target is a constructor.
|
||||
if (redirectionTarget.target is KernelFunctionBuilder) {
|
||||
KernelFunctionBuilder targetBuilder = redirectionTarget.target;
|
||||
target = targetBuilder.function;
|
||||
isConstructor = targetBuilder.isConstructor;
|
||||
if (isConstructor) {
|
||||
targetClass = targetBuilder.parent.target;
|
||||
}
|
||||
} else if (redirectionTarget.target is DillMemberBuilder &&
|
||||
(redirectionTarget.target.isConstructor ||
|
||||
redirectionTarget.target.isFactory)) {
|
||||
DillMemberBuilder targetBuilder = redirectionTarget.target;
|
||||
// It seems that the [redirectionTarget.target] is an instance of
|
||||
// [DillMemberBuilder] whenever the redirectee is an implicit constructor,
|
||||
// e.g.
|
||||
//
|
||||
// class A {
|
||||
// factory A() = B;
|
||||
// }
|
||||
// class B implements A {}
|
||||
//
|
||||
target = targetBuilder.member.function;
|
||||
isConstructor = targetBuilder.isConstructor;
|
||||
if (isConstructor) {
|
||||
targetClass = targetBuilder.member.enclosingClass;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionType inferredType = target.functionType;
|
||||
if (redirectionTarget.typeArguments != null &&
|
||||
inferredType.typeParameters.length !=
|
||||
redirectionTarget.typeArguments.length) {
|
||||
addProblem(
|
||||
templateTypeArgumentMismatch
|
||||
.withArguments(inferredType.typeParameters.length),
|
||||
redirectionTarget.charOffset,
|
||||
noLength);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Compute the substitution of the target class type parameters if
|
||||
// [redirectionTarget] has any type arguments. Any built type arguments are
|
||||
// stored in [typeArguments] for later use.
|
||||
Substitution substitution;
|
||||
List<DartType> typeArguments;
|
||||
if (redirectionTarget.typeArguments != null &&
|
||||
redirectionTarget.typeArguments.length > 0) {
|
||||
typeArguments = new List<DartType>();
|
||||
for (var i = 0; i < inferredType.typeParameters.length; i++) {
|
||||
var typeParameter = inferredType.typeParameters[i];
|
||||
var typeArgument = redirectionTarget.typeArguments[i].build(library);
|
||||
// Check whether the [typeArgument] respects the bounds of [typeParameter].
|
||||
if (typeArgument is TypeParameterType) {
|
||||
if (!typeEnvironment.isSubtypeOf(
|
||||
typeArgument.bound, typeParameter.bound)) {
|
||||
// TODO(hillerstrom): Use dmitrays' error message once his "bounds
|
||||
// checking" CL has landed.
|
||||
addProblem(
|
||||
templateRedirectingFactoryIncompatibleBounds.withArguments(
|
||||
typeArgument.parameter.name,
|
||||
typeArgument.bound,
|
||||
typeParameter.bound),
|
||||
redirectionTarget.charOffset,
|
||||
noLength);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
typeArguments.add(typeArgument);
|
||||
}
|
||||
substitution =
|
||||
Substitution.fromPairs(inferredType.typeParameters, typeArguments);
|
||||
} else if (redirectionTarget.typeArguments == null &&
|
||||
inferredType.typeParameters.length > 0) {
|
||||
// TODO(hillerstrom): In this case, we need to perform type inference on
|
||||
// the redirectee to obtain actual type arguments which would allow the
|
||||
// following program to type check:
|
||||
//
|
||||
// class A<T> {
|
||||
// factory A() = B;
|
||||
// }
|
||||
// class B<T> implements A<T> {
|
||||
// B();
|
||||
// }
|
||||
//
|
||||
return null;
|
||||
}
|
||||
|
||||
FunctionType redirecteeType;
|
||||
// If the target is a constructor then we need to patch the return type of
|
||||
// the inferred type, because the type inferrer always infers the return
|
||||
// type to be "void", whereas the inferred return type of a factory is its
|
||||
// enclosing class. TODO(hillerstrom): It may be worthwhile to change the
|
||||
// typing of constructors such that the return type is its enclosing class.
|
||||
if (isConstructor) {
|
||||
DartType returnType =
|
||||
new InterfaceType(targetClass, typeArguments ?? const <DartType>[]);
|
||||
|
||||
redirecteeType = new FunctionType(
|
||||
inferredType.positionalParameters, returnType,
|
||||
namedParameters: inferredType.namedParameters,
|
||||
typeParameters: inferredType.typeParameters,
|
||||
requiredParameterCount: inferredType.requiredParameterCount);
|
||||
} else {
|
||||
redirecteeType = inferredType;
|
||||
}
|
||||
|
||||
// Substitute if necessary.
|
||||
redirecteeType = substitution == null
|
||||
? redirecteeType
|
||||
: (substitution.substituteType(redirecteeType.withoutTypeParameters)
|
||||
as FunctionType);
|
||||
|
||||
return redirecteeType;
|
||||
}
|
||||
|
||||
String computeRedirecteeName(ConstructorReferenceBuilder redirectionTarget) {
|
||||
String targetName = redirectionTarget.fullNameForErrors;
|
||||
if (targetName == "") {
|
||||
return redirectionTarget.target.parent.fullNameForErrors;
|
||||
} else {
|
||||
return targetName;
|
||||
}
|
||||
}
|
||||
|
||||
void checkRedirectingFactory(KernelRedirectingFactoryBuilder factory,
|
||||
TypeEnvironment typeEnvironment) {
|
||||
// The factory type cannot contain any type parameters other than those of
|
||||
// its enclosing class, because constructors cannot specify type parameters
|
||||
// of their own.
|
||||
FunctionType factoryType =
|
||||
factory.procedure.function.functionType.withoutTypeParameters;
|
||||
FunctionType redirecteeType =
|
||||
computeRedirecteeType(factory.redirectionTarget, typeEnvironment);
|
||||
|
||||
// TODO(hillerstrom): It would be preferable to know whether a failure
|
||||
// happened during [_computeRedirecteeType].
|
||||
if (redirecteeType == null) return;
|
||||
|
||||
// Check whether [redirecteeType] <: [factoryType]. In the following let
|
||||
// [factoryType = (S_1, ..., S_i, {S_(i+1), ..., S_n}) -> S']
|
||||
// [redirecteeType = (T_1, ..., T_j, {T_(j+1), ..., T_m}) -> T'].
|
||||
|
||||
// Ensure that any extra parameters that [redirecteeType] might have are
|
||||
// optional.
|
||||
if (redirecteeType.requiredParameterCount >
|
||||
factoryType.requiredParameterCount) {
|
||||
addProblem(
|
||||
templateRedirectingFactoryProvidesTooFewRequiredParameters
|
||||
.withArguments(
|
||||
factory.fullNameForErrors,
|
||||
factoryType.requiredParameterCount,
|
||||
computeRedirecteeName(factory.redirectionTarget),
|
||||
redirecteeType.requiredParameterCount),
|
||||
factory.charOffset,
|
||||
noLength);
|
||||
return;
|
||||
}
|
||||
if (redirecteeType.positionalParameters.length <
|
||||
factoryType.positionalParameters.length) {
|
||||
String targetName = computeRedirecteeName(factory.redirectionTarget);
|
||||
addProblem(
|
||||
templateFactoryRedirecteeHasTooFewPositionalParameters.withArguments(
|
||||
targetName, redirecteeType.positionalParameters.length),
|
||||
factory.redirectionTarget.charOffset,
|
||||
noLength);
|
||||
return;
|
||||
}
|
||||
|
||||
// For each 0 < k < i check S_k <: T_k.
|
||||
for (int i = 0; i < factoryType.positionalParameters.length; ++i) {
|
||||
var factoryParameterType = factoryType.positionalParameters[i];
|
||||
var redirecteeParameterType = redirecteeType.positionalParameters[i];
|
||||
if (!typeEnvironment.isSubtypeOf(
|
||||
factoryParameterType, redirecteeParameterType)) {
|
||||
final factoryParameter =
|
||||
factory.target.function.positionalParameters[i];
|
||||
addProblem(
|
||||
templateRedirectingFactoryInvalidPositionalParameterType
|
||||
.withArguments(factoryParameter.name, factoryParameterType,
|
||||
redirecteeParameterType),
|
||||
factoryParameter.fileOffset,
|
||||
factoryParameter.name.length);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// For each i < k < n check that the named parameter S_k has a corresponding
|
||||
// named parameter T_l in [redirecteeType] for some j < l < m.
|
||||
int factoryTypeNameIndex = 0; // k.
|
||||
int redirecteeTypeNameIndex = 0; // l.
|
||||
|
||||
// The following code makes use of the invariant that [namedParameters] are
|
||||
// already sorted (i.e. it's a monotonic sequence) to determine in a linear
|
||||
// pass whether [factory.namedParameters] is a subset of
|
||||
// [redirectee.namedParameters]. In the comments below the symbol <= stands
|
||||
// for the usual lexicographic relation on strings.
|
||||
while (factoryTypeNameIndex < factoryType.namedParameters.length) {
|
||||
// If we have gone beyond the bound of redirectee's named parameters, then
|
||||
// signal a missing named parameter error.
|
||||
if (redirecteeTypeNameIndex == redirecteeType.namedParameters.length) {
|
||||
reportRedirectingFactoryMissingNamedParameter(
|
||||
factory, factoryType.namedParameters[factoryTypeNameIndex]);
|
||||
break;
|
||||
}
|
||||
|
||||
int result = redirecteeType.namedParameters[redirecteeTypeNameIndex].name
|
||||
.compareTo(factoryType.namedParameters[factoryTypeNameIndex].name);
|
||||
if (result < 0) {
|
||||
// T_l.name <= S_k.name.
|
||||
redirecteeTypeNameIndex++;
|
||||
} else if (result == 0) {
|
||||
// S_k.name <= T_l.name.
|
||||
NamedType factoryParameterType =
|
||||
factoryType.namedParameters[factoryTypeNameIndex];
|
||||
NamedType redirecteeParameterType =
|
||||
redirecteeType.namedParameters[redirecteeTypeNameIndex];
|
||||
// Check S_k <: T_l.
|
||||
if (!typeEnvironment.isSubtypeOf(
|
||||
factoryParameterType.type, redirecteeParameterType.type)) {
|
||||
var factoryFormal =
|
||||
factory.target.function.namedParameters[redirecteeTypeNameIndex];
|
||||
addProblem(
|
||||
templateRedirectingFactoryInvalidNamedParameterType.withArguments(
|
||||
factoryParameterType.name,
|
||||
factoryParameterType.type,
|
||||
redirecteeParameterType.type),
|
||||
factoryFormal.fileOffset,
|
||||
factoryFormal.name.length);
|
||||
return;
|
||||
}
|
||||
redirecteeTypeNameIndex++;
|
||||
factoryTypeNameIndex++;
|
||||
} else {
|
||||
// S_k.name <= T_l.name. By appealing to the monotinicity of
|
||||
// [namedParameters] and the transivity of <= it follows that for any
|
||||
// l', such that l < l', it must be the case that S_k <= T_l'. Thus the
|
||||
// named parameter is missing from the redirectee's parameter list.
|
||||
reportRedirectingFactoryMissingNamedParameter(
|
||||
factory, factoryType.namedParameters[factoryTypeNameIndex]);
|
||||
|
||||
// Continue with the next factory named parameter.
|
||||
factoryTypeNameIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// Report any unprocessed factory named parameters as missing.
|
||||
if (factoryTypeNameIndex < factoryType.namedParameters.length) {
|
||||
for (int i = factoryTypeNameIndex;
|
||||
i < factoryType.namedParameters.length;
|
||||
i++) {
|
||||
reportRedirectingFactoryMissingNamedParameter(
|
||||
factory, factoryType.namedParameters[factoryTypeNameIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
// Check that T' <: S'.
|
||||
if (!typeEnvironment.isSubtypeOf(
|
||||
redirecteeType.returnType, factoryType.returnType)) {
|
||||
String targetName = computeRedirecteeName(factory.redirectionTarget);
|
||||
addProblem(
|
||||
templateFactoryRedirecteeInvalidReturnType.withArguments(
|
||||
redirecteeType.returnType, targetName, factoryType.returnType),
|
||||
factory.redirectionTarget.charOffset,
|
||||
noLength);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void reportRedirectingFactoryMissingNamedParameter(
|
||||
KernelRedirectingFactoryBuilder factory, NamedType missingParameter) {
|
||||
addProblem(
|
||||
templateRedirectingFactoryMissingNamedParameter.withArguments(
|
||||
computeRedirecteeName(factory.redirectionTarget),
|
||||
missingParameter.name),
|
||||
factory.redirectionTarget.charOffset,
|
||||
noLength);
|
||||
}
|
||||
|
||||
void checkRedirectingFactories(TypeEnvironment typeEnvironment) {
|
||||
Map<String, MemberBuilder> constructors = this.constructors.local;
|
||||
Iterable<String> names = constructors.keys;
|
||||
for (String name in names) {
|
||||
Declaration constructor = constructors[name];
|
||||
if (constructor is KernelRedirectingFactoryBuilder) {
|
||||
checkRedirectingFactory(constructor, typeEnvironment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,6 +261,7 @@ class KernelTarget extends TargetImplementation {
|
||||
loader.checkSupertypes(myClasses);
|
||||
loader.checkOverrides(myClasses);
|
||||
loader.checkAbstractMembers(myClasses);
|
||||
loader.checkRedirectingFactories(myClasses);
|
||||
loader.addNoSuchMethodForwarders(myClasses);
|
||||
return component;
|
||||
},
|
||||
|
||||
@@ -610,16 +610,14 @@ class DietListener extends StackListener {
|
||||
final StackListener listener = createFunctionListener(builder);
|
||||
try {
|
||||
Parser parser = new Parser(listener);
|
||||
|
||||
if (metadata != null) {
|
||||
parser.parseMetadataStar(parser.syntheticPreviousToken(metadata));
|
||||
listener.pop();
|
||||
listener.pop(); // Pops metadata constants.
|
||||
}
|
||||
|
||||
token = parser.parseFormalParametersOpt(
|
||||
parser.syntheticPreviousToken(token), MemberKind.Factory);
|
||||
|
||||
listener.pop();
|
||||
listener.pop(); // Pops formal parameters.
|
||||
listener.checkEmpty(token.next.charOffset);
|
||||
} on DebugAbort {
|
||||
rethrow;
|
||||
|
||||
@@ -776,6 +776,17 @@ class SourceLoader<L> extends Loader<L> {
|
||||
ticker.logMs("Checked abstract members");
|
||||
}
|
||||
|
||||
void checkRedirectingFactories(List<SourceClassBuilder> sourceClasses) {
|
||||
if (!target.strongMode) return;
|
||||
for (SourceClassBuilder builder in sourceClasses) {
|
||||
if (builder.library.loader == this) {
|
||||
builder.checkRedirectingFactories(
|
||||
typeInferenceEngine.typeSchemaEnvironment);
|
||||
}
|
||||
}
|
||||
ticker.logMs("Checked redirecting factories");
|
||||
}
|
||||
|
||||
void addNoSuchMethodForwarders(List<SourceClassBuilder> sourceClasses) {
|
||||
if (!target.backendTarget.enableNoSuchMethodForwarders) return;
|
||||
|
||||
|
||||
@@ -2831,7 +2831,7 @@ DefaultValueInRedirectingFactoryConstructor:
|
||||
- >-
|
||||
class A {
|
||||
factory A.f({int x = 42}) = A.g;
|
||||
A.g() {}
|
||||
A.g({int x = 40}) {}
|
||||
}
|
||||
|
||||
UntranslatableUri:
|
||||
@@ -2856,3 +2856,84 @@ CantReadFile:
|
||||
PackagesFileFormat:
|
||||
template: "Problem in packages configuration file: #string"
|
||||
external: test/packages_format_error_test.dart
|
||||
|
||||
FactoryRedirecteeInvalidReturnType:
|
||||
template: "The return type '#type' of the constructor '#name' isn't a subtype of '#type2'."
|
||||
tip: "Try redirecting to a different constructor."
|
||||
analyzerCode: REDIRECT_TO_INVALID_RETURN_TYPE
|
||||
script:
|
||||
- >-
|
||||
class A {
|
||||
factory A() = B;
|
||||
}
|
||||
class B {
|
||||
B();
|
||||
}
|
||||
|
||||
FactoryRedirecteeHasTooFewPositionalParameters:
|
||||
template: "Redirection target '#name' accepts fewer arguments ('#count') than the redirecting factory can provide."
|
||||
tip: "Try redirecting to a different constructor."
|
||||
analyzerCode: REDIRECT_TO_INVALID_FUNCTION_TYPE
|
||||
script:
|
||||
- >-
|
||||
class A {
|
||||
factory A.one(int x) = A.zero;
|
||||
A.zero() {}
|
||||
}
|
||||
|
||||
RedirectingFactoryInvalidPositionalParameterType:
|
||||
template: "The type of parameter '#name' (#type) is not a subtype of the redirection target's corresponding parameter type (#type2)."
|
||||
tip: "Try changing either the type of the parameter or the redirection target."
|
||||
analyzerCode: REDIRECT_TO_INVALID_FUNCTION_TYPE
|
||||
script:
|
||||
- >-
|
||||
class A {
|
||||
factory A.i(int x) = A.s;
|
||||
A.s(String x) { }
|
||||
}
|
||||
|
||||
RedirectingFactoryMissingNamedParameter:
|
||||
template: "The constructor '#name' does not have a named parameter '#name2'."
|
||||
tip: "Try adding '#name2' as a named parameter to '#name'."
|
||||
analyzerCode: REDIRECT_TO_INVALID_FUNCTION_TYPE
|
||||
script:
|
||||
- >-
|
||||
class A {
|
||||
factory A.f({int x}) = A.g;
|
||||
A.g({int y}) { }
|
||||
}
|
||||
|
||||
RedirectingFactoryInvalidNamedParameterType:
|
||||
template: "The type of the named parameter '#name' (#type) is not a subtype of the redirection target's corresponding named parameter type (#type2)."
|
||||
tip: "Try changing either the type of the parameter or the redirection target."
|
||||
analyzerCode: REDIRECT_TO_INVALID_FUNCTION_TYPE
|
||||
script:
|
||||
- >-
|
||||
class A {
|
||||
factory A.f({int x}) = A.g;
|
||||
A.g({String x}) { }
|
||||
}
|
||||
|
||||
RedirectingFactoryProvidesTooFewRequiredParameters:
|
||||
template: "Redirecting factory '#name' can provide less arguments ('#count') than required by the redirection target '#name2' ('#count2')."
|
||||
tip: "Try redirecting to a different constructor."
|
||||
analyzerCode: REDIRECT_TO_INVALID_FUNCTION_TYPE
|
||||
script:
|
||||
- >-
|
||||
class A {
|
||||
factory A.f(int x) = A.g;
|
||||
A.g(int x, int y) {}
|
||||
}
|
||||
|
||||
RedirectingFactoryIncompatibleBounds:
|
||||
template: "The type variable '#name' has bound '#type' but the context expects a type variable with bound '#type2'."
|
||||
tip: "Try redirecting to a different constructor."
|
||||
analyzerCode: REDIRECT_TO_INVALID_RETURN_TYPE
|
||||
script:
|
||||
- >-
|
||||
class A<T extends int> {
|
||||
factory A() = B<T>;
|
||||
}
|
||||
class B<S extends String> implements A<int> {
|
||||
B();
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import "package:expect/expect.dart";
|
||||
|
||||
class G<A extends int, B extends String> {
|
||||
G();
|
||||
factory G.swap() = G<B,A>; /// 00: static type warning
|
||||
factory G.swap() = G<B,A>; /// 00: compile-time error
|
||||
factory G.retain() = G<A,B>;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,14 +32,12 @@ dart/snapshot_version_test: Fail, OK # Expects to find script snapshot relative
|
||||
|
||||
[ $compiler == app_jitk ]
|
||||
dart/data_uri_import_test/utf16: MissingRuntimeError
|
||||
dart/redirection_type_shuffling_test/00: RuntimeError
|
||||
dart/redirection_type_shuffling_test/none: RuntimeError
|
||||
dart/snapshot_version_test: RuntimeError
|
||||
|
||||
[ $compiler == dart2analyzer ]
|
||||
dart/byte_array_optimized_test: CompileTimeError # int64
|
||||
dart/byte_array_test: CompileTimeError # int64
|
||||
dart/redirection_type_shuffling_test/00: CompileTimeError
|
||||
|
||||
[ $compiler == dart2js ]
|
||||
dart/byte_array_optimized_test: Skip # compilers not aware of byte arrays
|
||||
@@ -110,6 +108,9 @@ cc/Service_Profile: Skip
|
||||
[ !$strong ]
|
||||
dart/callee_side_type_checks_test: SkipByDesign
|
||||
|
||||
[ !$checked && !$strong && $runtime == vm ]
|
||||
dart/redirection_type_shuffling_test/00: MissingCompileTimeError
|
||||
|
||||
# Following tests are failing in a weird way on macos/ia32/debug builds
|
||||
# need to investigate.
|
||||
[ $runtime == vm && $system == macos ]
|
||||
|
||||
@@ -62,6 +62,7 @@ LibTest/math/pow_A10_t01: CompileTimeError
|
||||
Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t01: MissingCompileTimeError
|
||||
Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t02: MissingCompileTimeError
|
||||
Language/Classes/Constructors/Constant_Constructors/invalid_constant_initializer_t02: MissingCompileTimeError
|
||||
Language/Classes/Constructors/Factories/function_type_t01: CompileTimeError # Expects a warning but this is an error in Dart 2
|
||||
Language/Classes/Constructors/Generative_Constructors/static_type_t01: CompileTimeError
|
||||
Language/Classes/Constructors/name_t01: MissingCompileTimeError
|
||||
Language/Classes/Constructors/name_t02: MissingCompileTimeError
|
||||
|
||||
@@ -15,8 +15,6 @@ Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass
|
||||
Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t06: MissingCompileTimeError # Legal, see #33235
|
||||
Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: MissingCompileTimeError # Issue 34192
|
||||
Language/Classes/Constructors/Factories/arguments_type_t01: MissingCompileTimeError # Issue 33308
|
||||
Language/Classes/Constructors/Factories/function_type_t01: MissingCompileTimeError # Issue 31590
|
||||
Language/Classes/Constructors/Factories/function_type_t02: MissingCompileTimeError # Issue 31590
|
||||
Language/Classes/Constructors/Generative_Constructors/final_variables_t01: CompileTimeError # Expects a warning, but this is an error in Dart 2
|
||||
Language/Classes/Constructors/Generative_Constructors/initializers_t15: CompileTimeError
|
||||
Language/Classes/Constructors/name_t01: MissingCompileTimeError # Legal, see #33235
|
||||
|
||||
@@ -257,11 +257,11 @@ class D extends C {
|
||||
'field3=IntConstant(99)))'),
|
||||
]),
|
||||
const TestData('redirect', '''
|
||||
class A<T> implements B {
|
||||
class A<T> implements B<Null> {
|
||||
final field1;
|
||||
const A({this.field1:42});
|
||||
}
|
||||
class B<S> implements C {
|
||||
class B<S> implements C<Null> {
|
||||
const factory B({field1}) = A<B<S>>;
|
||||
const factory B.named() = A<S>;
|
||||
}
|
||||
|
||||
@@ -233,11 +233,11 @@ class C extends B {
|
||||
}),
|
||||
]),
|
||||
const TestData('''
|
||||
class A<T> implements B {
|
||||
class A<T> implements B<Null> {
|
||||
final field1;
|
||||
const A({this.field1:42});
|
||||
}
|
||||
class B<S> implements C {
|
||||
class B<S> implements C<Null> {
|
||||
const factory B({field1}) = A<B<S>>;
|
||||
const factory B.named() = A<S>;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,8 @@ void main() {
|
||||
class Class extends B with A {}""", ["Class", "A"],
|
||||
["Class", "A"]);
|
||||
|
||||
await test("""class A {}
|
||||
class Class implements A {
|
||||
await test("""class A implements Class {}
|
||||
class Class {
|
||||
factory Class() = A;
|
||||
}""", ["A"], ["Class"]);
|
||||
}
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
// Dart test to verify incompatible constructor types
|
||||
|
||||
abstract class Point {
|
||||
factory Point(x, y) = PointImplementation;
|
||||
factory Point(int x, int y) = PointImplementation; //# 01: ok
|
||||
factory Point(x, y) = PointImplementation; //# 02: compile-time error
|
||||
}
|
||||
|
||||
class PointImplementation implements Point {
|
||||
PointImplementation(int x, int y) {} //# static type warning
|
||||
PointImplementation(int x, int y) {}
|
||||
}
|
||||
|
||||
main() {
|
||||
new Point(1, 2);
|
||||
new Point(1, 2); //# 01: continued
|
||||
new Point(1, 2); //# 02: continued
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ const_cast2_test/none: CompileTimeError # failing-by-design: Not a const express
|
||||
const_constructor3_test/04: MissingCompileTimeError # Side-effect of working around issue 33441 for int-to-double
|
||||
constructor_reference_test/27: MissingCompileTimeError # Issue 34403
|
||||
covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
|
||||
default_implementation2_test: CompileTimeError # Issue #34338, however, needs triage (#34337) and blocked (#34336)
|
||||
dynamic_prefix_core_test/01: MissingCompileTimeError # failing-by-design: #34339
|
||||
emit_const_fields_test: CompileTimeError # failing-by-design: #34340
|
||||
enum_syntax_test/05: Fail # Issue 34341
|
||||
@@ -124,7 +123,6 @@ super_call4_test/01: MissingCompileTimeError
|
||||
super_no_such_method4_test/01: MissingCompileTimeError # Issue 33553
|
||||
super_no_such_method5_test/01: MissingCompileTimeError # Issue 33553
|
||||
super_setter_test: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
|
||||
switch_case_test/none: CompileTimeError
|
||||
syntax_test/60: MissingCompileTimeError
|
||||
syntax_test/61: MissingCompileTimeError
|
||||
try_catch_on_syntax_test/10: MissingCompileTimeError
|
||||
@@ -139,7 +137,6 @@ type_promotion_functions_test/12: CompileTimeError
|
||||
type_promotion_functions_test/13: CompileTimeError
|
||||
type_promotion_functions_test/14: CompileTimeError
|
||||
type_promotion_functions_test/none: CompileTimeError
|
||||
type_variable_scope_test/none: Fail # Issue 11578
|
||||
type_variable_static_context_negative_test: Fail # Issue 12161
|
||||
vm/debug_break_enabled_vm_test: Skip
|
||||
vm/debug_break_vm_test/*: Skip
|
||||
|
||||
@@ -459,8 +459,6 @@ partial_tearoff_instantiation_test/05: Crash # Assertion failure: kind=special,m
|
||||
partial_tearoff_instantiation_test/06: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
|
||||
partial_tearoff_instantiation_test/07: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
|
||||
partial_tearoff_instantiation_test/08: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
|
||||
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
|
||||
redirecting_factory_malbounded_test/01: MissingCompileTimeError
|
||||
regress_13462_1_test: RuntimeError
|
||||
regress_18535_test: RuntimeError
|
||||
type_literal_prefix_call_test/00: MissingCompileTimeError
|
||||
@@ -515,8 +513,6 @@ no_such_method_native_test: RuntimeError
|
||||
no_such_method_test: RuntimeError
|
||||
overridden_no_such_method_test: RuntimeError
|
||||
recursive_generic_test: RuntimeError
|
||||
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
|
||||
redirecting_factory_malbounded_test/01: MissingCompileTimeError
|
||||
regress_13462_1_test: RuntimeError
|
||||
regress_18535_test: RuntimeError
|
||||
regress_21795_test: RuntimeError # Issue 12605
|
||||
|
||||
@@ -39,7 +39,6 @@ constructor_reference_test/27: MissingCompileTimeError # Issue https://github.co
|
||||
covariance_field_test/03: RuntimeError
|
||||
covariant_override/tear_off_type_test: RuntimeError # Issue 28395
|
||||
covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
|
||||
default_implementation2_test: CompileTimeError # Issue 30855
|
||||
deferred_load_library_wrong_args_test/01: MissingRuntimeError, RuntimeError # Issue 29920
|
||||
double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddc
|
||||
dynamic_prefix_core_test/01: MissingCompileTimeError
|
||||
@@ -170,7 +169,6 @@ super_operator_index5_test: RuntimeError # 33470
|
||||
super_operator_index7_test: RuntimeError # 33470
|
||||
super_operator_index8_test: RuntimeError # 33470
|
||||
super_setter_test: CompileTimeError # Invalid test, see https://github.com/dart-lang/sdk/issues/33837
|
||||
switch_case_test/none: CompileTimeError
|
||||
syntax_test/60: MissingCompileTimeError
|
||||
syntax_test/61: MissingCompileTimeError
|
||||
truncdiv_test: RuntimeError # Issue 29920
|
||||
@@ -191,7 +189,6 @@ type_promotion_functions_test/12: CompileTimeError # Issue 30895
|
||||
type_promotion_functions_test/13: CompileTimeError # Issue 30895
|
||||
type_promotion_functions_test/14: CompileTimeError # Issue 30895
|
||||
type_promotion_functions_test/none: CompileTimeError # Issue 30895
|
||||
type_variable_scope_test/none: CompileTimeError
|
||||
void/return_future_future_or_void_async_error1_test/none: CompileTimeError # issue #34319
|
||||
void/return_future_or_future_or_void_sync_error2_test/none: CompileTimeError # issue #34319
|
||||
void/return_future_or_void_sync_error4_test/none: CompileTimeError # issue #34319
|
||||
@@ -351,8 +348,6 @@ multiline_newline_test/06: MissingCompileTimeError
|
||||
multiline_newline_test/06r: MissingCompileTimeError
|
||||
no_such_method_mock_test: RuntimeError # Issue 31426 - Kernel does not introduce nSM for implemented fields.
|
||||
null_no_such_method_test: CompileTimeError # Issue 31533
|
||||
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
|
||||
redirecting_factory_malbounded_test/01: MissingCompileTimeError
|
||||
redirecting_factory_reflection_test: RuntimeError # UnimplementedError: node <InvalidExpression> `invalid-expression`
|
||||
regress_23408_test: CompileTimeError # Issue 31533
|
||||
regress_24283_test: RuntimeError # Expect.equals(expected: <-1>, actual: <4294967295>) fails.
|
||||
|
||||
@@ -232,15 +232,10 @@ const_cast2_test/01: CompileTimeError # Issue 32517
|
||||
const_cast2_test/none: CompileTimeError # Issue 32517
|
||||
const_constructor_mixin3_test: CompileTimeError # Issue 33644.
|
||||
const_constructor_mixin_test: CompileTimeError # Issue 33644.
|
||||
const_types_test/34: MissingCompileTimeError # Issue 31590
|
||||
const_types_test/39: MissingCompileTimeError # Issue 31590
|
||||
constructor_reference_test/27: MissingCompileTimeError # Issue 34403
|
||||
default_factory2_test/01: MissingCompileTimeError # Issue 31590
|
||||
default_factory_test/01: MissingCompileTimeError # Issue 31590
|
||||
deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
|
||||
deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
|
||||
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
|
||||
deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
|
||||
duplicate_export_collision_test/01: MissingCompileTimeError # Issue 12916
|
||||
f_bounded_quantification_test/01: MissingCompileTimeError # Issue 33308
|
||||
f_bounded_quantification_test/02: MissingCompileTimeError # Issue 33308
|
||||
@@ -258,7 +253,6 @@ issue34488_test/06: MissingCompileTimeError # Issue 34488
|
||||
malbounded_instantiation_test/01: MissingCompileTimeError # Issue 33308
|
||||
malbounded_instantiation_test/02: MissingCompileTimeError # Issue 33308
|
||||
malbounded_instantiation_test/03: MissingCompileTimeError # Issue 33308
|
||||
malbounded_redirecting_factory_test/02: MissingCompileTimeError # Issue 33308
|
||||
malbounded_redirecting_factory_test/03: MissingCompileTimeError # Issue 33308
|
||||
malbounded_redirecting_factory_test/04: MissingCompileTimeError # Issue 33308
|
||||
malbounded_redirecting_factory_test/05: MissingCompileTimeError # Issue 33308
|
||||
@@ -341,7 +335,6 @@ type_variable_bounds_test/03: MissingCompileTimeError # Issue 33308
|
||||
type_variable_bounds_test/04: MissingCompileTimeError # Issue 33308
|
||||
type_variable_bounds_test/05: MissingCompileTimeError # Issue 33308
|
||||
type_variable_bounds_test/06: MissingCompileTimeError # Issue 33308
|
||||
type_variable_bounds_test/11: MissingCompileTimeError # Issue 33308
|
||||
vm/debug_break_enabled_vm_test/01: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
|
||||
vm/debug_break_enabled_vm_test/none: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
|
||||
vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
|
||||
@@ -689,8 +682,6 @@ null_test/mirrors: Skip # Uses mirrors.
|
||||
null_test/none: SkipByDesign
|
||||
overridden_no_such_method_test: SkipByDesign
|
||||
parser_quirks_test: CompileTimeError # Issue 31533
|
||||
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
|
||||
redirecting_factory_malbounded_test/01: MissingCompileTimeError
|
||||
redirecting_factory_reflection_test: SkipByDesign
|
||||
regress_13462_0_test: SkipByDesign
|
||||
regress_13462_1_test: SkipByDesign
|
||||
@@ -1255,8 +1246,6 @@ no_main_test/01: DartkCrash
|
||||
no_such_method_mock_test: RuntimeError # Issue 31426
|
||||
null_no_such_method_test: CompileTimeError # Issue 31533
|
||||
parser_quirks_test: CompileTimeError # Issue 31533
|
||||
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
|
||||
redirecting_factory_malbounded_test/01: MissingCompileTimeError
|
||||
regress_22443_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
|
||||
regress_23408_test: RuntimeError, CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
|
||||
regress_29025_test: CompileTimeError # Issue 31402 (Variable declaration)
|
||||
@@ -1303,8 +1292,6 @@ assertion_initializer_const_error2_test/cc10: Pass # Works in --checked mode but
|
||||
|
||||
[ $fasta && $strong ]
|
||||
issue18628_2_test/01: MissingCompileTimeError
|
||||
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
|
||||
redirecting_factory_malbounded_test/01: MissingCompileTimeError
|
||||
type_promotion_logical_and_test/01: MissingCompileTimeError
|
||||
|
||||
[ $fasta && !$strong ]
|
||||
|
||||
@@ -17,19 +17,19 @@ class B implements A {
|
||||
operator ==(o) => true; // //# 00: compile-time error
|
||||
}
|
||||
|
||||
class C implements A {
|
||||
class C implements D {
|
||||
final int x;
|
||||
const C() : x = 0;
|
||||
const C.fromD() : x = 1;
|
||||
}
|
||||
|
||||
class D implements C {
|
||||
class D implements A {
|
||||
int get x => 0;
|
||||
const factory D() = C.fromD;
|
||||
}
|
||||
|
||||
main() {
|
||||
switch (new B()) {
|
||||
switch (new B()) {
|
||||
case const A.B(): Expect.fail("bad switch"); break; // //# 00: continued
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
// Test that type variables referenced from within static members are malformed.
|
||||
|
||||
class Foo<T> {
|
||||
class Foo<T> implements I<T> {
|
||||
Foo() {}
|
||||
|
||||
static
|
||||
|
||||
@@ -165,9 +165,6 @@ async/future_or_only_in_async_test/00: MissingCompileTimeError
|
||||
async/multiple_timer_test: Pass, Fail # Timing related
|
||||
isolate/issue_24243_parent_isolate_test: SkipByDesign # Requires type checks.
|
||||
|
||||
[ !$fasta && $strong ]
|
||||
mirrors/redirecting_factory_test: CompileTimeError # Issue 30855
|
||||
|
||||
[ !$fasta && !$strong ]
|
||||
isolate/isolate_import_test/01: MissingCompileTimeError
|
||||
mirrors/top_level_accessors_test/01: MissingCompileTimeError
|
||||
|
||||
@@ -12,6 +12,4 @@ mirrors/generic_f_bounded_mixin_application_test: CompileTimeError
|
||||
mirrors/mirrors_nsm_mismatch_test: CompileTimeError, OK
|
||||
mirrors/mirrors_nsm_test: CompileTimeError, OK
|
||||
mirrors/mirrors_nsm_test/dart2js: CompileTimeError, OK
|
||||
mirrors/redirecting_factory_test/01: StaticWarning # test issue X, The return type 'Class<T2, T1>' of the redirected constructor is not assignable to 'Class<T1, T2>'
|
||||
mirrors/redirecting_factory_test/none: StaticWarning # test issue X, The return type 'Class<T2, T1>' of the redirected constructor is not assignable to 'Class<T1, T2>
|
||||
mirrors/repeated_private_anon_mixin_app_test: CompileTimeError, OK # Intentional library name conflict.
|
||||
|
||||
@@ -98,8 +98,6 @@ mirrors/mirrors_nsm_mismatch_test: CompileTimeError
|
||||
mirrors/mirrors_nsm_test/dart2js: CompileTimeError
|
||||
mirrors/mirrors_nsm_test/none: CompileTimeError
|
||||
mirrors/native_class_test: CompileTimeError
|
||||
mirrors/redirecting_factory_different_type_test/01: MissingCompileTimeError
|
||||
mirrors/redirecting_factory_different_type_test/02: MissingCompileTimeError
|
||||
|
||||
[ $mode == debug && $runtime == vm && $strong && ($compiler == dartk || $compiler == dartkb) ]
|
||||
mirrors/other_declarations_location_test: Crash # Issue 33325 (assertion error, TypeParameter not having position).
|
||||
@@ -183,9 +181,7 @@ mirrors/other_declarations_location_test: RuntimeError # Issue 33325 (no source
|
||||
mirrors/parameter_of_mixin_app_constructor_test: RuntimeError # Issue 31402 (Invocation arguments)
|
||||
mirrors/private_symbol_test: RuntimeError # Issue 33326 - CFE/kernel invalid typedef substitution
|
||||
mirrors/private_types_test: RuntimeError # Issue 33326 - CFE/kernel invalid typedef substitution
|
||||
mirrors/redirecting_factory_different_type_test/01: MissingCompileTimeError
|
||||
mirrors/redirecting_factory_test/01: RuntimeError
|
||||
mirrors/redirecting_factory_test/02: RuntimeError
|
||||
mirrors/redirecting_factory_test/none: RuntimeError
|
||||
mirrors/reflect_class_test/none: RuntimeError
|
||||
mirrors/reflected_type_function_type_test: RuntimeError
|
||||
@@ -287,7 +283,6 @@ mirrors/invoke_closurization2_test: RuntimeError
|
||||
mirrors/invoke_throws_test: RuntimeError
|
||||
mirrors/mixin_members_test: RuntimeError
|
||||
mirrors/operator_test: RuntimeError
|
||||
mirrors/redirecting_factory_different_type_test/02: MissingCompileTimeError
|
||||
mirrors/redirecting_factory_different_type_test/none: RuntimeError
|
||||
mirrors/redirecting_factory_reflection_test: RuntimeError
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ mirrors/metadata_nested_constructor_call_test/none: CompileTimeError
|
||||
mirrors/mirrors_used*: SkipByDesign # Invalid tests. MirrorsUsed does not have a specification, and dart:mirrors is not required to hide declarations that are not covered by any MirrorsUsed annotation.
|
||||
mirrors/native_class_test: SkipByDesign # Imports dart:html
|
||||
mirrors/redirecting_factory_different_type_test/01: MissingCompileTimeError
|
||||
mirrors/redirecting_factory_test/01: RuntimeError
|
||||
mirrors/redirecting_factory_test/none: RuntimeError
|
||||
|
||||
[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $runtime == vm && !$checked ]
|
||||
mirrors/inference_and_no_such_method_test: RuntimeError
|
||||
@@ -41,6 +43,11 @@ mirrors/inference_and_no_such_method_test: RuntimeError
|
||||
[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $runtime == vm && $strong ]
|
||||
async/future_or_only_in_async_test/00: MissingCompileTimeError
|
||||
|
||||
[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkb && $runtime == vm && !$strong ]
|
||||
mirrors/redirecting_factory_test/02: MissingCompileTimeError
|
||||
mirrors/redirecting_factory_test/03: MissingCompileTimeError
|
||||
mirrors/redirecting_factory_test/04: MissingCompileTimeError
|
||||
|
||||
[ $compiler != dartk && $compiler != dartkb && $runtime == vm && !$strong ]
|
||||
mirrors/reflect_class_test/01: MissingCompileTimeError
|
||||
mirrors/reflect_class_test/02: MissingCompileTimeError
|
||||
|
||||
@@ -38,18 +38,20 @@ class Class<T1, T2> {
|
||||
factory Class.redirectingFactoryMoreUnnamedOptional(a, [b]) =
|
||||
Class<T1, T2>.factoryMoreUnnamedOptional;
|
||||
|
||||
factory Class.redirectingFactoryStringIntTypeParameters(a, b) =
|
||||
Class<String, int>.factoryNoOptional;
|
||||
factory Class.redirectingFactoryStringIntTypeParameters(a, b) = Class //
|
||||
<String, int> //# 03: compile-time error
|
||||
.factoryNoOptional;
|
||||
|
||||
factory Class.redirectingFactoryStringTypeParameters(a, b) = Class //
|
||||
<String> //# 02: static type warning
|
||||
<String> //# 02: compile-time error
|
||||
.factoryNoOptional;
|
||||
|
||||
factory Class.redirectingFactoryTypeParameters(a, b) =
|
||||
Class<T1, T2>.factoryNoOptional;
|
||||
|
||||
factory Class.redirectingFactoryReversedTypeParameters(a, b) =
|
||||
Class<T2, T1>.factoryNoOptional;
|
||||
factory Class.redirectingFactoryReversedTypeParameters(a, b) = Class //
|
||||
<T2, T1> //# 04: compile-time error
|
||||
.factoryNoOptional;
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
Reference in New Issue
Block a user