Project

General

Profile

1
"use strict";
2
/**
3
 * @license
4
 * Copyright Google Inc. All Rights Reserved.
5
 *
6
 * Use of this source code is governed by an MIT-style license that can be
7
 * found in the LICENSE file at https://angular.io/license
8
 */
9
Object.defineProperty(exports, "__esModule", { value: true });
10
var compiler_1 = require("@angular/compiler");
11
var ts = require("typescript");
12
var METHOD_THIS_NAME = 'this';
13
var CATCH_ERROR_NAME = 'error';
14
var CATCH_STACK_NAME = 'stack';
15
var TypeScriptNodeEmitter = (function () {
16
    function TypeScriptNodeEmitter() {
17
    }
18
    TypeScriptNodeEmitter.prototype.updateSourceFile = function (sourceFile, stmts, preamble) {
19
        var converter = new _NodeEmitterVisitor();
20
        var statements = stmts.map(function (stmt) { return stmt.visitStatement(converter, null); }).filter(function (stmt) { return stmt != null; });
21
        var newSourceFile = ts.updateSourceFileNode(sourceFile, converter.getReexports().concat(converter.getImports(), statements));
22
        if (preamble) {
23
            if (preamble.startsWith('/*') && preamble.endsWith('*/')) {
24
                preamble = preamble.substr(2, preamble.length - 4);
25
            }
26
            if (!statements.length) {
27
                statements.push(ts.createEmptyStatement());
28
            }
29
            statements[0] = ts.setSyntheticLeadingComments(statements[0], [{ kind: ts.SyntaxKind.MultiLineCommentTrivia, text: preamble, pos: -1, end: -1 }]);
30
        }
31
        return [newSourceFile, converter.getNodeMap()];
32
    };
33
    return TypeScriptNodeEmitter;
34
}());
35
exports.TypeScriptNodeEmitter = TypeScriptNodeEmitter;
36
function createLiteral(value) {
37
    if (value === null) {
38
        return ts.createNull();
39
    }
40
    else if (value === undefined) {
41
        return ts.createIdentifier('undefined');
42
    }
43
    else {
44
        return ts.createLiteral(value);
45
    }
46
}
47
/**
48
 * Visits an output ast and produces the corresponding TypeScript synthetic nodes.
49
 */
50
var _NodeEmitterVisitor = (function () {
51
    function _NodeEmitterVisitor() {
52
        this._nodeMap = new Map();
53
        this._importsWithPrefixes = new Map();
54
        this._reexports = new Map();
55
    }
56
    _NodeEmitterVisitor.prototype.getReexports = function () {
57
        return Array.from(this._reexports.entries())
58
            .map(function (_a) {
59
            var exportedFilePath = _a[0], reexports = _a[1];
60
            return ts.createExportDeclaration(
61
            /* decorators */ undefined, 
62
            /* modifiers */ undefined, ts.createNamedExports(reexports.map(function (_a) {
63
                var name = _a.name, as = _a.as;
64
                return ts.createExportSpecifier(name, as);
65
            })), 
66
            /* moduleSpecifier */ createLiteral(exportedFilePath));
67
        });
68
    };
69
    _NodeEmitterVisitor.prototype.getImports = function () {
70
        return Array.from(this._importsWithPrefixes.entries())
71
            .map(function (_a) {
72
            var namespace = _a[0], prefix = _a[1];
73
            return ts.createImportDeclaration(
74
            /* decorators */ undefined, 
75
            /* modifiers */ undefined, 
76
            /* importClause */ ts.createImportClause(
77
            /* name */ undefined, ts.createNamespaceImport(ts.createIdentifier(prefix))), 
78
            /* moduleSpecifier */ createLiteral(namespace));
79
        });
80
    };
81
    _NodeEmitterVisitor.prototype.getNodeMap = function () { return this._nodeMap; };
82
    _NodeEmitterVisitor.prototype.record = function (ngNode, tsNode) {
83
        var _this = this;
84
        if (tsNode && !this._nodeMap.has(tsNode)) {
85
            this._nodeMap.set(tsNode, ngNode);
86
            ts.forEachChild(tsNode, function (child) { return _this.record(ngNode, tsNode); });
87
        }
88
        return tsNode;
89
    };
90
    _NodeEmitterVisitor.prototype.getModifiers = function (stmt) {
91
        var modifiers = [];
92
        if (stmt.hasModifier(compiler_1.StmtModifier.Exported)) {
93
            modifiers.push(ts.createToken(ts.SyntaxKind.ExportKeyword));
94
        }
95
        return modifiers;
96
    };
97
    // StatementVisitor
98
    _NodeEmitterVisitor.prototype.visitDeclareVarStmt = function (stmt) {
99
        if (stmt.hasModifier(compiler_1.StmtModifier.Exported) && stmt.value instanceof compiler_1.ExternalExpr &&
100
            !stmt.type) {
101
            // check for a reexport
102
            var _a = stmt.value.value, name_1 = _a.name, moduleName = _a.moduleName;
103
            if (moduleName) {
104
                var reexports = this._reexports.get(moduleName);
105
                if (!reexports) {
106
                    reexports = [];
107
                    this._reexports.set(moduleName, reexports);
108
                }
109
                reexports.push({ name: name_1, as: stmt.name });
110
                return null;
111
            }
112
        }
113
        return this.record(stmt, ts.createVariableStatement(this.getModifiers(stmt), ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createIdentifier(stmt.name), 
114
            /* type */ undefined, (stmt.value && stmt.value.visitExpression(this, null)) || undefined)])));
115
    };
116
    _NodeEmitterVisitor.prototype.visitDeclareFunctionStmt = function (stmt, context) {
117
        return this.record(stmt, ts.createFunctionDeclaration(
118
        /* decorators */ undefined, this.getModifiers(stmt), 
119
        /* astrictToken */ undefined, stmt.name, /* typeParameters */ undefined, stmt.params.map(function (p) { return ts.createParameter(
120
        /* decorators */ undefined, /* modifiers */ undefined, 
121
        /* dotDotDotToken */ undefined, p.name); }), 
122
        /* type */ undefined, this._visitStatements(stmt.statements)));
123
    };
124
    _NodeEmitterVisitor.prototype.visitExpressionStmt = function (stmt) {
125
        return this.record(stmt, ts.createStatement(stmt.expr.visitExpression(this, null)));
126
    };
127
    _NodeEmitterVisitor.prototype.visitReturnStmt = function (stmt) {
128
        return this.record(stmt, ts.createReturn(stmt.value ? stmt.value.visitExpression(this, null) : undefined));
129
    };
130
    _NodeEmitterVisitor.prototype.visitDeclareClassStmt = function (stmt) {
131
        var _this = this;
132
        var modifiers = this.getModifiers(stmt);
133
        var fields = stmt.fields.map(function (field) { return ts.createProperty(
134
        /* decorators */ undefined, /* modifiers */ undefined, field.name, 
135
        /* questionToken */ undefined, 
136
        /* type */ undefined, ts.createNull()); });
137
        var getters = stmt.getters.map(function (getter) { return ts.createGetAccessor(
138
        /* decorators */ undefined, /* modifiers */ undefined, getter.name, /* parameters */ [], 
139
        /* type */ undefined, _this._visitStatements(getter.body)); });
140
        var constructor = (stmt.constructorMethod && [ts.createConstructor(
141
            /* decorators */ undefined, 
142
            /* modifiers */ undefined, 
143
            /* parameters */ stmt.constructorMethod.params.map(function (p) { return ts.createParameter(
144
            /* decorators */ undefined, 
145
            /* modifiers */ undefined, 
146
            /* dotDotDotToken */ undefined, p.name); }), this._visitStatements(stmt.constructorMethod.body))]) ||
147
            [];
148
        // TODO {chuckj}: Determine what should be done for a method with a null name.
149
        var methods = stmt.methods.filter(function (method) { return method.name; })
150
            .map(function (method) { return ts.createMethodDeclaration(
151
        /* decorators */ undefined, /* modifiers */ undefined, 
152
        /* astriskToken */ undefined, method.name /* guarded by filter */, 
153
        /* questionToken */ undefined, /* typeParameters */ undefined, method.params.map(function (p) { return ts.createParameter(
154
        /* decorators */ undefined, /* modifiers */ undefined, 
155
        /* dotDotDotToken */ undefined, p.name); }), 
156
        /* type */ undefined, _this._visitStatements(method.body)); });
157
        return this.record(stmt, ts.createClassDeclaration(
158
        /* decorators */ undefined, modifiers, stmt.name, /* typeParameters*/ undefined, stmt.parent && [ts.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [stmt.parent.visitExpression(this, null)])] ||
159
            [], fields.concat(getters, constructor, methods)));
160
    };
161
    _NodeEmitterVisitor.prototype.visitIfStmt = function (stmt) {
162
        return this.record(stmt, ts.createIf(stmt.condition.visitExpression(this, null), this._visitStatements(stmt.trueCase), stmt.falseCase && stmt.falseCase.length && this._visitStatements(stmt.falseCase) ||
163
            undefined));
164
    };
165
    _NodeEmitterVisitor.prototype.visitTryCatchStmt = function (stmt) {
166
        return this.record(stmt, ts.createTry(this._visitStatements(stmt.bodyStmts), ts.createCatchClause(CATCH_ERROR_NAME, this._visitStatementsPrefix([ts.createVariableStatement(
167
            /* modifiers */ undefined, [ts.createVariableDeclaration(CATCH_STACK_NAME, /* type */ undefined, ts.createPropertyAccess(ts.createIdentifier(CATCH_ERROR_NAME), ts.createIdentifier(CATCH_STACK_NAME)))])], stmt.catchStmts)), 
168
        /* finallyBlock */ undefined));
169
    };
170
    _NodeEmitterVisitor.prototype.visitThrowStmt = function (stmt) {
171
        return this.record(stmt, ts.createThrow(stmt.error.visitExpression(this, null)));
172
    };
173
    _NodeEmitterVisitor.prototype.visitCommentStmt = function (stmt) { return null; };
174
    // ExpressionVisitor
175
    _NodeEmitterVisitor.prototype.visitReadVarExpr = function (expr) {
176
        switch (expr.builtin) {
177
            case compiler_1.BuiltinVar.This:
178
                return this.record(expr, ts.createIdentifier(METHOD_THIS_NAME));
179
            case compiler_1.BuiltinVar.CatchError:
180
                return this.record(expr, ts.createIdentifier(CATCH_ERROR_NAME));
181
            case compiler_1.BuiltinVar.CatchStack:
182
                return this.record(expr, ts.createIdentifier(CATCH_STACK_NAME));
183
            case compiler_1.BuiltinVar.Super:
184
                return this.record(expr, ts.createSuper());
185
        }
186
        if (expr.name) {
187
            return this.record(expr, ts.createIdentifier(expr.name));
188
        }
189
        throw Error("Unexpected ReadVarExpr form");
190
    };
191
    _NodeEmitterVisitor.prototype.visitWriteVarExpr = function (expr) {
192
        return this.record(expr, ts.createAssignment(ts.createIdentifier(expr.name), expr.value.visitExpression(this, null)));
193
    };
194
    _NodeEmitterVisitor.prototype.visitWriteKeyExpr = function (expr) {
195
        return this.record(expr, ts.createAssignment(ts.createElementAccess(expr.receiver.visitExpression(this, null), expr.index.visitExpression(this, null)), expr.value.visitExpression(this, null)));
196
    };
197
    _NodeEmitterVisitor.prototype.visitWritePropExpr = function (expr) {
198
        return this.record(expr, ts.createAssignment(ts.createPropertyAccess(expr.receiver.visitExpression(this, null), expr.name), expr.value.visitExpression(this, null)));
199
    };
200
    _NodeEmitterVisitor.prototype.visitInvokeMethodExpr = function (expr) {
201
        var _this = this;
202
        var methodName = getMethodName(expr);
203
        return this.record(expr, ts.createCall(ts.createPropertyAccess(expr.receiver.visitExpression(this, null), methodName), 
204
        /* typeArguments */ undefined, expr.args.map(function (arg) { return arg.visitExpression(_this, null); })));
205
    };
206
    _NodeEmitterVisitor.prototype.visitInvokeFunctionExpr = function (expr) {
207
        var _this = this;
208
        return this.record(expr, ts.createCall(expr.fn.visitExpression(this, null), /* typeArguments */ undefined, expr.args.map(function (arg) { return arg.visitExpression(_this, null); })));
209
    };
210
    _NodeEmitterVisitor.prototype.visitInstantiateExpr = function (expr) {
211
        var _this = this;
212
        return this.record(expr, ts.createNew(expr.classExpr.visitExpression(this, null), /* typeArguments */ undefined, expr.args.map(function (arg) { return arg.visitExpression(_this, null); })));
213
    };
214
    _NodeEmitterVisitor.prototype.visitLiteralExpr = function (expr) { return this.record(expr, createLiteral(expr.value)); };
215
    _NodeEmitterVisitor.prototype.visitExternalExpr = function (expr) {
216
        return this.record(expr, this._visitIdentifier(expr.value));
217
    };
218
    _NodeEmitterVisitor.prototype.visitConditionalExpr = function (expr) {
219
        // TODO {chuckj}: Review use of ! on flaseCase. Should it be non-nullable?
220
        return this.record(expr, ts.createConditional(expr.condition.visitExpression(this, null), expr.trueCase.visitExpression(this, null), expr.falseCase.visitExpression(this, null)));
221
    };
222
    _NodeEmitterVisitor.prototype.visitNotExpr = function (expr) {
223
        return this.record(expr, ts.createPrefix(ts.SyntaxKind.ExclamationToken, expr.condition.visitExpression(this, null)));
224
    };
225
    _NodeEmitterVisitor.prototype.visitAssertNotNullExpr = function (expr) {
226
        return expr.condition.visitExpression(this, null);
227
    };
228
    _NodeEmitterVisitor.prototype.visitCastExpr = function (expr) {
229
        return expr.value.visitExpression(this, null);
230
    };
231
    _NodeEmitterVisitor.prototype.visitFunctionExpr = function (expr) {
232
        return this.record(expr, ts.createFunctionExpression(
233
        /* modifiers */ undefined, /* astriskToken */ undefined, /* name */ undefined, 
234
        /* typeParameters */ undefined, expr.params.map(function (p) { return ts.createParameter(
235
        /* decorators */ undefined, /* modifiers */ undefined, 
236
        /* dotDotDotToken */ undefined, p.name); }), 
237
        /* type */ undefined, this._visitStatements(expr.statements)));
238
    };
239
    _NodeEmitterVisitor.prototype.visitBinaryOperatorExpr = function (expr) {
240
        var binaryOperator;
241
        switch (expr.operator) {
242
            case compiler_1.BinaryOperator.And:
243
                binaryOperator = ts.SyntaxKind.AmpersandAmpersandToken;
244
                break;
245
            case compiler_1.BinaryOperator.Bigger:
246
                binaryOperator = ts.SyntaxKind.GreaterThanToken;
247
                break;
248
            case compiler_1.BinaryOperator.BiggerEquals:
249
                binaryOperator = ts.SyntaxKind.GreaterThanEqualsToken;
250
                break;
251
            case compiler_1.BinaryOperator.Divide:
252
                binaryOperator = ts.SyntaxKind.SlashToken;
253
                break;
254
            case compiler_1.BinaryOperator.Equals:
255
                binaryOperator = ts.SyntaxKind.EqualsEqualsToken;
256
                break;
257
            case compiler_1.BinaryOperator.Identical:
258
                binaryOperator = ts.SyntaxKind.EqualsEqualsEqualsToken;
259
                break;
260
            case compiler_1.BinaryOperator.Lower:
261
                binaryOperator = ts.SyntaxKind.LessThanToken;
262
                break;
263
            case compiler_1.BinaryOperator.LowerEquals:
264
                binaryOperator = ts.SyntaxKind.LessThanEqualsToken;
265
                break;
266
            case compiler_1.BinaryOperator.Minus:
267
                binaryOperator = ts.SyntaxKind.MinusToken;
268
                break;
269
            case compiler_1.BinaryOperator.Modulo:
270
                binaryOperator = ts.SyntaxKind.PercentToken;
271
                break;
272
            case compiler_1.BinaryOperator.Multiply:
273
                binaryOperator = ts.SyntaxKind.AsteriskToken;
274
                break;
275
            case compiler_1.BinaryOperator.NotEquals:
276
                binaryOperator = ts.SyntaxKind.ExclamationEqualsToken;
277
                break;
278
            case compiler_1.BinaryOperator.NotIdentical:
279
                binaryOperator = ts.SyntaxKind.ExclamationEqualsEqualsToken;
280
                break;
281
            case compiler_1.BinaryOperator.Or:
282
                binaryOperator = ts.SyntaxKind.BarBarToken;
283
                break;
284
            case compiler_1.BinaryOperator.Plus:
285
                binaryOperator = ts.SyntaxKind.PlusToken;
286
                break;
287
            default:
288
                throw new Error("Unknown operator: " + expr.operator);
289
        }
290
        return this.record(expr, ts.createBinary(expr.lhs.visitExpression(this, null), binaryOperator, expr.rhs.visitExpression(this, null)));
291
    };
292
    _NodeEmitterVisitor.prototype.visitReadPropExpr = function (expr) {
293
        return this.record(expr, ts.createPropertyAccess(expr.receiver.visitExpression(this, null), expr.name));
294
    };
295
    _NodeEmitterVisitor.prototype.visitReadKeyExpr = function (expr) {
296
        return this.record(expr, ts.createElementAccess(expr.receiver.visitExpression(this, null), expr.index.visitExpression(this, null)));
297
    };
298
    _NodeEmitterVisitor.prototype.visitLiteralArrayExpr = function (expr) {
299
        var _this = this;
300
        return this.record(expr, ts.createArrayLiteral(expr.entries.map(function (entry) { return entry.visitExpression(_this, null); })));
301
    };
302
    _NodeEmitterVisitor.prototype.visitLiteralMapExpr = function (expr) {
303
        var _this = this;
304
        return this.record(expr, ts.createObjectLiteral(expr.entries.map(function (entry) { return ts.createPropertyAssignment(entry.quoted ? ts.createLiteral(entry.key) : entry.key, entry.value.visitExpression(_this, null)); })));
305
    };
306
    _NodeEmitterVisitor.prototype.visitCommaExpr = function (expr) {
307
        var _this = this;
308
        return this.record(expr, expr.parts.map(function (e) { return e.visitExpression(_this, null); })
309
            .reduce(function (left, right) {
310
            return left ? ts.createBinary(left, ts.SyntaxKind.CommaToken, right) : right;
311
        }, null));
312
    };
313
    _NodeEmitterVisitor.prototype._visitStatements = function (statements) {
314
        return this._visitStatementsPrefix([], statements);
315
    };
316
    _NodeEmitterVisitor.prototype._visitStatementsPrefix = function (prefix, statements) {
317
        var _this = this;
318
        return ts.createBlock(prefix.concat(statements.map(function (stmt) { return stmt.visitStatement(_this, null); }).filter(function (f) { return f != null; })));
319
    };
320
    _NodeEmitterVisitor.prototype._visitIdentifier = function (value) {
321
        var name = value.name, moduleName = value.moduleName;
322
        var prefixIdent = null;
323
        if (moduleName) {
324
            var prefix = this._importsWithPrefixes.get(moduleName);
325
            if (prefix == null) {
326
                prefix = "i" + this._importsWithPrefixes.size;
327
                this._importsWithPrefixes.set(moduleName, prefix);
328
            }
329
            prefixIdent = ts.createIdentifier(prefix);
330
        }
331
        // name can only be null during JIT which never executes this code.
332
        var result = prefixIdent ? ts.createPropertyAccess(prefixIdent, name) : ts.createIdentifier(name);
333
        return result;
334
    };
335
    return _NodeEmitterVisitor;
336
}());
337
function getMethodName(methodRef) {
338
    if (methodRef.name) {
339
        return methodRef.name;
340
    }
341
    else {
342
        switch (methodRef.builtin) {
343
            case compiler_1.BuiltinMethod.Bind:
344
                return 'bind';
345
            case compiler_1.BuiltinMethod.ConcatArray:
346
                return 'concat';
347
            case compiler_1.BuiltinMethod.SubscribeObservable:
348
                return 'subscribe';
349
        }
350
    }
351
    throw new Error('Unexpected method reference form');
352
}
353
//# sourceMappingURL=node_emitter.js.map
(11-11/18)