mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 15:57:17 +00:00
[cfe] Support generic inline class constructors
Change-Id: Ibd12b14e1e8a1811734b4773c842e72a7fcb300c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/277684 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This commit is contained in:
parent
2083db9cdb
commit
8e07d492dd
|
@ -7,6 +7,7 @@ library fasta.formal_parameter_builder;
|
||||||
import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart'
|
import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart'
|
||||||
show FormalParameterKind, FormalParameterKindExtension;
|
show FormalParameterKind, FormalParameterKindExtension;
|
||||||
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
|
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
|
||||||
|
import 'package:front_end/src/fasta/source/constructor_declaration.dart';
|
||||||
import 'package:kernel/ast.dart'
|
import 'package:kernel/ast.dart'
|
||||||
show DartType, DynamicType, Expression, NullLiteral, VariableDeclaration;
|
show DartType, DynamicType, Expression, NullLiteral, VariableDeclaration;
|
||||||
import 'package:kernel/class_hierarchy.dart';
|
import 'package:kernel/class_hierarchy.dart';
|
||||||
|
@ -221,10 +222,14 @@ class FormalParameterBuilder extends ModifierBuilderImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
void finalizeInitializingFormal(
|
void finalizeInitializingFormal(
|
||||||
DeclarationBuilder declarationBuilder, ClassHierarchyBase hierarchy) {
|
DeclarationBuilder declarationBuilder,
|
||||||
|
ConstructorDeclaration constructorDeclaration,
|
||||||
|
ClassHierarchyBase hierarchy) {
|
||||||
Builder? fieldBuilder = declarationBuilder.lookupLocalMember(name);
|
Builder? fieldBuilder = declarationBuilder.lookupLocalMember(name);
|
||||||
if (fieldBuilder is SourceFieldBuilder) {
|
if (fieldBuilder is SourceFieldBuilder) {
|
||||||
type.registerInferredType(fieldBuilder.inferType(hierarchy));
|
DartType fieldType = fieldBuilder.inferType(hierarchy);
|
||||||
|
fieldType = constructorDeclaration.substituteFieldType(fieldType);
|
||||||
|
type.registerInferredType(fieldType);
|
||||||
} else {
|
} else {
|
||||||
type.registerInferredType(const DynamicType());
|
type.registerInferredType(const DynamicType());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1887,14 +1887,14 @@ class BodyBuilder extends StackListenerImpl
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
void finishConstructor(ConstructorDeclaration builder,
|
void finishConstructor(ConstructorDeclaration constructorDeclaration,
|
||||||
AsyncMarker asyncModifier, Statement? body,
|
AsyncMarker asyncModifier, Statement? body,
|
||||||
{required List<Object /* Expression | NamedExpression */ >?
|
{required List<Object /* Expression | NamedExpression */ >?
|
||||||
superParametersAsArguments}) {
|
superParametersAsArguments}) {
|
||||||
/// Quotes below are from [Dart Programming Language Specification, 4th
|
/// Quotes below are from [Dart Programming Language Specification, 4th
|
||||||
/// Edition](
|
/// Edition](
|
||||||
/// https://ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf).
|
/// https://ecma-international.org/publications/files/ECMA-ST/ECMA-408.pdf).
|
||||||
assert(builder == this.member);
|
assert(constructorDeclaration == this.member);
|
||||||
assert(() {
|
assert(() {
|
||||||
if (superParametersAsArguments == null) {
|
if (superParametersAsArguments == null) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -1933,9 +1933,9 @@ class BodyBuilder extends StackListenerImpl
|
||||||
"Expected 'superParametersAsArguments' "
|
"Expected 'superParametersAsArguments' "
|
||||||
"to be sorted by occurrence in file.");
|
"to be sorted by occurrence in file.");
|
||||||
|
|
||||||
Member member = builder.member;
|
Member member = constructorDeclaration.member;
|
||||||
FunctionNode function = builder.function;
|
FunctionNode function = constructorDeclaration.function;
|
||||||
List<FormalParameterBuilder>? formals = builder.formals;
|
List<FormalParameterBuilder>? formals = constructorDeclaration.formals;
|
||||||
if (formals != null) {
|
if (formals != null) {
|
||||||
for (int i = 0; i < formals.length; i++) {
|
for (int i = 0; i < formals.length; i++) {
|
||||||
FormalParameterBuilder parameter = formals[i];
|
FormalParameterBuilder parameter = formals[i];
|
||||||
|
@ -1992,7 +1992,7 @@ class BodyBuilder extends StackListenerImpl
|
||||||
if (initializers.last is SuperInitializer) {
|
if (initializers.last is SuperInitializer) {
|
||||||
SuperInitializer superInitializer =
|
SuperInitializer superInitializer =
|
||||||
initializers.last as SuperInitializer;
|
initializers.last as SuperInitializer;
|
||||||
if (builder.classDeclaration.isEnum) {
|
if (constructorDeclaration.classDeclaration.isEnum) {
|
||||||
initializers[initializers.length - 1] = buildInvalidInitializer(
|
initializers[initializers.length - 1] = buildInvalidInitializer(
|
||||||
buildProblem(fasta.messageEnumConstructorSuperInitializer,
|
buildProblem(fasta.messageEnumConstructorSuperInitializer,
|
||||||
superInitializer.fileOffset, noLength))
|
superInitializer.fileOffset, noLength))
|
||||||
|
@ -2054,19 +2054,19 @@ class BodyBuilder extends StackListenerImpl
|
||||||
List<InitializerInferenceResult> inferenceResults =
|
List<InitializerInferenceResult> inferenceResults =
|
||||||
new List<InitializerInferenceResult>.generate(
|
new List<InitializerInferenceResult>.generate(
|
||||||
initializers.length,
|
initializers.length,
|
||||||
(index) =>
|
(index) => typeInferrer.inferInitializer(
|
||||||
typeInferrer.inferInitializer(this, initializers[index]),
|
this, constructorDeclaration, initializers[index]),
|
||||||
growable: false);
|
growable: false);
|
||||||
|
|
||||||
if (!builder.isExternal) {
|
if (!constructorDeclaration.isExternal) {
|
||||||
for (int i = 0; i < initializers.length; i++) {
|
for (int i = 0; i < initializers.length; i++) {
|
||||||
builder.addInitializer(initializers[i], this,
|
constructorDeclaration.addInitializer(initializers[i], this,
|
||||||
inferenceResult: inferenceResults[i]);
|
inferenceResult: inferenceResults[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Initializer> builtInitializers = builder.initializers;
|
List<Initializer> builtInitializers = constructorDeclaration.initializers;
|
||||||
if (asyncModifier != AsyncMarker.Sync) {
|
if (asyncModifier != AsyncMarker.Sync) {
|
||||||
builtInitializers.add(buildInvalidInitializer(buildProblem(
|
builtInitializers.add(buildInvalidInitializer(buildProblem(
|
||||||
fasta.messageConstructorNotSync, body!.fileOffset, noLength)));
|
fasta.messageConstructorNotSync, body!.fileOffset, noLength)));
|
||||||
|
@ -2110,11 +2110,11 @@ class BodyBuilder extends StackListenerImpl
|
||||||
|
|
||||||
if (superTarget == null ||
|
if (superTarget == null ||
|
||||||
checkArgumentsForFunction(superTarget.function, arguments,
|
checkArgumentsForFunction(superTarget.function, arguments,
|
||||||
builder.charOffset, const <TypeParameter>[]) !=
|
constructorDeclaration.charOffset, const <TypeParameter>[]) !=
|
||||||
null) {
|
null) {
|
||||||
String superclass =
|
String superclass =
|
||||||
sourceClassBuilder!.supertypeBuilder!.fullNameForErrors;
|
sourceClassBuilder!.supertypeBuilder!.fullNameForErrors;
|
||||||
int length = builder.name.length;
|
int length = constructorDeclaration.name.length;
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
length = sourceClassBuilder!.cls.name.length;
|
length = sourceClassBuilder!.cls.name.length;
|
||||||
}
|
}
|
||||||
|
@ -2122,17 +2122,17 @@ class BodyBuilder extends StackListenerImpl
|
||||||
buildProblem(
|
buildProblem(
|
||||||
fasta.templateSuperclassHasNoDefaultConstructor
|
fasta.templateSuperclassHasNoDefaultConstructor
|
||||||
.withArguments(superclass),
|
.withArguments(superclass),
|
||||||
builder.charOffset,
|
constructorDeclaration.charOffset,
|
||||||
length),
|
length),
|
||||||
builder.charOffset);
|
constructorDeclaration.charOffset);
|
||||||
} else {
|
} else {
|
||||||
initializer = buildSuperInitializer(
|
initializer = buildSuperInitializer(
|
||||||
true, superTarget, arguments, builder.charOffset);
|
true, superTarget, arguments, constructorDeclaration.charOffset);
|
||||||
}
|
}
|
||||||
if (libraryFeatures.superParameters.isEnabled) {
|
if (libraryFeatures.superParameters.isEnabled) {
|
||||||
InitializerInferenceResult inferenceResult =
|
InitializerInferenceResult inferenceResult = typeInferrer
|
||||||
typeInferrer.inferInitializer(this, initializer);
|
.inferInitializer(this, constructorDeclaration, initializer);
|
||||||
builder.addInitializer(initializer, this,
|
constructorDeclaration.addInitializer(initializer, this,
|
||||||
inferenceResult: inferenceResult);
|
inferenceResult: inferenceResult);
|
||||||
} else {
|
} else {
|
||||||
builtInitializers.add(initializer);
|
builtInitializers.add(initializer);
|
||||||
|
@ -7895,10 +7895,14 @@ class BodyBuilder extends StackListenerImpl
|
||||||
..fileOffset = assignmentOffset
|
..fileOffset = assignmentOffset
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
|
ConstructorDeclaration constructorBuilder =
|
||||||
|
member as ConstructorDeclaration;
|
||||||
if (formal != null && formal.type is! OmittedTypeBuilder) {
|
if (formal != null && formal.type is! OmittedTypeBuilder) {
|
||||||
DartType formalType = formal.variable!.type;
|
DartType formalType = formal.variable!.type;
|
||||||
if (!typeEnvironment.isSubtypeOf(formalType, builder.fieldType,
|
DartType fieldType =
|
||||||
SubtypeCheckMode.withNullabilities)) {
|
constructorBuilder.substituteFieldType(builder.fieldType);
|
||||||
|
if (!typeEnvironment.isSubtypeOf(
|
||||||
|
formalType, fieldType, SubtypeCheckMode.withNullabilities)) {
|
||||||
libraryBuilder.addProblem(
|
libraryBuilder.addProblem(
|
||||||
fasta.templateInitializingFormalTypeMismatch.withArguments(
|
fasta.templateInitializingFormalTypeMismatch.withArguments(
|
||||||
name,
|
name,
|
||||||
|
@ -7914,8 +7918,6 @@ class BodyBuilder extends StackListenerImpl
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConstructorDeclaration constructorBuilder =
|
|
||||||
member as ConstructorDeclaration;
|
|
||||||
constructorBuilder.registerInitializedField(builder);
|
constructorBuilder.registerInitializedField(builder);
|
||||||
return builder.buildInitializer(assignmentOffset, expression,
|
return builder.buildInitializer(assignmentOffset, expression,
|
||||||
isSynthetic: formal != null);
|
isSynthetic: formal != null);
|
||||||
|
|
|
@ -54,4 +54,12 @@ abstract class ConstructorDeclaration implements SourceFunctionBuilder {
|
||||||
/// [registerInitializedField] and passes on the ownership of the collection
|
/// [registerInitializedField] and passes on the ownership of the collection
|
||||||
/// to the caller.
|
/// to the caller.
|
||||||
Set<SourceFieldBuilder>? takeInitializedFields();
|
Set<SourceFieldBuilder>? takeInitializedFields();
|
||||||
|
|
||||||
|
/// Substitute [fieldType] from the context of the enclosing class or
|
||||||
|
/// inline class to this constructor.
|
||||||
|
///
|
||||||
|
/// This is used for generic inline class constructors where the type
|
||||||
|
/// variable referring to the class type variables must be substituted for
|
||||||
|
/// the synthesized constructor type variables.
|
||||||
|
DartType substituteFieldType(DartType fieldType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1966,8 +1966,8 @@ class OutlineBuilder extends StackListenerImpl {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bool isStatic = (modifiers & staticMask) != 0;
|
bool isStatic = (modifiers & staticMask) != 0;
|
||||||
if (constructorName == null &&
|
bool isConstructor = constructorName != null;
|
||||||
!isStatic &&
|
if (!isStatic &&
|
||||||
(libraryBuilder.currentTypeParameterScopeBuilder.kind ==
|
(libraryBuilder.currentTypeParameterScopeBuilder.kind ==
|
||||||
TypeParameterScopeKind.extensionDeclaration ||
|
TypeParameterScopeKind.extensionDeclaration ||
|
||||||
libraryBuilder.currentTypeParameterScopeBuilder.kind ==
|
libraryBuilder.currentTypeParameterScopeBuilder.kind ==
|
||||||
|
@ -1997,53 +1997,56 @@ class OutlineBuilder extends StackListenerImpl {
|
||||||
typeVariables = synthesizedTypeVariables;
|
typeVariables = synthesizedTypeVariables;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<FormalParameterBuilder> synthesizedFormals = [];
|
if (!isConstructor) {
|
||||||
TypeBuilder thisType;
|
List<FormalParameterBuilder> synthesizedFormals = [];
|
||||||
if (declaration.kind == TypeParameterScopeKind.extensionDeclaration) {
|
TypeBuilder thisType;
|
||||||
thisType = declaration.extensionThisType;
|
if (declaration.kind == TypeParameterScopeKind.extensionDeclaration) {
|
||||||
} else {
|
thisType = declaration.extensionThisType;
|
||||||
thisType = libraryBuilder.addNamedType(
|
} else {
|
||||||
declaration.name,
|
thisType = libraryBuilder.addNamedType(
|
||||||
const NullabilityBuilder.omitted(),
|
declaration.name,
|
||||||
declaration.typeVariables != null
|
const NullabilityBuilder.omitted(),
|
||||||
? new List<TypeBuilder>.generate(
|
declaration.typeVariables != null
|
||||||
declaration.typeVariables!.length,
|
? new List<TypeBuilder>.generate(
|
||||||
(int index) =>
|
declaration.typeVariables!.length,
|
||||||
new NamedTypeBuilder.fromTypeDeclarationBuilder(
|
(int index) =>
|
||||||
typeVariables![index],
|
new NamedTypeBuilder.fromTypeDeclarationBuilder(
|
||||||
const NullabilityBuilder.omitted(),
|
typeVariables![index],
|
||||||
instanceTypeVariableAccess:
|
const NullabilityBuilder.omitted(),
|
||||||
InstanceTypeVariableAccessState.Allowed))
|
instanceTypeVariableAccess:
|
||||||
: null,
|
InstanceTypeVariableAccessState.Allowed))
|
||||||
charOffset,
|
: null,
|
||||||
instanceTypeVariableAccess:
|
charOffset,
|
||||||
InstanceTypeVariableAccessState.Allowed);
|
instanceTypeVariableAccess:
|
||||||
}
|
InstanceTypeVariableAccessState.Allowed);
|
||||||
if (substitution != null) {
|
|
||||||
List<NamedTypeBuilder> unboundTypes = [];
|
|
||||||
List<TypeVariableBuilder> unboundTypeVariables = [];
|
|
||||||
thisType = substitute(thisType, substitution,
|
|
||||||
unboundTypes: unboundTypes,
|
|
||||||
unboundTypeVariables: unboundTypeVariables);
|
|
||||||
for (NamedTypeBuilder unboundType in unboundTypes) {
|
|
||||||
declaration.registerUnresolvedNamedType(unboundType);
|
|
||||||
}
|
}
|
||||||
libraryBuilder.unboundTypeVariables.addAll(unboundTypeVariables);
|
if (substitution != null) {
|
||||||
|
List<NamedTypeBuilder> unboundTypes = [];
|
||||||
|
List<TypeVariableBuilder> unboundTypeVariables = [];
|
||||||
|
thisType = substitute(thisType, substitution,
|
||||||
|
unboundTypes: unboundTypes,
|
||||||
|
unboundTypeVariables: unboundTypeVariables);
|
||||||
|
for (NamedTypeBuilder unboundType in unboundTypes) {
|
||||||
|
declaration.registerUnresolvedNamedType(unboundType);
|
||||||
|
}
|
||||||
|
libraryBuilder.unboundTypeVariables.addAll(unboundTypeVariables);
|
||||||
|
}
|
||||||
|
synthesizedFormals.add(new FormalParameterBuilder(
|
||||||
|
/* metadata = */
|
||||||
|
null,
|
||||||
|
FormalParameterKind.requiredPositional,
|
||||||
|
finalMask,
|
||||||
|
thisType,
|
||||||
|
syntheticThisName,
|
||||||
|
null,
|
||||||
|
charOffset,
|
||||||
|
fileUri: uri,
|
||||||
|
isExtensionThis: true));
|
||||||
|
if (formals != null) {
|
||||||
|
synthesizedFormals.addAll(formals);
|
||||||
|
}
|
||||||
|
formals = synthesizedFormals;
|
||||||
}
|
}
|
||||||
synthesizedFormals.add(new FormalParameterBuilder(
|
|
||||||
/* metadata = */ null,
|
|
||||||
FormalParameterKind.requiredPositional,
|
|
||||||
finalMask,
|
|
||||||
thisType,
|
|
||||||
syntheticThisName,
|
|
||||||
null,
|
|
||||||
charOffset,
|
|
||||||
fileUri: uri,
|
|
||||||
isExtensionThis: true));
|
|
||||||
if (formals != null) {
|
|
||||||
synthesizedFormals.addAll(formals);
|
|
||||||
}
|
|
||||||
formals = synthesizedFormals;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declarationBuilder.resolveNamedTypes(typeVariables, libraryBuilder);
|
declarationBuilder.resolveNamedTypes(typeVariables, libraryBuilder);
|
||||||
|
|
|
@ -137,7 +137,8 @@ abstract class AbstractSourceConstructorBuilder
|
||||||
for (FormalParameterBuilder formal in formals!) {
|
for (FormalParameterBuilder formal in formals!) {
|
||||||
if (formal.type is InferableTypeBuilder) {
|
if (formal.type is InferableTypeBuilder) {
|
||||||
if (formal.isInitializingFormal) {
|
if (formal.isInitializingFormal) {
|
||||||
formal.finalizeInitializingFormal(declarationBuilder, hierarchy);
|
formal.finalizeInitializingFormal(
|
||||||
|
declarationBuilder, this, hierarchy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -903,6 +904,13 @@ class DeclaredSourceConstructorBuilder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
DartType substituteFieldType(DartType fieldType) {
|
||||||
|
// Nothing to do. Regular generative constructors don't have their own
|
||||||
|
// type variables.
|
||||||
|
return fieldType;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SyntheticSourceConstructorBuilder extends DillConstructorBuilder
|
class SyntheticSourceConstructorBuilder extends DillConstructorBuilder
|
||||||
|
@ -1150,8 +1158,8 @@ class SourceInlineClassConstructorBuilder
|
||||||
|
|
||||||
InlineClass inlineClass = inlineClassBuilder.inlineClass;
|
InlineClass inlineClass = inlineClassBuilder.inlineClass;
|
||||||
List<DartType> typeParameterTypes = <DartType>[];
|
List<DartType> typeParameterTypes = <DartType>[];
|
||||||
for (int i = 0; i < inlineClass.typeParameters.length; i++) {
|
for (int i = 0; i < function.typeParameters.length; i++) {
|
||||||
TypeParameter typeParameter = inlineClass.typeParameters[i];
|
TypeParameter typeParameter = function.typeParameters[i];
|
||||||
typeParameterTypes.add(
|
typeParameterTypes.add(
|
||||||
new TypeParameterType.withDefaultNullabilityForLibrary(
|
new TypeParameterType.withDefaultNullabilityForLibrary(
|
||||||
typeParameter, libraryBuilder.library));
|
typeParameter, libraryBuilder.library));
|
||||||
|
@ -1166,7 +1174,6 @@ class SourceInlineClassConstructorBuilder
|
||||||
buildFunction();
|
buildFunction();
|
||||||
_constructor.function.fileOffset = charOpenParenOffset;
|
_constructor.function.fileOffset = charOpenParenOffset;
|
||||||
_constructor.function.fileEndOffset = _constructor.fileEndOffset;
|
_constructor.function.fileEndOffset = _constructor.fileEndOffset;
|
||||||
_constructor.function.typeParameters = const <TypeParameter>[];
|
|
||||||
_constructor.isConst = isConst;
|
_constructor.isConst = isConst;
|
||||||
_constructor.isExternal = isExternal;
|
_constructor.isExternal = isExternal;
|
||||||
|
|
||||||
|
@ -1224,7 +1231,30 @@ class SourceInlineClassConstructorBuilder
|
||||||
@override
|
@override
|
||||||
bool get isEffectivelyRedirecting => isRedirecting;
|
bool get isEffectivelyRedirecting => isRedirecting;
|
||||||
|
|
||||||
// TODO(johnniwinther): Generate initializers and return statement.
|
Substitution? _substitutionCache;
|
||||||
|
|
||||||
|
Substitution get _substitution {
|
||||||
|
if (typeVariables != null) {
|
||||||
|
assert(
|
||||||
|
inlineClassBuilder.typeParameters!.length == typeVariables?.length);
|
||||||
|
_substitutionCache = Substitution.fromPairs(
|
||||||
|
inlineClassBuilder.inlineClass.typeParameters,
|
||||||
|
new List<DartType>.generate(
|
||||||
|
inlineClassBuilder.typeParameters!.length,
|
||||||
|
(int index) =>
|
||||||
|
new TypeParameterType.withDefaultNullabilityForLibrary(
|
||||||
|
function.typeParameters[index],
|
||||||
|
libraryBuilder.origin.library)));
|
||||||
|
} else {
|
||||||
|
_substitutionCache = Substitution.empty;
|
||||||
|
}
|
||||||
|
return _substitutionCache!;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
DartType substituteFieldType(DartType fieldType) {
|
||||||
|
return _substitution.substituteType(fieldType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _InitializerToStatementConverter implements InitializerVisitor<void> {
|
class _InitializerToStatementConverter implements InitializerVisitor<void> {
|
||||||
|
|
|
@ -389,27 +389,7 @@ abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl
|
||||||
function.returnType =
|
function.returnType =
|
||||||
returnType.build(libraryBuilder, TypeUse.returnType);
|
returnType.build(libraryBuilder, TypeUse.returnType);
|
||||||
}
|
}
|
||||||
if (isInlineClassInstanceMember && isConstructor) {
|
if (isExtensionInstanceMember || isInlineClassInstanceMember) {
|
||||||
SourceInlineClassBuilder inlineClassBuilder =
|
|
||||||
parent as SourceInlineClassBuilder;
|
|
||||||
// TODO(johnniwinther): Support [_thisTypeParameters] for inline class
|
|
||||||
// constructors.
|
|
||||||
List<DartType> typeArguments;
|
|
||||||
if (_thisTypeParameters != null) {
|
|
||||||
typeArguments = new List<DartType>.generate(
|
|
||||||
_thisTypeParameters!.length,
|
|
||||||
(int index) => new TypeParameterType(
|
|
||||||
_thisTypeParameters![index],
|
|
||||||
TypeParameterType.computeNullabilityFromBound(
|
|
||||||
_thisTypeParameters![index])));
|
|
||||||
} else {
|
|
||||||
typeArguments = [];
|
|
||||||
}
|
|
||||||
_thisVariable = new VariableDeclarationImpl(syntheticThisName,
|
|
||||||
isFinal: true,
|
|
||||||
type: new InlineType(inlineClassBuilder.inlineClass,
|
|
||||||
libraryBuilder.nonNullable, typeArguments));
|
|
||||||
} else if (isExtensionInstanceMember || isInlineClassInstanceMember) {
|
|
||||||
SourceDeclarationBuilderMixin declarationBuilder =
|
SourceDeclarationBuilderMixin declarationBuilder =
|
||||||
parent as SourceDeclarationBuilderMixin;
|
parent as SourceDeclarationBuilderMixin;
|
||||||
if (declarationBuilder.typeParameters != null) {
|
if (declarationBuilder.typeParameters != null) {
|
||||||
|
@ -418,7 +398,27 @@ abstract class SourceFunctionBuilderImpl extends SourceMemberBuilderImpl
|
||||||
count, (int index) => function.typeParameters[index],
|
count, (int index) => function.typeParameters[index],
|
||||||
growable: false);
|
growable: false);
|
||||||
}
|
}
|
||||||
_thisVariable = function.positionalParameters.first;
|
if (isInlineClassInstanceMember && isConstructor) {
|
||||||
|
SourceInlineClassBuilder inlineClassBuilder =
|
||||||
|
parent as SourceInlineClassBuilder;
|
||||||
|
List<DartType> typeArguments;
|
||||||
|
if (_thisTypeParameters != null) {
|
||||||
|
typeArguments = new List<DartType>.generate(
|
||||||
|
_thisTypeParameters!.length,
|
||||||
|
(int index) => new TypeParameterType(
|
||||||
|
_thisTypeParameters![index],
|
||||||
|
TypeParameterType.computeNullabilityFromBound(
|
||||||
|
_thisTypeParameters![index])));
|
||||||
|
} else {
|
||||||
|
typeArguments = [];
|
||||||
|
}
|
||||||
|
_thisVariable = new VariableDeclarationImpl(syntheticThisName,
|
||||||
|
isFinal: true,
|
||||||
|
type: new InlineType(inlineClassBuilder.inlineClass,
|
||||||
|
libraryBuilder.nonNullable, typeArguments));
|
||||||
|
} else {
|
||||||
|
_thisVariable = function.positionalParameters.first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ import '../kernel/internal_ast.dart';
|
||||||
import '../kernel/late_lowering.dart' as late_lowering;
|
import '../kernel/late_lowering.dart' as late_lowering;
|
||||||
import '../names.dart';
|
import '../names.dart';
|
||||||
import '../problems.dart' show unhandled;
|
import '../problems.dart' show unhandled;
|
||||||
|
import '../source/constructor_declaration.dart';
|
||||||
import '../source/source_library_builder.dart';
|
import '../source/source_library_builder.dart';
|
||||||
import '../uri_offset.dart';
|
import '../uri_offset.dart';
|
||||||
import 'closure_context.dart';
|
import 'closure_context.dart';
|
||||||
|
@ -128,12 +129,14 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||||
@override
|
@override
|
||||||
final TypeAnalyzerOptions options;
|
final TypeAnalyzerOptions options;
|
||||||
|
|
||||||
|
final ConstructorDeclaration? constructorDeclaration;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
late final SharedTypeAnalyzerErrors errors = new SharedTypeAnalyzerErrors(
|
late final SharedTypeAnalyzerErrors errors = new SharedTypeAnalyzerErrors(
|
||||||
helper: helper, uriForInstrumentation: uriForInstrumentation);
|
helper: helper, uriForInstrumentation: uriForInstrumentation);
|
||||||
|
|
||||||
InferenceVisitorImpl(
|
InferenceVisitorImpl(TypeInferrerImpl inferrer, InferenceHelper helper,
|
||||||
TypeInferrerImpl inferrer, InferenceHelper helper, this.operations)
|
this.constructorDeclaration, this.operations)
|
||||||
: options = new TypeAnalyzerOptions(
|
: options = new TypeAnalyzerOptions(
|
||||||
nullSafetyEnabled: inferrer.libraryBuilder.isNonNullableByDefault,
|
nullSafetyEnabled: inferrer.libraryBuilder.isNonNullableByDefault,
|
||||||
patternsEnabled: false),
|
patternsEnabled: false),
|
||||||
|
@ -1301,10 +1304,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
||||||
|
|
||||||
@override
|
@override
|
||||||
InitializerInferenceResult visitFieldInitializer(FieldInitializer node) {
|
InitializerInferenceResult visitFieldInitializer(FieldInitializer node) {
|
||||||
|
DartType fieldType = node.field.type;
|
||||||
|
fieldType = constructorDeclaration!.substituteFieldType(fieldType);
|
||||||
ExpressionInferenceResult initializerResult =
|
ExpressionInferenceResult initializerResult =
|
||||||
inferExpression(node.value, node.field.type);
|
inferExpression(node.value, fieldType);
|
||||||
Expression initializer = ensureAssignableResult(
|
Expression initializer = ensureAssignableResult(
|
||||||
node.field.type, initializerResult,
|
fieldType, initializerResult,
|
||||||
fileOffset: node.fileOffset)
|
fileOffset: node.fileOffset)
|
||||||
.expression;
|
.expression;
|
||||||
node.value = initializer..parent = node;
|
node.value = initializer..parent = node;
|
||||||
|
|
|
@ -9,6 +9,7 @@ import 'package:kernel/ast.dart';
|
||||||
import '../../base/instrumentation.dart' show Instrumentation;
|
import '../../base/instrumentation.dart' show Instrumentation;
|
||||||
import '../kernel/benchmarker.dart' show BenchmarkSubdivides, Benchmarker;
|
import '../kernel/benchmarker.dart' show BenchmarkSubdivides, Benchmarker;
|
||||||
import '../kernel/internal_ast.dart';
|
import '../kernel/internal_ast.dart';
|
||||||
|
import '../source/constructor_declaration.dart';
|
||||||
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
|
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
|
||||||
import 'closure_context.dart';
|
import 'closure_context.dart';
|
||||||
import 'inference_helper.dart' show InferenceHelper;
|
import 'inference_helper.dart' show InferenceHelper;
|
||||||
|
@ -59,8 +60,8 @@ abstract class TypeInferrer {
|
||||||
DartType returnType, AsyncMarker asyncMarker, Statement body);
|
DartType returnType, AsyncMarker asyncMarker, Statement body);
|
||||||
|
|
||||||
/// Performs type inference on the given constructor initializer.
|
/// Performs type inference on the given constructor initializer.
|
||||||
InitializerInferenceResult inferInitializer(
|
InitializerInferenceResult inferInitializer(InferenceHelper helper,
|
||||||
InferenceHelper helper, Initializer initializer);
|
ConstructorDeclaration constructorDeclaration, Initializer initializer);
|
||||||
|
|
||||||
/// Performs type inference on the given metadata annotations.
|
/// Performs type inference on the given metadata annotations.
|
||||||
void inferMetadata(
|
void inferMetadata(
|
||||||
|
@ -144,10 +145,12 @@ class TypeInferrerImpl implements TypeInferrer {
|
||||||
unpromotablePrivateFieldNames:
|
unpromotablePrivateFieldNames:
|
||||||
libraryBuilder.unpromotablePrivateFieldNames);
|
libraryBuilder.unpromotablePrivateFieldNames);
|
||||||
|
|
||||||
InferenceVisitorBase _createInferenceVisitor(InferenceHelper helper) {
|
InferenceVisitorBase _createInferenceVisitor(InferenceHelper helper,
|
||||||
|
[ConstructorDeclaration? constructorDeclaration]) {
|
||||||
// For full (non-top level) inference, we need access to the
|
// For full (non-top level) inference, we need access to the
|
||||||
// InferenceHelper so that we can perform error reporting.
|
// InferenceHelper so that we can perform error reporting.
|
||||||
return new InferenceVisitorImpl(this, helper, operations);
|
return new InferenceVisitorImpl(
|
||||||
|
this, helper, constructorDeclaration, operations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -244,14 +247,15 @@ class TypeInferrerImpl implements TypeInferrer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
InitializerInferenceResult inferInitializer(
|
InitializerInferenceResult inferInitializer(InferenceHelper helper,
|
||||||
InferenceHelper helper, Initializer initializer) {
|
ConstructorDeclaration constructorDeclaration, Initializer initializer) {
|
||||||
// Use polymorphic dispatch on [KernelInitializer] to perform whatever
|
// Use polymorphic dispatch on [KernelInitializer] to perform whatever
|
||||||
// kind of type inference is correct for this kind of initializer.
|
// kind of type inference is correct for this kind of initializer.
|
||||||
// TODO(paulberry): experiment to see if dynamic dispatch would be better,
|
// TODO(paulberry): experiment to see if dynamic dispatch would be better,
|
||||||
// so that the type hierarchy will be simpler (which may speed up "is"
|
// so that the type hierarchy will be simpler (which may speed up "is"
|
||||||
// checks).
|
// checks).
|
||||||
InferenceVisitorBase visitor = _createInferenceVisitor(helper);
|
InferenceVisitorBase visitor =
|
||||||
|
_createInferenceVisitor(helper, constructorDeclaration);
|
||||||
InitializerInferenceResult result = visitor.inferInitializer(initializer);
|
InitializerInferenceResult result = visitor.inferInitializer(initializer);
|
||||||
visitor.checkCleanState();
|
visitor.checkCleanState();
|
||||||
return result;
|
return result;
|
||||||
|
@ -356,11 +360,11 @@ class TypeInferrerImplBenchmarked implements TypeInferrer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
InitializerInferenceResult inferInitializer(
|
InitializerInferenceResult inferInitializer(InferenceHelper helper,
|
||||||
InferenceHelper helper, Initializer initializer) {
|
ConstructorDeclaration constructorDeclaration, Initializer initializer) {
|
||||||
benchmarker.beginSubdivide(BenchmarkSubdivides.inferInitializer);
|
benchmarker.beginSubdivide(BenchmarkSubdivides.inferInitializer);
|
||||||
InitializerInferenceResult result =
|
InitializerInferenceResult result =
|
||||||
impl.inferInitializer(helper, initializer);
|
impl.inferInitializer(helper, constructorDeclaration, initializer);
|
||||||
benchmarker.endSubdivide();
|
benchmarker.endSubdivide();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ inline class Class1 {
|
||||||
|
|
||||||
Class1.named1(this.it, int additional);
|
Class1.named1(this.it, int additional);
|
||||||
|
|
||||||
Class1.named2(this.it, int additional) {
|
Class1.named2(int this.it, int additional) {
|
||||||
print(additional);
|
print(additional);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ inline class Class1 {
|
||||||
Class1.named6(String text) : it = text.length;
|
Class1.named6(String text) : it = text.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO(johnniwinther): Support generic inline class constructors.
|
|
||||||
inline class Class2<T> {
|
inline class Class2<T> {
|
||||||
final T it;
|
final T it;
|
||||||
|
|
||||||
|
@ -32,7 +31,7 @@ inline class Class2<T> {
|
||||||
|
|
||||||
Class2.named1(this.it, int additional);
|
Class2.named1(this.it, int additional);
|
||||||
|
|
||||||
Class2.named2(this.it, int additional) {
|
Class2.named2(T this.it, int additional) {
|
||||||
print(additional);
|
print(additional);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,4 +44,4 @@ inline class Class2<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Class2.named6(List<T> list) : it = list.first;
|
Class2.named6(List<T> list) : it = list.first;
|
||||||
}*/
|
}
|
|
@ -11,6 +11,15 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor named5 = self::Class1|named5;
|
constructor named5 = self::Class1|named5;
|
||||||
constructor named6 = self::Class1|named6;
|
constructor named6 = self::Class1|named6;
|
||||||
}
|
}
|
||||||
|
inline class Class2<T extends core::Object? = dynamic> /* declaredRepresentationType = T% */ {
|
||||||
|
constructor • = self::Class2|;
|
||||||
|
constructor named1 = self::Class2|named1;
|
||||||
|
constructor named2 = self::Class2|named2;
|
||||||
|
constructor named3 = self::Class2|named3;
|
||||||
|
constructor named4 = self::Class2|named4;
|
||||||
|
constructor named5 = self::Class2|named5;
|
||||||
|
constructor named6 = self::Class2|named6;
|
||||||
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
|
@ -45,3 +54,37 @@ method Class1|named6(core::String text) → self::Class1 {
|
||||||
final self::Class1 #this = text.{core::String::length}{core::int};
|
final self::Class1 #this = text.{core::String::length}{core::int};
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class2|<T extends core::Object? = dynamic>(self::Class2|::T% it) → self::Class2<self::Class2|::T%> {
|
||||||
|
final self::Class2<self::Class2|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named1<T extends core::Object? = dynamic>(self::Class2|named1::T% it, core::int additional) → self::Class2<self::Class2|named1::T%> {
|
||||||
|
final self::Class2<self::Class2|named1::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named2<T extends core::Object? = dynamic>(self::Class2|named2::T% it, core::int additional) → self::Class2<self::Class2|named2::T%> {
|
||||||
|
final self::Class2<self::Class2|named2::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named3<T extends core::Object? = dynamic>(self::Class2|named3::T% it) → self::Class2<self::Class2|named3::T%> {
|
||||||
|
final self::Class2<self::Class2|named3::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named4<T extends core::Object? = dynamic>(core::int additional, self::Class2|named4::T% it) → self::Class2<self::Class2|named4::T%> {
|
||||||
|
final self::Class2<self::Class2|named4::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named5<T extends core::Object? = dynamic>(core::int additional, self::Class2|named5::T% it) → self::Class2<self::Class2|named5::T%> {
|
||||||
|
final self::Class2<self::Class2|named5::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named6<T extends core::Object? = dynamic>(core::List<self::Class2|named6::T%> list) → self::Class2<self::Class2|named6::T%> {
|
||||||
|
final self::Class2<self::Class2|named6::T%> #this = list.{core::Iterable::first}{self::Class2|named6::T%};
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,15 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor named5 = self::Class1|named5;
|
constructor named5 = self::Class1|named5;
|
||||||
constructor named6 = self::Class1|named6;
|
constructor named6 = self::Class1|named6;
|
||||||
}
|
}
|
||||||
|
inline class Class2<T extends core::Object? = dynamic> /* declaredRepresentationType = T% */ {
|
||||||
|
constructor • = self::Class2|;
|
||||||
|
constructor named1 = self::Class2|named1;
|
||||||
|
constructor named2 = self::Class2|named2;
|
||||||
|
constructor named3 = self::Class2|named3;
|
||||||
|
constructor named4 = self::Class2|named4;
|
||||||
|
constructor named5 = self::Class2|named5;
|
||||||
|
constructor named6 = self::Class2|named6;
|
||||||
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
|
@ -45,3 +54,37 @@ method Class1|named6(core::String text) → self::Class1 {
|
||||||
final self::Class1 #this = text.{core::String::length}{core::int};
|
final self::Class1 #this = text.{core::String::length}{core::int};
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class2|<T extends core::Object? = dynamic>(self::Class2|::T% it) → self::Class2<self::Class2|::T%> {
|
||||||
|
final self::Class2<self::Class2|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named1<T extends core::Object? = dynamic>(self::Class2|named1::T% it, core::int additional) → self::Class2<self::Class2|named1::T%> {
|
||||||
|
final self::Class2<self::Class2|named1::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named2<T extends core::Object? = dynamic>(self::Class2|named2::T% it, core::int additional) → self::Class2<self::Class2|named2::T%> {
|
||||||
|
final self::Class2<self::Class2|named2::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named3<T extends core::Object? = dynamic>(self::Class2|named3::T% it) → self::Class2<self::Class2|named3::T%> {
|
||||||
|
final self::Class2<self::Class2|named3::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named4<T extends core::Object? = dynamic>(core::int additional, self::Class2|named4::T% it) → self::Class2<self::Class2|named4::T%> {
|
||||||
|
final self::Class2<self::Class2|named4::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named5<T extends core::Object? = dynamic>(core::int additional, self::Class2|named5::T% it) → self::Class2<self::Class2|named5::T%> {
|
||||||
|
final self::Class2<self::Class2|named5::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named6<T extends core::Object? = dynamic>(core::List<self::Class2|named6::T%> list) → self::Class2<self::Class2|named6::T%> {
|
||||||
|
final self::Class2<self::Class2|named6::T%> #this = list.{core::Iterable::first}{self::Class2|named6::T%};
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
|
|
@ -3,9 +3,20 @@ class Class1 {
|
||||||
final int it;
|
final int it;
|
||||||
Class1(this.it);
|
Class1(this.it);
|
||||||
Class1.named1(this.it, int additional);
|
Class1.named1(this.it, int additional);
|
||||||
Class1.named2(this.it, int additional) {}
|
Class1.named2(int this.it, int additional) {}
|
||||||
Class1.named3(int it) : this.it = it;
|
Class1.named3(int it) : this.it = it;
|
||||||
Class1.named4(int additional, int it) : this.it = it;
|
Class1.named4(int additional, int it) : this.it = it;
|
||||||
Class1.named5(int additional, int it) : this.it = it {}
|
Class1.named5(int additional, int it) : this.it = it {}
|
||||||
Class1.named6(String text) : it = text.length;
|
Class1.named6(String text) : it = text.length;
|
||||||
}
|
}
|
||||||
|
inline
|
||||||
|
class Class2<T> {
|
||||||
|
final T it;
|
||||||
|
Class2(this.it);
|
||||||
|
Class2.named1(this.it, int additional);
|
||||||
|
Class2.named2(T this.it, int additional) {}
|
||||||
|
Class2.named3(T it) : this.it = it;
|
||||||
|
Class2.named4(int additional, T it) : this.it = it;
|
||||||
|
Class2.named5(int additional, T it) : this.it = it {}
|
||||||
|
Class2.named6(List<T> list) : it = list.first;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,15 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor named5 = self::Class1|named5;
|
constructor named5 = self::Class1|named5;
|
||||||
constructor named6 = self::Class1|named6;
|
constructor named6 = self::Class1|named6;
|
||||||
}
|
}
|
||||||
|
inline class Class2<T extends core::Object? = dynamic> /* declaredRepresentationType = T% */ {
|
||||||
|
constructor • = self::Class2|;
|
||||||
|
constructor named1 = self::Class2|named1;
|
||||||
|
constructor named2 = self::Class2|named2;
|
||||||
|
constructor named3 = self::Class2|named3;
|
||||||
|
constructor named4 = self::Class2|named4;
|
||||||
|
constructor named5 = self::Class2|named5;
|
||||||
|
constructor named6 = self::Class2|named6;
|
||||||
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
|
@ -45,3 +54,37 @@ method Class1|named6(core::String text) → self::Class1 {
|
||||||
final self::Class1 #this = text.{core::String::length}{core::int};
|
final self::Class1 #this = text.{core::String::length}{core::int};
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class2|<T extends core::Object? = dynamic>(self::Class2|::T% it) → self::Class2<self::Class2|::T%> {
|
||||||
|
final self::Class2<self::Class2|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named1<T extends core::Object? = dynamic>(self::Class2|named1::T% it, core::int additional) → self::Class2<self::Class2|named1::T%> {
|
||||||
|
final self::Class2<self::Class2|named1::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named2<T extends core::Object? = dynamic>(self::Class2|named2::T% it, core::int additional) → self::Class2<self::Class2|named2::T%> {
|
||||||
|
final self::Class2<self::Class2|named2::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named3<T extends core::Object? = dynamic>(self::Class2|named3::T% it) → self::Class2<self::Class2|named3::T%> {
|
||||||
|
final self::Class2<self::Class2|named3::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named4<T extends core::Object? = dynamic>(core::int additional, self::Class2|named4::T% it) → self::Class2<self::Class2|named4::T%> {
|
||||||
|
final self::Class2<self::Class2|named4::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named5<T extends core::Object? = dynamic>(core::int additional, self::Class2|named5::T% it) → self::Class2<self::Class2|named5::T%> {
|
||||||
|
final self::Class2<self::Class2|named5::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named6<T extends core::Object? = dynamic>(core::List<self::Class2|named6::T%> list) → self::Class2<self::Class2|named6::T%> {
|
||||||
|
final self::Class2<self::Class2|named6::T%> #this = list.{core::Iterable::first}{self::Class2|named6::T%};
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,15 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor named5 = self::Class1|named5;
|
constructor named5 = self::Class1|named5;
|
||||||
constructor named6 = self::Class1|named6;
|
constructor named6 = self::Class1|named6;
|
||||||
}
|
}
|
||||||
|
inline class Class2<T extends core::Object? = dynamic> /* declaredRepresentationType = T% */ {
|
||||||
|
constructor • = self::Class2|;
|
||||||
|
constructor named1 = self::Class2|named1;
|
||||||
|
constructor named2 = self::Class2|named2;
|
||||||
|
constructor named3 = self::Class2|named3;
|
||||||
|
constructor named4 = self::Class2|named4;
|
||||||
|
constructor named5 = self::Class2|named5;
|
||||||
|
constructor named6 = self::Class2|named6;
|
||||||
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
|
@ -45,3 +54,37 @@ method Class1|named6(core::String text) → self::Class1 {
|
||||||
final self::Class1 #this = text.{core::String::length}{core::int};
|
final self::Class1 #this = text.{core::String::length}{core::int};
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class2|<T extends core::Object? = dynamic>(self::Class2|::T% it) → self::Class2<self::Class2|::T%> {
|
||||||
|
final self::Class2<self::Class2|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named1<T extends core::Object? = dynamic>(self::Class2|named1::T% it, core::int additional) → self::Class2<self::Class2|named1::T%> {
|
||||||
|
final self::Class2<self::Class2|named1::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named2<T extends core::Object? = dynamic>(self::Class2|named2::T% it, core::int additional) → self::Class2<self::Class2|named2::T%> {
|
||||||
|
final self::Class2<self::Class2|named2::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named3<T extends core::Object? = dynamic>(self::Class2|named3::T% it) → self::Class2<self::Class2|named3::T%> {
|
||||||
|
final self::Class2<self::Class2|named3::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named4<T extends core::Object? = dynamic>(core::int additional, self::Class2|named4::T% it) → self::Class2<self::Class2|named4::T%> {
|
||||||
|
final self::Class2<self::Class2|named4::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named5<T extends core::Object? = dynamic>(core::int additional, self::Class2|named5::T% it) → self::Class2<self::Class2|named5::T%> {
|
||||||
|
final self::Class2<self::Class2|named5::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named6<T extends core::Object? = dynamic>(core::List<self::Class2|named6::T%> list) → self::Class2<self::Class2|named6::T%> {
|
||||||
|
final self::Class2<self::Class2|named6::T%> #this = list.{core::Iterable::first}{self::Class2|named6::T%};
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,15 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor named5 = self::Class1|named5;
|
constructor named5 = self::Class1|named5;
|
||||||
constructor named6 = self::Class1|named6;
|
constructor named6 = self::Class1|named6;
|
||||||
}
|
}
|
||||||
|
inline class Class2<T extends core::Object? = dynamic> /* declaredRepresentationType = T% */ {
|
||||||
|
constructor • = self::Class2|;
|
||||||
|
constructor named1 = self::Class2|named1;
|
||||||
|
constructor named2 = self::Class2|named2;
|
||||||
|
constructor named3 = self::Class2|named3;
|
||||||
|
constructor named4 = self::Class2|named4;
|
||||||
|
constructor named5 = self::Class2|named5;
|
||||||
|
constructor named6 = self::Class2|named6;
|
||||||
|
}
|
||||||
method Class1|(core::int it) → self::Class1
|
method Class1|(core::int it) → self::Class1
|
||||||
;
|
;
|
||||||
method Class1|named1(core::int it, core::int additional) → self::Class1
|
method Class1|named1(core::int it, core::int additional) → self::Class1
|
||||||
|
@ -25,3 +34,17 @@ method Class1|named5(core::int additional, core::int it) → self::Class1
|
||||||
;
|
;
|
||||||
method Class1|named6(core::String text) → self::Class1
|
method Class1|named6(core::String text) → self::Class1
|
||||||
;
|
;
|
||||||
|
method Class2|<T extends core::Object? = dynamic>(self::Class2|::T% it) → self::Class2<self::Class2|::T%>
|
||||||
|
;
|
||||||
|
method Class2|named1<T extends core::Object? = dynamic>(self::Class2|named1::T% it, core::int additional) → self::Class2<self::Class2|named1::T%>
|
||||||
|
;
|
||||||
|
method Class2|named2<T extends core::Object? = dynamic>(self::Class2|named2::T% it, core::int additional) → self::Class2<self::Class2|named2::T%>
|
||||||
|
;
|
||||||
|
method Class2|named3<T extends core::Object? = dynamic>(self::Class2|named3::T% it) → self::Class2<self::Class2|named3::T%>
|
||||||
|
;
|
||||||
|
method Class2|named4<T extends core::Object? = dynamic>(core::int additional, self::Class2|named4::T% it) → self::Class2<self::Class2|named4::T%>
|
||||||
|
;
|
||||||
|
method Class2|named5<T extends core::Object? = dynamic>(core::int additional, self::Class2|named5::T% it) → self::Class2<self::Class2|named5::T%>
|
||||||
|
;
|
||||||
|
method Class2|named6<T extends core::Object? = dynamic>(core::List<self::Class2|named6::T%> list) → self::Class2<self::Class2|named6::T%>
|
||||||
|
;
|
||||||
|
|
|
@ -11,6 +11,15 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor named5 = self::Class1|named5;
|
constructor named5 = self::Class1|named5;
|
||||||
constructor named6 = self::Class1|named6;
|
constructor named6 = self::Class1|named6;
|
||||||
}
|
}
|
||||||
|
inline class Class2<T extends core::Object? = dynamic> /* declaredRepresentationType = T% */ {
|
||||||
|
constructor • = self::Class2|;
|
||||||
|
constructor named1 = self::Class2|named1;
|
||||||
|
constructor named2 = self::Class2|named2;
|
||||||
|
constructor named3 = self::Class2|named3;
|
||||||
|
constructor named4 = self::Class2|named4;
|
||||||
|
constructor named5 = self::Class2|named5;
|
||||||
|
constructor named6 = self::Class2|named6;
|
||||||
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
|
@ -45,3 +54,37 @@ method Class1|named6(core::String text) → self::Class1 {
|
||||||
final self::Class1 #this = text.{core::String::length}{core::int};
|
final self::Class1 #this = text.{core::String::length}{core::int};
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class2|<T extends core::Object? = dynamic>(self::Class2|::T% it) → self::Class2<self::Class2|::T%> {
|
||||||
|
final self::Class2<self::Class2|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named1<T extends core::Object? = dynamic>(self::Class2|named1::T% it, core::int additional) → self::Class2<self::Class2|named1::T%> {
|
||||||
|
final self::Class2<self::Class2|named1::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named2<T extends core::Object? = dynamic>(self::Class2|named2::T% it, core::int additional) → self::Class2<self::Class2|named2::T%> {
|
||||||
|
final self::Class2<self::Class2|named2::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named3<T extends core::Object? = dynamic>(self::Class2|named3::T% it) → self::Class2<self::Class2|named3::T%> {
|
||||||
|
final self::Class2<self::Class2|named3::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named4<T extends core::Object? = dynamic>(core::int additional, self::Class2|named4::T% it) → self::Class2<self::Class2|named4::T%> {
|
||||||
|
final self::Class2<self::Class2|named4::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named5<T extends core::Object? = dynamic>(core::int additional, self::Class2|named5::T% it) → self::Class2<self::Class2|named5::T%> {
|
||||||
|
final self::Class2<self::Class2|named5::T%> #this = it;
|
||||||
|
{
|
||||||
|
core::print(additional);
|
||||||
|
}
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
method Class2|named6<T extends core::Object? = dynamic>(core::List<self::Class2|named6::T%> list) → self::Class2<self::Class2|named6::T%> {
|
||||||
|
final self::Class2<self::Class2|named6::T%> #this = list.{core::Iterable::first}{self::Class2|named6::T%};
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ inline class Class1 {
|
||||||
inline class Class2 = Object with Mixin;
|
inline class Class2 = Object with Mixin;
|
||||||
inline class Class3<T> {
|
inline class Class3<T> {
|
||||||
final List<T> it;
|
final List<T> it;
|
||||||
// TODO(johnniwinther): Support generic inline class constructor.
|
|
||||||
|
Class3(this.it);
|
||||||
}
|
}
|
||||||
|
|
||||||
method(Class1 c1, Class3<int> c3) {}
|
method(Class1 c1, Class3<int> c3) {}
|
|
@ -1,12 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/inline_class/inline_class_declaration.dart:13:17: Error: Final field 'it' is not initialized.
|
|
||||||
// Try to initialize the field in the declaration or in every constructor.
|
|
||||||
// final List<T> it;
|
|
||||||
// ^^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -21,9 +13,14 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor • = self::Class1|;
|
constructor • = self::Class1|;
|
||||||
}
|
}
|
||||||
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
||||||
|
constructor • = self::Class3|;
|
||||||
}
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class3|<T extends core::Object? = dynamic>(core::List<self::Class3|::T%> it) → self::Class3<self::Class3|::T%> {
|
||||||
|
final self::Class3<self::Class3|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/inline_class/inline_class_declaration.dart:13:17: Error: Final field 'it' is not initialized.
|
|
||||||
// Try to initialize the field in the declaration or in every constructor.
|
|
||||||
// final List<T> it;
|
|
||||||
// ^^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -21,9 +13,14 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor • = self::Class1|;
|
constructor • = self::Class1|;
|
||||||
}
|
}
|
||||||
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
||||||
|
constructor • = self::Class3|;
|
||||||
}
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class3|<T extends core::Object? = dynamic>(core::List<self::Class3|::T%> it) → self::Class3<self::Class3|::T%> {
|
||||||
|
final self::Class3<self::Class3|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
||||||
|
|
|
@ -9,5 +9,6 @@ class Class2 = Object with Mixin;
|
||||||
inline
|
inline
|
||||||
class Class3<T> {
|
class Class3<T> {
|
||||||
final List<T> it;
|
final List<T> it;
|
||||||
|
Class3(this.it);
|
||||||
}
|
}
|
||||||
method(Class1 c1, Class3<int> c3) {}
|
method(Class1 c1, Class3<int> c3) {}
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/inline_class/inline_class_declaration.dart:13:17: Error: Final field 'it' is not initialized.
|
|
||||||
// Try to initialize the field in the declaration or in every constructor.
|
|
||||||
// final List<T> it;
|
|
||||||
// ^^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -21,9 +13,14 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor • = self::Class1|;
|
constructor • = self::Class1|;
|
||||||
}
|
}
|
||||||
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
||||||
|
constructor • = self::Class3|;
|
||||||
}
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class3|<T extends core::Object? = dynamic>(core::List<self::Class3|::T%> it) → self::Class3<self::Class3|::T%> {
|
||||||
|
final self::Class3<self::Class3|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/inline_class/inline_class_declaration.dart:13:17: Error: Final field 'it' is not initialized.
|
|
||||||
// Try to initialize the field in the declaration or in every constructor.
|
|
||||||
// final List<T> it;
|
|
||||||
// ^^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -21,9 +13,14 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor • = self::Class1|;
|
constructor • = self::Class1|;
|
||||||
}
|
}
|
||||||
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
||||||
|
constructor • = self::Class3|;
|
||||||
}
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class3|<T extends core::Object? = dynamic>(core::List<self::Class3|::T%> it) → self::Class3<self::Class3|::T%> {
|
||||||
|
final self::Class3<self::Class3|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
||||||
|
|
|
@ -13,8 +13,11 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor • = self::Class1|;
|
constructor • = self::Class1|;
|
||||||
}
|
}
|
||||||
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
||||||
|
constructor • = self::Class3|;
|
||||||
}
|
}
|
||||||
method Class1|(core::int it) → self::Class1
|
method Class1|(core::int it) → self::Class1
|
||||||
;
|
;
|
||||||
|
method Class3|<T extends core::Object? = dynamic>(core::List<self::Class3|::T%> it) → self::Class3<self::Class3|::T%>
|
||||||
|
;
|
||||||
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic
|
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,12 +1,4 @@
|
||||||
library /*isNonNullableByDefault*/;
|
library /*isNonNullableByDefault*/;
|
||||||
//
|
|
||||||
// Problems in library:
|
|
||||||
//
|
|
||||||
// pkg/front_end/testcases/inline_class/inline_class_declaration.dart:13:17: Error: Final field 'it' is not initialized.
|
|
||||||
// Try to initialize the field in the declaration or in every constructor.
|
|
||||||
// final List<T> it;
|
|
||||||
// ^^
|
|
||||||
//
|
|
||||||
import self as self;
|
import self as self;
|
||||||
import "dart:core" as core;
|
import "dart:core" as core;
|
||||||
|
|
||||||
|
@ -21,9 +13,14 @@ inline class Class1 /* declaredRepresentationType = core::int */ {
|
||||||
constructor • = self::Class1|;
|
constructor • = self::Class1|;
|
||||||
}
|
}
|
||||||
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
inline class Class3<T extends core::Object? = dynamic> /* declaredRepresentationType = core::List<T%> */ {
|
||||||
|
constructor • = self::Class3|;
|
||||||
}
|
}
|
||||||
method Class1|(core::int it) → self::Class1 {
|
method Class1|(core::int it) → self::Class1 {
|
||||||
final self::Class1 #this = it;
|
final self::Class1 #this = it;
|
||||||
return #this;
|
return #this;
|
||||||
}
|
}
|
||||||
|
method Class3|<T extends core::Object? = dynamic>(core::List<self::Class3|::T%> it) → self::Class3<self::Class3|::T%> {
|
||||||
|
final self::Class3<self::Class3|::T%> #this = it;
|
||||||
|
return #this;
|
||||||
|
}
|
||||||
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
static method method(self::Class1 c1, self::Class3<core::int> c3) → dynamic {}
|
||||||
|
|
Loading…
Reference in a new issue