Socket
Socket
Sign inDemoInstall

@angular/tsc-wrapped

Package Overview
Dependencies
Maintainers
1
Versions
72
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@angular/tsc-wrapped - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

4

index.d.ts

@@ -1,5 +0,5 @@

export { TsickleHost, MetadataWriterHost } from './src/compiler_host';
export { main, CodegenExtension } from './src/main';
export { MetadataWriterHost, TsickleHost } from './src/compiler_host';
export { CodegenExtension, main } from './src/main';
export { default as AngularCompilerOptions } from './src/options';
export * from './src/collector';
export * from './src/schema';

@@ -6,4 +6,4 @@ "use strict";

var compiler_host_1 = require('./src/compiler_host');
exports.MetadataWriterHost = compiler_host_1.MetadataWriterHost;
exports.TsickleHost = compiler_host_1.TsickleHost;
exports.MetadataWriterHost = compiler_host_1.MetadataWriterHost;
var main_1 = require('./src/main');

@@ -10,0 +10,0 @@ exports.main = main_1.main;

{
"name": "@angular/tsc-wrapped",
"version": "0.1.0",
"version": "0.2.0",
"description": "Wraps the tsc CLI, allowing extensions.",

@@ -14,3 +14,3 @@ "homepage": "https://github.com/angular/angular/tree/master/tools/tsc-wrapped",

"dependencies": {
"tsickle": "^0.1.2"
"tsickle": "0.1.4"
},

@@ -17,0 +17,0 @@ "peerDependencies": {

import * as ts from 'typescript';
import { ImportMetadata } from './evaluator';
import { ModuleMetadata } from './schema';

@@ -9,3 +8,2 @@ /**

constructor();
collectImports(sourceFile: ts.SourceFile): ImportMetadata[];
/**

@@ -15,3 +13,3 @@ * Returns a JSON.stringify friendly form describing the decorators of the exported classes from

*/
getMetadata(sourceFile: ts.SourceFile, typeChecker: ts.TypeChecker): ModuleMetadata;
getMetadata(sourceFile: ts.SourceFile): ModuleMetadata;
}
"use strict";
var ts = require('typescript');
var evaluator_1 = require('./evaluator');
var schema_1 = require('./schema');
var symbols_1 = require('./symbols');

@@ -11,46 +12,2 @@ /**

}
MetadataCollector.prototype.collectImports = function (sourceFile) {
var imports = [];
var stripQuotes = function (s) { return s.replace(/^['"]|['"]$/g, ''); };
function visit(node) {
switch (node.kind) {
case ts.SyntaxKind.ImportDeclaration:
var importDecl = node;
var from = stripQuotes(importDecl.moduleSpecifier.getText());
var newImport = { from: from };
if (!importDecl.importClause) {
// Bare imports do not bring symbols into scope, so we don't need to record them
break;
}
if (importDecl.importClause.name) {
newImport['defaultName'] = importDecl.importClause.name.text;
}
var bindings = importDecl.importClause.namedBindings;
if (bindings) {
switch (bindings.kind) {
case ts.SyntaxKind.NamedImports:
var namedImports_1 = [];
bindings
.elements.forEach(function (i) {
var namedImport = { name: i.name.text };
if (i.propertyName) {
namedImport['propertyName'] = i.propertyName.text;
}
namedImports_1.push(namedImport);
});
newImport['namedImports'] = namedImports_1;
break;
case ts.SyntaxKind.NamespaceImport:
newImport['namespace'] = bindings.name.text;
break;
}
}
imports.push(newImport);
break;
}
ts.forEachChild(node, visit);
}
ts.forEachChild(sourceFile, visit);
return imports;
};
/**

@@ -60,18 +17,14 @@ * Returns a JSON.stringify friendly form describing the decorators of the exported classes from

*/
MetadataCollector.prototype.getMetadata = function (sourceFile, typeChecker) {
var locals = new symbols_1.Symbols();
var evaluator = new evaluator_1.Evaluator(typeChecker, locals, this.collectImports(sourceFile));
MetadataCollector.prototype.getMetadata = function (sourceFile) {
var locals = new symbols_1.Symbols(sourceFile);
var evaluator = new evaluator_1.Evaluator(locals);
var metadata;
function objFromDecorator(decoratorNode) {
return evaluator.evaluateNode(decoratorNode.expression);
}
function referenceFromType(type) {
if (type) {
var symbol_1 = type.getSymbol();
if (symbol_1) {
return evaluator.symbolReference(symbol_1);
}
}
function errorSym(message, node, context) {
return evaluator_1.errorSymbol(message, node, context, sourceFile);
}
function classMetadataOf(classDeclaration) {
var result = { __symbolic: "class" };
var result = { __symbolic: 'class' };
function getDecorators(decorators) {

@@ -82,2 +35,11 @@ if (decorators && decorators.length)

}
function referenceFrom(node) {
var result = evaluator.evaluateNode(node);
if (schema_1.isMetadataError(result) || schema_1.isMetadataSymbolicReferenceExpression(result)) {
return result;
}
else {
return errorSym('Symbol reference expected', node);
}
}
// Add class decorators

@@ -117,9 +79,13 @@ if (classDeclaration.decorators) {

if (isConstructor) {
var parameterType = typeChecker.getTypeAtLocation(parameter);
parametersData.push(referenceFromType(parameterType) || null);
if (parameter.type) {
parametersData.push(referenceFrom(parameter.type));
}
else {
parametersData.push(null);
}
hasParameterData = true;
}
}
var data = { __symbolic: isConstructor ? "constructor" : "method" };
var name_1 = isConstructor ? "__ctor__" : evaluator.nameOf(member.name);
var data = { __symbolic: isConstructor ? 'constructor' : 'method' };
var name_1 = isConstructor ? '__ctor__' : evaluator.nameOf(member.name);
if (methodDecorators) {

@@ -134,3 +100,5 @@ data.decorators = methodDecorators;

}
recordMember(name_1, data);
if (!schema_1.isMetadataError(name_1)) {
recordMember(name_1, data);
}
break;

@@ -143,3 +111,6 @@ case ts.SyntaxKind.PropertyDeclaration:

if (propertyDecorators) {
recordMember(evaluator.nameOf(property.name), { __symbolic: 'property', decorators: propertyDecorators });
var name_2 = evaluator.nameOf(property.name);
if (!schema_1.isMetadataError(name_2)) {
recordMember(name_2, { __symbolic: 'property', decorators: propertyDecorators });
}
}

@@ -154,37 +125,118 @@ break;

}
var metadata;
var symbols = typeChecker.getSymbolsInScope(sourceFile, ts.SymbolFlags.ExportValue);
for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) {
var symbol = symbols_2[_i];
for (var _a = 0, _b = symbol.getDeclarations(); _a < _b.length; _a++) {
var declaration = _b[_a];
switch (declaration.kind) {
case ts.SyntaxKind.ClassDeclaration:
var classDeclaration = declaration;
// Predeclare classes
ts.forEachChild(sourceFile, function (node) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration:
var classDeclaration = node;
var className = classDeclaration.name.text;
if (node.flags & ts.NodeFlags.Export) {
locals.define(className, { __symbolic: 'reference', name: className });
}
else {
locals.define(className, errorSym('Reference to non-exported class', node, { className: className }));
}
break;
}
});
ts.forEachChild(sourceFile, function (node) {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration:
var classDeclaration = node;
var className = classDeclaration.name.text;
if (node.flags & ts.NodeFlags.Export) {
if (classDeclaration.decorators) {
if (!metadata)
metadata = {};
metadata[classDeclaration.name.text] = classMetadataOf(classDeclaration);
metadata[className] = classMetadataOf(classDeclaration);
}
break;
case ts.SyntaxKind.VariableDeclaration:
var variableDeclaration = declaration;
if (variableDeclaration.initializer) {
var value = evaluator.evaluateNode(variableDeclaration.initializer);
if (value !== undefined) {
if (evaluator.isFoldable(variableDeclaration.initializer)) {
// Record the value for use in other initializers
locals.set(symbol, value);
}
// Otherwise don't record metadata for the class.
break;
case ts.SyntaxKind.FunctionDeclaration:
// Record functions that return a single value. Record the parameter
// names substitution will be performed by the StaticReflector.
if (node.flags & ts.NodeFlags.Export) {
var functionDeclaration = node;
var functionName = functionDeclaration.name.text;
var functionBody = functionDeclaration.body;
if (functionBody && functionBody.statements.length == 1) {
var statement = functionBody.statements[0];
if (statement.kind === ts.SyntaxKind.ReturnStatement) {
var returnStatement = statement;
if (returnStatement.expression) {
if (!metadata)
metadata = {};
metadata[functionName] = {
__symbolic: 'function',
parameters: namesOf(functionDeclaration.parameters),
value: evaluator.evaluateNode(returnStatement.expression)
};
}
}
}
}
// Otherwise don't record the function.
break;
case ts.SyntaxKind.VariableStatement:
var variableStatement = node;
var _loop_1 = function(variableDeclaration) {
if (variableDeclaration.name.kind == ts.SyntaxKind.Identifier) {
var nameNode = variableDeclaration.name;
var varValue = void 0;
if (variableDeclaration.initializer) {
varValue = evaluator.evaluateNode(variableDeclaration.initializer);
}
else {
varValue = errorSym('Variable not initialized', nameNode);
}
if (variableStatement.flags & ts.NodeFlags.Export ||
variableDeclaration.flags & ts.NodeFlags.Export) {
if (!metadata)
metadata = {};
metadata[evaluator.nameOf(variableDeclaration.name)] =
evaluator.evaluateNode(variableDeclaration.initializer);
metadata[nameNode.text] = varValue;
}
if (evaluator_1.isPrimitive(varValue)) {
locals.define(nameNode.text, varValue);
}
}
break;
}
else {
// Destructuring (or binding) declarations are not supported,
// var {<identifier>[, <identifer>]+} = <expression>;
// or
// var [<identifier>[, <identifier}+] = <expression>;
// are not supported.
var report_1 = function (nameNode) {
switch (nameNode.kind) {
case ts.SyntaxKind.Identifier:
var name_3 = nameNode;
var varValue = errorSym('Destructuring not supported', nameNode);
locals.define(name_3.text, varValue);
if (node.flags & ts.NodeFlags.Export) {
if (!metadata)
metadata = {};
metadata[name_3.text] = varValue;
}
break;
case ts.SyntaxKind.BindingElement:
var bindingElement = nameNode;
report_1(bindingElement.name);
break;
case ts.SyntaxKind.ObjectBindingPattern:
case ts.SyntaxKind.ArrayBindingPattern:
var bindings = nameNode;
bindings.elements.forEach(report_1);
break;
}
};
report_1(variableDeclaration.name);
}
};
for (var _i = 0, _a = variableStatement.declarationList.declarations; _i < _a.length; _i++) {
var variableDeclaration = _a[_i];
_loop_1(variableDeclaration);
}
break;
}
}
return metadata && { __symbolic: "module", metadata: metadata };
});
return metadata && { __symbolic: 'module', version: schema_1.VERSION, metadata: metadata };
};

@@ -194,2 +246,24 @@ return MetadataCollector;

exports.MetadataCollector = MetadataCollector;
// Collect parameter names from a function.
function namesOf(parameters) {
var result = [];
function addNamesOf(name) {
if (name.kind == ts.SyntaxKind.Identifier) {
var identifier = name;
result.push(identifier.text);
}
else {
var bindingPattern = name;
for (var _i = 0, _a = bindingPattern.elements; _i < _a.length; _i++) {
var element = _a[_i];
addNamesOf(element.name);
}
}
}
for (var _i = 0, parameters_2 = parameters; _i < parameters_2.length; _i++) {
var parameter = parameters_2[_i];
addNamesOf(parameter.name);
}
return result;
}
//# sourceMappingURL=collector.js.map

@@ -24,5 +24,6 @@ import * as ts from 'typescript';

export declare class TsickleHost extends DelegatingHost {
private program;
diagnostics: ts.Diagnostic[];
private TSICKLE_SUPPORT;
constructor(delegate: ts.CompilerHost);
constructor(delegate: ts.CompilerHost, program: ts.Program);
getSourceFile: (fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void) => ts.SourceFile;

@@ -29,0 +30,0 @@ }

@@ -7,5 +7,5 @@ "use strict";

};
var ts = require('typescript');
var fs_1 = require('fs');
var tsickle_1 = require('tsickle');
var ts = require('typescript');
var collector_1 = require('./collector');

@@ -43,5 +43,6 @@ /**

__extends(TsickleHost, _super);
function TsickleHost(delegate) {
function TsickleHost(delegate, program) {
var _this = this;
_super.call(this, delegate);
this.program = program;
// Additional diagnostics gathered by pre- and post-emit transformations.

@@ -54,7 +55,13 @@ this.diagnostics = [];

if (!/\.d\.ts$/.test(fileName)) {
var converted = tsickle_1.convertDecorators(fileName, originalContent);
if (converted.diagnostics) {
(_a = _this.diagnostics).push.apply(_a, converted.diagnostics);
try {
var converted = tsickle_1.convertDecorators(_this.program.getTypeChecker(), _this.program.getSourceFile(fileName));
if (converted.diagnostics) {
(_a = _this.diagnostics).push.apply(_a, converted.diagnostics);
}
newContent = converted.output + _this.TSICKLE_SUPPORT;
}
newContent = converted.output + _this.TSICKLE_SUPPORT;
catch (e) {
console.error('Cannot convertDecorators on file', fileName);
throw e;
}
}

@@ -80,3 +87,4 @@ return ts.createSourceFile(fileName, newContent, languageVersion, true);

_this.delegate.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles);
// TODO: remove this early return after https://github.com/Microsoft/TypeScript/pull/8412 is
// TODO: remove this early return after https://github.com/Microsoft/TypeScript/pull/8412
// is
// released

@@ -103,3 +111,3 @@ return;

var path_1 = emitFilePath.replace(/*DTS*/ /\.js$/, '.metadata.json');
var metadata = this.metadataCollector.getMetadata(sourceFile, this.program.getTypeChecker());
var metadata = this.metadataCollector.getMetadata(sourceFile);
if (metadata && metadata.metadata) {

@@ -106,0 +114,0 @@ var metadataText = JSON.stringify(metadata);

import * as ts from 'typescript';
import { MetadataError, MetadataValue } from './schema';
import { Symbols } from './symbols';
import { MetadataValue, MetadataSymbolicReferenceExpression } from './schema';
export declare function isPrimitive(value: any): boolean;
export interface ImportSpecifierMetadata {

@@ -14,2 +15,5 @@ name: string;

}
export declare function errorSymbol(message: string, node?: ts.Node, context?: {
[name: string]: string;
}, sourceFile?: ts.SourceFile): MetadataError;
/**

@@ -20,10 +24,5 @@ * Produce a symbolic representation of an expression folding values into their final value when

export declare class Evaluator {
private typeChecker;
private symbols;
private imports;
constructor(typeChecker: ts.TypeChecker, symbols: Symbols, imports: ImportMetadata[]);
symbolReference(symbol: ts.Symbol): MetadataSymbolicReferenceExpression;
private findImportNamespace(node);
private nodeSymbolReference(node);
nameOf(node: ts.Node): string;
constructor(symbols: Symbols);
nameOf(node: ts.Node): string | MetadataError;
/**

@@ -30,0 +29,0 @@ * Returns true if the expression represented by `node` can be folded into a literal expression.

"use strict";
var ts = require('typescript');
var schema_1 = require('./schema');
function isMethodCallOf(callExpression, memberName) {

@@ -33,5 +34,32 @@ var expression = callExpression.expression;

}
exports.isPrimitive = isPrimitive;
function isDefined(obj) {
return obj !== undefined;
}
function getSourceFileOfNode(node) {
while (node && node.kind != ts.SyntaxKind.SourceFile) {
node = node.parent;
}
return node;
}
/* @internal */
function errorSymbol(message, node, context, sourceFile) {
var result;
if (node) {
sourceFile = sourceFile || getSourceFileOfNode(node);
if (sourceFile) {
var _a = ts.getLineAndCharacterOfPosition(sourceFile, node.pos), line = _a.line, character = _a.character;
result = { __symbolic: 'error', message: message, line: line, character: character };
}
;
}
if (!result) {
result = { __symbolic: 'error', message: message };
}
if (context) {
result.context = context;
}
return result;
}
exports.errorSymbol = errorSymbol;
/**

@@ -42,54 +70,5 @@ * Produce a symbolic representation of an expression folding values into their final value when

var Evaluator = (function () {
function Evaluator(typeChecker, symbols, imports) {
this.typeChecker = typeChecker;
function Evaluator(symbols) {
this.symbols = symbols;
this.imports = imports;
}
Evaluator.prototype.symbolReference = function (symbol) {
if (symbol) {
var module_1;
var name_2 = symbol.name;
for (var _i = 0, _a = this.imports; _i < _a.length; _i++) {
var eachImport = _a[_i];
if (symbol.name === eachImport.defaultName) {
module_1 = eachImport.from;
name_2 = undefined;
}
if (eachImport.namedImports) {
for (var _b = 0, _c = eachImport.namedImports; _b < _c.length; _b++) {
var named = _c[_b];
if (symbol.name === named.name) {
name_2 = named.propertyName ? named.propertyName : named.name;
module_1 = eachImport.from;
break;
}
}
}
}
return { __symbolic: "reference", name: name_2, module: module_1 };
}
};
Evaluator.prototype.findImportNamespace = function (node) {
if (node.kind === ts.SyntaxKind.PropertyAccessExpression) {
var lhs = node.expression;
if (lhs.kind === ts.SyntaxKind.Identifier) {
// TOOD: Use Array.find when tools directory is upgraded to support es6 target
for (var _i = 0, _a = this.imports; _i < _a.length; _i++) {
var eachImport = _a[_i];
if (eachImport.namespace === lhs.text) {
return eachImport;
}
}
}
}
};
Evaluator.prototype.nodeSymbolReference = function (node) {
var importNamespace = this.findImportNamespace(node);
if (importNamespace) {
var result = this.symbolReference(this.typeChecker.getSymbolAtLocation(node.name));
result.module = importNamespace.from;
return result;
}
return this.symbolReference(this.typeChecker.getSymbolAtLocation(node));
};
Evaluator.prototype.nameOf = function (node) {

@@ -99,3 +78,9 @@ if (node.kind == ts.SyntaxKind.Identifier) {

}
return this.evaluateNode(node);
var result = this.evaluateNode(node);
if (schema_1.isMetadataError(result) || typeof result === 'string') {
return result;
}
else {
return errorSymbol('Name expected', node, { received: node.getText() });
}
};

@@ -138,3 +123,3 @@ /**

// We can fold a <array>.concat(<v>).
if (isMethodCallOf(callExpression, "concat") && callExpression.arguments.length === 1) {
if (isMethodCallOf(callExpression, 'concat') && callExpression.arguments.length === 1) {
var arrayNode = callExpression.expression.expression;

@@ -151,3 +136,3 @@ if (this.isFoldableWorker(arrayNode, folding) &&

// We can fold a call to CONST_EXPR
if (isCallOf(callExpression, "CONST_EXPR") && callExpression.arguments.length === 1)
if (isCallOf(callExpression, 'CONST_EXPR') && callExpression.arguments.length === 1)
return this.isFoldableWorker(callExpression.arguments[0], folding);

@@ -186,20 +171,6 @@ return false;

case ts.SyntaxKind.Identifier:
var symbol = this.typeChecker.getSymbolAtLocation(node);
if (symbol.flags & ts.SymbolFlags.Alias) {
symbol = this.typeChecker.getAliasedSymbol(symbol);
}
if (this.symbols.has(symbol))
var identifier = node;
var reference = this.symbols.resolve(identifier.text);
if (reference !== undefined && isPrimitive(reference)) {
return true;
// If this is a reference to a foldable variable then it is foldable too.
var variableDeclaration = (symbol.declarations && symbol.declarations.length && symbol.declarations[0]);
if (variableDeclaration.kind === ts.SyntaxKind.VariableDeclaration) {
var initializer = variableDeclaration.initializer;
if (folding.has(initializer)) {
// A recursive reference is not foldable.
return false;
}
folding.set(initializer, true);
var result = this.isFoldableWorker(initializer, folding);
folding.delete(initializer);
return result;
}

@@ -217,36 +188,77 @@ break;

var _this = this;
var error;
switch (node.kind) {
case ts.SyntaxKind.ObjectLiteralExpression:
var obj_1 = {};
var allPropertiesDefined_1 = true;
ts.forEachChild(node, function (child) {
switch (child.kind) {
case ts.SyntaxKind.ShorthandPropertyAssignment:
case ts.SyntaxKind.PropertyAssignment:
var assignment = child;
var propertyName = _this.nameOf(assignment.name);
var propertyValue = _this.evaluateNode(assignment.initializer);
obj_1[propertyName] = propertyValue;
allPropertiesDefined_1 = isDefined(propertyValue) && allPropertiesDefined_1;
if (schema_1.isMetadataError(propertyName)) {
error = propertyName;
return true;
}
var propertyValue = isPropertyAssignment(assignment) ?
_this.evaluateNode(assignment.initializer) :
{ __symbolic: 'reference', name: propertyName };
if (schema_1.isMetadataError(propertyValue)) {
error = propertyValue;
return true; // Stop the forEachChild.
}
else {
obj_1[propertyName] = propertyValue;
}
}
});
if (allPropertiesDefined_1)
return obj_1;
break;
if (error)
return error;
return obj_1;
case ts.SyntaxKind.ArrayLiteralExpression:
var arr_1 = [];
var allElementsDefined_1 = true;
ts.forEachChild(node, function (child) {
var value = _this.evaluateNode(child);
// Check for error
if (schema_1.isMetadataError(value)) {
error = value;
return true; // Stop the forEachChild.
}
// Handle spread expressions
if (schema_1.isMetadataSymbolicSpreadExpression(value)) {
if (Array.isArray(value.expression)) {
for (var _i = 0, _a = value.expression; _i < _a.length; _i++) {
var spreadValue = _a[_i];
arr_1.push(spreadValue);
}
return;
}
}
arr_1.push(value);
allElementsDefined_1 = isDefined(value) && allElementsDefined_1;
});
if (allElementsDefined_1)
return arr_1;
break;
if (error)
return error;
return arr_1;
case ts.SyntaxKind.SpreadElementExpression:
var spread = node;
var spreadExpression = this.evaluateNode(spread.expression);
return { __symbolic: 'spread', expression: spreadExpression };
case ts.SyntaxKind.CallExpression:
var callExpression = node;
if (isCallOf(callExpression, 'forwardRef') && callExpression.arguments.length === 1) {
var firstArgument = callExpression.arguments[0];
if (firstArgument.kind == ts.SyntaxKind.ArrowFunction) {
var arrowFunction = firstArgument;
return this.evaluateNode(arrowFunction.body);
}
}
var args_1 = callExpression.arguments.map(function (arg) { return _this.evaluateNode(arg); });
if (args_1.some(schema_1.isMetadataError)) {
return args_1.find(schema_1.isMetadataError);
}
if (this.isFoldable(callExpression)) {
if (isMethodCallOf(callExpression, "concat")) {
if (isMethodCallOf(callExpression, 'concat')) {
var arrayValue = this.evaluateNode(callExpression.expression.expression);
if (schema_1.isMetadataError(arrayValue))
return arrayValue;
return arrayValue.concat(args_1[0]);

@@ -256,46 +268,47 @@ }

// Always fold a CONST_EXPR even if the argument is not foldable.
if (isCallOf(callExpression, "CONST_EXPR") && callExpression.arguments.length === 1) {
if (isCallOf(callExpression, 'CONST_EXPR') && callExpression.arguments.length === 1) {
return args_1[0];
}
if (isCallOf(callExpression, 'forwardRef') && callExpression.arguments.length === 1) {
var firstArgument = callExpression.arguments[0];
if (firstArgument.kind == ts.SyntaxKind.ArrowFunction) {
var arrowFunction = firstArgument;
return this.evaluateNode(arrowFunction.body);
}
}
var expression = this.evaluateNode(callExpression.expression);
if (isDefined(expression) && args_1.every(isDefined)) {
var result = { __symbolic: "call", expression: expression };
if (args_1 && args_1.length) {
result.arguments = args_1;
}
return result;
if (schema_1.isMetadataError(expression)) {
return expression;
}
break;
var result = { __symbolic: 'call', expression: expression };
if (args_1 && args_1.length) {
result.arguments = args_1;
}
return result;
case ts.SyntaxKind.NewExpression:
var newExpression = node;
var newArgs = newExpression.arguments.map(function (arg) { return _this.evaluateNode(arg); });
if (newArgs.some(schema_1.isMetadataError)) {
return newArgs.find(schema_1.isMetadataError);
}
var newTarget = this.evaluateNode(newExpression.expression);
if (isDefined(newTarget) && newArgs.every(isDefined)) {
var result = { __symbolic: "new", expression: newTarget };
if (newArgs.length) {
result.arguments = newArgs;
}
return result;
if (schema_1.isMetadataError(newTarget)) {
return newTarget;
}
break;
var call = { __symbolic: 'new', expression: newTarget };
if (newArgs.length) {
call.arguments = newArgs;
}
return call;
case ts.SyntaxKind.PropertyAccessExpression: {
var propertyAccessExpression = node;
var expression_1 = this.evaluateNode(propertyAccessExpression.expression);
if (schema_1.isMetadataError(expression_1)) {
return expression_1;
}
var member = this.nameOf(propertyAccessExpression.name);
if (this.isFoldable(propertyAccessExpression.expression))
if (schema_1.isMetadataError(member)) {
return member;
}
if (expression_1 && this.isFoldable(propertyAccessExpression.expression))
return expression_1[member];
if (this.findImportNamespace(propertyAccessExpression)) {
return this.nodeSymbolReference(propertyAccessExpression);
if (schema_1.isMetadataModuleReferenceExpression(expression_1)) {
// A select into a module refrence and be converted into a reference to the symbol
// in the module
return { __symbolic: 'reference', module: expression_1.module, name: member };
}
if (isDefined(expression_1)) {
return { __symbolic: "select", expression: expression_1, member: member };
}
break;
return { __symbolic: 'select', expression: expression_1, member: member };
}

@@ -305,24 +318,58 @@ case ts.SyntaxKind.ElementAccessExpression: {

var expression_2 = this.evaluateNode(elementAccessExpression.expression);
if (schema_1.isMetadataError(expression_2)) {
return expression_2;
}
var index = this.evaluateNode(elementAccessExpression.argumentExpression);
if (schema_1.isMetadataError(expression_2)) {
return expression_2;
}
if (this.isFoldable(elementAccessExpression.expression) &&
this.isFoldable(elementAccessExpression.argumentExpression))
return expression_2[index];
if (isDefined(expression_2) && isDefined(index)) {
return { __symbolic: "index", expression: expression_2, index: index };
}
break;
return { __symbolic: 'index', expression: expression_2, index: index };
}
case ts.SyntaxKind.Identifier:
var symbol = this.typeChecker.getSymbolAtLocation(node);
if (symbol.flags & ts.SymbolFlags.Alias) {
symbol = this.typeChecker.getAliasedSymbol(symbol);
var identifier = node;
var name_2 = identifier.text;
var reference = this.symbols.resolve(name_2);
if (reference === undefined) {
// Encode as a global reference. StaticReflector will check the reference.
return { __symbolic: 'reference', name: name_2 };
}
if (this.symbols.has(symbol))
return this.symbols.get(symbol);
if (this.isFoldable(node)) {
// isFoldable implies, in this context, symbol declaration is a VariableDeclaration
var variableDeclaration = (symbol.declarations && symbol.declarations.length && symbol.declarations[0]);
return this.evaluateNode(variableDeclaration.initializer);
return reference;
case ts.SyntaxKind.TypeReference:
var typeReferenceNode = node;
var typeNameNode_1 = typeReferenceNode.typeName;
var getReference = function (node) {
if (typeNameNode_1.kind === ts.SyntaxKind.QualifiedName) {
var qualifiedName = node;
var left_1 = _this.evaluateNode(qualifiedName.left);
if (schema_1.isMetadataModuleReferenceExpression(left_1)) {
return {
__symbolic: 'reference', module: left_1.module, name: qualifiedName.right.text
};
}
return errorSymbol('Qualified type names not supported', node);
}
else {
var identifier_1 = typeNameNode_1;
var symbol = _this.symbols.resolve(identifier_1.text);
if (schema_1.isMetadataError(symbol) || schema_1.isMetadataSymbolicReferenceExpression(symbol)) {
return symbol;
}
return errorSymbol('Could not resolve type', node, { typeName: identifier_1.text });
}
};
var typeReference = getReference(typeNameNode_1);
if (schema_1.isMetadataError(typeReference)) {
return typeReference;
}
return this.nodeSymbolReference(node);
if (!schema_1.isMetadataModuleReferenceExpression(typeReference) &&
typeReferenceNode.typeArguments && typeReferenceNode.typeArguments.length) {
var args_2 = typeReferenceNode.typeArguments.map(function (element) { return _this.evaluateNode(element); });
// TODO: Remove typecast when upgraded to 2.0 as it will be corretly inferred.
// Some versions of 1.9 do not infer this correctly.
typeReference.arguments = args_2;
}
return typeReference;
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:

@@ -334,2 +381,17 @@ return node.text;

return parseFloat(node.text);
case ts.SyntaxKind.AnyKeyword:
return { __symbolic: 'reference', name: 'any' };
case ts.SyntaxKind.StringKeyword:
return { __symbolic: 'reference', name: 'string' };
case ts.SyntaxKind.NumberKeyword:
return { __symbolic: 'reference', name: 'number' };
case ts.SyntaxKind.BooleanKeyword:
return { __symbolic: 'reference', name: 'boolean' };
case ts.SyntaxKind.ArrayType:
var arrayTypeNode = node;
return {
__symbolic: 'reference',
name: 'Array',
arguments: [this.evaluateNode(arrayTypeNode.elementType)]
};
case ts.SyntaxKind.NullKeyword:

@@ -379,3 +441,3 @@ return null;

}
return { __symbolic: "pre", operator: operatorText, operand: operand };
return { __symbolic: 'pre', operator: operatorText, operand: operand };
case ts.SyntaxKind.BinaryExpression:

@@ -432,3 +494,3 @@ var binaryExpression = node;

return {
__symbolic: "binop",
__symbolic: 'binop',
operator: binaryExpression.operatorToken.getText(),

@@ -440,4 +502,7 @@ left: left,

break;
case ts.SyntaxKind.FunctionExpression:
case ts.SyntaxKind.ArrowFunction:
return errorSymbol('Function call not supported', node);
}
return undefined;
return errorSymbol('Expression form not supported', node);
};

@@ -447,2 +512,5 @@ return Evaluator;

exports.Evaluator = Evaluator;
function isPropertyAssignment(node) {
return node.kind == ts.SyntaxKind.PropertyAssignment;
}
//# sourceMappingURL=evaluator.js.map
import * as ts from 'typescript';
import NgOptions from './options';
export declare type CodegenExtension = (ngOptions: NgOptions, program: ts.Program, host: ts.CompilerHost) => Promise<any>;
export declare type CodegenExtension = (ngOptions: NgOptions, program: ts.Program, host: ts.CompilerHost) => Promise<void>;
export declare function main(project: string, basePath?: string, codegen?: CodegenExtension): Promise<any>;

@@ -16,6 +16,6 @@ "use strict";

// read the configuration options from wherever you store them
var _a = tsc_1.tsc.readConfiguration(project, basePath), parsed = _a.parsed, ngOptions_1 = _a.ngOptions;
var _a = tsc_1.tsc.readConfiguration(project, basePath), parsed_1 = _a.parsed, ngOptions_1 = _a.ngOptions;
ngOptions_1.basePath = basePath;
var host_1 = ts.createCompilerHost(parsed.options, true);
var program_1 = ts.createProgram(parsed.fileNames, parsed.options, host_1);
var host_1 = ts.createCompilerHost(parsed_1.options, true);
var program_1 = ts.createProgram(parsed_1.fileNames, parsed_1.options, host_1);
var errors = program_1.getOptionsDiagnostics();

@@ -27,6 +27,8 @@ tsc_1.check(errors);

return codegen(ngOptions_1, program_1, host_1).then(function () {
tsc_1.tsc.typeCheck(host_1, program_1);
// Create a new program since codegen files were created after making the old program
var newProgram = ts.createProgram(parsed_1.fileNames, parsed_1.options, host_1, program_1);
tsc_1.tsc.typeCheck(host_1, newProgram);
// Emit *.js with Decorators lowered to Annotations, and also *.js.map
var tsicklePreProcessor = new compiler_host_1.TsickleHost(host_1);
tsc_1.tsc.emit(tsicklePreProcessor, program_1);
var tsicklePreProcessor = new compiler_host_1.TsickleHost(host_1, newProgram);
tsc_1.tsc.emit(tsicklePreProcessor, newProgram);
if (!ngOptions_1.skipMetadataEmit) {

@@ -38,4 +40,4 @@ // Emit *.metadata.json and *.d.ts

// in the standard emit.
var metadataWriter = new compiler_host_1.MetadataWriterHost(host_1, program_1);
tsc_1.tsc.emit(metadataWriter, program_1);
var metadataWriter = new compiler_host_1.MetadataWriterHost(host_1, newProgram);
tsc_1.tsc.emit(metadataWriter, newProgram);
}

@@ -56,3 +58,3 @@ });

console.error(e.stack);
console.error("Compilation failed");
console.error('Compilation failed');
process.exit(1);

@@ -59,0 +61,0 @@ });

@@ -0,3 +1,5 @@

export declare const VERSION: number;
export interface ModuleMetadata {
__symbolic: "module";
__symbolic: 'module';
version: number;
metadata: {

@@ -9,4 +11,4 @@ [name: string]: (ClassMetadata | MetadataValue);

export interface ClassMetadata {
__symbolic: "class";
decorators?: MetadataSymbolicExpression[];
__symbolic: 'class';
decorators?: (MetadataSymbolicExpression | MetadataError)[];
members?: MetadataMap;

@@ -19,17 +21,23 @@ }

export interface MemberMetadata {
__symbolic: "constructor" | "method" | "property";
decorators?: MetadataSymbolicExpression[];
__symbolic: 'constructor' | 'method' | 'property';
decorators?: (MetadataSymbolicExpression | MetadataError)[];
}
export declare function isMemberMetadata(value: any): value is MemberMetadata;
export interface MethodMetadata extends MemberMetadata {
__symbolic: "constructor" | "method";
parameterDecorators?: MetadataSymbolicExpression[][];
__symbolic: 'constructor' | 'method';
parameterDecorators?: (MetadataSymbolicExpression | MetadataError)[][];
}
export declare function isMethodMetadata(value: any): value is MemberMetadata;
export interface ConstructorMetadata extends MethodMetadata {
__symbolic: "constructor";
parameters?: MetadataSymbolicExpression[];
__symbolic: 'constructor';
parameters?: (MetadataSymbolicExpression | MetadataError | null)[];
}
export declare function isConstructorMetadata(value: any): value is ConstructorMetadata;
export declare type MetadataValue = string | number | boolean | MetadataObject | MetadataArray | MetadataSymbolicExpression;
export interface FunctionMetadata {
__symbolic: 'function';
parameters: string[];
result: MetadataValue;
}
export declare function isFunctionMetadata(value: any): value is FunctionMetadata;
export declare type MetadataValue = string | number | boolean | MetadataObject | MetadataArray | MetadataSymbolicExpression | MetadataError;
export interface MetadataObject {

@@ -42,8 +50,8 @@ [name: string]: MetadataValue;

export interface MetadataSymbolicExpression {
__symbolic: "binary" | "call" | "index" | "new" | "pre" | "reference" | "select";
__symbolic: 'binary' | 'call' | 'index' | 'new' | 'pre' | 'reference' | 'select' | 'spread';
}
export declare function isMetadataSymbolicExpression(value: any): value is MetadataSymbolicExpression;
export interface MetadataSymbolicBinaryExpression extends MetadataSymbolicExpression {
__symbolic: "binary";
operator: "&&" | "||" | "|" | "^" | "&" | "==" | "!=" | "===" | "!==" | "<" | ">" | "<=" | ">=" | "instanceof" | "in" | "as" | "<<" | ">>" | ">>>" | "+" | "-" | "*" | "/" | "%" | "**";
__symbolic: 'binary';
operator: '&&' | '||' | '|' | '^' | '&' | '==' | '!=' | '===' | '!==' | '<' | '>' | '<=' | '>=' | 'instanceof' | 'in' | 'as' | '<<' | '>>' | '>>>' | '+' | '-' | '*' | '/' | '%' | '**';
left: MetadataValue;

@@ -54,3 +62,3 @@ right: MetadataValue;

export interface MetadataSymbolicIndexExpression extends MetadataSymbolicExpression {
__symbolic: "index";
__symbolic: 'index';
expression: MetadataValue;

@@ -61,3 +69,3 @@ index: MetadataValue;

export interface MetadataSymbolicCallExpression extends MetadataSymbolicExpression {
__symbolic: "call" | "new";
__symbolic: 'call' | 'new';
expression: MetadataValue;

@@ -68,15 +76,36 @@ arguments?: MetadataValue[];

export interface MetadataSymbolicPrefixExpression extends MetadataSymbolicExpression {
__symbolic: "pre";
operator: "+" | "-" | "~" | "!";
__symbolic: 'pre';
operator: '+' | '-' | '~' | '!';
operand: MetadataValue;
}
export declare function isMetadataSymbolicPrefixExpression(value: any): value is MetadataSymbolicPrefixExpression;
export interface MetadataSymbolicReferenceExpression extends MetadataSymbolicExpression {
__symbolic: "reference";
export interface MetadataGlobalReferenceExpression extends MetadataSymbolicExpression {
__symbolic: 'reference';
name: string;
arguments?: MetadataValue[];
}
export declare function isMetadataGlobalReferenceExpression(value: any): value is MetadataGlobalReferenceExpression;
export interface MetadataModuleReferenceExpression extends MetadataSymbolicExpression {
__symbolic: 'reference';
module: string;
}
export declare function isMetadataModuleReferenceExpression(value: any): value is MetadataModuleReferenceExpression;
export interface MetadataImportedSymbolReferenceExpression extends MetadataSymbolicExpression {
__symbolic: 'reference';
module: string;
name: string;
arguments?: MetadataValue[];
}
export declare function isMetadataImportedSymbolReferenceExpression(value: any): value is MetadataImportedSymbolReferenceExpression;
export interface MetadataImportedDefaultReferenceExpression extends MetadataSymbolicExpression {
__symbolic: 'reference';
module: string;
default: boolean;
arguments?: MetadataValue[];
}
export declare function isMetadataImportDefaultReference(value: any): value is MetadataImportedDefaultReferenceExpression;
export declare type MetadataSymbolicReferenceExpression = MetadataGlobalReferenceExpression | MetadataModuleReferenceExpression | MetadataImportedSymbolReferenceExpression | MetadataImportedDefaultReferenceExpression;
export declare function isMetadataSymbolicReferenceExpression(value: any): value is MetadataSymbolicReferenceExpression;
export interface MetadataSymbolicSelectExpression extends MetadataSymbolicExpression {
__symbolic: "select";
__symbolic: 'select';
expression: MetadataValue;

@@ -86,1 +115,32 @@ name: string;

export declare function isMetadataSymbolicSelectExpression(value: any): value is MetadataSymbolicSelectExpression;
export interface MetadataSymbolicSpreadExpression extends MetadataSymbolicExpression {
__symbolic: 'spread';
expression: MetadataValue;
}
export declare function isMetadataSymbolicSpreadExpression(value: any): value is MetadataSymbolicSpreadExpression;
export interface MetadataError {
__symbolic: 'error';
/**
* This message should be short and relatively discriptive and should be fixed once it is created.
* If the reader doesn't recognize the message, it will display the message unmodified. If the
* reader recognizes the error message is it free to use substitute message the is more
* descriptive and/or localized.
*/
message: string;
/**
* The line number of the error in the .ts file the metadata was created for.
*/
line?: number;
/**
* The number of utf8 code-units from the beginning of the file of the error.
*/
character?: number;
/**
* Context information that can be used to generate a more descriptive error message. The content
* of the context is dependent on the error message.
*/
context?: {
[name: string]: string;
};
}
export declare function isMetadataError(value: any): value is MetadataError;

@@ -0,8 +1,15 @@

// Metadata Schema
"use strict";
// If you make a backwards incompatible change to the schema, increment the VERSION number.
// If you make a backwards compatible change to the metadata (such as adding an option field) then
// leave VERSION the same. If possible, as many versions of the metadata that can represent the
// semantics of the file in an array. For example, when generating a version 2 file, if version 1
// can accurately represent the metadata, generate both version 1 and version 2 in an array.
exports.VERSION = 1;
function isModuleMetadata(value) {
return value && value.__symbolic === "module";
return value && value.__symbolic === 'module';
}
exports.isModuleMetadata = isModuleMetadata;
function isClassMetadata(value) {
return value && value.__symbolic === "class";
return value && value.__symbolic === 'class';
}

@@ -13,5 +20,5 @@ exports.isClassMetadata = isClassMetadata;

switch (value.__symbolic) {
case "constructor":
case "method":
case "property":
case 'constructor':
case 'method':
case 'property':
return true;

@@ -24,19 +31,24 @@ }

function isMethodMetadata(value) {
return value && (value.__symbolic === "constructor" || value.__symbolic === "method");
return value && (value.__symbolic === 'constructor' || value.__symbolic === 'method');
}
exports.isMethodMetadata = isMethodMetadata;
function isConstructorMetadata(value) {
return value && value.__symbolic === "constructor";
return value && value.__symbolic === 'constructor';
}
exports.isConstructorMetadata = isConstructorMetadata;
function isFunctionMetadata(value) {
return value && value.__symbolic === 'function';
}
exports.isFunctionMetadata = isFunctionMetadata;
function isMetadataSymbolicExpression(value) {
if (value) {
switch (value.__symbolic) {
case "binary":
case "call":
case "index":
case "new":
case "pre":
case "reference":
case "select":
case 'binary':
case 'call':
case 'index':
case 'new':
case 'pre':
case 'reference':
case 'select':
case 'spread':
return true;

@@ -49,25 +61,50 @@ }

function isMetadataSymbolicBinaryExpression(value) {
return value && value.__symbolic === "binary";
return value && value.__symbolic === 'binary';
}
exports.isMetadataSymbolicBinaryExpression = isMetadataSymbolicBinaryExpression;
function isMetadataSymbolicIndexExpression(value) {
return value && value.__symbolic === "index";
return value && value.__symbolic === 'index';
}
exports.isMetadataSymbolicIndexExpression = isMetadataSymbolicIndexExpression;
function isMetadataSymbolicCallExpression(value) {
return value && (value.__symbolic === "call" || value.__symbolic === "new");
return value && (value.__symbolic === 'call' || value.__symbolic === 'new');
}
exports.isMetadataSymbolicCallExpression = isMetadataSymbolicCallExpression;
function isMetadataSymbolicPrefixExpression(value) {
return value && value.__symbolic === "pre";
return value && value.__symbolic === 'pre';
}
exports.isMetadataSymbolicPrefixExpression = isMetadataSymbolicPrefixExpression;
function isMetadataGlobalReferenceExpression(value) {
return isMetadataSymbolicReferenceExpression(value) && value.name && !value.module;
}
exports.isMetadataGlobalReferenceExpression = isMetadataGlobalReferenceExpression;
function isMetadataModuleReferenceExpression(value) {
return isMetadataSymbolicReferenceExpression(value) && value.module && !value.name &&
!value.default;
}
exports.isMetadataModuleReferenceExpression = isMetadataModuleReferenceExpression;
function isMetadataImportedSymbolReferenceExpression(value) {
return isMetadataSymbolicReferenceExpression(value) && value.module && !!value.name;
}
exports.isMetadataImportedSymbolReferenceExpression = isMetadataImportedSymbolReferenceExpression;
function isMetadataImportDefaultReference(value) {
return isMetadataSymbolicReferenceExpression(value) && value.module && value.default;
}
exports.isMetadataImportDefaultReference = isMetadataImportDefaultReference;
function isMetadataSymbolicReferenceExpression(value) {
return value && value.__symbolic === "reference";
return value && value.__symbolic === 'reference';
}
exports.isMetadataSymbolicReferenceExpression = isMetadataSymbolicReferenceExpression;
function isMetadataSymbolicSelectExpression(value) {
return value && value.__symbolic === "select";
return value && value.__symbolic === 'select';
}
exports.isMetadataSymbolicSelectExpression = isMetadataSymbolicSelectExpression;
function isMetadataSymbolicSpreadExpression(value) {
return value && value.__symbolic === 'spread';
}
exports.isMetadataSymbolicSpreadExpression = isMetadataSymbolicSpreadExpression;
function isMetadataError(value) {
return value && value.__symbolic === 'error';
}
exports.isMetadataError = isMetadataError;
//# sourceMappingURL=schema.js.map
import * as ts from 'typescript';
/**
* A symbol table of ts.Symbol to a folded value used during expression folding in Evaluator.
*
* This is a thin wrapper around a Map<> using the first declaration location instead of the symbol
* itself as the key. In the TypeScript binder and type checker, mulitple symbols are sometimes
* created for a symbol depending on what scope it is in (e.g. export vs. local). Using the
* declaration node as the key results in these duplicate symbols being treated as identical.
*/
import { MetadataValue } from './schema';
export declare class Symbols {
private map;
has(symbol: ts.Symbol): boolean;
set(symbol: ts.Symbol, value: any): void;
get(symbol: ts.Symbol): any;
static empty: Symbols;
private sourceFile;
private _symbols;
constructor(sourceFile: ts.SourceFile);
resolve(name: string): MetadataValue | undefined;
define(name: string, value: MetadataValue): void;
has(name: string): boolean;
private readonly symbols;
private buildImports();
}
"use strict";
var a;
/**
* A symbol table of ts.Symbol to a folded value used during expression folding in Evaluator.
*
* This is a thin wrapper around a Map<> using the first declaration location instead of the symbol
* itself as the key. In the TypeScript binder and type checker, mulitple symbols are sometimes
* created for a symbol depending on what scope it is in (e.g. export vs. local). Using the
* declaration node as the key results in these duplicate symbols being treated as identical.
*/
var ts = require('typescript');
var Symbols = (function () {
function Symbols() {
this.map = new Map();
function Symbols(sourceFile) {
this.sourceFile = sourceFile;
}
Symbols.prototype.has = function (symbol) { return this.map.has(symbol.getDeclarations()[0]); };
Symbols.prototype.set = function (symbol, value) { this.map.set(symbol.getDeclarations()[0], value); };
Symbols.prototype.get = function (symbol) { return this.map.get(symbol.getDeclarations()[0]); };
Symbols.empty = new Symbols();
Symbols.prototype.resolve = function (name) { return this.symbols.get(name); };
Symbols.prototype.define = function (name, value) { this.symbols.set(name, value); };
Symbols.prototype.has = function (name) { return this.symbols.has(name); };
Object.defineProperty(Symbols.prototype, "symbols", {
get: function () {
var result = this._symbols;
if (!result) {
result = this._symbols = new Map();
populateBuiltins(result);
this.buildImports();
}
return result;
},
enumerable: true,
configurable: true
});
Symbols.prototype.buildImports = function () {
var symbols = this._symbols;
// Collect the imported symbols into this.symbols
var stripQuotes = function (s) { return s.replace(/^['"]|['"]$/g, ''); };
var visit = function (node) {
switch (node.kind) {
case ts.SyntaxKind.ImportEqualsDeclaration:
var importEqualsDeclaration = node;
if (importEqualsDeclaration.moduleReference.kind ===
ts.SyntaxKind.ExternalModuleReference) {
var externalReference = importEqualsDeclaration.moduleReference;
// An `import <identifier> = require(<module-specifier>);
var from_1 = stripQuotes(externalReference.expression.getText());
symbols.set(importEqualsDeclaration.name.text, { __symbolic: 'reference', module: from_1 });
}
else {
symbols.set(importEqualsDeclaration.name.text, { __symbolic: 'error', message: "Unsupported import syntax" });
}
break;
case ts.SyntaxKind.ImportDeclaration:
var importDecl = node;
if (!importDecl.importClause) {
// An `import <module-specifier>` clause which does not bring symbols into scope.
break;
}
var from = stripQuotes(importDecl.moduleSpecifier.getText());
if (importDecl.importClause.name) {
// An `import <identifier> form <module-specifier>` clause. Record the defualt symbol.
symbols.set(importDecl.importClause.name.text, { __symbolic: 'reference', module: from, default: true });
}
var bindings = importDecl.importClause.namedBindings;
if (bindings) {
switch (bindings.kind) {
case ts.SyntaxKind.NamedImports:
// An `import { [<identifier> [, <identifier>] } from <module-specifier>` clause
for (var _i = 0, _a = bindings.elements; _i < _a.length; _i++) {
var binding = _a[_i];
symbols.set(binding.name.text, {
__symbolic: 'reference',
module: from,
name: binding.propertyName ? binding.propertyName.text : binding.name.text
});
}
break;
case ts.SyntaxKind.NamespaceImport:
// An `input * as <identifier> from <module-specifier>` clause.
symbols.set(bindings.name.text, { __symbolic: 'reference', module: from });
break;
}
}
break;
}
ts.forEachChild(node, visit);
};
if (this.sourceFile) {
ts.forEachChild(this.sourceFile, visit);
}
};
return Symbols;
}());
exports.Symbols = Symbols;
function populateBuiltins(symbols) {
// From lib.core.d.ts (all "define const")
['Object', 'Function', 'String', 'Number', 'Array', 'Boolean', 'Map', 'NaN', 'Infinity', 'Math',
'Date', 'RegExp', 'Error', 'Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError',
'TypeError', 'URIError', 'JSON', 'ArrayBuffer', 'DataView', 'Int8Array', 'Uint8Array',
'Uint8ClampedArray', 'Uint16Array', 'Int16Array', 'Int32Array', 'Uint32Array', 'Float32Array',
'Float64Array']
.forEach(function (name) { return symbols.set(name, { __symbolic: 'reference', name: name }); });
}
//# sourceMappingURL=symbols.js.map

@@ -30,5 +30,5 @@ import * as ts from 'typescript';

};
typeCheck(compilerHost: ts.CompilerHost, oldProgram: ts.Program): void;
typeCheck(compilerHost: ts.CompilerHost, program: ts.Program): void;
emit(compilerHost: TsickleHost, oldProgram: ts.Program): number;
}
export declare var tsc: CompilerInterface;
"use strict";
var path = require('path');
var ts = require('typescript');
var path = require('path');
var DEBUG = false;

@@ -14,3 +14,4 @@ function debug(msg) {

function formatDiagnostics(diags) {
return diags.map(function (d) {
return diags
.map(function (d) {
var res = ts.DiagnosticCategory[d.category];

@@ -46,3 +47,3 @@ if (d.file) {

this.readDirectory(project);
project = path.join(project, "tsconfig.json");
project = path.join(project, 'tsconfig.json');
}

@@ -66,9 +67,7 @@ catch (e) {

};
Tsc.prototype.typeCheck = function (compilerHost, oldProgram) {
// Create a new program since codegen files were created after making the old program
var program = ts.createProgram(this.parsed.fileNames, this.parsed.options, compilerHost, oldProgram);
debug("Checking global diagnostics...");
Tsc.prototype.typeCheck = function (compilerHost, program) {
debug('Checking global diagnostics...');
check(program.getGlobalDiagnostics());
var diagnostics = [];
debug("Type checking...");
debug('Type checking...');
for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {

@@ -83,3 +82,3 @@ var sf = _a[_i];

var program = ts.createProgram(this.parsed.fileNames, this.parsed.options, compilerHost);
debug("Emitting outputs...");
debug('Emitting outputs...');
var emitResult = program.emit();

@@ -86,0 +85,0 @@ var diagnostics = [];

@@ -6,12 +6,14 @@ "use strict";

describe('Collector', function () {
var documentRegistry = ts.createDocumentRegistry();
var host;
var service;
var program;
var typeChecker;
var collector;
beforeEach(function () {
host = new typescript_mocks_1.Host(FILES, ['/app/app.component.ts', '/app/cases-data.ts', '/app/cases-no-data.ts', '/promise.ts']);
service = ts.createLanguageService(host);
host = new typescript_mocks_1.Host(FILES, [
'/app/app.component.ts', '/app/cases-data.ts', '/app/error-cases.ts', '/promise.ts',
'/unsupported-1.ts', '/unsupported-2.ts', 'import-star.ts', 'exported-functions.ts'
]);
service = ts.createLanguageService(host, documentRegistry);
program = service.getProgram();
typeChecker = program.getTypeChecker();
collector = new collector_1.MetadataCollector();

@@ -22,51 +24,30 @@ });

var sourceFile = program.getSourceFile('app/hero.ts');
var metadata = collector.getMetadata(sourceFile, typeChecker);
var metadata = collector.getMetadata(sourceFile);
expect(metadata).toBeUndefined();
});
it("should be able to collect import statements", function () {
var sourceFile = program.getSourceFile('app/app.component.ts');
expect(collector.collectImports(sourceFile))
.toEqual([
{
from: 'angular2/core',
namedImports: [{ name: 'MyComponent', propertyName: 'Component' }, { name: 'OnInit' }]
},
{ from: 'angular2/common', namespace: 'common' },
{ from: './hero', namedImports: [{ name: 'Hero' }] },
{ from: './hero-detail.component', namedImports: [{ name: 'HeroDetailComponent' }] },
{ from: './hero.service', defaultName: 'HeroService' }
]);
});
it("should be able to collect a simple component's metadata", function () {
it('should be able to collect a simple component\'s metadata', function () {
var sourceFile = program.getSourceFile('app/hero-detail.component.ts');
var metadata = collector.getMetadata(sourceFile, typeChecker);
var metadata = collector.getMetadata(sourceFile);
expect(metadata).toEqual({
__symbolic: 'module',
version: 1,
metadata: {
HeroDetailComponent: {
__symbolic: 'class',
decorators: [
{
decorators: [{
__symbolic: 'call',
expression: { __symbolic: 'reference', name: 'Component', module: 'angular2/core' },
arguments: [
{
expression: { __symbolic: 'reference', module: 'angular2/core', name: 'Component' },
arguments: [{
selector: 'my-hero-detail',
template: "\n <div *ngIf=\"hero\">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]=\"hero.name\" placeholder=\"name\"/>\n </div>\n </div>\n "
}
]
}
],
}]
}],
members: {
hero: [
{
hero: [{
__symbolic: 'property',
decorators: [
{
decorators: [{
__symbolic: 'call',
expression: { __symbolic: 'reference', name: 'Input', module: 'angular2/core' }
}
]
}
]
expression: { __symbolic: 'reference', module: 'angular2/core', name: 'Input' }
}]
}]
}

@@ -77,16 +58,15 @@ }

});
it("should be able to get a more complicated component's metadata", function () {
it('should be able to get a more complicated component\'s metadata', function () {
var sourceFile = program.getSourceFile('/app/app.component.ts');
var metadata = collector.getMetadata(sourceFile, typeChecker);
var metadata = collector.getMetadata(sourceFile);
expect(metadata).toEqual({
__symbolic: 'module',
version: 1,
metadata: {
AppComponent: {
__symbolic: 'class',
decorators: [
{
decorators: [{
__symbolic: 'call',
expression: { __symbolic: 'reference', name: 'Component', module: 'angular2/core' },
arguments: [
{
expression: { __symbolic: 'reference', module: 'angular2/core', name: 'Component' },
arguments: [{
selector: 'my-app',

@@ -97,27 +77,19 @@ template: "\n <h2>My Heroes</h2>\n <ul class=\"heroes\">\n <li *ngFor=\"#hero of heroes\"\n (click)=\"onSelect(hero)\"\n [class.selected]=\"hero === selectedHero\">\n <span class=\"badge\">{{hero.id | lowercase}}</span> {{hero.name | uppercase}}\n </li>\n </ul>\n <my-hero-detail [hero]=\"selectedHero\"></my-hero-detail>\n ",

__symbolic: 'reference',
module: './hero-detail.component',
name: 'HeroDetailComponent',
module: './hero-detail.component'
},
{ __symbolic: 'reference', name: 'NgFor', module: 'angular2/common' }
{ __symbolic: 'reference', module: 'angular2/common', name: 'NgFor' }
],
providers: [{ __symbolic: 'reference', name: undefined, module: './hero.service' }],
providers: [{ __symbolic: 'reference', module: './hero.service', default: true }],
pipes: [
{ __symbolic: 'reference', name: 'LowerCasePipe', module: 'angular2/common' },
{
__symbolic: 'reference',
name: 'UpperCasePipe',
module: 'angular2/common'
}
{ __symbolic: 'reference', module: 'angular2/common', name: 'LowerCasePipe' },
{ __symbolic: 'reference', module: 'angular2/common', name: 'UpperCasePipe' }
]
}
]
}
],
}]
}],
members: {
__ctor__: [
{
__ctor__: [{
__symbolic: 'constructor',
parameters: [{ __symbolic: 'reference', name: undefined, module: './hero.service' }]
}
],
parameters: [{ __symbolic: 'reference', module: './hero.service', default: true }]
}],
onSelect: [{ __symbolic: 'method' }],

@@ -133,17 +105,13 @@ ngOnInit: [{ __symbolic: 'method' }],

var sourceFile = program.getSourceFile('/app/mock-heroes.ts');
var metadata = collector.getMetadata(sourceFile, typeChecker);
var metadata = collector.getMetadata(sourceFile);
expect(metadata).toEqual({
__symbolic: 'module',
version: 1,
metadata: {
HEROES: [
{ "id": 11, "name": "Mr. Nice" },
{ "id": 12, "name": "Narco" },
{ "id": 13, "name": "Bombasto" },
{ "id": 14, "name": "Celeritas" },
{ "id": 15, "name": "Magneta" },
{ "id": 16, "name": "RubberMan" },
{ "id": 17, "name": "Dynama" },
{ "id": 18, "name": "Dr IQ" },
{ "id": 19, "name": "Magma" },
{ "id": 20, "name": "Tornado" }
{ 'id': 11, 'name': 'Mr. Nice' }, { 'id': 12, 'name': 'Narco' },
{ 'id': 13, 'name': 'Bombasto' }, { 'id': 14, 'name': 'Celeritas' },
{ 'id': 15, 'name': 'Magneta' }, { 'id': 16, 'name': 'RubberMan' },
{ 'id': 17, 'name': 'Dynama' }, { 'id': 18, 'name': 'Dr IQ' }, { 'id': 19, 'name': 'Magma' },
{ 'id': 20, 'name': 'Tornado' }
]

@@ -153,7 +121,7 @@ }

});
it('should have no data produced for the no data cases', function () {
var sourceFile = program.getSourceFile('/app/cases-no-data.ts');
it('should return undefined for modules that have no metadata', function () {
var sourceFile = program.getSourceFile('/app/error-cases.ts');
expect(sourceFile).toBeTruthy(sourceFile);
var metadata = collector.getMetadata(sourceFile, typeChecker);
expect(metadata).toBeFalsy();
var metadata = collector.getMetadata(sourceFile);
expect(metadata).toBeUndefined();
});

@@ -164,24 +132,20 @@ var casesFile;

casesFile = program.getSourceFile('/app/cases-data.ts');
casesMetadata = collector.getMetadata(casesFile, typeChecker);
casesMetadata = collector.getMetadata(casesFile);
});
it('should provide null for an any ctor pameter type', function () {
it('should provide any reference for an any ctor parameter type', function () {
var casesAny = casesMetadata.metadata['CaseAny'];
expect(casesAny).toBeTruthy();
var ctorData = casesAny.members['__ctor__'];
expect(ctorData).toEqual([{ __symbolic: 'constructor', parameters: [null] }]);
expect(ctorData).toEqual([{ __symbolic: 'constructor', parameters: [{ __symbolic: 'reference', name: 'any' }] }]);
});
it('should record annotations on set and get declarations', function () {
var propertyData = {
name: [
{
name: [{
__symbolic: 'property',
decorators: [
{
decorators: [{
__symbolic: 'call',
expression: { __symbolic: 'reference', module: 'angular2/core', name: 'Input' },
arguments: ['firstName']
}
]
}
]
}]
}]
};

@@ -195,2 +159,128 @@ var caseGetProp = casesMetadata.metadata['GetProp'];

});
it('should record references to parameterized types', function () {
var casesForIn = casesMetadata.metadata['NgFor'];
expect(casesForIn).toEqual({
__symbolic: 'class',
decorators: [{
__symbolic: 'call',
expression: { __symbolic: 'reference', module: 'angular2/core', name: 'Injectable' }
}],
members: {
__ctor__: [{
__symbolic: 'constructor',
parameters: [{
__symbolic: 'reference',
name: 'ClassReference',
arguments: [{ __symbolic: 'reference', name: 'NgForRow' }]
}]
}]
}
});
});
it('should report errors for destructured imports', function () {
var unsupported1 = program.getSourceFile('/unsupported-1.ts');
var metadata = collector.getMetadata(unsupported1);
expect(metadata).toEqual({
__symbolic: 'module',
version: 1,
metadata: {
a: { __symbolic: 'error', message: 'Destructuring not supported', line: 1, character: 16 },
b: { __symbolic: 'error', message: 'Destructuring not supported', line: 1, character: 18 },
c: { __symbolic: 'error', message: 'Destructuring not supported', line: 2, character: 16 },
d: { __symbolic: 'error', message: 'Destructuring not supported', line: 2, character: 18 },
e: { __symbolic: 'error', message: 'Variable not initialized', line: 3, character: 14 }
}
});
});
it('should report an error for references to unexpected types', function () {
var unsupported1 = program.getSourceFile('/unsupported-2.ts');
var metadata = collector.getMetadata(unsupported1);
var barClass = metadata.metadata['Bar'];
var ctor = barClass.members['__ctor__'][0];
var parameter = ctor.parameters[0];
expect(parameter).toEqual({
__symbolic: 'error',
message: 'Reference to non-exported class',
line: 1,
character: 45,
context: { className: 'Foo' }
});
});
it('should be able to handle import star type references', function () {
var importStar = program.getSourceFile('/import-star.ts');
var metadata = collector.getMetadata(importStar);
var someClass = metadata.metadata['SomeClass'];
var ctor = someClass.members['__ctor__'][0];
var parameters = ctor.parameters;
expect(parameters).toEqual([
{ __symbolic: 'reference', module: 'angular2/common', name: 'NgFor' }
]);
});
it('should be able to record functions', function () {
var exportedFunctions = program.getSourceFile('/exported-functions.ts');
var metadata = collector.getMetadata(exportedFunctions);
expect(metadata).toEqual({
__symbolic: 'module',
version: 1,
metadata: {
one: {
__symbolic: 'function',
parameters: ['a', 'b', 'c'],
value: {
a: { __symbolic: 'reference', name: 'a' },
b: { __symbolic: 'reference', name: 'b' },
c: { __symbolic: 'reference', name: 'c' }
}
},
two: {
__symbolic: 'function',
parameters: ['a', 'b', 'c'],
value: {
a: { __symbolic: 'reference', name: 'a' },
b: { __symbolic: 'reference', name: 'b' },
c: { __symbolic: 'reference', name: 'c' }
}
},
three: {
__symbolic: 'function',
parameters: ['a', 'b', 'c'],
value: [
{ __symbolic: 'reference', name: 'a' }, { __symbolic: 'reference', name: 'b' },
{ __symbolic: 'reference', name: 'c' }
]
},
supportsState: {
__symbolic: 'function',
parameters: [],
value: {
__symbolic: 'pre',
operator: '!',
operand: {
__symbolic: 'pre',
operator: '!',
operand: {
__symbolic: 'select',
expression: {
__symbolic: 'select',
expression: { __symbolic: 'reference', name: 'window' },
member: 'history'
},
member: 'pushState'
}
}
}
}
}
});
});
it('should be able to handle import star type references', function () {
var importStar = program.getSourceFile('/import-star.ts');
var metadata = collector.getMetadata(importStar);
var someClass = metadata.metadata['SomeClass'];
var ctor = someClass.members['__ctor__'][0];
var parameters = ctor.parameters;
expect(parameters).toEqual([
{ __symbolic: 'reference', module: 'angular2/common', name: 'NgFor' }
]);
});
});

@@ -200,13 +290,24 @@ // TODO: Do not use \` in a template literal as it confuses clang-format

'app': {
'app.component.ts': "\n import {Component as MyComponent, OnInit} from 'angular2/core';\n import * as common from 'angular2/common';\n import {Hero} from './hero';\n import {HeroDetailComponent} from './hero-detail.component';\n import HeroService from './hero.service';\n // thrown away\n import 'angular2/core';\n\n @MyComponent({\n selector: 'my-app',\n template:" + "`" + "\n <h2>My Heroes</h2>\n <ul class=\"heroes\">\n <li *ngFor=\"#hero of heroes\"\n (click)=\"onSelect(hero)\"\n [class.selected]=\"hero === selectedHero\">\n <span class=\"badge\">{{hero.id | lowercase}}</span> {{hero.name | uppercase}}\n </li>\n </ul>\n <my-hero-detail [hero]=\"selectedHero\"></my-hero-detail>\n " +
"`" + ",\n directives: [HeroDetailComponent, common.NgFor],\n providers: [HeroService],\n pipes: [common.LowerCasePipe, common.UpperCasePipe]\n })\n export class AppComponent implements OnInit {\n public title = 'Tour of Heroes';\n public heroes: Hero[];\n public selectedHero: Hero;\n\n constructor(private _heroService: HeroService) { }\n\n onSelect(hero: Hero) { this.selectedHero = hero; }\n\n ngOnInit() {\n this.getHeroes()\n }\n\n getHeroes() {\n this._heroService.getHeroesSlowly().then(heros => this.heroes = heros);\n }\n }",
'app.component.ts': "\n import {Component as MyComponent, OnInit} from 'angular2/core';\n import * as common from 'angular2/common';\n import {Hero} from './hero';\n import {HeroDetailComponent} from './hero-detail.component';\n import HeroService from './hero.service';\n // thrown away\n import 'angular2/core';\n\n @MyComponent({\n selector: 'my-app',\n template:" +
'`' +
"\n <h2>My Heroes</h2>\n <ul class=\"heroes\">\n <li *ngFor=\"#hero of heroes\"\n (click)=\"onSelect(hero)\"\n [class.selected]=\"hero === selectedHero\">\n <span class=\"badge\">{{hero.id | lowercase}}</span> {{hero.name | uppercase}}\n </li>\n </ul>\n <my-hero-detail [hero]=\"selectedHero\"></my-hero-detail>\n " +
'`' +
",\n directives: [HeroDetailComponent, common.NgFor],\n providers: [HeroService],\n pipes: [common.LowerCasePipe, common.UpperCasePipe]\n })\n export class AppComponent implements OnInit {\n public title = 'Tour of Heroes';\n public heroes: Hero[];\n public selectedHero: Hero;\n\n constructor(private _heroService: HeroService) { }\n\n onSelect(hero: Hero) { this.selectedHero = hero; }\n\n ngOnInit() {\n this.getHeroes()\n }\n\n getHeroes() {\n this._heroService.getHeroesSlowly().then(heros => this.heroes = heros);\n }\n }",
'hero.ts': "\n export interface Hero {\n id: number;\n name: string;\n }",
'hero-detail.component.ts': "\n import {Component, Input} from 'angular2/core';\n import {Hero} from './hero';\n\n @Component({\n selector: 'my-hero-detail',\n template: " + "`" + "\n <div *ngIf=\"hero\">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]=\"hero.name\" placeholder=\"name\"/>\n </div>\n </div>\n " + "`" + ",\n })\n export class HeroDetailComponent {\n @Input() public hero: Hero;\n }",
'hero-detail.component.ts': "\n import {Component, Input} from 'angular2/core';\n import {Hero} from './hero';\n\n @Component({\n selector: 'my-hero-detail',\n template: " +
'`' +
"\n <div *ngIf=\"hero\">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]=\"hero.name\" placeholder=\"name\"/>\n </div>\n </div>\n " +
'`' +
",\n })\n export class HeroDetailComponent {\n @Input() public hero: Hero;\n }",
'mock-heroes.ts': "\n import {Hero as Hero} from './hero';\n\n export const HEROES: Hero[] = [\n {\"id\": 11, \"name\": \"Mr. Nice\"},\n {\"id\": 12, \"name\": \"Narco\"},\n {\"id\": 13, \"name\": \"Bombasto\"},\n {\"id\": 14, \"name\": \"Celeritas\"},\n {\"id\": 15, \"name\": \"Magneta\"},\n {\"id\": 16, \"name\": \"RubberMan\"},\n {\"id\": 17, \"name\": \"Dynama\"},\n {\"id\": 18, \"name\": \"Dr IQ\"},\n {\"id\": 19, \"name\": \"Magma\"},\n {\"id\": 20, \"name\": \"Tornado\"}\n ];",
'default-exporter.ts': "\n let a: string;\n export default a;\n ",
'hero.service.ts': "\n import {Injectable} from 'angular2/core';\n import {HEROES} from './mock-heroes';\n import {Hero} from './hero';\n\n @Injectable()\n class HeroService {\n getHeros() {\n return Promise.resolve(HEROES);\n }\n\n getHeroesSlowly() {\n return new Promise<Hero[]>(resolve =>\n setTimeout(()=>resolve(HEROES), 2000)); // 2 seconds\n }\n }\n export default HeroService;",
'cases-data.ts': "\n import {Injectable, Input} from 'angular2/core';\n\n @Injectable()\n export class CaseAny {\n constructor(param: any) {}\n }\n\n @Injectable()\n export class GetProp {\n private _name: string;\n @Input('firstName') get name(): string {\n return this._name;\n }\n }\n\n @Injectable()\n export class SetProp {\n private _name: string;\n @Input('firstName') set name(value: string) {\n this._name = value;\n }\n }\n\n @Injectable()\n export class FullProp {\n private _name: string;\n @Input('firstName') get name(): string {\n return this._name;\n }\n set name(value: string) {\n this._name = value;\n }\n }\n ",
'cases-no-data.ts': "\n import HeroService from './hero.service';\n\n export class CaseCtor {\n constructor(private _heroService: HeroService) { }\n }\n "
'cases-data.ts': "\n import {Injectable, Input} from 'angular2/core';\n\n @Injectable()\n export class CaseAny {\n constructor(param: any) {}\n }\n\n @Injectable()\n export class GetProp {\n private _name: string;\n @Input('firstName') get name(): string {\n return this._name;\n }\n }\n\n @Injectable()\n export class SetProp {\n private _name: string;\n @Input('firstName') set name(value: string) {\n this._name = value;\n }\n }\n\n @Injectable()\n export class FullProp {\n private _name: string;\n @Input('firstName') get name(): string {\n return this._name;\n }\n set name(value: string) {\n this._name = value;\n }\n }\n\n export class ClassReference<T> { }\n export class NgForRow {\n\n }\n\n @Injectable()\n export class NgFor {\n constructor (public ref: ClassReference<NgForRow>) {}\n }\n ",
'error-cases.ts': "\n import HeroService from './hero.service';\n\n export class CaseCtor {\n constructor(private _heroService: HeroService) { }\n }\n "
},
'promise.ts': "\n interface PromiseLike<T> {\n then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;\n then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;\n }\n\n interface Promise<T> {\n then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): Promise<TResult>;\n then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): Promise<TResult>;\n catch(onrejected?: (reason: any) => T | PromiseLike<T>): Promise<T>;\n catch(onrejected?: (reason: any) => void): Promise<T>;\n }\n\n interface PromiseConstructor {\n prototype: Promise<any>;\n new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;\n reject(reason: any): Promise<void>;\n reject<T>(reason: any): Promise<T>;\n resolve<T>(value: T | PromiseLike<T>): Promise<T>;\n resolve(): Promise<void>;\n }\n\n declare var Promise: PromiseConstructor;\n ",
'unsupported-1.ts': "\n export let {a, b} = {a: 1, b: 2};\n export let [c, d] = [1, 2];\n export let e;\n ",
'unsupported-2.ts': "\n import {Injectable} from 'angular2/core';\n\n class Foo {}\n\n @Injectable()\n export class Bar {\n constructor(private f: Foo) {}\n }\n ",
'import-star.ts': "\n import {Injectable} from 'angular2/core';\n import * as common from 'angular2/common';\n\n @Injectable()\n export class SomeClass {\n constructor(private f: common.NgFor) {}\n }\n ",
'exported-functions.ts': "\n export function one(a: string, b: string, c: string) {\n return {a: a, b: b, c: c};\n }\n export function two(a: string, b: string, c: string) {\n return {a, b, c};\n }\n export function three({a, b, c}: {a: string, b: string, c: string}) {\n return [a, b, c];\n }\n export function supportsState(): boolean {\n return !!window.history.pushState;\n }\n ",
'node_modules': {

@@ -213,0 +314,0 @@ 'angular2': {

"use strict";
var ts = require('typescript');
var typescript_mocks_1 = require('./typescript.mocks');
var evaluator_1 = require('../src/evaluator');
var symbols_1 = require('../src/symbols');
var typescript_mocks_1 = require('./typescript.mocks');
describe('Evaluator', function () {
var documentRegistry = ts.createDocumentRegistry();
var host;

@@ -14,8 +15,11 @@ var service;

beforeEach(function () {
host = new typescript_mocks_1.Host(FILES, ['expressions.ts', 'const_expr.ts', 'forwardRef.ts', 'classes.ts', 'newExpression.ts']);
service = ts.createLanguageService(host);
host = new typescript_mocks_1.Host(FILES, [
'expressions.ts', 'consts.ts', 'const_expr.ts', 'forwardRef.ts', 'classes.ts',
'newExpression.ts', 'errors.ts'
]);
service = ts.createLanguageService(host, documentRegistry);
program = service.getProgram();
typeChecker = program.getTypeChecker();
symbols = new symbols_1.Symbols();
evaluator = new evaluator_1.Evaluator(typeChecker, symbols, []);
symbols = new symbols_1.Symbols(null);
evaluator = new evaluator_1.Evaluator(symbols);
});

@@ -27,3 +31,6 @@ it('should not have typescript errors in test data', function () {

typescript_mocks_1.expectNoDiagnostics(service.getSyntacticDiagnostics(sourceFile.fileName));
typescript_mocks_1.expectNoDiagnostics(service.getSemanticDiagnostics(sourceFile.fileName));
if (sourceFile.fileName != 'errors.ts') {
// Skip errors.ts because we it has intentional semantic errors that we are testing for.
typescript_mocks_1.expectNoDiagnostics(service.getSemanticDiagnostics(sourceFile.fileName));
}
}

@@ -40,4 +47,10 @@ });

var expressions = program.getSourceFile('expressions.ts');
symbols.define('someName', 'some-name');
symbols.define('someBool', true);
symbols.define('one', 1);
symbols.define('two', 2);
expect(evaluator.isFoldable(typescript_mocks_1.findVar(expressions, 'three').initializer)).toBeTruthy();
expect(evaluator.isFoldable(typescript_mocks_1.findVar(expressions, 'four').initializer)).toBeTruthy();
symbols.define('three', 3);
symbols.define('four', 4);
expect(evaluator.isFoldable(typescript_mocks_1.findVar(expressions, 'obj').initializer)).toBeTruthy();

@@ -55,4 +68,10 @@ expect(evaluator.isFoldable(typescript_mocks_1.findVar(expressions, 'arr').initializer)).toBeTruthy();

var expressions = program.getSourceFile('expressions.ts');
symbols.define('someName', 'some-name');
symbols.define('someBool', true);
symbols.define('one', 1);
symbols.define('two', 2);
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'three').initializer)).toBe(3);
symbols.define('three', 3);
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'four').initializer)).toBe(4);
symbols.define('four', 4);
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'obj').initializer))

@@ -73,9 +92,9 @@ .toEqual({ one: 1, two: 2, three: 3, four: 4 });

expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'bEqual').initializer))
.toEqual(1 == "1");
.toEqual(1 == '1');
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'bNotEqual').initializer))
.toEqual(1 != "1");
.toEqual(1 != '1');
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'bIdentical').initializer))
.toEqual(1 === "1");
.toEqual(1 === '1');
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'bNotIdentical').initializer))
.toEqual(1 !== "1");
.toEqual(1 !== '1');
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'bLessThan').initializer)).toEqual(1 < 2);

@@ -96,5 +115,5 @@ expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'bGreaterThan').initializer)).toEqual(1 > 2);

expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'recursiveA').initializer))
.toEqual({ __symbolic: "reference", name: "recursiveB", module: undefined });
.toEqual({ __symbolic: 'reference', name: 'recursiveB' });
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(expressions, 'recursiveB').initializer))
.toEqual({ __symbolic: "reference", name: "recursiveA", module: undefined });
.toEqual({ __symbolic: 'reference', name: 'recursiveA' });
});

@@ -112,18 +131,65 @@ it('should correctly handle special cases for CONST_EXPR', function () {

it('should return new expressions', function () {
evaluator =
new evaluator_1.Evaluator(typeChecker, symbols, [{ from: './classes', namedImports: [{ name: 'Value' }] }]);
symbols.define('Value', { __symbolic: 'reference', module: './classes', name: 'Value' });
evaluator = new evaluator_1.Evaluator(symbols);
var newExpression = program.getSourceFile('newExpression.ts');
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(newExpression, 'someValue').initializer))
.toEqual({
__symbolic: "new",
expression: { __symbolic: "reference", name: "Value", module: "./classes" },
arguments: ["name", 12]
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(newExpression, 'someValue').initializer)).toEqual({
__symbolic: 'new',
expression: { __symbolic: 'reference', name: 'Value', module: './classes' },
arguments: ['name', 12]
});
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(newExpression, 'complex').initializer))
.toEqual({
__symbolic: "new",
expression: { __symbolic: "reference", name: "Value", module: "./classes" },
arguments: ["name", 12]
expect(evaluator.evaluateNode(typescript_mocks_1.findVar(newExpression, 'complex').initializer)).toEqual({
__symbolic: 'new',
expression: { __symbolic: 'reference', name: 'Value', module: './classes' },
arguments: ['name', 12]
});
});
it('should return errors for unsupported expressions', function () {
var errors = program.getSourceFile('errors.ts');
var aDecl = typescript_mocks_1.findVar(errors, 'a');
expect(evaluator.evaluateNode(aDecl.type)).toEqual({
__symbolic: 'error',
message: 'Qualified type names not supported',
line: 5,
character: 10
});
var fDecl = typescript_mocks_1.findVar(errors, 'f');
expect(evaluator.evaluateNode(fDecl.initializer))
.toEqual({ __symbolic: 'error', message: 'Function call not supported', line: 6, character: 11 });
var eDecl = typescript_mocks_1.findVar(errors, 'e');
expect(evaluator.evaluateNode(eDecl.type)).toEqual({
__symbolic: 'error',
message: 'Could not resolve type',
line: 7,
character: 10,
context: { typeName: 'NotFound' }
});
var sDecl = typescript_mocks_1.findVar(errors, 's');
expect(evaluator.evaluateNode(sDecl.initializer)).toEqual({
__symbolic: 'error',
message: 'Name expected',
line: 8,
character: 13,
context: { received: '1' }
});
var tDecl = typescript_mocks_1.findVar(errors, 't');
expect(evaluator.evaluateNode(tDecl.initializer)).toEqual({
__symbolic: 'error',
message: 'Expression form not supported',
line: 9,
character: 11
});
});
it('should be able to fold an array spread', function () {
var expressions = program.getSourceFile('expressions.ts');
symbols.define('arr', [1, 2, 3, 4]);
var arrSpread = typescript_mocks_1.findVar(expressions, 'arrSpread');
expect(evaluator.evaluateNode(arrSpread.initializer)).toEqual([0, 1, 2, 3, 4, 5]);
});
it('should be able to produce a spread expression', function () {
var expressions = program.getSourceFile('expressions.ts');
var arrSpreadRef = typescript_mocks_1.findVar(expressions, 'arrSpreadRef');
expect(evaluator.evaluateNode(arrSpreadRef.initializer)).toEqual([
0, { __symbolic: 'spread', expression: { __symbolic: 'reference', name: 'arrImport' } }, 5
]);
});
});

@@ -133,4 +199,4 @@ var FILES = {

'classes.ts': "\n export class Value {\n constructor(public name: string, public value: any) {}\n }\n ",
'consts.ts': "\n export var someName = 'some-name';\n export var someBool = true;\n export var one = 1;\n export var two = 2;\n ",
'expressions.ts': "\n import {someName, someBool, one, two} from './consts';\n\n export var three = one + two;\n export var four = two * two;\n export var obj = { one: one, two: two, three: three, four: four };\n export var arr = [one, two, three, four];\n export var bTrue = someBool;\n export var bFalse = !someBool;\n export var bAnd = someBool && someBool;\n export var bOr = someBool || someBool;\n export var nDiv = four / two;\n export var nMod = (four + one) % two;\n\n export var bLOr = false || true; // true\n export var bLAnd = true && true; // true\n export var bBOr = 0x11 | 0x22; // 0x33\n export var bBAnd = 0x11 & 0x03; // 0x01\n export var bXor = 0x11 ^ 0x21; // 0x20\n export var bEqual = 1 == <any>\"1\"; // true\n export var bNotEqual = 1 != <any>\"1\"; // false\n export var bIdentical = 1 === <any>\"1\"; // false\n export var bNotIdentical = 1 !== <any>\"1\"; // true\n export var bLessThan = 1 < 2; // true\n export var bGreaterThan = 1 > 2; // false\n export var bLessThanEqual = 1 <= 2; // true\n export var bGreaterThanEqual = 1 >= 2; // false\n export var bShiftLeft = 1 << 2; // 0x04\n export var bShiftRight = -1 >> 2; // -1\n export var bShiftRightU = -1 >>> 2; // 0x3fffffff\n \n export var recursiveA = recursiveB;\n export var recursiveB = recursiveA;\n ",
'consts.ts': "\n export var someName = 'some-name';\n export var someBool = true;\n export var one = 1;\n export var two = 2;\n export var arrImport = [1, 2, 3, 4];\n ",
'expressions.ts': "\n import {arrImport} from './consts';\n\n export var someName = 'some-name';\n export var someBool = true;\n export var one = 1;\n export var two = 2;\n\n export var three = one + two;\n export var four = two * two;\n export var obj = { one: one, two: two, three: three, four: four };\n export var arr = [one, two, three, four];\n export var bTrue = someBool;\n export var bFalse = !someBool;\n export var bAnd = someBool && someBool;\n export var bOr = someBool || someBool;\n export var nDiv = four / two;\n export var nMod = (four + one) % two;\n\n export var bLOr = false || true; // true\n export var bLAnd = true && true; // true\n export var bBOr = 0x11 | 0x22; // 0x33\n export var bBAnd = 0x11 & 0x03; // 0x01\n export var bXor = 0x11 ^ 0x21; // 0x20\n export var bEqual = 1 == <any>\"1\"; // true\n export var bNotEqual = 1 != <any>\"1\"; // false\n export var bIdentical = 1 === <any>\"1\"; // false\n export var bNotIdentical = 1 !== <any>\"1\"; // true\n export var bLessThan = 1 < 2; // true\n export var bGreaterThan = 1 > 2; // false\n export var bLessThanEqual = 1 <= 2; // true\n export var bGreaterThanEqual = 1 >= 2; // false\n export var bShiftLeft = 1 << 2; // 0x04\n export var bShiftRight = -1 >> 2; // -1\n export var bShiftRightU = -1 >>> 2; // 0x3fffffff\n\n export var arrSpread = [0, ...arr, 5];\n\n export var arrSpreadRef = [0, ...arrImport, 5];\n\n export var recursiveA = recursiveB;\n export var recursiveB = recursiveA;\n ",
'A.ts': "\n import {Pipe} from './directives';\n\n @Pipe({name: 'A', pure: false})\n export class A {}",

@@ -140,4 +206,5 @@ 'B.ts': "\n import {Pipe} from './directives';\n import {someName, someBool} from './consts';\n\n @Pipe({name: someName, pure: someBool})\n export class B {}",

'forwardRef.ts': "\n function forwardRef(value: any) { return value; }\n export var bTrue = forwardRef(() => true);\n export var bFalse = forwardRef(() => false);\n ",
'newExpression.ts': "\n import {Value} from './classes';\n function CONST_EXPR(value: any) { return value; }\n function forwardRef(value: any) { return value; }\n export const someValue = new Value(\"name\", 12);\n export const complex = CONST_EXPR(new Value(\"name\", forwardRef(() => 12)));\n "
'newExpression.ts': "\n import {Value} from './classes';\n function CONST_EXPR(value: any) { return value; }\n function forwardRef(value: any) { return value; }\n export const someValue = new Value(\"name\", 12);\n export const complex = CONST_EXPR(new Value(\"name\", forwardRef(() => 12)));\n ",
'errors.ts': "\n declare namespace Foo {\n type A = string;\n }\n\n let a: Foo.A = 'some value';\n let f = () => 1;\n let e: NotFound;\n let s = { 1: 1, 2: 2 };\n let t = typeof 12;\n ",
};
//# sourceMappingURL=evaluator.spec.js.map
"use strict";
var ts = require('typescript');
var schema_1 = require('../src/schema');
var symbols_1 = require('../src/symbols');

@@ -7,15 +9,85 @@ var typescript_mocks_1 = require('./typescript.mocks');

var someValue = 'some-value';
var someSymbol = typescript_mocks_1.MockSymbol.of('some-symbol');
var aliasSymbol = new typescript_mocks_1.MockSymbol('some-symbol', someSymbol.getDeclarations()[0]);
var missingSymbol = typescript_mocks_1.MockSymbol.of('some-other-symbol');
beforeEach(function () { return symbols = new symbols_1.Symbols(); });
it('should be able to add a symbol', function () { return symbols.set(someSymbol, someValue); });
beforeEach(function () { return symbols.set(someSymbol, someValue); });
it('should be able to `has` a symbol', function () { return expect(symbols.has(someSymbol)).toBeTruthy(); });
it('should be able to `get` a symbol value', function () { return expect(symbols.get(someSymbol)).toBe(someValue); });
it('should be able to `has` an alias symbol', function () { return expect(symbols.has(aliasSymbol)).toBeTruthy(); });
it('should be able to `get` a symbol value', function () { return expect(symbols.get(aliasSymbol)).toBe(someValue); });
it('should be able to determine symbol is missing', function () { return expect(symbols.has(missingSymbol)).toBeFalsy(); });
it('should return undefined from `get` for a missing symbol', function () { return expect(symbols.get(missingSymbol)).toBeUndefined(); });
beforeEach(function () { return symbols = new symbols_1.Symbols(null); });
it('should be able to add a symbol', function () { return symbols.define('someSymbol', someValue); });
beforeEach(function () { return symbols.define('someSymbol', someValue); });
it('should be able to `has` a symbol', function () { return expect(symbols.has('someSymbol')).toBeTruthy(); });
it('should be able to `get` a symbol value', function () { return expect(symbols.resolve('someSymbol')).toBe(someValue); });
it('should be able to `get` a symbol value', function () { return expect(symbols.resolve('someSymbol')).toBe(someValue); });
it('should be able to determine symbol is missing', function () { return expect(symbols.has('missingSymbol')).toBeFalsy(); });
it('should return undefined from `get` for a missing symbol', function () { return expect(symbols.resolve('missingSymbol')).toBeUndefined(); });
var host;
var service;
var program;
var expressions;
var imports;
beforeEach(function () {
host = new typescript_mocks_1.Host(FILES, ['consts.ts', 'expressions.ts', 'imports.ts']);
service = ts.createLanguageService(host);
program = service.getProgram();
expressions = program.getSourceFile('expressions.ts');
imports = program.getSourceFile('imports.ts');
});
it('should not have syntax errors in the test sources', function () {
typescript_mocks_1.expectNoDiagnostics(service.getCompilerOptionsDiagnostics());
for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) {
var sourceFile = _a[_i];
typescript_mocks_1.expectNoDiagnostics(service.getSyntacticDiagnostics(sourceFile.fileName));
}
});
it('should be able to find the source files', function () {
expect(expressions).toBeDefined();
expect(imports).toBeDefined();
});
it('should be able to create symbols for a source file', function () {
var symbols = new symbols_1.Symbols(expressions);
expect(symbols).toBeDefined();
});
it('should be able to find symbols in expression', function () {
var symbols = new symbols_1.Symbols(expressions);
expect(symbols.has('someName')).toBeTruthy();
expect(symbols.resolve('someName'))
.toEqual({ __symbolic: 'reference', module: './consts', name: 'someName' });
expect(symbols.has('someBool')).toBeTruthy();
expect(symbols.resolve('someBool'))
.toEqual({ __symbolic: 'reference', module: './consts', name: 'someBool' });
});
it('should be able to detect a * import', function () {
var symbols = new symbols_1.Symbols(imports);
expect(symbols.resolve('b')).toEqual({ __symbolic: 'reference', module: 'b' });
});
it('should be able to detect importing a default export', function () {
var symbols = new symbols_1.Symbols(imports);
expect(symbols.resolve('d')).toEqual({ __symbolic: 'reference', module: 'd', default: true });
});
it('should be able to import a renamed symbol', function () {
var symbols = new symbols_1.Symbols(imports);
expect(symbols.resolve('g')).toEqual({ __symbolic: 'reference', name: 'f', module: 'f' });
});
it('should be able to resolve any symbol in core global scope', function () {
var core = program.getSourceFiles().find(function (source) { return source.fileName.endsWith('lib.d.ts'); });
expect(core).toBeDefined();
var visit = function (node) {
switch (node.kind) {
case ts.SyntaxKind.VariableStatement:
case ts.SyntaxKind.VariableDeclarationList:
return ts.forEachChild(node, visit);
case ts.SyntaxKind.VariableDeclaration:
var variableDeclaration = node;
var nameNode = variableDeclaration.name;
var name_1 = nameNode.text;
var result = symbols.resolve(name_1);
expect(schema_1.isMetadataGlobalReferenceExpression(result) && result.name).toEqual(name_1);
// Ignore everything after Float64Array as it is IE specific.
return name_1 === 'Float64Array';
}
return false;
};
ts.forEachChild(core, visit);
});
});
var FILES = {
'consts.ts': "\n export var someName = 'some-name';\n export var someBool = true;\n export var one = 1;\n export var two = 2;\n ",
'expressions.ts': "\n import {someName, someBool, one, two} from './consts';\n ",
'imports.ts': "\n import * as b from 'b';\n import 'c';\n import d from 'd';\n import {f as g} from 'f';\n "
};
//# sourceMappingURL=symbols.spec.js.map

@@ -7,4 +7,4 @@ "use strict";

};
var fs = require('fs');
var path = require('path');
var fs = require('fs');
var ts = require('typescript');

@@ -24,3 +24,3 @@ var Host = (function () {

Host.prototype.getScriptFileNames = function () { return this.scripts; };
Host.prototype.getScriptVersion = function (fileName) { return "1"; };
Host.prototype.getScriptVersion = function (fileName) { return '1'; };
Host.prototype.getScriptSnapshot = function (fileName) {

@@ -130,3 +130,3 @@ var content = this.getFileContent(fileName);

var diagnostic = diagnostics_1[_i];
var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
var message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
var _a = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start), line = _a.line, character = _a.character;

@@ -133,0 +133,0 @@ console.log(diagnostic.file.fileName + " (" + (line + 1) + "," + (character + 1) + "): " + message);

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc