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:
Daniel Hillerström
2018-09-19 06:20:20 +00:00
committed by commit-bot@chromium.org
parent 4134b95a3d
commit de984e58cb
25 changed files with 689 additions and 63 deletions
@@ -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;
+82 -1
View File
@@ -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>;
}
+3 -2
View File
@@ -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 ]
+1
View File
@@ -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
-2
View File
@@ -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.
-13
View File
@@ -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 ]
+3 -3
View File
@@ -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
-3
View File
@@ -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
-2
View File
@@ -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.
-5
View File
@@ -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
+7
View File
@@ -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() {