Skip to content

Commit 772f6f6

Browse files
author
John Messerly
committed
fixes #185, track const ctor dependencies, plus a static field fix
[email protected] Review URL: https://codereview.chromium.org/1141663003
1 parent 8040611 commit 772f6f6

File tree

7 files changed

+70
-30
lines changed

7 files changed

+70
-30
lines changed

pkg/dev_compiler/lib/runtime/dart/convert.js

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,24 @@ var collection = dart.import(collection);
618618
},
619619
set _nameToEncoding(_) {}
620620
});
621+
let _name = Symbol('_name');
622+
class HtmlEscapeMode extends core.Object {
623+
_(name, escapeLtGt, escapeQuot, escapeApos, escapeSlash) {
624+
this[_name] = name;
625+
this.escapeLtGt = escapeLtGt;
626+
this.escapeQuot = escapeQuot;
627+
this.escapeApos = escapeApos;
628+
this.escapeSlash = escapeSlash;
629+
}
630+
toString() {
631+
return this[_name];
632+
}
633+
}
634+
dart.defineNamedConstructor(HtmlEscapeMode, '_');
635+
dart.setSignature(HtmlEscapeMode, {
636+
methods: () => ({toString: dart.functionType(core.String, [])})
637+
});
638+
HtmlEscapeMode.UNKNOWN = dart.const(new HtmlEscapeMode._('unknown', true, true, true, true));
621639
let _convert = Symbol('_convert');
622640
class HtmlEscape extends Converter$(core.String, core.String) {
623641
HtmlEscape(mode) {
@@ -702,24 +720,6 @@ var collection = dart.import(collection);
702720
})
703721
});
704722
let HTML_ESCAPE = dart.const(new HtmlEscape());
705-
let _name = Symbol('_name');
706-
class HtmlEscapeMode extends core.Object {
707-
_(name, escapeLtGt, escapeQuot, escapeApos, escapeSlash) {
708-
this[_name] = name;
709-
this.escapeLtGt = escapeLtGt;
710-
this.escapeQuot = escapeQuot;
711-
this.escapeApos = escapeApos;
712-
this.escapeSlash = escapeSlash;
713-
}
714-
toString() {
715-
return this[_name];
716-
}
717-
}
718-
dart.defineNamedConstructor(HtmlEscapeMode, '_');
719-
dart.setSignature(HtmlEscapeMode, {
720-
methods: () => ({toString: dart.functionType(core.String, [])})
721-
});
722-
HtmlEscapeMode.UNKNOWN = dart.const(new HtmlEscapeMode._('unknown', true, true, true, true));
723723
HtmlEscapeMode.ATTRIBUTE = dart.const(new HtmlEscapeMode._('attribute', false, true, false, false));
724724
HtmlEscapeMode.ELEMENT = dart.const(new HtmlEscapeMode._('element', true, false, false, true));
725725
let _escape = Symbol('_escape');
@@ -2807,9 +2807,9 @@ var collection = dart.import(collection);
28072807
exports.ChunkedConversionSink = ChunkedConversionSink;
28082808
exports.ByteConversionSink = ByteConversionSink;
28092809
exports.ByteConversionSinkBase = ByteConversionSinkBase;
2810+
exports.HtmlEscapeMode = HtmlEscapeMode;
28102811
exports.HtmlEscape = HtmlEscape;
28112812
exports.HTML_ESCAPE = HTML_ESCAPE;
2812-
exports.HtmlEscapeMode = HtmlEscapeMode;
28132813
exports.JsonUnsupportedObjectError = JsonUnsupportedObjectError;
28142814
exports.JsonCyclicError = JsonCyclicError;
28152815
exports.JsonCodec = JsonCodec;

pkg/dev_compiler/lib/src/codegen/js_codegen.dart

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
716716
// Generate optional/named argument value assignment. These can not have
717717
// side effects, and may be used by the constructor's initializers, so it's
718718
// nice to do them first.
719+
// Also for const constructors we need to ensure default values are
720+
// available for use by top-level constant initializers.
721+
ClassDeclaration cls = node.parent;
722+
if (node.constKeyword != null) _loader.startTopLevel(cls.element);
719723
var init = _emitArgumentInitializers(node, constructor: true);
724+
if (node.constKeyword != null) _loader.finishTopLevel(cls.element);
720725
if (init != null) body.add(init);
721726

722727
// Redirecting constructors: these are not allowed to have initializers,
@@ -735,7 +740,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
735740
// These are expanded into each non-redirecting constructor.
736741
// In the future we may want to create an initializer function if we have
737742
// multiple constructors, but it needs to be balanced against readability.
738-
body.add(_initializeFields(node, fields));
743+
body.add(_initializeFields(node.parent, fields, node));
739744

740745
var superCall = node.initializers.firstWhere(
741746
(i) => i is SuperConstructorInvocation, orElse: () => null);
@@ -800,9 +805,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
800805
/// 3. constructor field initializers,
801806
/// 4. initialize fields not covered in 1-3
802807
JS.Statement _initializeFields(
803-
AstNode node, List<FieldDeclaration> fieldDecls) {
804-
var unit = node.getAncestor((a) => a is CompilationUnit);
808+
ClassDeclaration cls, List<FieldDeclaration> fieldDecls,
809+
[ConstructorDeclaration ctor]) {
810+
var unit = cls.getAncestor((a) => a is CompilationUnit);
805811
var constField = new ConstFieldVisitor(types, unit);
812+
bool isConst = ctor != null && ctor.constKeyword != null;
813+
if (isConst) _loader.startTopLevel(cls.element);
806814

807815
// Run field initializers if they can have side-effects.
808816
var fields = new Map<FieldElement, JS.Expression>();
@@ -819,19 +827,16 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
819827
}
820828

821829
// Initialize fields from `this.fieldName` parameters.
822-
if (node is ConstructorDeclaration) {
823-
var parameters = node.parameters;
824-
var initializers = node.initializers;
825-
826-
for (var p in parameters.parameters) {
830+
if (ctor != null) {
831+
for (var p in ctor.parameters.parameters) {
827832
var element = p.element;
828833
if (element is FieldFormalParameterElement) {
829834
fields[element.field] = _visit(p);
830835
}
831836
}
832837

833838
// Run constructor field initializers such as `: foo = bar.baz`
834-
for (var init in initializers) {
839+
for (var init in ctor.initializers) {
835840
if (init is ConstructorFieldInitializer) {
836841
fields[init.fieldName.staticElement] = _visit(init.expression);
837842
}
@@ -860,6 +865,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
860865
var access = _emitMemberName(e.name, type: e.enclosingElement.type);
861866
body.add(js.statement('this.# = #;', [access, initialValue]));
862867
});
868+
869+
if (isConst) _loader.finishTopLevel(cls.element);
863870
return _statement(body);
864871
}
865872

@@ -1981,7 +1988,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ConversionVisitor {
19811988
/// Shared code for [PrefixedIdentifier] and [PropertyAccess].
19821989
JS.Expression _emitGet(Expression target, SimpleIdentifier memberId) {
19831990
var member = memberId.staticElement;
1984-
bool isStatic = member is ExecutableElement && member.isStatic;
1991+
if (member is PropertyAccessorElement) member = member.variable;
1992+
bool isStatic = member is ClassMemberElement && member.isStatic;
1993+
if (isStatic) {
1994+
_loader.declareBeforeUse(member);
1995+
}
19851996
var name = _emitMemberName(memberId.name,
19861997
type: getStaticType(target), isStatic: isStatic);
19871998
if (rules.isDynamicTarget(target)) {

pkg/dev_compiler/lib/src/dependency_graph.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,10 @@ const corelibOrder = const [
503503
'dart.typed_data',
504504
'dart._isolate_helper',
505505
'dart._js_primitives',
506+
'dart.convert',
506507

507508
// TODO(jmesserly): add others
508509
/*
509-
'dart.convert',
510510
'dart._foreign_helper',
511511
'dart._interceptors',
512512
'dart._native_typed_data',

pkg/dev_compiler/test/codegen/expect/fieldtest.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ var core = dart.import(core);
8383
});
8484
let Generic = Generic$();
8585
Generic.bar = 'hello';
86+
class StaticFieldOrder1 extends core.Object {}
87+
dart.setSignature(StaticFieldOrder1, {});
88+
StaticFieldOrder1.d = 4;
89+
StaticFieldOrder1.c = dart.notNull(StaticFieldOrder1.d) + 2;
90+
StaticFieldOrder1.b = dart.notNull(StaticFieldOrder1.c) + 3;
91+
StaticFieldOrder1.a = dart.notNull(StaticFieldOrder1.b) + 1;
92+
class StaticFieldOrder2 extends core.Object {}
93+
dart.setSignature(StaticFieldOrder2, {});
94+
StaticFieldOrder2.d = 4;
95+
StaticFieldOrder2.c = dart.notNull(StaticFieldOrder2.d) + 2;
96+
StaticFieldOrder2.b = dart.notNull(StaticFieldOrder2.c) + 3;
97+
StaticFieldOrder2.a = dart.notNull(StaticFieldOrder2.b) + 1;
8698
function main() {
8799
let a = new A();
88100
foo(a);
@@ -103,5 +115,7 @@ var core = dart.import(core);
103115
exports.Derived = Derived;
104116
exports.Generic$ = Generic$;
105117
exports.Generic = Generic;
118+
exports.StaticFieldOrder1 = StaticFieldOrder1;
119+
exports.StaticFieldOrder2 = StaticFieldOrder2;
106120
exports.main = main;
107121
})(fieldtest, core);

pkg/dev_compiler/test/codegen/expect/html_input.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<script src="dev_compiler/runtime/dart/typed_data.js"></script>
1515
<script src="dev_compiler/runtime/dart/_isolate_helper.js"></script>
1616
<script src="dev_compiler/runtime/dart/_js_primitives.js"></script>
17+
<script src="dev_compiler/runtime/dart/convert.js"></script>
1718
<script src="dir/html_input_d.js"></script>
1819
<script src="dir/html_input_b.js"></script>
1920
<script src="dir/html_input_e.js"></script>

pkg/dev_compiler/test/codegen/expect/sunflower/sunflower.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ <h1>drfibonacci's Sunflower Spectacular</h1>
3939
<script src="dev_compiler/runtime/dart/typed_data.js"></script>
4040
<script src="dev_compiler/runtime/dart/_isolate_helper.js"></script>
4141
<script src="dev_compiler/runtime/dart/_js_primitives.js"></script>
42+
<script src="dev_compiler/runtime/dart/convert.js"></script>
4243
<script src="dom.js"></script>
4344
<script src="sunflower.js"></script>
4445
<script>_isolate_helper.startRootIsolate(sunflower.main, []);</script>

pkg/dev_compiler/test/codegen/fieldtest.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,19 @@ class Generic<T> {
5151
static String bar = 'hello';
5252
}
5353

54+
class StaticFieldOrder1 {
55+
static const a = b + 1;
56+
static const c = d + 2;
57+
static const b = c + 3;
58+
static const d = 4;
59+
}
60+
class StaticFieldOrder2 {
61+
static const a = StaticFieldOrder2.b + 1;
62+
static const c = StaticFieldOrder2.d + 2;
63+
static const b = StaticFieldOrder2.c + 3;
64+
static const d = 4;
65+
}
66+
5467
void main() {
5568
var a = new A();
5669
foo(a);

0 commit comments

Comments
 (0)