mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 10:33:03 +00:00
[cfe] Update inference for redirecting factory constructors
Closes #34714. Bug: https://github.com/dart-lang/sdk/issues/34714 Change-Id: Ia1f6845d2ae623ecba01fd5e60dcaed975471f6b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/147181 Commit-Queue: Dmitry Stefantsov <dmitryas@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
af99babc6c
commit
3b93b85aef
|
@ -4,12 +4,15 @@
|
|||
|
||||
import 'dart:core' hide MapEntry;
|
||||
|
||||
import 'package:front_end/src/fasta/dill/dill_member_builder.dart';
|
||||
import 'package:front_end/src/fasta/kernel/kernel_api.dart';
|
||||
import 'package:kernel/ast.dart';
|
||||
|
||||
import 'package:kernel/type_algebra.dart';
|
||||
|
||||
import '../kernel/class_hierarchy_builder.dart';
|
||||
import '../kernel/forest.dart';
|
||||
import '../kernel/internal_ast.dart';
|
||||
import '../kernel/redirecting_factory_body.dart' show RedirectingFactoryBody;
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
|
@ -21,6 +24,9 @@ import '../problems.dart' show unexpected, unhandled;
|
|||
|
||||
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
|
||||
|
||||
import '../type_inference/type_inferrer.dart';
|
||||
import '../type_inference/type_schema.dart';
|
||||
|
||||
import 'builder.dart';
|
||||
import 'constructor_reference_builder.dart';
|
||||
import 'extension_builder.dart';
|
||||
|
@ -717,6 +723,79 @@ class RedirectingFactoryBuilder extends ProcedureBuilderImpl {
|
|||
return _procedure;
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(LibraryBuilder library, CoreTypes coreTypes) {
|
||||
super.buildOutlineExpressions(library, coreTypes);
|
||||
LibraryBuilder thisLibrary = this.library;
|
||||
if (thisLibrary is SourceLibraryBuilder) {
|
||||
RedirectingFactoryBody redirectingFactoryBody = member.function.body;
|
||||
if (redirectingFactoryBody.typeArguments != null &&
|
||||
redirectingFactoryBody.typeArguments.any((t) => t is UnknownType)) {
|
||||
TypeInferrerImpl inferrer = thisLibrary.loader.typeInferenceEngine
|
||||
.createLocalTypeInferrer(
|
||||
fileUri, classBuilder.thisType, thisLibrary, null);
|
||||
inferrer.helper = thisLibrary.loader
|
||||
.createBodyBuilderForOutlineExpression(
|
||||
this.library, classBuilder, this, classBuilder.scope, fileUri);
|
||||
Builder targetBuilder = redirectionTarget.target;
|
||||
Member target;
|
||||
if (targetBuilder is FunctionBuilder) {
|
||||
target = targetBuilder.member;
|
||||
} else if (targetBuilder is DillMemberBuilder) {
|
||||
target = targetBuilder.member;
|
||||
} else {
|
||||
unhandled("${targetBuilder.runtimeType}", "buildOutlineExpressions",
|
||||
charOffset, fileUri);
|
||||
}
|
||||
Arguments targetInvocationArguments;
|
||||
{
|
||||
List<Expression> positionalArguments = <Expression>[];
|
||||
for (VariableDeclaration parameter
|
||||
in member.function.positionalParameters) {
|
||||
positionalArguments.add(new VariableGetImpl(
|
||||
parameter,
|
||||
inferrer.typePromoter.getFactForAccess(parameter, 0),
|
||||
inferrer.typePromoter.currentScope,
|
||||
forNullGuardedAccess: false));
|
||||
}
|
||||
List<NamedExpression> namedArguments = <NamedExpression>[];
|
||||
for (VariableDeclaration parameter
|
||||
in member.function.namedParameters) {
|
||||
namedArguments.add(new NamedExpression(
|
||||
parameter.name,
|
||||
new VariableGetImpl(
|
||||
parameter,
|
||||
inferrer.typePromoter.getFactForAccess(parameter, 0),
|
||||
inferrer.typePromoter.currentScope,
|
||||
forNullGuardedAccess: false)));
|
||||
}
|
||||
// If arguments are created using [Forest.createArguments], and the
|
||||
// type arguments are omitted, they are to be inferred.
|
||||
targetInvocationArguments = const Forest().createArguments(
|
||||
member.fileOffset, positionalArguments,
|
||||
named: namedArguments);
|
||||
}
|
||||
InvocationInferenceResult result = inferrer.inferInvocation(
|
||||
function.returnType,
|
||||
charOffset,
|
||||
target.function.computeFunctionType(Nullability.nonNullable),
|
||||
targetInvocationArguments);
|
||||
List<DartType> typeArguments;
|
||||
if (result.inferredType is InterfaceType) {
|
||||
typeArguments = (result.inferredType as InterfaceType).typeArguments;
|
||||
} else {
|
||||
// Assume that the error is reported elsewhere, use 'dynamic' for
|
||||
// recovery.
|
||||
typeArguments = new List<DartType>.filled(
|
||||
target.enclosingClass.typeParameters.length, const DynamicType(),
|
||||
growable: true);
|
||||
}
|
||||
member.function.body =
|
||||
new RedirectingFactoryBody(target, typeArguments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
List<ClassMember> get localMembers =>
|
||||
throw new UnsupportedError('${runtimeType}.localMembers');
|
||||
|
|
|
@ -419,7 +419,6 @@ class InferenceVisitor
|
|||
node.target.function
|
||||
.computeThisFunctionType(inferrer.library.nonNullable),
|
||||
node.arguments,
|
||||
node.name,
|
||||
returnType:
|
||||
computeConstructorReturnType(node.target, inferrer.coreTypes),
|
||||
isConst: node.isConst);
|
||||
|
@ -449,8 +448,8 @@ class InferenceVisitor
|
|||
: new FunctionType(
|
||||
[], const DynamicType(), inferrer.library.nonNullable);
|
||||
TypeArgumentsInfo typeArgumentsInfo = getTypeArgumentsInfo(node.arguments);
|
||||
InvocationInferenceResult result = inferrer.inferInvocation(typeContext,
|
||||
node.fileOffset, calleeType, node.arguments, node.target.name);
|
||||
InvocationInferenceResult result = inferrer.inferInvocation(
|
||||
typeContext, node.fileOffset, calleeType, node.arguments);
|
||||
Expression replacement = new StaticInvocation(node.target, node.arguments);
|
||||
if (!inferrer.isTopLevel && node.target != null) {
|
||||
inferrer.library.checkBoundsInStaticInvocation(
|
||||
|
@ -702,7 +701,6 @@ class InferenceVisitor
|
|||
node.target.function
|
||||
.computeThisFunctionType(inferrer.library.nonNullable),
|
||||
node.arguments,
|
||||
node.name,
|
||||
returnType:
|
||||
computeConstructorReturnType(node.target, inferrer.coreTypes),
|
||||
isConst: node.isConst);
|
||||
|
@ -1061,7 +1059,6 @@ class InferenceVisitor
|
|||
.computeThisFunctionType(inferrer.library.nonNullable)
|
||||
.withoutTypeParameters),
|
||||
node.argumentsJudgment,
|
||||
node.target.name,
|
||||
returnType: inferrer.thisType,
|
||||
skipTypeArgumentInference: true);
|
||||
}
|
||||
|
@ -4850,7 +4847,6 @@ class InferenceVisitor
|
|||
node.target.function
|
||||
.computeThisFunctionType(inferrer.library.nonNullable),
|
||||
node.arguments,
|
||||
node.target.name,
|
||||
returnType: inferrer.coreTypes.thisInterfaceType(
|
||||
node.target.enclosingClass, inferrer.library.nonNullable),
|
||||
skipTypeArgumentInference: true);
|
||||
|
@ -5014,7 +5010,7 @@ class InferenceVisitor
|
|||
[], const DynamicType(), inferrer.library.nonNullable);
|
||||
TypeArgumentsInfo typeArgumentsInfo = getTypeArgumentsInfo(node.arguments);
|
||||
InvocationInferenceResult result = inferrer.inferInvocation(
|
||||
typeContext, node.fileOffset, calleeType, node.arguments, node.name);
|
||||
typeContext, node.fileOffset, calleeType, node.arguments);
|
||||
if (!inferrer.isTopLevel && node.target != null) {
|
||||
inferrer.library.checkBoundsInStaticInvocation(
|
||||
node,
|
||||
|
@ -5061,7 +5057,6 @@ class InferenceVisitor
|
|||
.computeThisFunctionType(inferrer.library.nonNullable)
|
||||
.withoutTypeParameters),
|
||||
node.arguments,
|
||||
node.target.name,
|
||||
returnType: inferrer.thisType,
|
||||
skipTypeArgumentInference: true);
|
||||
}
|
||||
|
@ -5688,7 +5683,7 @@ class InferenceVisitor
|
|||
FunctionType calleeType =
|
||||
new FunctionType([], inferredType, inferrer.library.nonNullable);
|
||||
inferrer.inferInvocation(
|
||||
typeContext, node.fileOffset, calleeType, node.arguments, null);
|
||||
typeContext, node.fileOffset, calleeType, node.arguments);
|
||||
}
|
||||
return new ExpressionInferenceResult(inferredType, node);
|
||||
}
|
||||
|
|
|
@ -321,10 +321,10 @@ class KernelTarget extends TargetImplementation {
|
|||
loader.checkTypes();
|
||||
loader.checkOverrides(myClasses);
|
||||
loader.checkAbstractMembers(myClasses);
|
||||
loader.checkRedirectingFactories(myClasses);
|
||||
loader.addNoSuchMethodForwarders(myClasses);
|
||||
loader.checkMixins(myClasses);
|
||||
loader.buildOutlineExpressions(loader.coreTypes);
|
||||
loader.checkRedirectingFactories(myClasses);
|
||||
_updateDelayedParameterTypes();
|
||||
installAllComponentProblems(loader.allComponentProblems);
|
||||
loader.allComponentProblems.clear();
|
||||
|
|
|
@ -35,10 +35,10 @@ import '../dill/dill_member_builder.dart' show DillMemberBuilder;
|
|||
|
||||
import '../fasta_codes.dart';
|
||||
|
||||
import '../kernel/redirecting_factory_body.dart' show redirectingName;
|
||||
import '../kernel/kernel_builder.dart' show compareProcedures;
|
||||
import '../kernel/kernel_target.dart' show KernelTarget;
|
||||
import '../kernel/redirecting_factory_body.dart' show RedirectingFactoryBody;
|
||||
import '../kernel/redirecting_factory_body.dart' show redirectingName;
|
||||
import '../kernel/type_algorithms.dart'
|
||||
show Variance, computeTypeVariableBuilderVariance;
|
||||
|
||||
|
@ -48,6 +48,8 @@ import '../problems.dart' show unexpected, unhandled;
|
|||
|
||||
import '../scope.dart';
|
||||
|
||||
import '../type_inference/type_schema.dart';
|
||||
|
||||
import 'source_library_builder.dart' show SourceLibraryBuilder;
|
||||
|
||||
Class initializeClass(
|
||||
|
@ -1054,29 +1056,19 @@ class SourceClassBuilder extends ClassBuilderImpl
|
|||
addRedirectingConstructor(declaration, library, referenceFrom);
|
||||
}
|
||||
if (targetBuilder is FunctionBuilder) {
|
||||
List<DartType> typeArguments = declaration.typeArguments;
|
||||
if (typeArguments == null) {
|
||||
// TODO(32049) If type arguments aren't specified, they should
|
||||
// be inferred. Currently, the inference is not performed.
|
||||
// The code below is a workaround.
|
||||
typeArguments = new List<DartType>.filled(
|
||||
targetBuilder.member.enclosingClass.typeParameters.length,
|
||||
const DynamicType(),
|
||||
growable: true);
|
||||
}
|
||||
List<DartType> typeArguments = declaration.typeArguments ??
|
||||
new List<DartType>.filled(
|
||||
targetBuilder
|
||||
.member.enclosingClass.typeParameters.length,
|
||||
const UnknownType());
|
||||
declaration.setRedirectingFactoryBody(
|
||||
targetBuilder.member, typeArguments);
|
||||
} else if (targetBuilder is DillMemberBuilder) {
|
||||
List<DartType> typeArguments = declaration.typeArguments;
|
||||
if (typeArguments == null) {
|
||||
// TODO(32049) If type arguments aren't specified, they should
|
||||
// be inferred. Currently, the inference is not performed.
|
||||
// The code below is a workaround.
|
||||
typeArguments = new List<DartType>.filled(
|
||||
targetBuilder.member.enclosingClass.typeParameters.length,
|
||||
const DynamicType(),
|
||||
growable: true);
|
||||
}
|
||||
List<DartType> typeArguments = declaration.typeArguments ??
|
||||
new List<DartType>.filled(
|
||||
targetBuilder
|
||||
.member.enclosingClass.typeParameters.length,
|
||||
const UnknownType());
|
||||
declaration.setRedirectingFactoryBody(
|
||||
targetBuilder.member, typeArguments);
|
||||
} else if (targetBuilder is AmbiguousBuilder) {
|
||||
|
|
|
@ -2005,7 +2005,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
}
|
||||
|
||||
InvocationInferenceResult inferInvocation(DartType typeContext, int offset,
|
||||
FunctionType calleeType, Arguments arguments, Name targetName,
|
||||
FunctionType calleeType, Arguments arguments,
|
||||
{List<VariableDeclaration> hoistedExpressions,
|
||||
bool isOverloadedArithmeticOperator: false,
|
||||
DartType returnType,
|
||||
|
@ -2022,22 +2022,16 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
if (extensionTypeParameterCount != 0) {
|
||||
assert(returnType == null,
|
||||
"Unexpected explicit return type for extension method invocation.");
|
||||
return _inferGenericExtensionMethodInvocation(
|
||||
extensionTypeParameterCount,
|
||||
typeContext,
|
||||
offset,
|
||||
calleeType,
|
||||
arguments,
|
||||
targetName,
|
||||
hoistedExpressions,
|
||||
return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
|
||||
typeContext, offset, calleeType, arguments, hoistedExpressions,
|
||||
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
|
||||
receiverType: receiverType,
|
||||
skipTypeArgumentInference: skipTypeArgumentInference,
|
||||
isConst: isConst,
|
||||
isImplicitExtensionMember: isImplicitExtensionMember);
|
||||
}
|
||||
return _inferInvocation(typeContext, offset, calleeType, arguments,
|
||||
targetName, hoistedExpressions,
|
||||
return _inferInvocation(
|
||||
typeContext, offset, calleeType, arguments, hoistedExpressions,
|
||||
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
|
||||
receiverType: receiverType,
|
||||
returnType: returnType,
|
||||
|
@ -2053,7 +2047,6 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
int offset,
|
||||
FunctionType calleeType,
|
||||
Arguments arguments,
|
||||
Name targetName,
|
||||
List<VariableDeclaration> hoistedExpressions,
|
||||
{bool isOverloadedArithmeticOperator: false,
|
||||
DartType receiverType,
|
||||
|
@ -2073,7 +2066,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
arguments.fileOffset, [arguments.positional.first],
|
||||
types: getExplicitExtensionTypeArguments(arguments));
|
||||
_inferInvocation(const UnknownType(), offset, extensionFunctionType,
|
||||
extensionArguments, targetName, hoistedExpressions,
|
||||
extensionArguments, hoistedExpressions,
|
||||
skipTypeArgumentInference: skipTypeArgumentInference,
|
||||
receiverType: receiverType,
|
||||
isImplicitExtensionMember: isImplicitExtensionMember,
|
||||
|
@ -2099,7 +2092,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
arguments.fileOffset, arguments.positional.skip(1).toList(),
|
||||
named: arguments.named, types: getExplicitTypeArguments(arguments));
|
||||
InvocationInferenceResult result = _inferInvocation(typeContext, offset,
|
||||
targetFunctionType, targetArguments, targetName, hoistedExpressions,
|
||||
targetFunctionType, targetArguments, hoistedExpressions,
|
||||
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
|
||||
skipTypeArgumentInference: skipTypeArgumentInference,
|
||||
isConst: isConst,
|
||||
|
@ -2124,7 +2117,6 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
int offset,
|
||||
FunctionType calleeType,
|
||||
Arguments arguments,
|
||||
Name targetName,
|
||||
List<VariableDeclaration> hoistedExpressions,
|
||||
{bool isOverloadedArithmeticOperator: false,
|
||||
bool isBinaryOperator: false,
|
||||
|
@ -2636,7 +2628,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
{bool isImplicitCall}) {
|
||||
assert(isImplicitCall != null);
|
||||
InvocationInferenceResult result = inferInvocation(
|
||||
typeContext, fileOffset, unknownFunction, arguments, name,
|
||||
typeContext, fileOffset, unknownFunction, arguments,
|
||||
hoistedExpressions: hoistedExpressions,
|
||||
receiverType: const DynamicType(),
|
||||
isImplicitCall: isImplicitCall);
|
||||
|
@ -2660,7 +2652,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
{bool isImplicitCall}) {
|
||||
assert(isImplicitCall != null);
|
||||
InvocationInferenceResult result = inferInvocation(
|
||||
typeContext, fileOffset, unknownFunction, arguments, name,
|
||||
typeContext, fileOffset, unknownFunction, arguments,
|
||||
hoistedExpressions: hoistedExpressions,
|
||||
receiverType: receiverType,
|
||||
isImplicitCall: isImplicitCall);
|
||||
|
@ -2694,7 +2686,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
implicitInvocationPropertyName: implicitInvocationPropertyName,
|
||||
extensionAccessCandidates:
|
||||
target.isAmbiguous ? target.candidates : null);
|
||||
inferInvocation(typeContext, fileOffset, unknownFunction, arguments, name,
|
||||
inferInvocation(typeContext, fileOffset, unknownFunction, arguments,
|
||||
hoistedExpressions: hoistedExpressions,
|
||||
receiverType: receiverType,
|
||||
isImplicitCall: isExpressionInvocation || isImplicitCall);
|
||||
|
@ -2749,8 +2741,8 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
} else {
|
||||
StaticInvocation staticInvocation = transformExtensionMethodInvocation(
|
||||
fileOffset, target, receiver, arguments);
|
||||
InvocationInferenceResult result = inferInvocation(typeContext,
|
||||
fileOffset, functionType, staticInvocation.arguments, name,
|
||||
InvocationInferenceResult result = inferInvocation(
|
||||
typeContext, fileOffset, functionType, staticInvocation.arguments,
|
||||
hoistedExpressions: hoistedExpressions,
|
||||
receiverType: receiverType,
|
||||
isImplicitExtensionMember: true,
|
||||
|
@ -2797,7 +2789,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
assert(target.isCallFunction || target.isNullableCallFunction);
|
||||
FunctionType functionType = getFunctionType(target, receiverType);
|
||||
InvocationInferenceResult result = inferInvocation(
|
||||
typeContext, fileOffset, functionType, arguments, callName,
|
||||
typeContext, fileOffset, functionType, arguments,
|
||||
hoistedExpressions: hoistedExpressions,
|
||||
receiverType: receiverType,
|
||||
isImplicitCall: isImplicitCall);
|
||||
|
@ -2874,7 +2866,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
contravariantCheck = true;
|
||||
}
|
||||
InvocationInferenceResult result = inferInvocation(
|
||||
typeContext, fileOffset, functionType, arguments, target.member?.name,
|
||||
typeContext, fileOffset, functionType, arguments,
|
||||
hoistedExpressions: hoistedExpressions,
|
||||
receiverType: receiverType,
|
||||
isImplicitCall: isImplicitCall);
|
||||
|
@ -3349,7 +3341,7 @@ class TypeInferrerImpl implements TypeInferrer {
|
|||
FunctionType functionType = getFunctionType(target, receiverType);
|
||||
|
||||
InvocationInferenceResult result = inferInvocation(
|
||||
typeContext, fileOffset, functionType, arguments, target.member?.name,
|
||||
typeContext, fileOffset, functionType, arguments,
|
||||
isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
|
||||
receiverType: receiverType,
|
||||
isImplicitExtensionMember: target.isExtensionMember);
|
||||
|
|
13
pkg/front_end/testcases/general/issue34714.dart
Normal file
13
pkg/front_end/testcases/general/issue34714.dart
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) 2020, 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<T> {
|
||||
factory A() = B; // Should infer B<T>.
|
||||
}
|
||||
|
||||
class B<T> implements A<T> {
|
||||
B();
|
||||
}
|
||||
|
||||
main() {}
|
|
@ -0,0 +1,35 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A<T extends core::Object* = dynamic> extends core::Object {
|
||||
static field dynamic _redirecting# = <dynamic>[self::A::•];
|
||||
static factory •<T extends core::Object* = dynamic>() → self::A<self::A::•::T*>*
|
||||
let dynamic #redirecting_factory = self::B::• in let self::A::•::T* #typeArg0 = null in invalid-expression;
|
||||
abstract member-signature get _identityHashCode() → core::int*;
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
|
||||
abstract member-signature operator ==(dynamic other) → core::bool*;
|
||||
abstract member-signature get hashCode() → core::int*;
|
||||
abstract member-signature method toString() → core::String*;
|
||||
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
|
||||
abstract member-signature get runtimeType() → core::Type*;
|
||||
}
|
||||
class B<T extends core::Object* = dynamic> extends core::Object implements self::A<self::B::T*> {
|
||||
constructor •() → self::B<self::B::T*>*
|
||||
;
|
||||
abstract member-signature get _identityHashCode() → core::int*;
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
|
||||
abstract member-signature operator ==(dynamic other) → core::bool*;
|
||||
abstract member-signature get hashCode() → core::int*;
|
||||
abstract member-signature method toString() → core::String*;
|
||||
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
|
||||
abstract member-signature get runtimeType() → core::Type*;
|
||||
}
|
||||
static method main() → dynamic
|
||||
;
|
|
@ -0,0 +1,35 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A<T extends core::Object* = dynamic> extends core::Object {
|
||||
static field dynamic _redirecting# = <dynamic>[self::A::•];
|
||||
static factory •<T extends core::Object* = dynamic>() → self::A<self::A::•::T*>*
|
||||
let dynamic #redirecting_factory = self::B::• in let self::A::•::T* #typeArg0 = null in invalid-expression;
|
||||
abstract member-signature get _identityHashCode() → core::int*;
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
|
||||
abstract member-signature operator ==(dynamic other) → core::bool*;
|
||||
abstract member-signature get hashCode() → core::int*;
|
||||
abstract member-signature method toString() → core::String*;
|
||||
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
|
||||
abstract member-signature get runtimeType() → core::Type*;
|
||||
}
|
||||
class B<T extends core::Object* = dynamic> extends core::Object implements self::A<self::B::T*> {
|
||||
constructor •() → self::B<self::B::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
abstract member-signature get _identityHashCode() → core::int*;
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
|
||||
abstract member-signature operator ==(dynamic other) → core::bool*;
|
||||
abstract member-signature get hashCode() → core::int*;
|
||||
abstract member-signature method toString() → core::String*;
|
||||
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
|
||||
abstract member-signature get runtimeType() → core::Type*;
|
||||
}
|
||||
static method main() → dynamic {}
|
|
@ -0,0 +1,35 @@
|
|||
library;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A<T extends core::Object* = dynamic> extends core::Object {
|
||||
static field dynamic _redirecting# = <dynamic>[self::A::•];
|
||||
static factory •<T extends core::Object* = dynamic>() → self::A<self::A::•::T*>*
|
||||
let<BottomType> #redirecting_factory = self::B::• in let self::A::•::T* #typeArg0 = null in invalid-expression;
|
||||
abstract member-signature get _identityHashCode() → core::int*;
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
|
||||
abstract member-signature operator ==(dynamic other) → core::bool*;
|
||||
abstract member-signature get hashCode() → core::int*;
|
||||
abstract member-signature method toString() → core::String*;
|
||||
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
|
||||
abstract member-signature get runtimeType() → core::Type*;
|
||||
}
|
||||
class B<T extends core::Object* = dynamic> extends core::Object implements self::A<self::B::T*> {
|
||||
constructor •() → self::B<self::B::T*>*
|
||||
: super core::Object::•()
|
||||
;
|
||||
abstract member-signature get _identityHashCode() → core::int*;
|
||||
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
|
||||
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
|
||||
abstract member-signature operator ==(dynamic other) → core::bool*;
|
||||
abstract member-signature get hashCode() → core::int*;
|
||||
abstract member-signature method toString() → core::String*;
|
||||
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
|
||||
abstract member-signature get runtimeType() → core::Type*;
|
||||
}
|
||||
static method main() → dynamic {}
|
Loading…
Reference in a new issue