mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 18:49:37 +00:00
[fasta] Preserve information about const constructors in outline.
- for classes with const constructors parse field initializers; - for const constructions parse initializer lists and default parameter values; Fixes issue https://github.com/dart-lang/sdk/issues/37357 Fixes issue https://github.com/dart-lang/sdk/issues/36635 Change-Id: Iff0e47f8bd2925cee9f42a2b309de4de84e99cad Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/108279 Commit-Queue: Vyacheslav Egorov <vegorov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
25319ef7a6
commit
a86db84e0a
|
@ -996,8 +996,14 @@ class AstBuilder extends StackListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
assert(optionalOrNull('this', thisKeyword));
|
||||
assert(thisKeyword == null
|
||||
? periodAfterThis == null
|
||||
|
|
|
@ -762,11 +762,17 @@ class ForwardingTestListener extends ForwardingListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
end('FormalParameter');
|
||||
super.endFormalParameter(
|
||||
thisKeyword, periodAfterThis, nameToken, kind, memberKind);
|
||||
super.endFormalParameter(thisKeyword, periodAfterThis, nameToken,
|
||||
initializerStart, initializerEnd, kind, memberKind);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -297,8 +297,14 @@ class MiniAstBuilder extends StackListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
debugEvent("FormalParameter");
|
||||
pop(); // Name
|
||||
pop(); // Type
|
||||
|
|
|
@ -50,4 +50,6 @@ abstract class FormalParameterBuilder<T extends TypeBuilder>
|
|||
String get fullNameForErrors => name;
|
||||
|
||||
FormalParameterBuilder forFormalParameterInitializerScope();
|
||||
|
||||
void buildOutlineExpressions(LibraryBuilder library);
|
||||
}
|
||||
|
|
|
@ -633,6 +633,7 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
ProcedureBuilder<TypeBuilder> member = this.member;
|
||||
scope = member.computeFormalParameterInitializerScope(scope);
|
||||
if (member is KernelConstructorBuilder) {
|
||||
member.prepareInitializers();
|
||||
if (member.formals != null) {
|
||||
for (KernelFormalParameterBuilder formal in member.formals) {
|
||||
if (formal.isInitializingFormal) {
|
||||
|
@ -1128,6 +1129,16 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
return fakeReturn.expression;
|
||||
}
|
||||
|
||||
void parseInitializers(Token token) {
|
||||
Parser parser = new Parser(this);
|
||||
if (!token.isEof) {
|
||||
token = parser.parseInitializers(token);
|
||||
checkEmpty(token.charOffset);
|
||||
} else {
|
||||
handleNoInitializers();
|
||||
}
|
||||
}
|
||||
|
||||
Expression parseFieldInitializer(Token token) {
|
||||
Parser parser = new Parser(this);
|
||||
token = parser.parseExpression(parser.syntheticPreviousToken(token));
|
||||
|
@ -2886,8 +2897,14 @@ abstract class BodyBuilder extends ScopeListener<JumpTarget>
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
debugEvent("FormalParameter");
|
||||
if (thisKeyword != null) {
|
||||
if (!inConstructor) {
|
||||
|
|
|
@ -59,8 +59,8 @@ class KernelBodyBuilder extends BodyBuilder {
|
|||
classBuilder,
|
||||
member?.isInstanceMember ?? false,
|
||||
fileUri,
|
||||
library.loader.typeInferenceEngine
|
||||
?.createLocalTypeInferrer(fileUri, null, library));
|
||||
library.loader.typeInferenceEngine?.createLocalTypeInferrer(
|
||||
fileUri, classBuilder?.target?.thisType, library));
|
||||
|
||||
@override
|
||||
void enterThenForTypePromotion(Expression condition) {
|
||||
|
|
|
@ -109,7 +109,16 @@ class KernelFieldBuilder extends FieldBuilder<Expression> {
|
|||
ClassBuilder classBuilder = isClassMember ? parent : null;
|
||||
KernelMetadataBuilder.buildAnnotations(
|
||||
field, metadata, library, classBuilder, this);
|
||||
if (constInitializerToken != null) {
|
||||
|
||||
// For modular compilation we need to include initializers of all const
|
||||
// fields and all non-static final fields in classes with const constructors
|
||||
// into the outline.
|
||||
if ((isConst ||
|
||||
(isFinal &&
|
||||
!isStatic &&
|
||||
isClassMember &&
|
||||
classBuilder.hasConstConstructor)) &&
|
||||
constInitializerToken != null) {
|
||||
Scope scope = classBuilder?.scope ?? library.scope;
|
||||
KernelBodyBuilder bodyBuilder =
|
||||
new KernelBodyBuilder.forOutlineExpression(
|
||||
|
@ -118,7 +127,6 @@ class KernelFieldBuilder extends FieldBuilder<Expression> {
|
|||
isConst ? ConstantContext.inferred : ConstantContext.none;
|
||||
initializer = bodyBuilder.parseFieldInitializer(constInitializerToken)
|
||||
..parent = field;
|
||||
constInitializerToken = null;
|
||||
bodyBuilder.typeInferrer
|
||||
?.inferFieldInitializer(bodyBuilder, field.type, field.initializer);
|
||||
if (library.loader is SourceLoader) {
|
||||
|
@ -128,6 +136,7 @@ class KernelFieldBuilder extends FieldBuilder<Expression> {
|
|||
}
|
||||
bodyBuilder.resolveRedirectingFactoryTargets();
|
||||
}
|
||||
constInitializerToken = null;
|
||||
}
|
||||
|
||||
Field get target => field;
|
||||
|
|
|
@ -6,16 +6,28 @@ library fasta.kernel_formal_parameter_builder;
|
|||
|
||||
import 'package:kernel/ast.dart' show VariableDeclaration;
|
||||
|
||||
import '../constant_context.dart' show ConstantContext;
|
||||
|
||||
import '../modifier.dart' show finalMask, initializingFormalMask;
|
||||
|
||||
import '../scanner.dart' show Token;
|
||||
|
||||
import '../scope.dart' show Scope;
|
||||
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import 'kernel_body_builder.dart' show KernelBodyBuilder;
|
||||
|
||||
import 'kernel_builder.dart'
|
||||
show
|
||||
ClassBuilder,
|
||||
Declaration,
|
||||
FormalParameterBuilder,
|
||||
KernelConstructorBuilder,
|
||||
KernelFieldBuilder,
|
||||
KernelLibraryBuilder,
|
||||
KernelTypeBuilder,
|
||||
LibraryBuilder,
|
||||
MetadataBuilder,
|
||||
TypeBuilder;
|
||||
|
||||
|
@ -25,6 +37,8 @@ class KernelFormalParameterBuilder
|
|||
extends FormalParameterBuilder<KernelTypeBuilder> {
|
||||
VariableDeclaration declaration;
|
||||
|
||||
Token initializerToken;
|
||||
|
||||
KernelFormalParameterBuilder(
|
||||
List<MetadataBuilder> metadata,
|
||||
int modifiers,
|
||||
|
@ -83,4 +97,31 @@ class KernelFormalParameterBuilder
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(LibraryBuilder library) {
|
||||
// For modular compilation we need to include initializers for all
|
||||
// parameters of const constructors into the outline.
|
||||
if (parent is KernelConstructorBuilder &&
|
||||
parent.target.isConst &&
|
||||
initializerToken != null) {
|
||||
final ClassBuilder classBuilder = parent.parent;
|
||||
Scope scope = classBuilder.scope;
|
||||
KernelBodyBuilder bodyBuilder =
|
||||
new KernelBodyBuilder.forOutlineExpression(
|
||||
library, classBuilder, this, scope, fileUri);
|
||||
bodyBuilder.constantContext = ConstantContext.required;
|
||||
target.initializer = bodyBuilder.parseFieldInitializer(initializerToken)
|
||||
..parent = target;
|
||||
bodyBuilder.typeInferrer?.inferParameterInitializer(
|
||||
bodyBuilder, target.initializer, target.type);
|
||||
if (library.loader is SourceLoader) {
|
||||
SourceLoader loader = library.loader;
|
||||
loader.transformPostInference(target, bodyBuilder.transformSetLiterals,
|
||||
bodyBuilder.transformCollections);
|
||||
}
|
||||
bodyBuilder.resolveRedirectingFactoryTargets();
|
||||
}
|
||||
initializerToken = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -704,7 +704,7 @@ class KernelLibraryBuilder
|
|||
currentDeclaration?.hasConstConstructor = true;
|
||||
// const constructors will have their initializers compiled and written
|
||||
// into the outline.
|
||||
procedure.beginInitializers = beginInitializers;
|
||||
procedure.beginInitializers = beginInitializers ?? Token.eof(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -901,12 +901,14 @@ class KernelLibraryBuilder
|
|||
KernelTypeBuilder type,
|
||||
String name,
|
||||
bool hasThis,
|
||||
int charOffset) {
|
||||
int charOffset,
|
||||
Token initializerToken) {
|
||||
if (hasThis) {
|
||||
modifiers |= initializingFormalMask;
|
||||
}
|
||||
KernelFormalParameterBuilder formal = new KernelFormalParameterBuilder(
|
||||
metadata, modifiers, type, name, this, charOffset);
|
||||
formal.initializerToken = initializerToken;
|
||||
if (legacyMode && hasThis && type == null) {
|
||||
(untypedInitializingFormals ??= <KernelFormalParameterBuilder>[])
|
||||
.add(formal);
|
||||
|
|
|
@ -36,6 +36,8 @@ import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute;
|
|||
|
||||
import '../../scanner/token.dart' show Token;
|
||||
|
||||
import '../constant_context.dart' show ConstantContext;
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
|
||||
import '../messages.dart'
|
||||
|
@ -55,9 +57,13 @@ import '../problems.dart' show unexpected;
|
|||
|
||||
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
|
||||
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import '../type_inference/type_inference_engine.dart'
|
||||
show IncludesTypeParametersCovariantly;
|
||||
|
||||
import 'kernel_body_builder.dart' show KernelBodyBuilder;
|
||||
|
||||
import 'kernel_builder.dart'
|
||||
show
|
||||
ClassBuilder,
|
||||
|
@ -238,6 +244,22 @@ abstract class KernelFunctionBuilder
|
|||
|
||||
Member build(SourceLibraryBuilder library);
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(LibraryBuilder library) {
|
||||
KernelMetadataBuilder.buildAnnotations(
|
||||
target, metadata, library, isClassMember ? parent : null, this);
|
||||
|
||||
if (formals != null) {
|
||||
// For const constructors we need to include default parameter values
|
||||
// into the outline. For all other formals we need to call
|
||||
// buildOutlineExpressions to clear initializerToken to prevent
|
||||
// consuming too much memory.
|
||||
for (FormalParameterBuilder<KernelTypeBuilder> formal in formals) {
|
||||
formal.buildOutlineExpressions(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void becomeNative(Loader loader) {
|
||||
Declaration constructor = loader.getNativeAnnotation();
|
||||
Arguments arguments =
|
||||
|
@ -359,12 +381,6 @@ class KernelProcedureBuilder extends KernelFunctionBuilder {
|
|||
return procedure;
|
||||
}
|
||||
|
||||
@override
|
||||
void buildOutlineExpressions(LibraryBuilder library) {
|
||||
KernelMetadataBuilder.buildAnnotations(
|
||||
target, metadata, library, isClassMember ? parent : null, this);
|
||||
}
|
||||
|
||||
Procedure get target => origin.procedure;
|
||||
|
||||
@override
|
||||
|
@ -491,8 +507,24 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
|
|||
|
||||
@override
|
||||
void buildOutlineExpressions(LibraryBuilder library) {
|
||||
KernelMetadataBuilder.buildAnnotations(
|
||||
target, metadata, library, parent, this);
|
||||
super.buildOutlineExpressions(library);
|
||||
|
||||
// For modular compilation purposes we need to include initializers
|
||||
// for const constructors into the outline.
|
||||
if (isConst && beginInitializers != null) {
|
||||
ClassBuilder classBuilder = parent;
|
||||
KernelBodyBuilder bodyBuilder =
|
||||
new KernelBodyBuilder.forOutlineExpression(
|
||||
library, classBuilder, this, classBuilder.scope, fileUri);
|
||||
bodyBuilder.constantContext = ConstantContext.inferred;
|
||||
bodyBuilder.parseInitializers(beginInitializers);
|
||||
if (library.loader is SourceLoader) {
|
||||
SourceLoader loader = library.loader;
|
||||
loader.transformPostInference(target, bodyBuilder.transformSetLiterals,
|
||||
bodyBuilder.transformCollections);
|
||||
}
|
||||
bodyBuilder.resolveRedirectingFactoryTargets();
|
||||
}
|
||||
beginInitializers = null;
|
||||
}
|
||||
|
||||
|
@ -601,6 +633,21 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
|
|||
reportPatchMismatch(patch);
|
||||
}
|
||||
}
|
||||
|
||||
void prepareInitializers() {
|
||||
// For const constructors we parse initializers already at the outlining
|
||||
// stage, there is no easy way to make body building stage skip initializer
|
||||
// parsing, so we simply clear parsed initializers and rebuild them
|
||||
// again.
|
||||
// Note: this method clears both initializers from the target Kernel node
|
||||
// and internal state associated with parsing initializers.
|
||||
if (target.isConst) {
|
||||
target.initializers.length = 0;
|
||||
redirectingInitializer = null;
|
||||
superInitializer = null;
|
||||
hasMovedSuperInitializer = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KernelRedirectingFactoryBuilder extends KernelProcedureBuilder {
|
||||
|
|
|
@ -641,10 +641,16 @@ class ForwardingListener implements Listener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
listener?.endFormalParameter(
|
||||
thisKeyword, periodAfterThis, nameToken, kind, memberKind);
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
listener?.endFormalParameter(thisKeyword, periodAfterThis, nameToken,
|
||||
initializerStart, initializerEnd, kind, memberKind);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -294,8 +294,14 @@ class Listener implements UnescapeErrorListener {
|
|||
void beginFormalParameter(Token token, MemberKind kind, Token requiredToken,
|
||||
Token covariantToken, Token varFinalOrConst) {}
|
||||
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
logEvent("FormalParameter");
|
||||
}
|
||||
|
||||
|
|
|
@ -1495,10 +1495,12 @@ class Parser {
|
|||
next = token.next;
|
||||
|
||||
String value = next.stringValue;
|
||||
Token initializerStart, initializerEnd;
|
||||
if ((identical('=', value)) || (identical(':', value))) {
|
||||
Token equal = next;
|
||||
initializerStart = equal.next;
|
||||
listener.beginFormalParameterDefaultValueExpression();
|
||||
token = parseExpression(equal);
|
||||
token = initializerEnd = parseExpression(equal);
|
||||
next = token.next;
|
||||
listener.endFormalParameterDefaultValueExpression();
|
||||
// TODO(danrubel): Consider removing the last parameter from the
|
||||
|
@ -1519,8 +1521,8 @@ class Parser {
|
|||
} else {
|
||||
listener.handleFormalParameterWithoutValue(next);
|
||||
}
|
||||
listener.endFormalParameter(
|
||||
thisKeyword, periodAfterThis, nameToken, parameterKind, memberKind);
|
||||
listener.endFormalParameter(thisKeyword, periodAfterThis, nameToken,
|
||||
initializerStart, initializerEnd, parameterKind, memberKind);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ class OutlineBuilder extends StackListener {
|
|||
final bool stringExpectedAfterNative;
|
||||
bool inConstructor = false;
|
||||
bool inConstructorName = false;
|
||||
bool inConstConstructor = false;
|
||||
int importIndex = 0;
|
||||
|
||||
String nativeMethodName;
|
||||
|
@ -746,6 +747,9 @@ class OutlineBuilder extends StackListener {
|
|||
} else {
|
||||
modifiers ??= <Modifier>[];
|
||||
modifiers.add(Const);
|
||||
if (inConstructor) {
|
||||
inConstConstructor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
push(varFinalOrConst?.charOffset ?? -1);
|
||||
|
@ -838,7 +842,7 @@ class OutlineBuilder extends StackListener {
|
|||
.resolveTypes(typeVariables, library);
|
||||
if (name is ParserRecovery) {
|
||||
nativeMethodName = null;
|
||||
inConstructor = false;
|
||||
inConstructor = inConstConstructor = false;
|
||||
return;
|
||||
}
|
||||
String constructorName =
|
||||
|
@ -897,7 +901,7 @@ class OutlineBuilder extends StackListener {
|
|||
isTopLevel: false);
|
||||
}
|
||||
nativeMethodName = null;
|
||||
inConstructor = false;
|
||||
inConstructor = inConstConstructor = false;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1015,8 +1019,14 @@ class OutlineBuilder extends StackListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
debugEvent("FormalParameter");
|
||||
int charOffset = pop();
|
||||
Object name = pop();
|
||||
|
@ -1027,7 +1037,13 @@ class OutlineBuilder extends StackListener {
|
|||
push(name);
|
||||
} else {
|
||||
push(library.addFormalParameter(
|
||||
metadata, modifiers, type, name, thisKeyword != null, charOffset));
|
||||
metadata,
|
||||
modifiers,
|
||||
type,
|
||||
name,
|
||||
thisKeyword != null,
|
||||
charOffset,
|
||||
inConstConstructor ? initializerStart : null));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1520,7 +1536,7 @@ class OutlineBuilder extends StackListener {
|
|||
endToken.charOffset,
|
||||
nativeMethodName);
|
||||
nativeMethodName = null;
|
||||
inConstructor = false;
|
||||
inConstructor = inConstConstructor = false;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -71,7 +71,7 @@ import '../fasta_codes.dart'
|
|||
|
||||
import '../import.dart' show Import;
|
||||
|
||||
import '../modifier.dart' show constMask;
|
||||
import '../modifier.dart' show constMask, finalMask;
|
||||
|
||||
import '../problems.dart' show unexpected, unhandled;
|
||||
|
||||
|
@ -400,8 +400,11 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|||
int modifiers, T type, List<FieldInfo> fieldInfos) {
|
||||
for (FieldInfo info in fieldInfos) {
|
||||
bool isConst = modifiers & constMask != 0;
|
||||
bool isFinal = modifiers & finalMask != 0;
|
||||
bool potentiallyNeedInitializerInOutline = isConst || isFinal;
|
||||
Token startToken;
|
||||
if (isConst || (type == null && !legacyMode)) {
|
||||
if (potentiallyNeedInitializerInOutline ||
|
||||
(type == null && !legacyMode)) {
|
||||
startToken = info.initializerToken;
|
||||
}
|
||||
if (startToken != null) {
|
||||
|
@ -414,7 +417,8 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|||
bool hasInitializer = info.initializerToken != null;
|
||||
addField(documentationComment, metadata, modifiers, type, info.name,
|
||||
info.charOffset, info.charEndOffset, startToken, hasInitializer,
|
||||
constInitializerToken: isConst ? startToken : null);
|
||||
constInitializerToken:
|
||||
potentiallyNeedInitializerInOutline ? startToken : null);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,8 +490,14 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|||
int charEndOffset,
|
||||
String nativeMethodName);
|
||||
|
||||
FormalParameterBuilder addFormalParameter(List<MetadataBuilder> metadata,
|
||||
int modifiers, T type, String name, bool hasThis, int charOffset);
|
||||
FormalParameterBuilder addFormalParameter(
|
||||
List<MetadataBuilder> metadata,
|
||||
int modifiers,
|
||||
T type,
|
||||
String name,
|
||||
bool hasThis,
|
||||
int charOffset,
|
||||
Token initializerToken);
|
||||
|
||||
TypeVariableBuilder addTypeVariable(String name, T bound, int charOffset);
|
||||
|
||||
|
|
|
@ -619,8 +619,14 @@ class TypePromotionLookAheadListener extends Listener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
debugEvent("FormalParameter", thisKeyword);
|
||||
state.pop(); // Parameter name.
|
||||
}
|
||||
|
|
|
@ -2802,8 +2802,14 @@ class TypeInfoListener implements Listener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endFormalParameter(Token thisKeyword, Token periodAfterThis,
|
||||
Token nameToken, FormalParameterKind kind, MemberKind memberKind) {
|
||||
void endFormalParameter(
|
||||
Token thisKeyword,
|
||||
Token periodAfterThis,
|
||||
Token nameToken,
|
||||
Token initializerStart,
|
||||
Token initializerEnd,
|
||||
FormalParameterKind kind,
|
||||
MemberKind memberKind) {
|
||||
calls.add('endFormalParameter $thisKeyword $periodAfterThis '
|
||||
'$nameToken $kind $memberKind');
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ class Strength extends core::Object {
|
|||
final field core::int value;
|
||||
final field core::String name;
|
||||
const constructor •(core::int value, core::String name) → self::Strength
|
||||
: self::Strength::value = value, self::Strength::name = name
|
||||
;
|
||||
method nextWeaker() → self::Strength
|
||||
;
|
||||
|
@ -27,6 +28,7 @@ class Strength extends core::Object {
|
|||
abstract class Constraint extends core::Object {
|
||||
final field self::Strength strength;
|
||||
const constructor •(self::Strength strength) → self::Constraint
|
||||
: self::Constraint::strength = strength
|
||||
;
|
||||
abstract method isSatisfied() → core::bool;
|
||||
abstract method markUnsatisfied() → void;
|
||||
|
|
|
@ -5,6 +5,7 @@ import "dart:core" as core;
|
|||
class Fisk<T extends core::Object = dynamic> extends core::Object {
|
||||
final field self::Fisk::T x;
|
||||
const constructor fisk(self::Fisk::T x) → self::Fisk<self::Fisk::T>
|
||||
: self::Fisk::x = x
|
||||
;
|
||||
}
|
||||
class Foo extends core::Object {
|
||||
|
|
|
@ -11,10 +11,6 @@ library;
|
|||
// external foo(String x) {
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
|
||||
// const A.named2() : x = new Object();
|
||||
// ^^^
|
||||
|
@ -31,6 +27,10 @@ library;
|
|||
// const A.named2() : x = new Object();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
|
||||
// external foo(String x) {
|
||||
// ^
|
||||
|
|
|
@ -11,10 +11,6 @@ library;
|
|||
// external foo(String x) {
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
|
||||
// const A.named2() : x = new Object();
|
||||
// ^^^
|
||||
|
@ -31,6 +27,10 @@ library;
|
|||
// const A.named2() : x = new Object();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
|
||||
// external foo(String x) {
|
||||
// ^
|
||||
|
|
|
@ -11,14 +11,34 @@ library;
|
|||
// external foo(String x) {
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
|
||||
// const A.named2() : x = new Object();
|
||||
// ^^^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:10:24: Warning: 'x' is a final instance variable that has already been initialized.
|
||||
// const A.named2() : x = new Object();
|
||||
// ^
|
||||
// pkg/front_end/testcases/many_errors.dart:6:9: Context: 'x' was initialized here.
|
||||
// final x = null;
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const A.named2() : x = new Object();
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class A extends core::Object {
|
||||
final field dynamic x;
|
||||
final field dynamic x = null;
|
||||
constructor named1() → self::A
|
||||
;
|
||||
const constructor named2() → self::A
|
||||
: final dynamic #t1 = throw invalid-expression "pkg/front_end/testcases/many_errors.dart:10:24: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
Try using a constructor or factory that is 'const'.
|
||||
const A.named2() : x = new Object();
|
||||
^"
|
||||
;
|
||||
}
|
||||
class B extends core::Object {
|
||||
|
|
|
@ -11,10 +11,6 @@ library;
|
|||
// external foo(String x) {
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
|
||||
// const A.named2() : x = new Object();
|
||||
// ^^^
|
||||
|
@ -31,6 +27,10 @@ library;
|
|||
// const A.named2() : x = new Object();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
|
||||
// external foo(String x) {
|
||||
// ^
|
||||
|
|
|
@ -11,10 +11,6 @@ library;
|
|||
// external foo(String x) {
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:10:26: Error: New expression is not a constant expression.
|
||||
// const A.named2() : x = new Object();
|
||||
// ^^^
|
||||
|
@ -31,6 +27,10 @@ library;
|
|||
// const A.named2() : x = new Object();
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:8:26: Error: Constructor bodies can't use 'async', 'async*', or 'sync*'.
|
||||
// const A.named1() sync* {}
|
||||
// ^
|
||||
//
|
||||
// pkg/front_end/testcases/many_errors.dart:13:24: Error: An external or native method can't have a body.
|
||||
// external foo(String x) {
|
||||
// ^
|
||||
|
|
|
@ -5,11 +5,13 @@ import "dart:core" as core;
|
|||
class A extends core::Object {
|
||||
final field core::int bar;
|
||||
const constructor •(core::int bar) → self::A
|
||||
: self::A::bar = bar
|
||||
;
|
||||
}
|
||||
class B extends core::Object {
|
||||
final field self::A baz;
|
||||
const constructor •(self::A baz) → self::B
|
||||
: self::B::baz = baz
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
|
|
|
@ -5,6 +5,7 @@ import "dart:core" as core;
|
|||
class A extends core::Object {
|
||||
final field core::int x;
|
||||
const constructor •(core::int x) → self::A
|
||||
: self::A::x = x
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
|
|
@ -1,9 +1,21 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_constructor_redirection.dart:6:21: Warning: Too many positional arguments: 0 allowed, but 1 found.
|
||||
// Try removing the extra positional arguments.
|
||||
// const C() : this.x(1);
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class C extends core::Object {
|
||||
const constructor •() → self::C
|
||||
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/bad_constructor_redirection.dart:6:21: Error: Too many positional arguments: 0 allowed, but 1 found.
|
||||
Try removing the extra positional arguments.
|
||||
const C() : this.x(1);
|
||||
^"
|
||||
;
|
||||
const constructor x() → self::C
|
||||
;
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
library;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Warning: Too few positional arguments: 1 required, 0 given.
|
||||
// const B() : super();
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -8,6 +15,9 @@ class A extends core::Object {
|
|||
}
|
||||
class B extends self::A {
|
||||
const constructor •() → self::B
|
||||
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/bad_explicit_super_constructor.dart:10:20: Error: Too few positional arguments: 1 required, 0 given.
|
||||
const B() : super();
|
||||
^"
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
|
|
@ -7,11 +7,18 @@ library;
|
|||
// const C() : this.x;
|
||||
// ^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: Can't access 'this' in a field initializer.
|
||||
// const C() : this.x;
|
||||
// ^^^^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
class C extends core::Object {
|
||||
const constructor •() → self::C
|
||||
: final dynamic #t1 = invalid-expression "pkg/front_end/testcases/rasta/issue_000034.dart:6:15: Error: This couldn't be parsed.
|
||||
const C() : this.x;
|
||||
^"
|
||||
;
|
||||
}
|
||||
static method main() → dynamic
|
||||
|
|
|
@ -11,6 +11,7 @@ class A<N extends core::Object = dynamic, S extends core::Object = dynamic, U ex
|
|||
constructor empty() → self::A<self::A::N, self::A::S, self::A::U>
|
||||
;
|
||||
const constructor c(self::A::U u, self::A::S s) → self::A<self::A::N, self::A::S, self::A::U>
|
||||
: self::A::field = const <dynamic>[null]
|
||||
;
|
||||
static factory f<N extends core::Object = dynamic, S extends core::Object = dynamic, U extends core::Object = dynamic>(self::A::f::S s) → self::A<self::A::f::N, self::A::f::S, self::A::f::U>
|
||||
;
|
||||
|
|
|
@ -13,6 +13,7 @@ class A extends core::Object {
|
|||
}
|
||||
class B<T extends core::Object = dynamic> extends self::A {
|
||||
const constructor •() → self::B<self::B::T>
|
||||
: super self::A::empty()
|
||||
;
|
||||
method toString() → core::String
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue