Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(587)

Unified Diff: lib/src/codegen/js_codegen.dart

Issue 1767803002: a few small refactorings to closure workarounds (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/closure/closure_type.dart ('k') | lib/src/codegen/js_metalet.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/codegen/js_codegen.dart
diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
index cd4b5c9b812a71288b821e696a00ae6110152b5a..ba422122e11c403b259e2e3602844037b0c0e55f 100644
--- a/lib/src/codegen/js_codegen.dart
+++ b/lib/src/codegen/js_codegen.dart
@@ -377,11 +377,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
}
- var classExpr = new JS.ClassExpression(
- new JS.Identifier(element.name), _classHeritage(element), body);
-
- return _finishClassDef(
- element.type, _emitClassHeritageWorkaround(classExpr));
+ var cls = _emitClassDeclaration(element, body);
+ return _finishClassDef(element.type, cls);
}
JS.Statement _emitJsType(String dartClassName, DartObject jsName) {
@@ -421,11 +418,11 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
}
- var classExpr = new JS.ClassExpression(new JS.Identifier(type.name),
- _classHeritage(classElem), _emitClassMethods(node, ctors, fields),
- typeParams: _emitTypeFormals(classElem.typeParameters),
- fields:
- _emitFieldDeclarations(classElem, fields, staticFields).toList());
+ var allFields = new List.from(fields)..addAll(staticFields);
+
+ var classDecl = _emitClassDeclaration(
+ classElem, _emitClassMethods(node, ctors, fields),
+ fields: allFields);
String jsPeerName;
var jsPeer = findAnnotation(classElem, isJsPeerInterface);
@@ -442,7 +439,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
}
- var body = _finishClassMembers(classElem, classExpr, ctors, fields,
+ var body = _finishClassMembers(classElem, classDecl, ctors, fields,
staticFields, methods, node.metadata, jsPeerName);
var result = _finishClassDef(type, body);
@@ -467,36 +464,24 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
List<JS.Identifier> _emitTypeFormals(List<TypeParameterElement> typeFormals) {
- if (!options.closure) return null;
return typeFormals
.map((t) => new JS.Identifier(t.name))
.toList(growable: false);
}
- /// Emit field declarations for TypeScript & Closure's ES6_TYPED
+ /// Emits a field declaration for TypeScript & Closure's ES6_TYPED
/// (e.g. `class Foo { i: string; }`)
- Iterable<JS.VariableDeclarationList> _emitFieldDeclarations(
- ClassElement classElem,
- List<FieldDeclaration> fields,
- List<FieldDeclaration> staticFields) sync* {
- if (!options.closure) return;
-
- makeInitialization(VariableDeclaration decl) =>
- new JS.VariableInitialization(
- new JS.Identifier(
- // TODO(ochafik): use a refactored _emitMemberName instead.
- decl.name.name,
- type: emitTypeRef(decl.element.type)),
- null);
-
- for (var field in fields) {
- yield new JS.VariableDeclarationList(
- null, field.fields.variables.map(makeInitialization).toList());
- }
- for (var field in staticFields) {
- yield new JS.VariableDeclarationList(
- 'static', field.fields.variables.map(makeInitialization).toList());
- }
+ JS.VariableDeclarationList _emitTypeScriptField(FieldDeclaration field) {
+ return new JS.VariableDeclarationList(
+ field.isStatic ? 'static' : null,
+ field.fields.variables
+ .map((decl) => new JS.VariableInitialization(
+ new JS.Identifier(
+ // TODO(ochafik): use a refactored _emitMemberName instead.
+ decl.name.name,
+ type: emitTypeRef(decl.element.type)),
+ null))
+ .toList(growable: false));
}
@override
@@ -527,7 +512,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
// Create enum class
var classExpr = new JS.ClassExpression(
- id, _classHeritage(element), [constructor, toStringF]);
+ id, _emitClassHeritage(element), [constructor, toStringF]);
var result = <JS.Statement>[js.statement('#', classExpr)];
// Create static fields for each enum value
@@ -608,7 +593,33 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
return false;
}
- JS.Expression _classHeritage(ClassElement element) {
+ JS.Statement _emitClassDeclaration(
+ ClassElement element, List<JS.Method> methods,
+ {List<FieldDeclaration> fields}) {
+ String name = element.name;
+ var heritage = _emitClassHeritage(element);
+ var typeParams = _emitTypeFormals(element.typeParameters);
+ var jsFields = fields?.map(_emitTypeScriptField)?.toList();
+
+ // Workaround for Closure: super classes must be qualified paths.
+ // TODO(jmesserly): is there a bug filed? we need to get out of the business
+ // of working around bugs in other transpilers...
+ JS.Statement workaroundSuper = null;
+ if (options.closure && heritage is JS.Call) {
+ var superVar = new JS.TemporaryId('$name\$super');
+ workaroundSuper = js.statement('const # = #;', [superVar, heritage]);
+ heritage = superVar;
+ }
+ var decl = new JS.ClassDeclaration(new JS.ClassExpression(
+ new JS.Identifier(name), heritage, methods,
+ typeParams: typeParams, fields: jsFields));
+ if (workaroundSuper != null) {
+ return new JS.Block([workaroundSuper, decl]);
+ }
+ return decl;
+ }
+
+ JS.Expression _emitClassHeritage(ClassElement element) {
var type = element.type;
if (type.isObject) return null;
@@ -758,34 +769,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
}
- _isQualifiedPath(JS.Expression node) =>
- node is JS.Identifier ||
- node is JS.PropertyAccess &&
- _isQualifiedPath(node.receiver) &&
- node.selector is JS.LiteralString;
-
- /// Workaround for Closure: super classes must be qualified paths.
- JS.Statement _emitClassHeritageWorkaround(JS.ClassExpression cls) {
- if (options.closure &&
- cls.heritage != null &&
- !_isQualifiedPath(cls.heritage)) {
- var superVar = new JS.TemporaryId(cls.name.name + r'$super');
- return _statement([
- js.statement('const # = #;', [superVar, cls.heritage]),
- new JS.ClassDeclaration(new JS.ClassExpression(
- cls.name, superVar, cls.methods,
- typeParams: cls.typeParams, fields: cls.fields))
- ]);
- }
- return new JS.ClassDeclaration(cls);
- }
-
/// Emit class members that need to come after the class declaration, such
/// as static fields. See [_emitClassMethods] for things that are emitted
/// inside the ES6 `class { ... }` node.
JS.Statement _finishClassMembers(
ClassElement classElem,
- JS.ClassExpression cls,
+ JS.Statement classDecl,
List<ConstructorDeclaration> ctors,
List<FieldDeclaration> fields,
List<FieldDeclaration> staticFields,
@@ -818,7 +807,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
}
}
- body.add(_emitClassHeritageWorkaround(cls));
+ body.add(classDecl);
// TODO(jmesserly): we should really just extend native Array.
if (jsPeerName != null && classElem.typeParameters.isNotEmpty) {
@@ -3499,7 +3488,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor
// TODO(jmesserly): this will need to be a generic method, if we ever want to
// self-host strong mode.
- List /*<T>*/ _visitList /*<T>*/ (Iterable<AstNode> nodes) {
+ List/*<T>*/ _visitList/*<T>*/(Iterable<AstNode> nodes) {
if (nodes == null) return null;
var result = /*<T>*/ [];
for (var node in nodes) result.add(_visit(node));
@@ -3820,6 +3809,7 @@ class JSGenerator extends CodeGenerator {
? Uri.parse('http://${flags.host}:${flags.port}/')
: null;
return writeJsLibrary(module, out, compiler.inputBaseDir, serverUri,
+ emitTypes: options.closure,
emitSourceMaps: options.emitSourceMaps,
fileSystem: compiler.fileSystem);
}
« no previous file with comments | « lib/src/closure/closure_type.dart ('k') | lib/src/codegen/js_metalet.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698