Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit b1b36fe

Browse files
author
John Messerly
committed
improve top-level field codegen: avoid Element.node getter
also correctly exports the values of top-level fields, and ensures it uses the most up-to-date value for mutable top-level fields we can likely improve this further once we have ES6 modules, but it seems like an okay start [email protected] Review URL: https://chromereviews.googleplex.com/147927013
1 parent af2ee34 commit b1b36fe

File tree

4 files changed

+64
-42
lines changed

4 files changed

+64
-42
lines changed

lib/src/codegen/js_codegen.dart

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ var $libName;
7979

8080
if (_exports.isNotEmpty) out.write('// Exports:\n');
8181

82+
// TODO(jmesserly): make these immutable?
8283
for (var name in _exports) {
8384
out.write('${libraryInfo.name}.$name = $name;\n');
8485
}
@@ -302,13 +303,10 @@ var $libName;
302303
var unsetFields = new Map<String, Expression>();
303304
for (var declaration in fields) {
304305
for (var field in declaration.fields.variables) {
305-
if (!_isConstantField(field)) {
306-
field.name.accept(this);
307-
out.write(' = ');
308-
field.initializer.accept(this);
309-
out.write(';\n');
310-
} else {
306+
if (_isFieldInitConstant(field)) {
311307
unsetFields[field.name.name] = field.initializer;
308+
} else {
309+
_visitNode(field, suffix: ';\n');
312310
}
313311
}
314312
}
@@ -611,29 +609,39 @@ var $libName;
611609

612610
@override
613611
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
614-
_visitNode(node.variables);
612+
var constFields = <VariableDeclaration>[];
613+
for (var field in node.variables.variables) {
614+
var name = field.name.name;
615+
if (field.isConst) {
616+
// constant fields don't change, so we can generate them as `let`
617+
// but add them to the module's exports
618+
_visitNode(field, prefix: 'let ', suffix: ';\n');
619+
if (isPublic(name)) _exports.add(name);
620+
} else if (_isFieldInitConstant(field)) {
621+
_visitNode(field, suffix: ';\n');
622+
} else {
623+
_lazyFields.add(field);
624+
}
625+
}
615626
}
616627

617628
@override
618629
void visitVariableDeclarationList(VariableDeclarationList node) {
619-
var topLevel = node.parent is TopLevelVariableDeclaration;
620-
621-
var declarations = node.variables;
622-
623-
var wroteLet = false;
624-
for (var node in declarations) {
625-
if (topLevel && !_isConstantField(node)) {
626-
_lazyFields.add(node);
627-
continue;
628-
}
630+
_visitNodeList(node.variables, prefix: 'let ', separator: ', ');
631+
}
629632

630-
wroteLet = true;
631-
out.write(node == declarations.first ? 'let ' : ', ');
632-
out.write(node.name.name);
633-
_visitNode(node.initializer, prefix: ' = ');
633+
@override
634+
void visitVariableDeclaration(VariableDeclaration node) {
635+
node.name.accept(this);
636+
out.write(' = ');
637+
if (node.initializer != null) {
638+
node.initializer.accept(this);
639+
} else {
640+
// explicitly initialize to null, so we don't need to worry about
641+
// `undefined`.
642+
// TODO(jmesserly): do this only for vars that aren't definitely assigned.
643+
out.write('null');
634644
}
635-
636-
if (topLevel && wroteLet) out.write(';\n');
637645
}
638646

639647
void _flushLazyFields() {
@@ -1013,7 +1021,7 @@ var $libName;
10131021
out.write('/* Unimplemented ${node.runtimeType}: $node */');
10141022
}
10151023

1016-
bool _isConstantField(VariableDeclaration field) =>
1024+
bool _isFieldInitConstant(VariableDeclaration field) =>
10171025
field.initializer == null || _computeConstant(field) is ValidResult;
10181026

10191027
EvaluationResultImpl _computeConstant(VariableDeclaration field) {
@@ -1051,11 +1059,7 @@ var $libName;
10511059
if (element is PropertyAccessorElement) {
10521060
element = (element as PropertyAccessorElement).variable;
10531061
}
1054-
return element is TopLevelVariableElement &&
1055-
// TODO(sigmund): refactor so we can remove `.node` here. This may
1056-
// require tracking in our checker for const values, so we can look it
1057-
// up cheaply here.
1058-
!_isConstantField(element.node);
1062+
return element is TopLevelVariableElement && !element.isConst;
10591063
}
10601064

10611065
/// Safely visit the given node, with an optional prefix or suffix.

test/codegen/expect/DeltaBlue/DeltaBlue.dart.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ var DeltaBlue;
4949
}
5050
addConstraint() {
5151
this.addToGraph();
52-
planner.incrementalAdd(this);
52+
DeltaBlue.planner.incrementalAdd(this);
5353
}
5454
satisfy(mark) {
5555
this.chooseMethod(/* Unimplemented: DownCast: dynamic to int */ mark);
@@ -64,12 +64,12 @@ var DeltaBlue;
6464
let overridden = out.determinedBy;
6565
if (overridden !== null) overridden.this.markUnsatisfied();
6666
out.determinedBy = this;
67-
if (!planner.addPropagate(this, /* Unimplemented: DownCast: dynamic to int */ mark)) dart_core.print("Cycle encountered");
67+
if (!DeltaBlue.planner.addPropagate(this, /* Unimplemented: DownCast: dynamic to int */ mark)) dart_core.print("Cycle encountered");
6868
out.mark = /* Unimplemented: DownCast: dynamic to int */ mark;
6969
return overridden;
7070
}
7171
destroyConstraint() {
72-
if (this.isSatisfied()) planner.incrementalRemove(this);
72+
if (this.isSatisfied()) DeltaBlue.planner.incrementalRemove(this);
7373
this.removeFromGraph();
7474
}
7575
isInput() { return false; }
@@ -355,7 +355,7 @@ var DeltaBlue;
355355

356356
// Function chainTest: (int) → void
357357
function chainTest(n) {
358-
planner = new Planner();
358+
DeltaBlue.planner = new Planner();
359359
let prev = null, first = null, last = null;
360360
for (let i = 0; i <= n; i++) {
361361
let v = new Variable("v", 0);
@@ -366,7 +366,7 @@ var DeltaBlue;
366366
}
367367
new StayConstraint(last, STRONG_DEFAULT);
368368
let edit = new EditConstraint(first, PREFERRED);
369-
let plan = planner.extractPlanFromConstraints(/* Unimplemented ArrayList */[edit]);
369+
let plan = DeltaBlue.planner.extractPlanFromConstraints(/* Unimplemented ArrayList */[edit]);
370370
for (let i = 0; i < 100; i++) {
371371
first.value = i;
372372
plan.execute();
@@ -379,7 +379,7 @@ var DeltaBlue;
379379

380380
// Function projectionTest: (int) → void
381381
function projectionTest(n) {
382-
planner = new Planner();
382+
DeltaBlue.planner = new Planner();
383383
let scale = new Variable("scale", 10);
384384
let offset = new Variable("offset", 1000);
385385
let src = null, dst = null;
@@ -408,23 +408,33 @@ var DeltaBlue;
408408
// Function change: (Variable, int) → void
409409
function change(v, newValue) {
410410
let edit = new EditConstraint(v, PREFERRED);
411-
let plan = planner.extractPlanFromConstraints(/* Unimplemented ArrayList */[edit]);
411+
let plan = DeltaBlue.planner.extractPlanFromConstraints(/* Unimplemented ArrayList */[edit]);
412412
for (let i = 0; i < 10; i++) {
413413
v.value = newValue;
414414
plan.execute();
415415
}
416416
edit.destroyConstraint();
417417
}
418418

419-
let planner;
419+
DeltaBlue.planner = null;
420420
// Exports:
421421
DeltaBlue.main = main;
422422
DeltaBlue.DeltaBlue = DeltaBlue;
423423
DeltaBlue.Strength = Strength;
424+
DeltaBlue.REQUIRED = REQUIRED;
425+
DeltaBlue.STRONG_PREFERRED = STRONG_PREFERRED;
426+
DeltaBlue.PREFERRED = PREFERRED;
427+
DeltaBlue.STRONG_DEFAULT = STRONG_DEFAULT;
428+
DeltaBlue.NORMAL = NORMAL;
429+
DeltaBlue.WEAK_DEFAULT = WEAK_DEFAULT;
430+
DeltaBlue.WEAKEST = WEAKEST;
424431
DeltaBlue.Constraint = Constraint;
425432
DeltaBlue.UnaryConstraint = UnaryConstraint;
426433
DeltaBlue.StayConstraint = StayConstraint;
427434
DeltaBlue.EditConstraint = EditConstraint;
435+
DeltaBlue.NONE = NONE;
436+
DeltaBlue.FORWARD = FORWARD;
437+
DeltaBlue.BACKWARD = BACKWARD;
428438
DeltaBlue.BinaryConstraint = BinaryConstraint;
429439
DeltaBlue.ScaleConstraint = ScaleConstraint;
430440
DeltaBlue.EqualityConstraint = EqualityConstraint;

test/codegen/expect/dom/dom.dart.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var dom;
1919
}
2020

2121
let overload = new Overload();
22-
let document;
22+
dom.document = null;
2323
class Document {
2424
}
2525

@@ -93,6 +93,7 @@ var dom;
9393
dom.JsType = JsType;
9494
dom.JsGlobal = JsGlobal;
9595
dom.Overload = Overload;
96+
dom.overload = overload;
9697
dom.Document = Document;
9798
dom.Element = Element;
9899
dom.Event = Event;

test/codegen/expect/sunflower/sunflower.dart.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var sunflower;
1111
// Function querySelector: (String) → Element
1212
function querySelector(selector) { return dom.document.querySelector(selector); }
1313

14-
let seeds = 0;
14+
sunflower.seeds = 0;
1515
dart.defineLazyProperties(sunflower, {
1616
get slider() { return /* Unimplemented: DownCast: Element to InputElement */ querySelector("#slider") },
1717
get notes() { return querySelector("#notes") },
@@ -52,19 +52,26 @@ var sunflower;
5252

5353
// Function draw: () → void
5454
function draw() {
55-
seeds = dart_core.int.parse(sunflower.slider.value);
55+
sunflower.seeds = dart_core.int.parse(sunflower.slider.value);
5656
sunflower.context.clearRect(0, 0, MAX_D, MAX_D);
57-
for (let i = 0; i < seeds; i++) {
57+
for (let i = 0; i < sunflower.seeds; i++) {
5858
let theta = i * TAU / sunflower.PHI;
5959
let r = dart_math.sqrt(i) * SCALE_FACTOR;
6060
let x = centerX + r * dart_math.cos(theta);
6161
let y = centerY - r * dart_math.sin(theta);
6262
new SunflowerSeed(x, y).draw();
6363
}
64-
sunflower.notes.textContent = "" + (seeds) + " seeds";
64+
sunflower.notes.textContent = "" + (sunflower.seeds) + " seeds";
6565
}
6666

6767
// Exports:
68+
sunflower.ORANGE = ORANGE;
69+
sunflower.SEED_RADIUS = SEED_RADIUS;
70+
sunflower.SCALE_FACTOR = SCALE_FACTOR;
71+
sunflower.TAU = TAU;
72+
sunflower.MAX_D = MAX_D;
73+
sunflower.centerX = centerX;
74+
sunflower.centerY = centerY;
6875
sunflower.querySelector = querySelector;
6976
sunflower.Circle = Circle;
7077
sunflower.SunflowerSeed = SunflowerSeed;

0 commit comments

Comments
 (0)