mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:40:07 +00:00
[cfe] Store the initializer tokens in constructor builders
For const constructors, we need to compile the initializer expressions and write them into the outline so that we can perform modular constant evaluation. As a first step, preserve the tokens for the initializer expressions in const constructor builders when building the outline. Currently they are discarded later during outline building at the point when we should compile them instead. Change-Id: Ief8d94ceb752b2315982d720836496b7d597e55c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107509 Commit-Queue: Vyacheslav Egorov <vegorov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
bbbeb8b509
commit
9f32f9b87e
|
@ -1447,8 +1447,8 @@ class AstBuilder extends StackListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
assert(getOrSet == null ||
|
||||
optional('get', getOrSet) ||
|
||||
optional('set', getOrSet));
|
||||
|
|
|
@ -908,10 +908,11 @@ class ForwardingTestListener extends ForwardingListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
end('Method');
|
||||
super.endMethod(getOrSet, beginToken, beginParam, endToken);
|
||||
super.endMethod(
|
||||
getOrSet, beginToken, beginParam, beginInitializers, endToken);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -393,8 +393,8 @@ class MiniAstBuilder extends StackListener {
|
|||
NullValue.Metadata);
|
||||
}
|
||||
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
debugEvent("Method");
|
||||
pop(); // Body
|
||||
pop(); // Initializers
|
||||
|
|
|
@ -671,9 +671,10 @@ class KernelLibraryBuilder
|
|||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
String nativeMethodName) {
|
||||
String nativeMethodName,
|
||||
{Token beginInitializers}) {
|
||||
MetadataCollector metadataCollector = loader.target.metadataCollector;
|
||||
ProcedureBuilder procedure = new KernelConstructorBuilder(
|
||||
KernelConstructorBuilder procedure = new KernelConstructorBuilder(
|
||||
metadata,
|
||||
modifiers & ~abstractMask,
|
||||
returnType,
|
||||
|
@ -699,7 +700,12 @@ class KernelLibraryBuilder
|
|||
if (nativeMethodName != null) {
|
||||
addNativeMethod(procedure);
|
||||
}
|
||||
if (procedure.isConst) currentDeclaration?.hasConstConstructor = true;
|
||||
if (procedure.isConst) {
|
||||
currentDeclaration?.hasConstConstructor = true;
|
||||
// const constructors will have their initializers compiled and written
|
||||
// into the outline.
|
||||
procedure.beginInitializers = beginInitializers;
|
||||
}
|
||||
}
|
||||
|
||||
void addProcedure(
|
||||
|
|
|
@ -34,6 +34,8 @@ import 'package:kernel/ast.dart'
|
|||
|
||||
import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute;
|
||||
|
||||
import '../../scanner/token.dart' show Token;
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
|
||||
import '../messages.dart'
|
||||
|
@ -415,6 +417,8 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
|
|||
|
||||
RedirectingInitializer redirectingInitializer;
|
||||
|
||||
Token beginInitializers;
|
||||
|
||||
@override
|
||||
KernelConstructorBuilder actualOrigin;
|
||||
|
||||
|
@ -489,6 +493,7 @@ class KernelConstructorBuilder extends KernelFunctionBuilder {
|
|||
void buildOutlineExpressions(LibraryBuilder library) {
|
||||
KernelMetadataBuilder.buildAnnotations(
|
||||
target, metadata, library, parent, this);
|
||||
beginInitializers = null;
|
||||
}
|
||||
|
||||
FunctionNode buildFunction(LibraryBuilder library) {
|
||||
|
|
|
@ -774,9 +774,10 @@ class ForwardingListener implements Listener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
listener?.endMethod(getOrSet, beginToken, beginParam, endToken);
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
listener?.endMethod(
|
||||
getOrSet, beginToken, beginParam, beginInitializers, endToken);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -747,8 +747,8 @@ class Listener implements UnescapeErrorListener {
|
|||
/// - initializers
|
||||
/// - async marker
|
||||
/// - body
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
logEvent("Method");
|
||||
}
|
||||
|
||||
|
|
|
@ -2516,7 +2516,7 @@ class Parser {
|
|||
|
||||
Token parseInitializersOpt(Token token) {
|
||||
if (optional(':', token.next)) {
|
||||
return parseInitializers(token);
|
||||
return parseInitializers(token.next);
|
||||
} else {
|
||||
listener.handleNoInitializers();
|
||||
return token;
|
||||
|
@ -2529,7 +2529,7 @@ class Parser {
|
|||
/// ;
|
||||
/// ```
|
||||
Token parseInitializers(Token token) {
|
||||
Token begin = token.next;
|
||||
Token begin = token;
|
||||
assert(optional(':', begin));
|
||||
listener.beginInitializers(begin);
|
||||
int count = 0;
|
||||
|
@ -3241,8 +3241,10 @@ class Parser {
|
|||
? MemberKind.StaticMethod
|
||||
: MemberKind.NonStaticMethod;
|
||||
Token beforeParam = token;
|
||||
token = parseGetterOrFormalParameters(token, name, isGetter, kind);
|
||||
token = parseInitializersOpt(token);
|
||||
Token beforeInitializers =
|
||||
parseGetterOrFormalParameters(token, name, isGetter, kind);
|
||||
token = parseInitializersOpt(beforeInitializers);
|
||||
if (token == beforeInitializers) beforeInitializers = null;
|
||||
|
||||
AsyncModifier savedAsyncModifier = asyncState;
|
||||
Token asyncToken = token.next;
|
||||
|
@ -3264,7 +3266,8 @@ class Parser {
|
|||
(staticToken == null || externalToken != null) && inPlainSync);
|
||||
}
|
||||
asyncState = savedAsyncModifier;
|
||||
listener.endMethod(getOrSet, beforeStart.next, beforeParam.next, token);
|
||||
listener.endMethod(getOrSet, beforeStart.next, beforeParam.next,
|
||||
beforeInitializers?.next, token);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
|
|
@ -575,8 +575,8 @@ class DietListener extends StackListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
debugEvent("Method");
|
||||
// TODO(danrubel): Consider removing the beginParam parameter
|
||||
// and using bodyToken, but pushing a NullValue on the stack
|
||||
|
|
|
@ -754,8 +754,8 @@ class OutlineBuilder extends StackListener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
debugEvent("Method");
|
||||
MethodBody bodyKind = pop();
|
||||
if (bodyKind == MethodBody.RedirectingFactoryBody) {
|
||||
|
@ -871,7 +871,8 @@ class OutlineBuilder extends StackListener {
|
|||
charOffset,
|
||||
formalsOffset,
|
||||
endToken.charOffset,
|
||||
nativeMethodName);
|
||||
nativeMethodName,
|
||||
beginInitializers: beginInitializers);
|
||||
} else {
|
||||
if (isConst) {
|
||||
addProblem(messageConstMethod, varFinalOrConstOffset, 5);
|
||||
|
|
|
@ -431,7 +431,8 @@ abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
|
|||
int charOffset,
|
||||
int charOpenParenOffset,
|
||||
int charEndOffset,
|
||||
String nativeMethodName);
|
||||
String nativeMethodName,
|
||||
{Token beginInitializers});
|
||||
|
||||
void addProcedure(
|
||||
String documentationComment,
|
||||
|
|
|
@ -962,8 +962,8 @@ class TypePromotionLookAheadListener extends Listener {
|
|||
}
|
||||
|
||||
@override
|
||||
void endMethod(
|
||||
Token getOrSet, Token beginToken, Token beginParam, Token endToken) {
|
||||
void endMethod(Token getOrSet, Token beginToken, Token beginParam,
|
||||
Token beginInitializers, Token endToken) {
|
||||
debugEvent("endMethod", endToken);
|
||||
state.pop(); // Method name.
|
||||
state.checkEmpty(endToken);
|
||||
|
|
Loading…
Reference in a new issue