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

Side by Side Diff: lib/module.ts

Issue 2394683003: JS Interop Facade generation polish.
Patch Set: more cleanup Created 4 years, 2 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 unified diff | Download patch
« no previous file with comments | « lib/merge.ts ('k') | lib/type.ts » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 import * as ts from 'typescript'; 1 import * as ts from 'typescript';
2 2
3 import * as base from './base'; 3 import * as base from './base';
4 import {FacadeConverter} from './facade_converter'; 4 import {FacadeConverter} from './facade_converter';
5 import {OutputContext, Transpiler} from './main'; 5 import {OutputContext, Transpiler} from './main';
6 6
7 export default class ModuleTranspiler extends base.TranspilerBase { 7 export default class ModuleTranspiler extends base.TranspilerBase {
8 constructor(tr: Transpiler, private fc: FacadeConverter, private generateLibra ryName: boolean) { 8 constructor(tr: Transpiler, private fc: FacadeConverter, private moduleName: s tring) {
9 super(tr); 9 super(tr);
10 } 10 }
11 11
12 visitNode(node: ts.Node): boolean { 12 visitNode(node: ts.Node): boolean {
13 switch (node.kind) { 13 switch (node.kind) {
14 case ts.SyntaxKind.SourceFile: 14 case ts.SyntaxKind.SourceFile:
15 this.pushContext(OutputContext.Import); 15 this.pushContext(OutputContext.Import);
16 this.emit('@JS()'); 16 let sourceFile = node as ts.SourceFile;
17 let moduleName = this.moduleName;
18 if (sourceFile.moduleName) {
19 moduleName = sourceFile.moduleName;
20 }
21 sourceFile.statements.forEach((n: ts.Node) => {
22 if (n.kind === ts.SyntaxKind.GlobalModuleExportDeclaration) {
23 let decl = n as ts.GlobalModuleExportDeclaration;
24 moduleName = base.ident(decl.name);
25 }
26 });
27 if (moduleName) {
28 this.emit('@JS("' + moduleName + '")');
29 } else {
30 this.emit('@JS()');
31 }
17 this.emit('library'); 32 this.emit('library');
18 this.emit(this.getLibraryName()); 33 this.emit(this.getLibraryName());
19 this.emit(';'); 34 this.emit(';');
20 this.popContext(); 35 this.popContext();
21 36
22 this.emitImport('package:js/js.dart'); 37 this.emitImport('package:js/js.dart');
23 ts.forEachChild(node, this.visit.bind(this)); 38 // The declaration transpiler is responsible for emitting the contents o f the source file.
24 break; 39 return false;
25 case ts.SyntaxKind.EndOfFileToken: 40 case ts.SyntaxKind.EndOfFileToken:
26 ts.forEachChild(node, this.visit.bind(this)); 41 ts.forEachChild(node, this.visit.bind(this));
27 break; 42 break;
28 case ts.SyntaxKind.ImportDeclaration: 43 case ts.SyntaxKind.ImportDeclaration:
29 let importDecl = <ts.ImportDeclaration>node; 44 let importDecl = <ts.ImportDeclaration>node;
30 if (importDecl.importClause) { 45 if (importDecl.importClause) {
31 if (this.isEmptyImport(importDecl)) return true; 46 if (this.isEmptyImport(importDecl)) return true;
32 this.emit('import'); 47 this.emit('import');
33 this.visitExternalModuleReferenceExpr(importDecl.moduleSpecifier); 48 this.visitExternalModuleReferenceExpr(importDecl.moduleSpecifier);
34 this.visit(importDecl.importClause); 49 this.visit(importDecl.importClause);
(...skipping 29 matching lines...) Expand all
64 this.visitList((<ts.NamedExports>node).elements); 79 this.visitList((<ts.NamedExports>node).elements);
65 break; 80 break;
66 case ts.SyntaxKind.ImportSpecifier: 81 case ts.SyntaxKind.ImportSpecifier:
67 case ts.SyntaxKind.ExportSpecifier: 82 case ts.SyntaxKind.ExportSpecifier:
68 let spec = <ts.ImportOrExportSpecifier>node; 83 let spec = <ts.ImportOrExportSpecifier>node;
69 if (spec.propertyName) { 84 if (spec.propertyName) {
70 this.reportError(spec.propertyName, 'import/export renames are unsuppo rted in Dart'); 85 this.reportError(spec.propertyName, 'import/export renames are unsuppo rted in Dart');
71 } 86 }
72 this.fc.visitTypeName(spec.name); 87 this.fc.visitTypeName(spec.name);
73 break; 88 break;
89 case ts.SyntaxKind.GlobalModuleExportDeclaration:
90 // We handle this globally exporting all files in the packge with the sp ecified global
91 // module export location.
92 break;
74 case ts.SyntaxKind.ExportDeclaration: 93 case ts.SyntaxKind.ExportDeclaration:
75 let exportDecl = <ts.ExportDeclaration>node; 94 let exportDecl = <ts.ExportDeclaration>node;
76 this.emit('export'); 95 this.emit('export');
77 if (exportDecl.moduleSpecifier) { 96 if (exportDecl.moduleSpecifier) {
78 this.visitExternalModuleReferenceExpr(exportDecl.moduleSpecifier); 97 this.visitExternalModuleReferenceExpr(exportDecl.moduleSpecifier);
79 } else { 98 } else {
80 this.reportError(node, 're-exports must have a module URL (export x fr om "./y").'); 99 this.reportError(node, 're-exports must have a module URL (export x fr om "./y").');
81 } 100 }
82 if (exportDecl.exportClause) this.visit(exportDecl.exportClause); 101 if (exportDecl.exportClause) this.visit(exportDecl.exportClause);
83 this.emit(';'); 102 this.emit(';\n');
84 break; 103 break;
85 case ts.SyntaxKind.ImportEqualsDeclaration: 104 case ts.SyntaxKind.ImportEqualsDeclaration:
86 let importEqDecl = <ts.ImportEqualsDeclaration>node; 105 let importEqDecl = <ts.ImportEqualsDeclaration>node;
87 this.pushContext(OutputContext.Import); 106 this.pushContext(OutputContext.Import);
88 this.emit('import'); 107 this.emit('import');
89 this.visit(importEqDecl.moduleReference); 108 this.visit(importEqDecl.moduleReference);
90 this.emit('as'); 109 this.emit('as');
91 this.fc.visitTypeName(importEqDecl.name); 110 this.fc.visitTypeName(importEqDecl.name);
92 this.emit(';'); 111 this.emit(';\n');
93 this.popContext(); 112 this.popContext();
94 break; 113 break;
95 case ts.SyntaxKind.ExternalModuleReference: 114 case ts.SyntaxKind.ExternalModuleReference:
96 this.visitExternalModuleReferenceExpr((<ts.ExternalModuleReference>node) .expression); 115 this.visitExternalModuleReferenceExpr((<ts.ExternalModuleReference>node) .expression);
97 break; 116 break;
98 117
99 default: 118 default:
100 return false; 119 return false;
101 } 120 }
102 return true; 121 return true;
103 } 122 }
104 123
105 private static isIgnoredImport(e: ts.ImportSpecifier) { return false; } 124 private static isIgnoredImport(e: ts.ImportSpecifier) { return false; }
106 125
107 private visitExternalModuleReferenceExpr(expr: ts.Expression) { 126 private visitExternalModuleReferenceExpr(expr: ts.Expression) {
108 // TODO: what if this isn't a string literal? 127 // TODO: what if this isn't a string literal?
109 let moduleName = <ts.StringLiteral>expr; 128 let moduleName = <ts.StringLiteral>expr;
110 let text = moduleName.text; 129 let text = moduleName.text;
111 if (text.match(/^\.\//)) { 130 if (text.match(/^\.\//)) {
112 // Strip './' to be more Dart-idiomatic. 131 // Strip './' to be more Dart-idiomatic.
113 text = text.substring(2); 132 text = text.substring(2);
114 } else if (!text.match(/^\.\.\//)) { 133 } else if (!text.match(/^\.\.\//)) {
115 // Unprefixed imports are package imports. 134 // Unprefixed imports are package imports.
116 text = 'package:' + text; 135 text = 'package:' + text;
136 } else {
137 // TODO(jacobr): actually handle imports in different directories. We assu me for now that all
138 // files in a library will be output to a single directory for codegen sim plicity.
139 let parts = text.split('/');
140 text = parts[parts.length - 1];
117 } 141 }
142
118 this.emit(JSON.stringify(text + '.dart')); 143 this.emit(JSON.stringify(text + '.dart'));
119 } 144 }
120 145
121 private isEmptyImport(n: ts.ImportDeclaration): boolean { 146 private isEmptyImport(n: ts.ImportDeclaration): boolean {
122 let bindings = n.importClause.namedBindings; 147 let bindings = n.importClause.namedBindings;
123 if (bindings.kind !== ts.SyntaxKind.NamedImports) return false; 148 if (bindings.kind !== ts.SyntaxKind.NamedImports) return false;
124 let elements = (<ts.NamedImports>bindings).elements; 149 let elements = (<ts.NamedImports>bindings).elements;
125 if (elements.length === 0) return true; 150 if (elements.length === 0) return true;
126 return elements.every(ModuleTranspiler.isIgnoredImport); 151 return elements.every(ModuleTranspiler.isIgnoredImport);
127 } 152 }
128 153
129 private filterImports(ns: ts.ImportOrExportSpecifier[]) { 154 private filterImports(ns: ts.ImportOrExportSpecifier[]) {
130 return ns.filter((e) => !ModuleTranspiler.isIgnoredImport(e)); 155 return ns.filter((e) => !ModuleTranspiler.isIgnoredImport(e));
131 } 156 }
132 157
133 getLibraryName(nameForTest?: string) { 158 getLibraryName(jsFileName?: string) {
134 let fileName = this.getRelativeFileName(nameForTest); 159 let fileName = this.getDartFileName(jsFileName);
135 let parts = fileName.split('/'); 160 let parts = fileName.split('/');
136 return parts.filter((p) => p.length > 0) 161 return parts.filter((p) => p.length > 0 && p !== '..')
137 .map((p) => p.replace(/[^\w.]/g, '_')) 162 .map((p) => p.replace(/[^\w.]/g, '_'))
138 .map((p) => p.replace(/\.d\.ts$/g, '')) 163 .map((p) => p.replace(/\.dart$/, ''))
139 .map((p) => p.replace(/\.[jt]s$/g, ''))
140 .map((p) => p.replace(/\./g, ''))
141 .map((p) => FacadeConverter.DART_RESERVED_WORDS.indexOf(p) !== -1 ? '_' + p : p) 164 .map((p) => FacadeConverter.DART_RESERVED_WORDS.indexOf(p) !== -1 ? '_' + p : p)
142 .filter((p) => p.length > 0) 165 .filter((p) => p.length > 0)
143 .join('.'); 166 .join('.');
144 } 167 }
145 } 168 }
OLDNEW
« no previous file with comments | « lib/merge.ts ('k') | lib/type.ts » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698