mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:29:47 +00:00
[cfe] Infer type arguments for explicit extension application
Change-Id: I52d97abf85eadea679f2a48563f575eca1fd8436 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115140 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
parent
9f57cf71d7
commit
c50621a560
|
@ -3525,6 +3525,31 @@ class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
}
|
||||
}
|
||||
|
||||
Expression buildExtensionMethodInvocation(
|
||||
int fileOffset, Procedure target, Arguments arguments) {
|
||||
// TODO(johnniwinther): Check type argument count.
|
||||
List<TypeParameter> typeParameters = target.function.typeParameters;
|
||||
LocatedMessage argMessage = checkArgumentsForFunction(
|
||||
target.function, arguments, fileOffset, typeParameters);
|
||||
if (argMessage != null) {
|
||||
return wrapSyntheticExpression(
|
||||
throwNoSuchMethodError(
|
||||
forest.createNullLiteral(null)..fileOffset = fileOffset,
|
||||
target.name.name,
|
||||
arguments,
|
||||
fileOffset,
|
||||
candidate: target,
|
||||
message: argMessage),
|
||||
fileOffset);
|
||||
}
|
||||
|
||||
StaticInvocation node = new StaticInvocation(target, arguments)
|
||||
..fileOffset = fileOffset;
|
||||
// TODO(johnniwinther): Check type argument bounds.
|
||||
//libraryBuilder.checkBoundsInStaticInvocation(node, typeEnvironment, uri);
|
||||
return node;
|
||||
}
|
||||
|
||||
@override
|
||||
LocatedMessage checkArgumentsForFunction(FunctionNode function,
|
||||
Arguments arguments, int offset, List<TypeParameter> typeParameters) {
|
||||
|
|
|
@ -1659,6 +1659,20 @@ class ExtensionInstanceAccessGenerator extends Generator {
|
|||
@override
|
||||
String get _plainNameForRead => (readTarget ?? writeTarget).name.name;
|
||||
|
||||
int get _extensionTypeParameterCount => extensionTypeParameters?.length ?? 0;
|
||||
|
||||
List<DartType> _createExtensionTypeArguments() {
|
||||
List<DartType> extensionTypeArguments = const <DartType>[];
|
||||
if (extensionTypeParameters != null) {
|
||||
extensionTypeArguments = [];
|
||||
for (TypeParameter typeParameter in extensionTypeParameters) {
|
||||
extensionTypeArguments
|
||||
.add(_forest.createTypeParameterType(typeParameter));
|
||||
}
|
||||
}
|
||||
return extensionTypeArguments;
|
||||
}
|
||||
|
||||
@override
|
||||
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
|
||||
Expression read;
|
||||
|
@ -1668,19 +1682,15 @@ class ExtensionInstanceAccessGenerator extends Generator {
|
|||
read = _helper.desugarSyntheticExpression(read);
|
||||
}
|
||||
} else {
|
||||
List<DartType> typeArguments;
|
||||
if (extensionTypeParameters != null) {
|
||||
typeArguments = [];
|
||||
for (TypeParameter typeParameter in extensionTypeParameters) {
|
||||
typeArguments.add(_forest.createTypeParameterType(typeParameter));
|
||||
}
|
||||
}
|
||||
read = _helper.buildStaticInvocation(
|
||||
read = _helper.buildExtensionMethodInvocation(
|
||||
fileOffset,
|
||||
readTarget,
|
||||
_helper.forest.createArguments(fileOffset,
|
||||
[_helper.createVariableGet(extensionThis, fileOffset)],
|
||||
types: typeArguments),
|
||||
charOffset: fileOffset);
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
fileOffset,
|
||||
_extensionTypeParameterCount,
|
||||
0,
|
||||
_helper.createVariableGet(extensionThis, fileOffset),
|
||||
extensionTypeArguments: _createExtensionTypeArguments()));
|
||||
}
|
||||
complexAssignment?.read = read;
|
||||
return read;
|
||||
|
@ -1696,19 +1706,16 @@ class ExtensionInstanceAccessGenerator extends Generator {
|
|||
write = _helper.desugarSyntheticExpression(write);
|
||||
}
|
||||
} else {
|
||||
List<DartType> typeArguments;
|
||||
if (extensionTypeParameters != null) {
|
||||
typeArguments = [];
|
||||
for (TypeParameter typeParameter in extensionTypeParameters) {
|
||||
typeArguments.add(_forest.createTypeParameterType(typeParameter));
|
||||
}
|
||||
}
|
||||
write = _helper.buildStaticInvocation(
|
||||
write = _helper.buildExtensionMethodInvocation(
|
||||
fileOffset,
|
||||
writeTarget,
|
||||
_helper.forest.createArguments(fileOffset,
|
||||
[_helper.createVariableGet(extensionThis, fileOffset), value],
|
||||
types: typeArguments),
|
||||
charOffset: token.charOffset);
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
fileOffset,
|
||||
_extensionTypeParameterCount,
|
||||
0,
|
||||
_helper.createVariableGet(extensionThis, fileOffset),
|
||||
extensionTypeArguments: _createExtensionTypeArguments(),
|
||||
positionalArguments: [value]));
|
||||
}
|
||||
complexAssignment?.write = write;
|
||||
write.fileOffset = fileOffset;
|
||||
|
@ -1718,26 +1725,19 @@ class ExtensionInstanceAccessGenerator extends Generator {
|
|||
@override
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
if (invokeTarget != null) {
|
||||
List<Expression> positionalArguments = [
|
||||
_helper.createVariableGet(extensionThis, offset)
|
||||
]..addAll(arguments.positional);
|
||||
List<DartType> typeArguments;
|
||||
if (extensionTypeParameters != null) {
|
||||
typeArguments = [];
|
||||
for (TypeParameter typeParameter in extensionTypeParameters) {
|
||||
typeArguments.add(_forest.createTypeParameterType(typeParameter));
|
||||
}
|
||||
if (arguments.types.isNotEmpty) {
|
||||
typeArguments.addAll(arguments.types);
|
||||
}
|
||||
} else if (arguments.types.isNotEmpty) {
|
||||
typeArguments = arguments.types;
|
||||
}
|
||||
return _helper.buildStaticInvocation(
|
||||
return _helper.buildExtensionMethodInvocation(
|
||||
offset,
|
||||
invokeTarget,
|
||||
_forest.createArguments(fileOffset, positionalArguments,
|
||||
named: arguments.named, types: typeArguments),
|
||||
charOffset: offset);
|
||||
_forest.createArgumentsForExtensionMethod(
|
||||
fileOffset,
|
||||
_extensionTypeParameterCount,
|
||||
invokeTarget.function.typeParameters.length -
|
||||
_extensionTypeParameterCount,
|
||||
_helper.createVariableGet(extensionThis, offset),
|
||||
extensionTypeArguments: _createExtensionTypeArguments(),
|
||||
typeArguments: arguments.types,
|
||||
positionalArguments: arguments.positional,
|
||||
namedArguments: arguments.named));
|
||||
} else {
|
||||
return _helper.buildMethodInvocation(buildSimpleRead(), callName,
|
||||
arguments, adjustForImplicitCall(_plainNameForRead, offset),
|
||||
|
@ -1879,6 +1879,10 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
|
|||
@override
|
||||
String get _plainNameForRead => (readTarget ?? writeTarget).name.name;
|
||||
|
||||
List<DartType> _createExtensionTypeArguments() {
|
||||
return explicitTypeArguments ?? const <DartType>[];
|
||||
}
|
||||
|
||||
@override
|
||||
Expression _makeRead(ComplexAssignmentJudgment complexAssignment) {
|
||||
Expression read;
|
||||
|
@ -1888,11 +1892,12 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
|
|||
read = _helper.desugarSyntheticExpression(read);
|
||||
}
|
||||
} else {
|
||||
read = _helper.buildStaticInvocation(
|
||||
read = _helper.buildExtensionMethodInvocation(
|
||||
fileOffset,
|
||||
readTarget,
|
||||
_helper.forest.createArguments(fileOffset, [receiver],
|
||||
types: explicitTypeArguments),
|
||||
charOffset: fileOffset);
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
fileOffset, extensionTypeParameterCount, 0, receiver,
|
||||
extensionTypeArguments: _createExtensionTypeArguments()));
|
||||
}
|
||||
complexAssignment?.read = read;
|
||||
return read;
|
||||
|
@ -1908,11 +1913,13 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
|
|||
write = _helper.desugarSyntheticExpression(write);
|
||||
}
|
||||
} else {
|
||||
write = _helper.buildStaticInvocation(
|
||||
write = _helper.buildExtensionMethodInvocation(
|
||||
fileOffset,
|
||||
writeTarget,
|
||||
_helper.forest.createArguments(fileOffset, [receiver, value],
|
||||
types: explicitTypeArguments),
|
||||
charOffset: token.charOffset);
|
||||
_helper.forest.createArgumentsForExtensionMethod(
|
||||
fileOffset, extensionTypeParameterCount, 0, receiver,
|
||||
extensionTypeArguments: _createExtensionTypeArguments(),
|
||||
positionalArguments: [value]));
|
||||
}
|
||||
complexAssignment?.write = write;
|
||||
write.fileOffset = fileOffset;
|
||||
|
@ -1922,22 +1929,19 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
|
|||
@override
|
||||
Expression doInvocation(int offset, Arguments arguments) {
|
||||
if (invokeTarget != null) {
|
||||
List<Expression> positionalArguments = [receiver]
|
||||
..addAll(arguments.positional);
|
||||
List<DartType> typeArguments;
|
||||
if (explicitTypeArguments != null) {
|
||||
typeArguments = []..addAll(explicitTypeArguments);
|
||||
if (arguments.types.isNotEmpty) {
|
||||
typeArguments.addAll(arguments.types);
|
||||
}
|
||||
} else if (arguments.types.isNotEmpty) {
|
||||
typeArguments = arguments.types;
|
||||
}
|
||||
return _helper.buildStaticInvocation(
|
||||
return _helper.buildExtensionMethodInvocation(
|
||||
fileOffset,
|
||||
invokeTarget,
|
||||
_forest.createArguments(fileOffset, positionalArguments,
|
||||
named: arguments.named, types: typeArguments),
|
||||
charOffset: offset);
|
||||
_forest.createArgumentsForExtensionMethod(
|
||||
fileOffset,
|
||||
extensionTypeParameterCount,
|
||||
invokeTarget.function.typeParameters.length -
|
||||
extensionTypeParameterCount,
|
||||
receiver,
|
||||
extensionTypeArguments: _createExtensionTypeArguments(),
|
||||
typeArguments: arguments.types,
|
||||
positionalArguments: arguments.positional,
|
||||
namedArguments: arguments.named));
|
||||
} else {
|
||||
return _helper.buildMethodInvocation(buildSimpleRead(), callName,
|
||||
arguments, adjustForImplicitCall(_plainNameForRead, offset),
|
||||
|
@ -1968,7 +1972,7 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
|
|||
/// extension B on A<int> {
|
||||
/// method() {}
|
||||
/// }
|
||||
/// extension C<T> {
|
||||
/// extension C<T> on A<T> {
|
||||
/// T get field => 0;
|
||||
/// set field(T _) {}
|
||||
/// }
|
||||
|
|
|
@ -83,6 +83,9 @@ abstract class ExpressionGeneratorHelper implements InferenceHelper {
|
|||
Expression buildStaticInvocation(Procedure target, Arguments arguments,
|
||||
{Constness constness, int charOffset});
|
||||
|
||||
Expression buildExtensionMethodInvocation(
|
||||
int fileOffset, Procedure target, Arguments arguments);
|
||||
|
||||
Expression throwNoSuchMethodError(
|
||||
Expression receiver, String name, Arguments arguments, int offset,
|
||||
{Member candidate,
|
||||
|
|
|
@ -67,6 +67,21 @@ class Forest {
|
|||
..fileOffset = fileOffset ?? TreeNode.noOffset;
|
||||
}
|
||||
|
||||
Arguments createArgumentsForExtensionMethod(int fileOffset,
|
||||
int extensionTypeParameterCount, typeParameterCount, Expression receiver,
|
||||
{List<DartType> extensionTypeArguments = const <DartType>[],
|
||||
List<DartType> typeArguments = const <DartType>[],
|
||||
List<Expression> positionalArguments = const <Expression>[],
|
||||
List<NamedExpression> namedArguments = const <NamedExpression>[]}) {
|
||||
return new ArgumentsJudgment.forExtensionMethod(
|
||||
extensionTypeParameterCount, typeParameterCount, receiver,
|
||||
extensionTypeArguments: extensionTypeArguments,
|
||||
typeArguments: typeArguments,
|
||||
positionalArguments: positionalArguments,
|
||||
namedArguments: namedArguments)
|
||||
..fileOffset = fileOffset ?? TreeNode.noOffset;
|
||||
}
|
||||
|
||||
Arguments createArgumentsEmpty(int fileOffset) {
|
||||
return createArguments(fileOffset, <Expression>[]);
|
||||
}
|
||||
|
|
|
@ -1709,8 +1709,12 @@ class InferenceVisitor
|
|||
replacement = inferrer.helper.forest.createStaticInvocation(
|
||||
node.fileOffset,
|
||||
writeTarget.member,
|
||||
inferrer.helper.forest.createArguments(
|
||||
node.fileOffset, [node.receiver, node.rhs])));
|
||||
inferrer.helper.forest.createArgumentsForExtensionMethod(
|
||||
node.fileOffset,
|
||||
writeTarget.extensionTypeParameterCount,
|
||||
0,
|
||||
node.receiver,
|
||||
positionalArguments: [node.rhs])));
|
||||
inferrer.storeInferredType(replacement, inferredType);
|
||||
} else {
|
||||
node._replaceWithDesugared();
|
||||
|
|
|
@ -109,9 +109,50 @@ InterfaceType computeConstructorReturnType(Member constructor) {
|
|||
}
|
||||
}
|
||||
|
||||
int getExtensionTypeParameterCount(Arguments arguments) {
|
||||
if (arguments is ArgumentsJudgment) {
|
||||
return arguments._extensionTypeParameterCount;
|
||||
} else {
|
||||
// TODO(johnniwinther): Remove this path or assert why it is accepted.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int getExtensionTypeArgumentCount(Arguments arguments) {
|
||||
if (arguments is ArgumentsJudgment) {
|
||||
return arguments._extensionTypeArgumentCount;
|
||||
} else {
|
||||
// TODO(johnniwinther): Remove this path or assert why it is accepted.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
List<DartType> getExplicitExtensionTypeArguments(Arguments arguments) {
|
||||
if (arguments is ArgumentsJudgment) {
|
||||
if (arguments._extensionTypeArgumentCount == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return arguments.types
|
||||
.take(arguments._extensionTypeArgumentCount)
|
||||
.toList();
|
||||
}
|
||||
} else {
|
||||
// TODO(johnniwinther): Remove this path or assert why it is accepted.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
List<DartType> getExplicitTypeArguments(Arguments arguments) {
|
||||
if (arguments is ArgumentsJudgment) {
|
||||
return arguments._hasExplicitTypeArguments ? arguments.types : null;
|
||||
if (arguments._explicitTypeArgumentCount == 0) {
|
||||
return null;
|
||||
} else if (arguments._extensionTypeParameterCount == 0) {
|
||||
return arguments.types;
|
||||
} else {
|
||||
return arguments.types
|
||||
.skip(arguments._extensionTypeParameterCount)
|
||||
.toList();
|
||||
}
|
||||
} else {
|
||||
// This code path should only be taken in situations where there are no
|
||||
// type arguments at all, e.g. calling a user-definable operator.
|
||||
|
@ -140,25 +181,61 @@ class ClassInferenceInfo {
|
|||
|
||||
/// Concrete shadow object representing a set of invocation arguments.
|
||||
class ArgumentsJudgment extends Arguments {
|
||||
bool _hasExplicitTypeArguments;
|
||||
// TODO(johnniwinther): Move this to the static invocation instead.
|
||||
final int _extensionTypeParameterCount;
|
||||
|
||||
final int _extensionTypeArgumentCount;
|
||||
|
||||
int _explicitTypeArgumentCount;
|
||||
|
||||
List<Expression> get positionalJudgments => positional.cast();
|
||||
|
||||
ArgumentsJudgment(List<Expression> positional,
|
||||
{List<DartType> types, List<NamedExpression> named})
|
||||
: _hasExplicitTypeArguments = types != null && types.isNotEmpty,
|
||||
: _explicitTypeArgumentCount = types?.length ?? 0,
|
||||
_extensionTypeParameterCount = 0,
|
||||
_extensionTypeArgumentCount = 0,
|
||||
super(positional, types: types, named: named);
|
||||
|
||||
ArgumentsJudgment.forExtensionMethod(int extensionTypeParameterCount,
|
||||
int typeParameterCount, Expression receiver,
|
||||
{List<DartType> extensionTypeArguments = const <DartType>[],
|
||||
List<DartType> typeArguments = const <DartType>[],
|
||||
List<Expression> positionalArguments = const <Expression>[],
|
||||
List<NamedExpression> namedArguments = const <NamedExpression>[]})
|
||||
: _extensionTypeParameterCount = extensionTypeParameterCount,
|
||||
_extensionTypeArgumentCount = extensionTypeArguments.length,
|
||||
_explicitTypeArgumentCount = typeArguments.length,
|
||||
assert(
|
||||
extensionTypeArguments.isEmpty ||
|
||||
extensionTypeArguments.length == extensionTypeParameterCount,
|
||||
"Extension type arguments must be empty or complete."),
|
||||
super(<Expression>[receiver]..addAll(positionalArguments),
|
||||
named: namedArguments,
|
||||
types: <DartType>[]
|
||||
..addAll(_normalizeTypeArguments(
|
||||
extensionTypeParameterCount, extensionTypeArguments))
|
||||
..addAll(
|
||||
_normalizeTypeArguments(typeParameterCount, typeArguments)));
|
||||
|
||||
static List<DartType> _normalizeTypeArguments(
|
||||
int length, List<DartType> arguments) {
|
||||
if (arguments.isEmpty && length > 0) {
|
||||
return new List<DartType>.filled(length, const UnknownType());
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
static void setNonInferrableArgumentTypes(
|
||||
ArgumentsJudgment arguments, List<DartType> types) {
|
||||
arguments.types.clear();
|
||||
arguments.types.addAll(types);
|
||||
arguments._hasExplicitTypeArguments = true;
|
||||
arguments._explicitTypeArgumentCount = types.length;
|
||||
}
|
||||
|
||||
static void removeNonInferrableArgumentTypes(ArgumentsJudgment arguments) {
|
||||
arguments.types.clear();
|
||||
arguments._hasExplicitTypeArguments = false;
|
||||
arguments._explicitTypeArgumentCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE.md file.
|
||||
|
||||
import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
|
||||
import 'package:kernel/ast.dart' as kernel;
|
||||
|
||||
import 'package:kernel/ast.dart'
|
||||
|
@ -49,7 +50,8 @@ import 'package:kernel/ast.dart'
|
|||
TypeParameterType,
|
||||
VariableDeclaration,
|
||||
VariableGet,
|
||||
VoidType;
|
||||
VoidType,
|
||||
setParents;
|
||||
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
|
||||
|
@ -108,7 +110,8 @@ import '../kernel/kernel_shadow_ast.dart'
|
|||
ShadowTypeInferenceEngine,
|
||||
ShadowTypeInferrer,
|
||||
VariableDeclarationJudgment,
|
||||
getExplicitTypeArguments;
|
||||
getExplicitTypeArguments,
|
||||
getExtensionTypeParameterCount;
|
||||
|
||||
import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
|
||||
|
||||
|
@ -1320,9 +1323,96 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
this.helper = null;
|
||||
}
|
||||
|
||||
DartType inferInvocation(DartType typeContext, int offset,
|
||||
FunctionType calleeType, DartType returnType, Arguments arguments,
|
||||
{bool isOverloadedArithmeticOperator: false,
|
||||
DartType receiverType,
|
||||
bool skipTypeArgumentInference: false,
|
||||
bool isConst: false}) {
|
||||
int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
|
||||
if (extensionTypeParameterCount != 0) {
|
||||
return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
|
||||
typeContext, offset, calleeType, returnType, arguments,
|
||||
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
|
||||
receiverType: receiverType,
|
||||
skipTypeArgumentInference: skipTypeArgumentInference,
|
||||
isConst: isConst);
|
||||
}
|
||||
return _inferInvocation(
|
||||
typeContext, offset, calleeType, returnType, arguments,
|
||||
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
|
||||
receiverType: receiverType,
|
||||
skipTypeArgumentInference: skipTypeArgumentInference,
|
||||
isConst: isConst);
|
||||
}
|
||||
|
||||
DartType _inferGenericExtensionMethodInvocation(
|
||||
int extensionTypeParameterCount,
|
||||
DartType typeContext,
|
||||
int offset,
|
||||
FunctionType calleeType,
|
||||
DartType returnType,
|
||||
Arguments arguments,
|
||||
{bool isOverloadedArithmeticOperator: false,
|
||||
DartType receiverType,
|
||||
bool skipTypeArgumentInference: false,
|
||||
bool isConst: false}) {
|
||||
FunctionType extensionFunctionType = new FunctionType(
|
||||
[calleeType.positionalParameters.first], const DynamicType(),
|
||||
requiredParameterCount: 1,
|
||||
typeParameters: calleeType.typeParameters
|
||||
.take(extensionTypeParameterCount)
|
||||
.toList());
|
||||
Arguments extensionArguments = helper.forest.createArguments(
|
||||
arguments.fileOffset, [arguments.positional.first],
|
||||
types: getExplicitExtensionTypeArguments(arguments));
|
||||
_inferInvocation(null, offset, extensionFunctionType, const DynamicType(),
|
||||
extensionArguments,
|
||||
skipTypeArgumentInference: skipTypeArgumentInference);
|
||||
Substitution extensionSubstitution = Substitution.fromPairs(
|
||||
extensionFunctionType.typeParameters, extensionArguments.types);
|
||||
List<TypeParameter> targetTypeParameters = const <TypeParameter>[];
|
||||
if (calleeType.typeParameters.length > extensionTypeParameterCount) {
|
||||
targetTypeParameters =
|
||||
calleeType.typeParameters.skip(extensionTypeParameterCount).toList();
|
||||
}
|
||||
FunctionType targetFunctionType = new FunctionType(
|
||||
calleeType.positionalParameters.skip(1).toList(), calleeType.returnType,
|
||||
requiredParameterCount: calleeType.requiredParameterCount - 1,
|
||||
namedParameters: calleeType.namedParameters,
|
||||
typeParameters: targetTypeParameters);
|
||||
targetFunctionType =
|
||||
extensionSubstitution.substituteType(targetFunctionType);
|
||||
DartType targetReturnType =
|
||||
extensionSubstitution.substituteType(returnType);
|
||||
DartType targetReceiverType = receiverType != null
|
||||
? extensionSubstitution.substituteType(receiverType)
|
||||
: null;
|
||||
Arguments targetArguments = helper.forest.createArguments(
|
||||
arguments.fileOffset, arguments.positional.skip(1).toList(),
|
||||
named: arguments.named, types: getExplicitTypeArguments(arguments));
|
||||
DartType inferredType = _inferInvocation(typeContext, offset,
|
||||
targetFunctionType, targetReturnType, targetArguments,
|
||||
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
|
||||
receiverType: targetReceiverType,
|
||||
skipTypeArgumentInference: skipTypeArgumentInference,
|
||||
isConst: isConst);
|
||||
arguments.positional.clear();
|
||||
arguments.positional.addAll(extensionArguments.positional);
|
||||
arguments.positional.addAll(targetArguments.positional);
|
||||
setParents(arguments.positional, arguments);
|
||||
// The `targetArguments.named` is the same list as `arguments.named` so
|
||||
// we just need to ensure that parent relations are realigned.
|
||||
setParents(arguments.named, arguments);
|
||||
arguments.types.clear();
|
||||
arguments.types.addAll(extensionArguments.types);
|
||||
arguments.types.addAll(targetArguments.types);
|
||||
return inferredType;
|
||||
}
|
||||
|
||||
/// Performs the type inference steps that are shared by all kinds of
|
||||
/// invocations (constructors, instance methods, and static methods).
|
||||
DartType inferInvocation(DartType typeContext, int offset,
|
||||
DartType _inferInvocation(DartType typeContext, int offset,
|
||||
FunctionType calleeType, DartType returnType, Arguments arguments,
|
||||
{bool isOverloadedArithmeticOperator: false,
|
||||
DartType receiverType,
|
||||
|
@ -1724,15 +1814,21 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
expression);
|
||||
Expression replacement;
|
||||
if (target.isExtensionMember) {
|
||||
Procedure procedure = target.member;
|
||||
expression.parent.replaceChild(
|
||||
expression,
|
||||
replacement = helper.forest.createStaticInvocation(
|
||||
expression.fileOffset,
|
||||
target.member,
|
||||
arguments = helper.forest.createArguments(
|
||||
arguments.fileOffset, [receiver, ...arguments.positional],
|
||||
named: arguments.named,
|
||||
types: getExplicitTypeArguments(arguments))));
|
||||
arguments = helper.forest.createArgumentsForExtensionMethod(
|
||||
arguments.fileOffset,
|
||||
target.extensionTypeParameterCount,
|
||||
procedure.function.typeParameters.length -
|
||||
target.extensionTypeParameterCount,
|
||||
receiver,
|
||||
positionalArguments: arguments.positional,
|
||||
namedArguments: arguments.named,
|
||||
typeArguments: arguments.types)));
|
||||
}
|
||||
DartType inferredType = inferInvocation(typeContext, fileOffset,
|
||||
functionType, functionType.returnType, arguments,
|
||||
|
@ -1861,7 +1957,8 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
replacement = expression = helper.forest.createStaticInvocation(
|
||||
fileOffset,
|
||||
readTarget.member,
|
||||
helper.forest.createArguments(fileOffset, [receiver])));
|
||||
helper.forest.createArgumentsForExtensionMethod(fileOffset,
|
||||
readTarget.extensionTypeParameterCount, 0, receiver)));
|
||||
break;
|
||||
case kernel.ProcedureKind.Method:
|
||||
expression.parent.replaceChild(
|
||||
|
@ -1869,7 +1966,8 @@ abstract class TypeInferrerImpl extends TypeInferrer {
|
|||
replacement = expression = helper.forest.createStaticInvocation(
|
||||
fileOffset,
|
||||
readTarget.tearoffTarget,
|
||||
helper.forest.createArguments(fileOffset, [receiver])));
|
||||
helper.forest.createArgumentsForExtensionMethod(fileOffset,
|
||||
readTarget.extensionTypeParameterCount, 0, receiver)));
|
||||
break;
|
||||
case kernel.ProcedureKind.Setter:
|
||||
case kernel.ProcedureKind.Factory:
|
||||
|
|
|
@ -2129,6 +2129,7 @@ reading
|
|||
reads
|
||||
ready
|
||||
real
|
||||
realigned
|
||||
realized
|
||||
really
|
||||
reason
|
||||
|
@ -2193,6 +2194,7 @@ relate
|
|||
related
|
||||
relation
|
||||
relational
|
||||
relations
|
||||
relationship
|
||||
relationships
|
||||
relative
|
||||
|
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
class A {}
|
||||
class B extends A {}
|
||||
class C extends B {}
|
||||
|
||||
class GenericClass<T> {}
|
||||
|
||||
extension GenericExtension<T> on GenericClass<T> {
|
||||
T get property => null;
|
||||
|
||||
T method(T t) => null;
|
||||
|
||||
S genericMethod1<S>(S s) => null;
|
||||
}
|
||||
|
||||
main() {
|
||||
A aVariable;
|
||||
C cVariable;
|
||||
|
||||
GenericClass<A> aClass;
|
||||
GenericClass<B> bClass;
|
||||
GenericClass<C> cClass;
|
||||
|
||||
cVariable = GenericExtension(aClass).property;
|
||||
cVariable = GenericExtension<A>(aClass).property;
|
||||
cVariable = GenericExtension<B>(aClass).property;
|
||||
cVariable = GenericExtension<C>(aClass).property;
|
||||
|
||||
cVariable = GenericExtension(bClass).property;
|
||||
cVariable = GenericExtension<A>(bClass).property;
|
||||
cVariable = GenericExtension<B>(bClass).property;
|
||||
cVariable = GenericExtension<C>(bClass).property;
|
||||
|
||||
aVariable = GenericExtension(cClass).property;
|
||||
aVariable = GenericExtension<A>(cClass).property;
|
||||
aVariable = GenericExtension<B>(cClass).property;
|
||||
aVariable = GenericExtension<C>(cClass).property;
|
||||
|
||||
cVariable = GenericExtension(aClass).method(aVariable);
|
||||
cVariable = GenericExtension<A>(aClass).method(aVariable);
|
||||
cVariable = GenericExtension<B>(aClass).method(aVariable);
|
||||
cVariable = GenericExtension<C>(aClass).method(aVariable);
|
||||
|
||||
cVariable = GenericExtension(bClass).method(aVariable);
|
||||
cVariable = GenericExtension<A>(bClass).method(aVariable);
|
||||
cVariable = GenericExtension<B>(bClass).method(aVariable);
|
||||
cVariable = GenericExtension<C>(bClass).method(aVariable);
|
||||
|
||||
aVariable = GenericExtension(cClass).method(aVariable);
|
||||
aVariable = GenericExtension<A>(cClass).method(aVariable);
|
||||
aVariable = GenericExtension<B>(cClass).method(aVariable);
|
||||
aVariable = GenericExtension<C>(cClass).method(aVariable);
|
||||
|
||||
cVariable = GenericExtension(aClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension(aClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension(aClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension(aClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1<C>(aVariable);
|
||||
|
||||
cVariable = GenericExtension(bClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension(bClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension(bClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension(bClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1<C>(aVariable);
|
||||
|
||||
cVariable = GenericExtension(cClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension(cClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension(cClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension(cClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1<C>(aVariable);
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1(aVariable);
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1<A>(aVariable);
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1<B>(aVariable);
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1<C>(aVariable);
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A extends core::Object {
|
||||
synthetic constructor •() → self::A*
|
||||
;
|
||||
}
|
||||
class B extends self::A {
|
||||
synthetic constructor •() → self::B*
|
||||
;
|
||||
}
|
||||
class C extends self::B {
|
||||
synthetic constructor •() → self::C*
|
||||
;
|
||||
}
|
||||
class GenericClass<T extends core::Object* = dynamic> extends core::Object {
|
||||
synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
|
||||
;
|
||||
}
|
||||
extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
|
||||
get property = self::GenericExtension|get#property;
|
||||
method method = self::GenericExtension|method;
|
||||
tearoff method = self::GenericExtension|get#method;
|
||||
method genericMethod1 = self::GenericExtension|genericMethod1;
|
||||
tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
|
||||
}
|
||||
static method GenericExtension|get#property<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::#T*>* #this) → self::GenericExtension|get#property::#T*
|
||||
;
|
||||
static method GenericExtension|method<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::#T*>* #this, self::GenericExtension|method::#T* t) → self::GenericExtension|method::#T*
|
||||
;
|
||||
static method GenericExtension|get#method<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::#T*>* #this) → (self::GenericExtension|get#method::#T*) →* self::GenericExtension|get#method::#T*
|
||||
return (self::GenericExtension|get#method::#T* t) → self::GenericExtension|get#method::#T* => self::GenericExtension|method<self::GenericExtension|get#method::#T*>(#this, t);
|
||||
static method GenericExtension|genericMethod1<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::#T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
|
||||
;
|
||||
static method GenericExtension|get#genericMethod1<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::#T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
|
||||
return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::#T*, S*>(#this, s);
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -0,0 +1,120 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A extends core::Object {
|
||||
synthetic constructor •() → self::A*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class B extends self::A {
|
||||
synthetic constructor •() → self::B*
|
||||
: super self::A::•()
|
||||
;
|
||||
}
|
||||
class C extends self::B {
|
||||
synthetic constructor •() → self::C*
|
||||
: super self::B::•()
|
||||
;
|
||||
}
|
||||
class GenericClass<T extends core::Object* = dynamic> extends core::Object {
|
||||
synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
|
||||
get property = self::GenericExtension|get#property;
|
||||
method method = self::GenericExtension|method;
|
||||
tearoff method = self::GenericExtension|get#method;
|
||||
method genericMethod1 = self::GenericExtension|genericMethod1;
|
||||
tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
|
||||
}
|
||||
static method GenericExtension|get#property<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::#T*>* #this) → self::GenericExtension|get#property::#T*
|
||||
return null;
|
||||
static method GenericExtension|method<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::#T*>* #this, self::GenericExtension|method::#T* t) → self::GenericExtension|method::#T*
|
||||
return null;
|
||||
static method GenericExtension|get#method<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::#T*>* #this) → (self::GenericExtension|get#method::#T*) →* self::GenericExtension|get#method::#T*
|
||||
return (self::GenericExtension|get#method::#T* t) → self::GenericExtension|get#method::#T* => self::GenericExtension|method<self::GenericExtension|get#method::#T*>(#this, t);
|
||||
static method GenericExtension|genericMethod1<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::#T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
|
||||
return null;
|
||||
static method GenericExtension|get#genericMethod1<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::#T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
|
||||
return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::#T*, S*>(#this, s);
|
||||
static method main() → dynamic {
|
||||
self::A* aVariable;
|
||||
self::C* cVariable;
|
||||
self::GenericClass<self::A*>* aClass;
|
||||
self::GenericClass<self::B*>* bClass;
|
||||
self::GenericClass<self::C*>* cClass;
|
||||
cVariable = self::GenericExtension|get#property<self::A*>(aClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::A*>(aClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::B*>(aClass as{TypeError} self::GenericClass<self::B*>*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*);
|
||||
cVariable = self::GenericExtension|get#property<self::B*>(bClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::A*>(bClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::B*>(bClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*);
|
||||
aVariable = self::GenericExtension|get#property<self::C*>(cClass);
|
||||
aVariable = self::GenericExtension|get#property<self::A*>(cClass);
|
||||
aVariable = self::GenericExtension|get#property<self::B*>(cClass);
|
||||
aVariable = self::GenericExtension|get#property<self::C*>(cClass);
|
||||
cVariable = self::GenericExtension|method<self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::B*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|method<self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
aVariable = self::GenericExtension|method<self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
aVariable = self::GenericExtension|method<self::A*>(cClass, aVariable);
|
||||
aVariable = self::GenericExtension|method<self::B*>(cClass, aVariable as{TypeError} self::B*);
|
||||
aVariable = self::GenericExtension|method<self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(aClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(aClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A extends core::Object {
|
||||
synthetic constructor •() → self::A*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
class B extends self::A {
|
||||
synthetic constructor •() → self::B*
|
||||
: super self::A::•()
|
||||
;
|
||||
}
|
||||
class C extends self::B {
|
||||
synthetic constructor •() → self::C*
|
||||
: super self::B::•()
|
||||
;
|
||||
}
|
||||
class GenericClass<T extends core::Object* = dynamic> extends core::Object {
|
||||
synthetic constructor •() → self::GenericClass<self::GenericClass::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
extension GenericExtension<T extends core::Object* = dynamic> on self::GenericClass<T*>* {
|
||||
get property = self::GenericExtension|get#property;
|
||||
method method = self::GenericExtension|method;
|
||||
tearoff method = self::GenericExtension|get#method;
|
||||
method genericMethod1 = self::GenericExtension|genericMethod1;
|
||||
tearoff genericMethod1 = self::GenericExtension|get#genericMethod1;
|
||||
}
|
||||
static method GenericExtension|get#property<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#property::#T*>* #this) → self::GenericExtension|get#property::#T*
|
||||
return null;
|
||||
static method GenericExtension|method<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|method::#T*>* #this, self::GenericExtension|method::#T* t) → self::GenericExtension|method::#T*
|
||||
return null;
|
||||
static method GenericExtension|get#method<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#method::#T*>* #this) → (self::GenericExtension|get#method::#T*) →* self::GenericExtension|get#method::#T*
|
||||
return (self::GenericExtension|get#method::#T* t) → self::GenericExtension|get#method::#T* => self::GenericExtension|method<self::GenericExtension|get#method::#T*>(#this, t);
|
||||
static method GenericExtension|genericMethod1<#T extends core::Object* = dynamic, S extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|genericMethod1::#T*>* #this, self::GenericExtension|genericMethod1::S* s) → self::GenericExtension|genericMethod1::S*
|
||||
return null;
|
||||
static method GenericExtension|get#genericMethod1<#T extends core::Object* = dynamic>(final self::GenericClass<self::GenericExtension|get#genericMethod1::#T*>* #this) → <S extends core::Object* = dynamic>(S*) →* S*
|
||||
return <S extends core::Object* = dynamic>(S* s) → S* => self::GenericExtension|genericMethod1<self::GenericExtension|get#genericMethod1::#T*, S*>(#this, s);
|
||||
static method main() → dynamic {
|
||||
self::A* aVariable;
|
||||
self::C* cVariable;
|
||||
self::GenericClass<self::A*>* aClass;
|
||||
self::GenericClass<self::B*>* bClass;
|
||||
self::GenericClass<self::C*>* cClass;
|
||||
cVariable = self::GenericExtension|get#property<self::A*>(aClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::A*>(aClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::B*>(aClass as{TypeError} self::GenericClass<self::B*>*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*);
|
||||
cVariable = self::GenericExtension|get#property<self::B*>(bClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::A*>(bClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::B*>(bClass) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|get#property<self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*);
|
||||
aVariable = self::GenericExtension|get#property<self::C*>(cClass);
|
||||
aVariable = self::GenericExtension|get#property<self::A*>(cClass);
|
||||
aVariable = self::GenericExtension|get#property<self::B*>(cClass);
|
||||
aVariable = self::GenericExtension|get#property<self::C*>(cClass);
|
||||
cVariable = self::GenericExtension|method<self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::B*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|method<self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|method<self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
aVariable = self::GenericExtension|method<self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
aVariable = self::GenericExtension|method<self::A*>(cClass, aVariable);
|
||||
aVariable = self::GenericExtension|method<self::B*>(cClass, aVariable as{TypeError} self::B*);
|
||||
aVariable = self::GenericExtension|method<self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(aClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(aClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(aClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(aClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(aClass as{TypeError} self::GenericClass<self::B*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(aClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(bClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(bClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(bClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(bClass as{TypeError} self::GenericClass<self::C*>*, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::A*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::B*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::A*>(cClass, aVariable) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::B*>(cClass, aVariable as{TypeError} self::B*) as{TypeError} self::C*;
|
||||
cVariable = self::GenericExtension|genericMethod1<self::C*, self::C*>(cClass, aVariable as{TypeError} self::C*);
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:27:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(aClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:28:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(aClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:29:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(aClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:30:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(aClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:32:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(bClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:33:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(bClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:34:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(bClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:35:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(bClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:37:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension(cClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:38:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension<A>(cClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:39:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension<B>(cClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:40:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension<C>(cClass).property;
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:42:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(aClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:43:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(aClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:44:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(aClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:45:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(aClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:47:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(bClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:48:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(bClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:49:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(bClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:50:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(bClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:52:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension(cClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:53:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension<A>(cClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:54:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension<B>(cClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:55:13: Context: Write to aVariable@453
|
||||
aVariable = GenericExtension<C>(cClass).method(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:57:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(aClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:58:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(aClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:59:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(aClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:60:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(aClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:61:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:62:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:63:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:64:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(aClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:65:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:66:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:67:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:68:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(aClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:69:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:70:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:71:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:72:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(aClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:74:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(bClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:75:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(bClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:76:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(bClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:77:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(bClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:78:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:79:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:80:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:81:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(bClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:82:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:83:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:84:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:85:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(bClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:86:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:87:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:88:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:89:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(bClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:91:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(cClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:92:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(cClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:93:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(cClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:94:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension(cClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:95:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:96:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:97:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:98:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<A>(cClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:99:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:100:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:101:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:102:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<B>(cClass).genericMethod1<C>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:103:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:104:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1<A>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:105:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1<B>(aVariable);
|
||||
^
|
||||
pkg/front_end/testcases/extensions/explicit_extension_inference.dart:106:13: Context: Write to cVariable@468
|
||||
cVariable = GenericExtension<C>(cClass).genericMethod1<C>(aVariable);
|
||||
^
|
|
@ -59,11 +59,22 @@ main() {
|
|||
expect(42, tearOffInteger1());
|
||||
expect('int', Extension1.latestType);
|
||||
expect(87, tearOff2());
|
||||
// TODO(johnniwinther): Handle partially provided type arguments
|
||||
//expect(52, Extension1<num>(c).genericMethod(10));
|
||||
//expect(97, Extension2<num>(c).genericMethod(10));
|
||||
//expect(52, Extension1<num>(c).genericMethod<num>(10));
|
||||
//expect(97, Extension2<num>(c).genericMethod<num>(10));
|
||||
expect(52, Extension1<num>(c).genericMethod(10));
|
||||
expect('num:int', Extension1.latestType);
|
||||
expect(52, Extension1<int>(c).genericMethod(10));
|
||||
expect('int:int', Extension1.latestType);
|
||||
expect(97, Extension2<num>(c).genericMethod(10));
|
||||
expect(52, Extension1<num>(c).genericMethod<num>(10));
|
||||
expect('num:num', Extension1.latestType);
|
||||
expect(52, Extension1<int>(c).genericMethod<num>(10));
|
||||
expect('int:num', Extension1.latestType);
|
||||
expect(97, Extension2<num>(c).genericMethod<num>(10));
|
||||
expect(52, Extension1(c).genericMethod(10));
|
||||
expect('int:int', Extension1.latestType);
|
||||
expect(52, Extension1(c).genericMethod<num>(10));
|
||||
expect('int:num', Extension1.latestType);
|
||||
expect(52, Extension1(c).genericMethod<int>(10));
|
||||
expect('int:int', Extension1.latestType);
|
||||
var genericTearOffNumber1 = Extension1<num>(c).genericMethod;
|
||||
var genericTearOffInteger1 = Extension1<int>(c).genericMethod;
|
||||
var genericTearOff2 = Extension2<num>(c).genericMethod;
|
||||
|
|
|
@ -84,6 +84,22 @@ static method main() → dynamic {
|
|||
self::expect(42, tearOffInteger1.call());
|
||||
self::expect("int", self::Extension1|latestType);
|
||||
self::expect(87, tearOff2.call());
|
||||
self::expect(52, self::Extension1|genericMethod<core::num*, core::int*>(c, 10));
|
||||
self::expect("num:int", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::int*>(c, 10));
|
||||
self::expect("int:int", self::Extension1|latestType);
|
||||
self::expect(97, self::Extension2|genericMethod<core::num*, core::int*>(c, 10));
|
||||
self::expect(52, self::Extension1|genericMethod<core::num*, core::num*>(c, 10));
|
||||
self::expect("num:num", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::num*>(c, 10));
|
||||
self::expect("int:num", self::Extension1|latestType);
|
||||
self::expect(97, self::Extension2|genericMethod<core::num*, core::num*>(c, 10));
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::int*>(c, 10));
|
||||
self::expect("int:int", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::num*>(c, 10));
|
||||
self::expect("int:num", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::int*>(c, 10));
|
||||
self::expect("int:int", self::Extension1|latestType);
|
||||
<S extends core::num* = dynamic>(S*) →* core::num* genericTearOffNumber1 = self::Extension1|get#genericMethod<core::num*>(c);
|
||||
<S extends core::num* = dynamic>(S*) →* core::int* genericTearOffInteger1 = self::Extension1|get#genericMethod<core::int*>(c);
|
||||
<S extends core::num* = dynamic>(S*) →* core::num* genericTearOff2 = self::Extension2|get#genericMethod<core::num*>(c);
|
||||
|
|
|
@ -84,6 +84,22 @@ static method main() → dynamic {
|
|||
self::expect(42, tearOffInteger1.call());
|
||||
self::expect("int", self::Extension1|latestType);
|
||||
self::expect(87, tearOff2.call());
|
||||
self::expect(52, self::Extension1|genericMethod<core::num*, core::int*>(c, 10));
|
||||
self::expect("num:int", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::int*>(c, 10));
|
||||
self::expect("int:int", self::Extension1|latestType);
|
||||
self::expect(97, self::Extension2|genericMethod<core::num*, core::int*>(c, 10));
|
||||
self::expect(52, self::Extension1|genericMethod<core::num*, core::num*>(c, 10));
|
||||
self::expect("num:num", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::num*>(c, 10));
|
||||
self::expect("int:num", self::Extension1|latestType);
|
||||
self::expect(97, self::Extension2|genericMethod<core::num*, core::num*>(c, 10));
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::int*>(c, 10));
|
||||
self::expect("int:int", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::num*>(c, 10));
|
||||
self::expect("int:num", self::Extension1|latestType);
|
||||
self::expect(52, self::Extension1|genericMethod<core::int*, core::int*>(c, 10));
|
||||
self::expect("int:int", self::Extension1|latestType);
|
||||
<S extends core::num* = dynamic>(S*) →* core::num* genericTearOffNumber1 = self::Extension1|get#genericMethod<core::num*>(c);
|
||||
<S extends core::num* = dynamic>(S*) →* core::int* genericTearOffInteger1 = self::Extension1|get#genericMethod<core::int*>(c);
|
||||
<S extends core::num* = dynamic>(S*) →* core::num* genericTearOff2 = self::Extension2|get#genericMethod<core::num*>(c);
|
||||
|
|
|
@ -63,9 +63,9 @@ library;
|
|||
// method(a) {}
|
||||
// ^^^^^^^^^^^^^...
|
||||
//
|
||||
// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
|
||||
// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
|
||||
// Extension(c1).method<int>(null);
|
||||
// ^
|
||||
// ^
|
||||
// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
|
||||
// method(a) {}
|
||||
// ^^^^^^^^^^^^^...
|
||||
|
@ -196,9 +196,9 @@ Try removing the extra positional arguments.
|
|||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
|
||||
Extension(c1).method(1, a: 2);
|
||||
^";
|
||||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
|
||||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
|
||||
Extension(c1).method<int>(null);
|
||||
^";
|
||||
^";
|
||||
self::GenericClass<core::int*>* c2 = new self::GenericClass::•<core::int*>();
|
||||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:42:3: Error: Explicit extension application requires exactly 1 positional argument.
|
||||
GenericExtension().method();
|
||||
|
|
|
@ -63,9 +63,9 @@ library;
|
|||
// method(a) {}
|
||||
// ^^^^^^^^^^^^^...
|
||||
//
|
||||
// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
|
||||
// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
|
||||
// Extension(c1).method<int>(null);
|
||||
// ^
|
||||
// ^
|
||||
// pkg/front_end/testcases/extensions/invalid_explicit_access.dart:8:3: Context: Found this candidate, but the arguments don't match.
|
||||
// method(a) {}
|
||||
// ^^^^^^^^^^^^^...
|
||||
|
@ -196,9 +196,9 @@ Try removing the extra positional arguments.
|
|||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:38:27: Error: No named parameter with the name 'a'.
|
||||
Extension(c1).method(1, a: 2);
|
||||
^";
|
||||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:17: Error: Expected 0 type arguments.
|
||||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:39:3: Error: Expected 0 type arguments.
|
||||
Extension(c1).method<int>(null);
|
||||
^";
|
||||
^";
|
||||
self::GenericClass<core::int*>* c2 = new self::GenericClass::•<core::int*>();
|
||||
invalid-expression "pkg/front_end/testcases/extensions/invalid_explicit_access.dart:42:3: Error: Explicit extension application requires exactly 1 positional argument.
|
||||
GenericExtension().method();
|
||||
|
|
|
@ -11,6 +11,7 @@ expression/main: TextSerializationFailure # Was: Pass
|
|||
extensions/direct_instance_access: TextSerializationFailure
|
||||
extensions/direct_static_access: TextSerializationFailure
|
||||
extensions/explicit_extension_access: TextSerializationFailure
|
||||
extensions/explicit_extension_inference: TextSerializationFailure
|
||||
extensions/explicit_generic_extension_access: TextSerializationFailure
|
||||
extensions/explicit_this: TextSerializationFailure
|
||||
extensions/extension_methods: TextSerializationFailure
|
||||
|
|
Loading…
Reference in a new issue