Skip to content

Commit a5f7345

Browse files
MarkzipanCommit Queue
authored andcommitted
[ddc] Updating representation for virtual and lazy fields.
This restructures all fields as accessor/value-store pairs, providing a level of indirection required for hot reload. Major updates include: - All fields (top-level, lazy, virtual, etc.) now have a value store (represented as a private top-level symbol). The value store is initialized on first access for the initializer. - Lazy value stores are prefixed with '_#v_' to indicate that they are not replaced on a hot reload. - `declareClass` and `declareTopLevelProperties` are introduced to append classes/members to libraries. These functions extend the 'original' entity/class with fields introduced by a properties object, ignoring the special lazy value stores mentioned above. - `defineLazy` is replaced with the above operations. - Virtual/instance fields are still initialized by inside their constructor on first load (so their getter forwards to its value store). On hot reload, however, uninitialized fields are lazily initialized. - Final fields now use a sentinel value to check for late initialization errors during the initialization loop. - The JS AST is extended to support class properties. Change-Id: I5cc3548477d83897273f3b993b304a804754ec0e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/386971 Reviewed-by: Nicholas Shahan <[email protected]>
1 parent 6fd34c9 commit a5f7345

File tree

7 files changed

+424
-216
lines changed

7 files changed

+424
-216
lines changed

pkg/dev_compiler/lib/src/js_ast/nodes.dart

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,8 +1802,11 @@ class ObjectInitializer extends Expression {
18021802
class Property extends Node {
18031803
final Expression name;
18041804
final Expression value;
1805+
final bool isStatic;
1806+
final bool isClassProperty;
18051807

1806-
Property(this.name, this.value);
1808+
Property(this.name, this.value,
1809+
{this.isStatic = false, this.isClassProperty = false});
18071810

18081811
@override
18091812
T accept<T>(NodeVisitor<T> visitor) => visitor.visitProperty(this);
@@ -1815,7 +1818,8 @@ class Property extends Node {
18151818
}
18161819

18171820
@override
1818-
Property _clone() => Property(name, value);
1821+
Property _clone() => Property(name, value,
1822+
isStatic: isStatic, isClassProperty: isClassProperty);
18191823
}
18201824

18211825
// TODO(jmesserly): parser does not support this yet.
@@ -1925,9 +1929,9 @@ class ClassDeclaration extends Statement {
19251929
class ClassExpression extends Expression {
19261930
final Identifier name;
19271931
final Expression? heritage;
1928-
final List<Method> methods;
1932+
final List<Property> properties;
19291933

1930-
ClassExpression(this.name, this.heritage, this.methods);
1934+
ClassExpression(this.name, this.heritage, this.properties);
19311935

19321936
@override
19331937
T accept<T>(NodeVisitor<T> visitor) => visitor.visitClassExpression(this);
@@ -1936,7 +1940,7 @@ class ClassExpression extends Expression {
19361940
void visitChildren(NodeVisitor visitor) {
19371941
name.accept(visitor);
19381942
heritage?.accept(visitor);
1939-
for (Method element in methods) {
1943+
for (Property element in properties) {
19401944
element.accept(visitor);
19411945
}
19421946
}
@@ -1945,7 +1949,7 @@ class ClassExpression extends Expression {
19451949
ClassDeclaration toStatement() => ClassDeclaration(this);
19461950

19471951
@override
1948-
ClassExpression _clone() => ClassExpression(name, heritage, methods);
1952+
ClassExpression _clone() => ClassExpression(name, heritage, properties);
19491953

19501954
@override
19511955
int get precedenceLevel => PRIMARY_LOW_PRECEDENCE;
@@ -1957,8 +1961,13 @@ class Method extends Node implements Property {
19571961
final Fun function;
19581962
final bool isGetter;
19591963
final bool isSetter;
1964+
1965+
@override
19601966
final bool isStatic;
19611967

1968+
@override
1969+
final bool isClassProperty = false;
1970+
19621971
Method(this.name, this.function,
19631972
{this.isGetter = false, this.isSetter = false, this.isStatic = false}) {
19641973
assert(!isGetter || function.params.isEmpty);
@@ -2121,6 +2130,8 @@ class InterpolatedMethod extends Expression
21212130
@override
21222131
bool get isStatic => throw _unsupported;
21232132
@override
2133+
bool get isClassProperty => throw _unsupported;
2134+
@override
21242135
Fun get function => throw _unsupported;
21252136
Error get _unsupported =>
21262137
UnsupportedError('$runtimeType does not support this member.');
@@ -2561,13 +2572,13 @@ abstract class Transformer extends BaseVisitor<Node> {
25612572
Node visitClassExpression(ClassExpression node) {
25622573
final name = visit<Identifier>(node.name);
25632574
final heritage = visitNullable<Expression>(node.heritage);
2564-
final methods = visitList<Method>(node.methods);
2575+
final properties = visitList<Property>(node.properties);
25652576
if (isUnchanged(name, node.name) &&
25662577
isUnchanged(heritage, node.heritage) &&
2567-
isUnchangedList(methods, node.methods)) {
2578+
isUnchangedList(properties, node.properties)) {
25682579
return node;
25692580
}
2570-
return ClassExpression(name, heritage, methods);
2581+
return ClassExpression(name, heritage, properties);
25712582
}
25722583

25732584
@override

pkg/dev_compiler/lib/src/js_ast/printer.dart

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,11 +1149,21 @@ class Printer implements NodeVisitor {
11491149

11501150
@override
11511151
void visitProperty(Property node) {
1152+
if (node.isStatic) {
1153+
out('static ');
1154+
}
11521155
propertyNameOut(node.name);
1153-
out(':');
1156+
if (node.isClassProperty) {
1157+
out(' =');
1158+
} else {
1159+
out(':');
1160+
}
11541161
spaceOut();
11551162
visitNestedExpression(node.value, ASSIGNMENT,
11561163
newInForInit: false, newAtStatementBegin: false);
1164+
if (node.isClassProperty) {
1165+
out(';');
1166+
}
11571167
}
11581168

11591169
@override
@@ -1198,13 +1208,13 @@ class Printer implements NodeVisitor {
11981208
visit(node.heritage!);
11991209
}
12001210
spaceOut();
1201-
if (node.methods.isNotEmpty) {
1211+
if (node.properties.isNotEmpty) {
12021212
out('{');
12031213
lineOut();
12041214
indentMore();
1205-
for (var method in node.methods) {
1215+
for (var property in node.properties) {
12061216
indent();
1207-
visit(method);
1217+
visit(property);
12081218
lineOut();
12091219
}
12101220
indentLess();
@@ -1503,7 +1513,7 @@ class VarCollector extends BaseVisitorVoid {
15031513
void visitClassExpression(ClassExpression node) {
15041514
// Note that we don't bother collecting the name of the class.
15051515
node.heritage?.accept(this);
1506-
for (Method method in node.methods) {
1516+
for (Property method in node.properties) {
15071517
method.accept(this);
15081518
}
15091519
}
@@ -1813,7 +1823,7 @@ abstract class VariableDeclarationVisitor extends BaseVisitorVoid {
18131823
void visitClassExpression(ClassExpression node) {
18141824
declare(node.name);
18151825
node.heritage?.accept(this);
1816-
for (Method element in node.methods) {
1826+
for (Property element in node.properties) {
18171827
element.accept(this);
18181828
}
18191829
}

pkg/dev_compiler/lib/src/js_ast/template.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,8 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
726726
Instantiator<Property> visitProperty(Property node) {
727727
var makeName = visit(node.name) as Instantiator<Expression>;
728728
var makeValue = visit(node.value) as Instantiator<Expression>;
729-
return (arguments) => Property(makeName(arguments), makeValue(arguments));
729+
return (arguments) => Property(makeName(arguments), makeValue(arguments),
730+
isStatic: node.isStatic, isClassProperty: node.isClassProperty);
730731
}
731732

732733
@override
@@ -756,13 +757,13 @@ class InstantiatorGeneratorVisitor implements NodeVisitor<Instantiator> {
756757

757758
@override
758759
Instantiator<ClassExpression> visitClassExpression(ClassExpression node) {
759-
var makeMethods = node.methods.map(visitSplayableExpression).toList();
760+
var makeProperties = node.properties.map(visitSplayableExpression).toList();
760761
var makeName = visit(node.name) as Instantiator<Identifier>;
761762
var makeHeritage =
762763
visitNullable(node.heritage) as Instantiator<Expression?>;
763764

764765
return (arguments) => ClassExpression(makeName(arguments),
765-
makeHeritage(arguments), splayNodes(makeMethods, arguments));
766+
makeHeritage(arguments), splayNodes(makeProperties, arguments));
766767
}
767768

768769
@override

0 commit comments

Comments
 (0)