[cfe] Fix scope bug for initializers in text serialization

The initializers are in the scope of the parameters of constructor's
FunctionNode, but they aren't children nodes of that FunctionNode.

Change-Id: I48c5876f50ae186db47b3ba222a469ef311ce62c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/154692
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
Dmitry Stefantsov 2020-07-17 13:24:28 +00:00 committed by commit-bot@chromium.org
parent ab10857992
commit 7909babc75
4 changed files with 59 additions and 40 deletions

View file

@ -362,6 +362,7 @@ class KernelTextSerialization
});
return await CompilerContext.runWithOptions(options,
(compilerContext) async {
component.computeCanonicalNames();
compilerContext.uriToSource.addAll(component.uriToSource);
TextSerializationVerifier verifier =
new TextSerializationVerifier(root: component.root);

View file

@ -314,6 +314,11 @@ class VerificationState {
void mergeToParent() {
// Pass the free occurrences of variables and type parameters to the parent.
if (parent != null) {
if (parent.node is Constructor && node is FunctionNode) {
// Parameters of constructor's function node are visible in
// constructor's initializers.
parent.variableDeclarations.addAll(variableDeclarations);
}
parent.usedVariables
.addAll(usedVariables.difference(variableDeclarations));
parent.usedTypeParameters
@ -382,12 +387,12 @@ class TextSerializationVerifier extends RecursiveVisitor<void> {
exitNode(node);
}
void enterNode(node) {
void enterNode(Node node) {
pushStateFor(node);
currentState.handleDeclarations();
}
void exitNode(node) {
void exitNode(Node node) {
if (!identical(node, currentState.node)) {
throw new StateError("Trying to remove node '${node}' from the stack, "
"while another node '${currentState.node}' is on the top of it.");

View file

@ -1386,36 +1386,48 @@ TextSerializer<AsyncMarker> asyncMarkerSerializer = Case(
key: (e) => e.value,
value: (e) => Wrapped((_) => null, (_) => e.key, Nothing())));
TextSerializer<FunctionNode> functionNodeSerializer = new Wrapped(
(w) => Tuple2(
w.asyncMarker,
Tuple2(
TextSerializer<Tuple2<FunctionNode, List<Initializer>>>
functionNodeWithInitializersSerializer = Wrapped(
(w) => Tuple2(
w.first.asyncMarker,
Tuple2(
w.typeParameters,
Tuple3(
w.positionalParameters.sublist(0, w.requiredParameterCount),
w.positionalParameters.sublist(w.requiredParameterCount),
w.namedParameters)),
Tuple2(w.returnType, w.body))),
(u) => FunctionNode(u.second.second.second,
typeParameters: u.second.first.first,
positionalParameters:
u.second.first.second.first + u.second.first.second.second,
namedParameters: u.second.first.second.third,
requiredParameterCount: u.second.first.second.first.length,
returnType: u.second.second.first,
asyncMarker: u.first),
Tuple2Serializer(
asyncMarkerSerializer,
Bind(
Rebind(
typeParametersSerializer,
Tuple2(
w.first.typeParameters,
Tuple3(
w.first.positionalParameters
.sublist(0, w.first.requiredParameterCount),
w.first.positionalParameters
.sublist(w.first.requiredParameterCount),
w.first.namedParameters)),
Tuple3(w.first.returnType, w.second, w.first.body))),
(u) => Tuple2(
FunctionNode(u.second.second.third,
typeParameters: u.second.first.first,
positionalParameters:
u.second.first.second.first + u.second.first.second.second,
namedParameters: u.second.first.second.third,
requiredParameterCount: u.second.first.second.first.length,
returnType: u.second.second.first,
asyncMarker: u.first),
u.second.second.second),
Tuple2Serializer(
asyncMarkerSerializer,
Bind(
Rebind(
typeParametersSerializer,
Tuple3Serializer(
ListSerializer(variableDeclarationSerializer),
ListSerializer(variableDeclarationSerializer),
ListSerializer(variableDeclarationSerializer))),
Tuple3Serializer(
ListSerializer(variableDeclarationSerializer),
ListSerializer(variableDeclarationSerializer),
ListSerializer(variableDeclarationSerializer))),
Tuple2Serializer(
dartTypeSerializer, Optional(statementSerializer)))));
dartTypeSerializer,
Optional(ListSerializer(initializerSerializer)),
Optional(statementSerializer)))));
TextSerializer<FunctionNode> functionNodeSerializer = Wrapped(
(w) => Tuple2(w, null),
(u) => u.first,
functionNodeWithInitializersSerializer);
const Map<int, String> procedureFlagToName = const {
Procedure.FlagStatic: "static",
@ -1603,11 +1615,12 @@ TextSerializer<Procedure> factorySerializer = Wrapped(
nameSerializer, procedureFlagsSerializer, functionNodeSerializer));
TextSerializer<Constructor> constructorSerializer = Wrapped(
(w) => Tuple4(w.name, w.flags, w.initializers, w.function),
(u) => Constructor(u.fourth, name: u.first, initializers: u.third)
..flags = u.second,
Tuple4Serializer(nameSerializer, constructorFlagsSerializer,
ListSerializer(initializerSerializer), functionNodeSerializer));
(w) => Tuple3(w.name, w.flags, Tuple2(w.function, w.initializers)),
(u) =>
Constructor(u.third.first, name: u.first, initializers: u.third.second)
..flags = u.second,
Tuple3Serializer(nameSerializer, constructorFlagsSerializer,
functionNodeWithInitializersSerializer));
TextSerializer<RedirectingFactoryConstructor>
redirectingFactoryConstructorSerializer = Wrapped(

View file

@ -391,7 +391,7 @@ void test() {
expectation: ''
'(expr (fun (sync) ("T^0") ((dynamic)) ((dynamic)) ("t1^1" '
'() (par "T^0" _) _ ()) ("t2^2" () (par "T^0" _) '
'_ ()) () (par "T^0" _) (ret (get-var "t1^1" _))))',
'_ ()) () (par "T^0" _) _ (ret (get-var "t1^1" _))))',
makeSerializationState: () =>
new SerializationState(new SerializationEnvironment(null)),
makeDeserializationState: () => new DeserializationState(
@ -416,7 +416,7 @@ void test() {
expectation: ''
'(method (public "foo") ((static))'
' (sync) () () () ("x^0" () (dynamic) _ ()) () ()'
' (dynamic) (ret (get-var "x^0" _)))',
' (dynamic) _ (ret (get-var "x^0" _)))',
makeSerializationState: () =>
new SerializationState(new SerializationEnvironment(null)),
makeDeserializationState: () => new DeserializationState(
@ -452,11 +452,11 @@ void test() {
''
' ((method (public "foo") ((static))'
' (sync) () () () ("x^0" () (dynamic) _ ()) () () (dynamic)'
' (ret (get-var "x^0" _)))'
' _ (ret (get-var "x^0" _)))'
''
' (method (public "bar") ((static))'
' (sync) () () () ("x^0" () (dynamic) _ ()) () () (dynamic)'
' (ret'
' _ (ret'
' (invoke-static "package:foo/bar.dart::@methods::foo"'
' () ((get-var "x^0" _)) ()))))'
''
@ -491,7 +491,7 @@ void test() {
''
' ((method (public "foo") ((static))'
' (sync) () () () () () () (interface "package:foo/bar.dart::A" ())'
' (ret (null))))'
' _ (ret (null))))'
''
' ("A" () () () () _ _ () ())'
''