Merge pull request #7675 from Microsoft/transforms-fixTypeErrors

Transforms fix type errors
This commit is contained in:
Ron Buckton
2016-03-24 16:26:06 -07:00
24 changed files with 583 additions and 196 deletions

1
.gitignore vendored
View File

@@ -13,6 +13,7 @@ tests/baselines/rwc/*
tests/baselines/test262/*
tests/baselines/reference/projectOutput/*
tests/baselines/local/projectOutput/*
tests/baselines/reference/testresults.tap
tests/services/baselines/prototyping/local/*
tests/services/browser/typescriptServices.js
scripts/configureNightly.js

View File

@@ -5,6 +5,7 @@ var os = require("os");
var path = require("path");
var child_process = require("child_process");
var Linter = require("tslint");
var readline = require("readline");
// Variables
var compilerDirectory = "src/compiler/";
@@ -673,9 +674,14 @@ function cleanTestDirs() {
}
// used to pass data from jake command line directly to run.js
function writeTestConfigFile(tests, light, testConfigFile) {
function writeTestConfigFile(testConfigFile, tests, light, stackTraceLimit) {
console.log('Running test(s): ' + tests);
var testConfigContents = JSON.stringify({ test: [tests], light: light });
var testConfig = { test: [tests], light: light };
if (/^(\d+|full)$/.test(stackTraceLimit)) {
testConfig.stackTraceLimit = stackTraceLimit;
}
var testConfigContents = JSON.stringify(testConfig);
fs.writeFileSync('test.config', testConfigContents);
}
@@ -685,6 +691,124 @@ function deleteTemporaryProjectOutput() {
}
}
function runTestsAndWriteOutput(file) {
cleanTestDirs();
var tests = process.env.test || process.env.tests || process.env.t;
var light = process.env.light || false;
var testConfigFile = 'test.config';
if (fs.existsSync(testConfigFile)) {
fs.unlinkSync(testConfigFile);
}
if (tests || light) {
writeTestConfigFile(testConfigFile, tests, light, 10);
}
if (tests && tests.toLocaleLowerCase() === "rwc") {
testTimeout = 100000;
}
var args = [];
args.push("-R", "TAP");
args.push("--no-colors");
args.push("-t", testTimeout);
if (tests) {
args.push("-g", '"' + tests + '"');
}
args.push(run);
var cmd = "mocha " + args.join(" ");
console.log(cmd);
var ex = jake.createExec([cmd], { windowsVerbatimArguments: true });
var out = fs.createWriteStream(file);
var tapRange = /^(\d+)\.\.(\d+)(?:$|\r\n?|\n)/;
var tapOk = /^ok\s/;
var tapNotOk = /^not\sok/;
var tapComment = /^#/;
var typeError = /^\s+TypeError:/;
var progress = new ProgressBar("Running tests...");
var expectedTestCount = 0;
var testCount = 0;
var failureCount = 0;
var successCount = 0;
var comments = [];
var typeErrorCount = 0;
ex.addListener("stdout", function (output) {
var m = tapRange.exec(output);
if (m) {
expectedTestCount = parseInt(m[2]);
return;
}
out.write(output);
if (tapOk.test(output)) {
successCount++;
}
else if (tapNotOk.test(output)) {
failureCount++;
}
else {
if (tapComment.test(output)) {
comments.push(output.toString().trim());
}
else if (typeError.test(output)) {
typeErrorCount++;
}
return;
}
testCount++;
var percentComplete = testCount * 100 / expectedTestCount;
updateProgress(percentComplete);
});
function updateProgress(percentComplete) {
progress.update(percentComplete,
/*foregroundColor*/ failureCount > 0
? "red"
: successCount === expectedTestCount
? "green"
: "cyan",
/*backgroundColor*/ "gray"
);
}
ex.addListener("stderr", function (output) {
progress.hide();
process.stderr.write(output.toString().trim() + os.EOL);
progress.show();
});
ex.addListener("cmdEnd", function () {
if (progress.visible) {
updateProgress(100);
process.stdout.write("done." + os.EOL);
}
console.log(comments.join(os.EOL));
deleteTemporaryProjectOutput();
complete();
});
ex.addListener("error", function (e, status) {
if (progress.visible) {
updateProgress(100);
process.stdout.write("done." + os.EOL);
}
console.log(comments.join(os.EOL));
if (typeErrorCount) {
console.log("# type errors: %s", typeErrorCount);
}
deleteTemporaryProjectOutput();
fail("Process exited with code " + status);
});
ex.run();
}
function runConsoleTests(defaultReporter, defaultSubsets) {
cleanTestDirs();
var debug = process.env.debug || process.env.d;
@@ -696,7 +820,7 @@ function runConsoleTests(defaultReporter, defaultSubsets) {
}
if (tests || light) {
writeTestConfigFile(tests, light, testConfigFile);
writeTestConfigFile(testConfigFile, tests, light);
}
if (tests && tests.toLocaleLowerCase() === "rwc") {
@@ -749,6 +873,10 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() {
runConsoleTests('mocha-fivemat-progress-reporter', []);
}, {async: true});
task("runtests-file", ["build-rules", "tests", builtLocalDirectory], function () {
runTestsAndWriteOutput("tests/baselines/local/testresults.tap");
}, { async: true });
desc("Generates code coverage data via instanbul");
task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run;
@@ -780,7 +908,7 @@ task("runtests-browser", ["tests", "browserify", builtLocalDirectory, servicesFi
fs.unlinkSync(testConfigFile);
}
if(tests || light) {
writeTestConfigFile(tests, light, testConfigFile);
writeTestConfigFile(testConfigFile, tests, light);
}
tests = tests ? tests : '';
@@ -1031,3 +1159,85 @@ task("lint-server", ["build-rules"], function() {
lintWatchFile(lintTargets[i]);
}
});
function ProgressBar(title) {
this.title = title;
}
ProgressBar.prototype = {
progressChars: ["\u0020", "\u2591", "\u2592", "\u2593", "\u2588"],
colors: {
foreground: {
black: "\u001b[90m",
red: "\u001b[91m",
green: "\u001b[92m",
yellow: "\u001b[93m",
blue: "\u001b[94m",
magenta: "\u001b[95m",
cyan: "\u001b[96m",
white: "\u001b[97m",
gray: "\u001b[37m"
},
background: {
black: "\u001b[40m",
red: "\u001b[41m",
green: "\u001b[42m",
yellow: "\u001b[43m",
blue: "\u001b[44m",
magenta: "\u001b[45m",
cyan: "\u001b[46m",
white: "\u001b[47m",
gray: "\u001b[100m"
},
reset: "\u001b[0m"
},
update: function (percentComplete, foregroundColor, backgroundColor) {
var progress = "";
for (var i = 0; i < 100; i += 4) {
progress += this.progressChars[Math.floor(Math.max(0, Math.min(4, percentComplete - i)))];
}
foregroundColor = foregroundColor && this.colors.foreground[foregroundColor];
backgroundColor = backgroundColor && this.colors.background[backgroundColor];
if (foregroundColor || backgroundColor) {
if (foregroundColor) {
progress = foregroundColor + progress;
}
if (backgroundColor) {
progress = backgroundColor + progress;
}
progress += this.colors.reset;
}
if (this._lastProgress !== progress || !this.visible) {
this._print(progress);
}
},
hide: function () {
if (this.visible) {
this._savedProgress = this._lastProgress;
this.clear();
}
},
show: function () {
if (this._savedProgress && !this.visible) {
this._print(this._savedProgress);
this._savedProgress = undefined;
}
},
clear: function () {
if (this._lastProgress) {
readline.moveCursor(process.stdout, -process.stdout.columns, 0);
readline.clearLine(process.stdout, 1);
this._lastProgress = undefined;
this.visible = false;
}
},
_print: function (progress) {
readline.moveCursor(process.stdout, -process.stdout.columns, 0);
process.stdout.write(this.title ? progress + " " + this.title : progress);
readline.clearLine(process.stdout, 1);
this._lastProgress = progress;
this.visible = true;
}
};

View File

@@ -1079,12 +1079,10 @@ namespace ts {
declare var process: any;
declare var require: any;
const currentAssertionLevel = getDevelopmentMode() === "development"
? AssertionLevel.Normal
: AssertionLevel.None;
let currentAssertionLevel: AssertionLevel;
export function shouldAssert(level: AssertionLevel): boolean {
return currentAssertionLevel >= level;
return getCurrentAssertionLevel() >= level;
}
export function assert(expression: boolean, message?: string, verboseDebugInfo?: () => string): void {
@@ -1102,15 +1100,21 @@ namespace ts {
Debug.assert(/*expression*/ false, message);
}
function getDevelopmentMode() {
return typeof require !== "undefined"
&& typeof process !== "undefined"
&& !process.browser
&& process.nextTick
&& process.env
&& process.env.NODE_ENV
? String(process.env.NODE_ENV).toLowerCase()
: undefined;
function getCurrentAssertionLevel() {
if (currentAssertionLevel !== undefined) {
return currentAssertionLevel;
}
const developmentMode = sys && /^development$/i.test(sys.getEnvironmentVariable("NODE_ENV"));
if (developmentMode === undefined) {
return AssertionLevel.None;
}
currentAssertionLevel = developmentMode
? AssertionLevel.Normal
: AssertionLevel.None;
return currentAssertionLevel;
}
}

View File

@@ -114,10 +114,11 @@ namespace ts {
// Literals
export function createLiteral(textSource: StringLiteral | Identifier, location?: TextRange): StringLiteral;
export function createLiteral(value: string, location?: TextRange): StringLiteral;
export function createLiteral(value: number, location?: TextRange): LiteralExpression;
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression {
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
if (typeof value === "number") {
const node = <LiteralExpression>createNode(SyntaxKind.NumericLiteral, location);
node.text = value.toString();
@@ -126,9 +127,15 @@ namespace ts {
else if (typeof value === "boolean") {
return <PrimaryExpression>createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location);
}
else if (typeof value === "string") {
const node = <StringLiteral>createNode(SyntaxKind.StringLiteral, location);
node.text = value;
return node;
}
else {
const node = <StringLiteral>createNode(SyntaxKind.StringLiteral, location);
node.text = String(value);
node.textSourceNode = value;
node.text = value.text;
return node;
}
}
@@ -138,6 +145,7 @@ namespace ts {
export function createIdentifier(text: string, location?: TextRange): Identifier {
const node = <Identifier>createNode(SyntaxKind.Identifier, location);
node.text = escapeIdentifier(text);
node.originalKeywordKind = stringToToken(text);
return node;
}
@@ -423,11 +431,11 @@ namespace ts {
return block;
}
export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList, location?: TextRange): VariableStatement {
export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[], location?: TextRange): VariableStatement {
const node = <VariableStatement>createNode(SyntaxKind.VariableStatement, location);
node.decorators = undefined;
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
node.declarationList = declarationList;
node.declarationList = isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList;
return node;
}

View File

@@ -668,7 +668,7 @@ const _super = (function (geti, seti) {
// SyntaxKind.TemplateMiddle
// SyntaxKind.TemplateTail
function emitLiteral(node: LiteralLikeNode) {
const text = getLiteralText(node, currentSourceFile, languageVersion);
const text = getLiteralTextOfNode(node);
if ((compilerOptions.sourceMap || compilerOptions.inlineSourceMap)
&& (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) {
writer.writeLiteral(text);
@@ -980,7 +980,7 @@ const _super = (function (geti, seti) {
function needsDotDotForPropertyAccess(expression: Expression) {
if (expression.kind === SyntaxKind.NumericLiteral) {
// check if numeric literal was originally written with a dot
const text = getLiteralText(<LiteralExpression>expression, currentSourceFile, languageVersion);
const text = getLiteralTextOfNode(<LiteralExpression>expression);
return text.indexOf(tokenToString(SyntaxKind.DotToken)) < 0;
}
else {
@@ -2343,14 +2343,15 @@ const _super = (function (geti, seti) {
return node;
}
function getTextOfNode(node: Node, includeTrivia?: boolean) {
if (isIdentifier(node)) {
if (node.autoGenerateKind) {
return getGeneratedIdentifier(node);
}
else if (nodeIsSynthesized(node) || !node.parent) {
return unescapeIdentifier(node.text);
}
function getTextOfNode(node: Node, includeTrivia?: boolean): string {
if (isGeneratedIdentifier(node)) {
return getGeneratedIdentifier(node);
}
else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) {
return unescapeIdentifier(node.text);
}
else if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
return getTextOfNode((<StringLiteral>node).textSourceNode, includeTrivia);
}
else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) {
return node.text;
@@ -2359,6 +2360,20 @@ const _super = (function (geti, seti) {
return getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
}
function getLiteralTextOfNode(node: LiteralLikeNode): string {
if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
const textSourceNode = (<StringLiteral>node).textSourceNode;
if (isIdentifier(textSourceNode)) {
return "\"" + escapeNonAsciiCharacters(escapeString(getTextOfNode(textSourceNode))) + "\"";
}
else {
return getLiteralTextOfNode(textSourceNode);
}
}
return getLiteralText(node, currentSourceFile, languageVersion);
}
function tryGetConstEnumValue(node: Node): number {
if (compilerOptions.isolatedModules) {
return undefined;
@@ -2452,7 +2467,7 @@ const _super = (function (geti, seti) {
}
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
const name = node.name.text;
const name = getTextOfNode(node.name);
// Use module/enum name itself if it is unique, otherwise make a unique variation
return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
}
@@ -2472,10 +2487,10 @@ const _super = (function (geti, seti) {
return makeUniqueName("class");
}
function generateNameForNode(node: Node) {
function generateNameForNode(node: Node): string {
switch (node.kind) {
case SyntaxKind.Identifier:
return makeUniqueName((<Identifier>node).text);
return makeUniqueName(getTextOfNode(node));
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.EnumDeclaration:
return generateNameForModuleOrEnum(<ModuleDeclaration | EnumDeclaration>node);
@@ -2502,14 +2517,37 @@ const _super = (function (geti, seti) {
case GeneratedIdentifierKind.Unique:
return makeUniqueName(node.text);
case GeneratedIdentifierKind.Node:
return generateNameForNode(getOriginalNode(node));
return generateNameForNode(getSourceNodeForGeneratedName(node));
}
}
function getGeneratedIdentifier(node: Identifier) {
const id = getOriginalNodeId(node);
const id = getNodeIdForGeneratedIdentifier(node);
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateIdentifier(node)));
}
function getSourceNodeForGeneratedName(name: Identifier) {
let node: Node = name;
while (node.original !== undefined) {
node = node.original;
if (isIdentifier(node) && node.autoGenerateKind === GeneratedIdentifierKind.Node) {
break;
}
}
return node;
}
function getNodeIdForGeneratedIdentifier(node: Identifier) {
switch (node.autoGenerateKind) {
case GeneratedIdentifierKind.Auto:
case GeneratedIdentifierKind.Loop:
case GeneratedIdentifierKind.Unique:
return getNodeId(node);
case GeneratedIdentifierKind.Node:
return getNodeId(getSourceNodeForGeneratedName(node));
}
}
}
function createDelimiterMap() {

View File

@@ -365,20 +365,18 @@ namespace ts {
ensureIdentifier(propertyName.expression, /*reuseIdentifierExpressions*/ false, /*location*/ propertyName, emitTempVariableAssignment)
);
}
else if (isIdentifier(propertyName)) {
return createPropertyAccess(
expression,
propertyName.text
);
}
else {
// We create a synthetic copy of the identifier in order to avoid the rewriting that might
// otherwise occur when the identifier is emitted.
else if (isLiteralExpression(propertyName)) {
return createElementAccess(
expression,
getSynthesizedClone(propertyName)
);
}
else {
return createPropertyAccess(
expression,
isGeneratedIdentifier(propertyName) ? getSynthesizedClone(propertyName) : createIdentifier(propertyName.text)
);
}
}
}

View File

@@ -280,7 +280,7 @@ namespace ts {
if (moduleKind !== ModuleKind.AMD) {
if (!node.importClause) {
// import "mod";
addNode(statements,
statements.push(
createStatement(
createRequireCall(node),
/*location*/ node
@@ -291,7 +291,7 @@ namespace ts {
const variables: VariableDeclaration[] = [];
if (namespaceDeclaration && !isDefaultImport(node)) {
// import * as n from "mod";
addNode(variables,
variables.push(
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
createRequireCall(node)
@@ -303,7 +303,7 @@ namespace ts {
// import { x, y } from "mod";
// import d, { x, y } from "mod";
// import d, * as n from "mod";
addNode(variables,
variables.push(
createVariableDeclaration(
getGeneratedNameForNode(node),
createRequireCall(node)
@@ -311,7 +311,7 @@ namespace ts {
);
if (namespaceDeclaration && isDefaultImport(node)) {
addNode(variables,
variables.push(
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
getGeneratedNameForNode(node)
@@ -320,7 +320,7 @@ namespace ts {
}
}
addNode(statements,
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList(variables),
@@ -331,7 +331,7 @@ namespace ts {
}
else if (namespaceDeclaration && isDefaultImport(node)) {
// import d, * as n from "mod";
addNode(statements,
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
@@ -346,7 +346,7 @@ namespace ts {
}
addExportImportAssignments(statements, node);
return statements;
return singleOrMany(statements);
}
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
@@ -409,7 +409,7 @@ namespace ts {
const statements: Statement[] = [];
// export { x, y } from "mod";
if (moduleKind !== ModuleKind.AMD) {
addNode(statements,
statements.push(
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
@@ -428,7 +428,7 @@ namespace ts {
generatedName,
specifier.propertyName || specifier.name
);
addNode(statements,
statements.push(
createStatement(
createExportAssignment(specifier.name, exportedValue),
/*location*/ specifier
@@ -437,7 +437,7 @@ namespace ts {
}
}
return statements;
return singleOrMany(statements);
}
else {
// export * from "mod";
@@ -456,18 +456,22 @@ namespace ts {
}
function visitExportAssignment(node: ExportAssignment): VisitResult<Statement> {
if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
const statements: Statement[] = [];
addExportDefault(statements, node.expression, /*location*/ node);
return statements;
if (!node.isExportEquals) {
const original = getOriginalNode(node);
if (nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original)) {
const statements: Statement[] = [];
addExportDefault(statements, node.expression, /*location*/ node);
return statements;
}
}
return undefined;
}
function addExportDefault(statements: Statement[], expression: Expression, location: TextRange): void {
addNode(statements, tryCreateExportDefaultCompat());
addNode(statements,
tryAddExportDefaultCompat(statements);
statements.push(
createStatement(
createExportAssignment(
createIdentifier("default"),
@@ -478,25 +482,29 @@ namespace ts {
);
}
function tryCreateExportDefaultCompat(): Statement {
function tryAddExportDefaultCompat(statements: Statement[]) {
const original = getOriginalNode(currentSourceFile);
Debug.assert(original.kind === SyntaxKind.SourceFile);
if (!(<SourceFile>original).symbol.exports["___esModule"]) {
if (!original.symbol.exports["___esModule"]) {
if (languageVersion === ScriptTarget.ES3) {
return createStatement(
createExportAssignment(
createIdentifier("__esModule"),
createLiteral(true)
statements.push(
createStatement(
createExportAssignment(
createIdentifier("__esModule"),
createLiteral(true)
)
)
);
}
else {
return createStatement(
createObjectDefineProperty(
createIdentifier("exports"),
createLiteral("__esModule"),
{ value: createLiteral(true) }
statements.push(
createStatement(
createObjectDefineProperty(
createIdentifier("exports"),
createLiteral("__esModule"),
{ value: createLiteral(true) }
)
)
);
}
@@ -653,13 +661,48 @@ namespace ts {
}
function substituteExpressionIdentifier(node: Identifier): Expression {
const container = resolver.getReferencedExportContainer(node);
if (container && container.kind === SyntaxKind.SourceFile) {
return createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(node),
/*location*/ node
);
const original = getOriginalNode(node);
if (isIdentifier(original)) {
const container = resolver.getReferencedExportContainer(original);
if (container) {
if (container.kind === SyntaxKind.SourceFile) {
return createPropertyAccess(
createIdentifier("exports"),
getSynthesizedClone(node),
/*location*/ node
);
}
}
else {
const declaration = resolver.getReferencedImportDeclaration(original);
if (declaration) {
if (declaration.kind === SyntaxKind.ImportClause) {
if (languageVersion >= ScriptTarget.ES5) {
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent),
createIdentifier("default"),
/*location*/ node
);
}
else {
return createElementAccess(
getGeneratedNameForNode(declaration.parent),
createLiteral("default"),
/*location*/ node
);
}
}
else if (declaration.kind === SyntaxKind.ImportSpecifier) {
const name = (<ImportSpecifier>declaration).propertyName
|| (<ImportSpecifier>declaration).name;
return createPropertyAccess(
getGeneratedNameForNode(declaration.parent.parent.parent),
getSynthesizedClone(name),
/*location*/ node
);
}
}
}
}
return node;
@@ -677,7 +720,7 @@ namespace ts {
const moduleName = getExternalModuleName(importNode);
if (moduleName.kind === SyntaxKind.StringLiteral) {
return tryRenameExternalModule(<StringLiteral>moduleName)
|| getSynthesizedClone(<StringLiteral>moduleName);
|| createLiteral(<StringLiteral>moduleName);
}
return undefined;

View File

@@ -5,7 +5,7 @@
namespace ts {
export function transformSystemModule(context: TransformationContext) {
interface DependencyGroup {
name: Identifier;
name: StringLiteral;
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[];
}
@@ -26,7 +26,7 @@ namespace ts {
context.enableExpressionSubstitution(SyntaxKind.PrefixUnaryExpression);
context.enableExpressionSubstitution(SyntaxKind.PostfixUnaryExpression);
context.expressionSubstitution = substituteExpression;
context.enableEmitNotification(SyntaxKind.SourceFile);
const exportFunctionForFileMap: Identifier[] = [];
@@ -45,12 +45,6 @@ namespace ts {
return transformSourceFile;
function onEmitNode(node: Node, emit: (node: Node) => void): void {
exportFunctionForFile = exportFunctionForFileMap[getNodeId(node)];
previousOnEmitNode(node, emit);
exportFunctionForFile = undefined;
}
function transformSourceFile(node: SourceFile) {
if (isExternalModule(node) || compilerOptions.isolatedModules) {
currentSourceFile = node;
@@ -125,7 +119,7 @@ namespace ts {
createStatement(
createCall(
createPropertyAccess(createIdentifier("System"), "register"),
node.moduleName
node.moduleName
? [createLiteral(node.moduleName), dependencies, body]
: [dependencies, body]
)
@@ -339,7 +333,8 @@ namespace ts {
const setters: Expression[] = [];
for (const group of dependencyGroups) {
// derive a unique name for parameter from the first named entry in the group
const parameterName = createUniqueName(forEach(group.externalImports, getLocalNameTextForExternalImport) || "");
const localName = forEach(group.externalImports, getLocalNameForExternalImport);
const parameterName = localName ? getGeneratedNameForNode(localName) : createUniqueName("");
const statements: Statement[] = [];
for (const entry of group.externalImports) {
const importVariableName = getLocalNameForExternalImport(entry);
@@ -547,11 +542,14 @@ namespace ts {
}
function visitExportAssignment(node: ExportAssignment): Statement {
if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
return createExportStatement(
createLiteral("default"),
node.expression
);
if (!node.isExportEquals) {
const original = getOriginalNode(node);
if (nodeIsSynthesized(original) || resolver.isValueAliasDeclaration(original)) {
return createExportStatement(
createLiteral("default"),
node.expression
);
}
}
return undefined;
@@ -626,7 +624,7 @@ namespace ts {
if (!hasModifier(node, ModifierFlags.Default)) {
recordExportName(name);
}
node = newNode;
}
@@ -642,7 +640,7 @@ namespace ts {
return [
node,
createExportStatement(name, name)
]
];
}
return node;
}
@@ -917,6 +915,17 @@ namespace ts {
// Substitutions
//
function onEmitNode(node: Node, emit: (node: Node) => void): void {
if (node.kind === SyntaxKind.SourceFile) {
exportFunctionForFile = exportFunctionForFileMap[getNodeId(node)];
previousOnEmitNode(node, emit);
exportFunctionForFile = undefined;
}
else {
previousOnEmitNode(node, emit);
}
}
/**
* Substitute the expression, if necessary.
*
@@ -1073,7 +1082,7 @@ namespace ts {
function substituteUnaryExpression(node: PrefixUnaryExpression | PostfixUnaryExpression): Expression {
const operand = node.operand;
const operator = node.operator;
const substitute =
const substitute =
isIdentifier(operand) &&
(
node.kind === SyntaxKind.PostfixUnaryExpression ||
@@ -1090,9 +1099,9 @@ namespace ts {
return call;
}
else {
return operator === SyntaxKind.PlusPlusToken
return operator === SyntaxKind.PlusPlusToken
? createSubtract(call, createLiteral(1))
: createAdd(call, createLiteral(1))
: createAdd(call, createLiteral(1));
}
}
}
@@ -1121,11 +1130,6 @@ namespace ts {
return undefined;
}
function getLocalNameTextForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): string {
const name = getLocalNameForExternalImport(node);
return name ? name.text : undefined;
}
function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration): Identifier {
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node)) {
@@ -1182,14 +1186,17 @@ namespace ts {
]),
m,
createBlock([
createIf(
condition,
createStatement(
createAssignment(
createElementAccess(exports, n),
createElementAccess(m, n)
setNodeEmitFlags(
createIf(
condition,
createStatement(
createAssignment(
createElementAccess(exports, n),
createElementAccess(m, n)
)
)
)
),
NodeEmitFlags.SingleLine
)
])
),
@@ -1200,7 +1207,7 @@ namespace ts {
)
)
],
/*location*/ undefined,
/*location*/ undefined,
/*multiline*/ true)
)
);
@@ -1243,7 +1250,6 @@ namespace ts {
if (isImportClause(importDeclaration)) {
importAlias = getGeneratedNameForNode(importDeclaration.parent);
name = createIdentifier("default");
name.originalKeywordKind = SyntaxKind.DefaultKeyword;
}
else if (isImportSpecifier(importDeclaration)) {
importAlias = getGeneratedNameForNode(importDeclaration.parent.parent.parent);

View File

@@ -463,7 +463,7 @@ namespace ts {
}
else if (node.decorators) {
if (isDefaultExternalModuleExport(node)) {
statements.push(createExportDefault(name));
statements.push(createExportDefault(name || getGeneratedNameForNode(node)));
}
else if (isNamedExternalModuleExport(node)) {
statements.push(createExternalModuleExport(name));
@@ -581,6 +581,10 @@ namespace ts {
node
);
if (!name) {
name = getGeneratedNameForNode(node);
}
// Record an alias to avoid class double-binding.
let decoratedClassAlias: Identifier;
if (resolver.getNodeCheckFlags(getOriginalNode(node)) & NodeCheckFlags.DecoratedClassWithSelfReference) {
@@ -2440,7 +2444,10 @@ namespace ts {
* @param node The import equals declaration node.
*/
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<Statement> {
Debug.assert(!isExternalModuleImportEqualsDeclaration(node));
if (isExternalModuleImportEqualsDeclaration(node)) {
return visitEachChild(node, visitor, context);
}
if (shouldElideImportEqualsDeclaration(node)) {
return undefined;
}

View File

@@ -480,6 +480,7 @@ namespace ts {
// @kind(SyntaxKind.StaticKeyword)
export interface Modifier extends Node { }
/*@internal*/
export const enum GeneratedIdentifierKind {
None, // Not automatically generated.
Auto, // Automatically generated identifier.
@@ -490,9 +491,9 @@ namespace ts {
// @kind(SyntaxKind.Identifier)
export interface Identifier extends PrimaryExpression {
text: string; // Text of identifier (with escapes converted to characters)
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
text: string; // Text of identifier (with escapes converted to characters)
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
}
// @kind(SyntaxKind.QualifiedName)
@@ -803,6 +804,8 @@ namespace ts {
// @kind(SyntaxKind.StringLiteral)
export interface StringLiteral extends LiteralExpression {
_stringLiteralBrand: any;
/* @internal */
textSourceNode?: Identifier | StringLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
}
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.

View File

@@ -2982,7 +2982,7 @@ namespace ts {
break;
case SyntaxKind.ImportEqualsDeclaration:
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(node)) {
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference && resolver.isReferencedAliasDeclaration(getOriginalNode(node))) {
// import x = require("mod") where x is referenced
externalImports.push(<ImportEqualsDeclaration>node);
}
@@ -2995,7 +2995,7 @@ namespace ts {
externalImports.push(<ExportDeclaration>node);
hasExportStars = true;
}
else if (resolver.isValueAliasDeclaration(node)) {
else if (resolver.isValueAliasDeclaration(getOriginalNode(node))) {
// export { x, y } from "mod" where at least one export is a value symbol
externalImports.push(<ExportDeclaration>node);
}

View File

@@ -1,7 +1,7 @@
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
@@ -346,7 +346,7 @@ namespace Utils {
assert.equal(node1.end, node2.end, "node1.end !== node2.end");
assert.equal(node1.kind, node2.kind, "node1.kind !== node2.kind");
// call this on both nodes to ensure all propagated flags have been set (and thus can be
// call this on both nodes to ensure all propagated flags have been set (and thus can be
// compared).
assert.equal(ts.containsParseError(node1), ts.containsParseError(node2));
assert.equal(node1.flags, node2.flags, "node1.flags !== node2.flags");
@@ -391,6 +391,60 @@ namespace Utils {
throw new Error("Could not find child in parent");
}
const maxHarnessFrames = 1;
export function filterStack(error: Error, stackTraceLimit: number = Infinity) {
const stack = <string>(<any>error).stack;
if (stack) {
const lines = stack.split(/\r\n?|\n/g);
const filtered: string[] = [];
let frameCount = 0;
let harnessFrameCount = 0;
for (let line of lines) {
if (isStackFrame(line)) {
if (frameCount >= stackTraceLimit
|| isMocha(line)
|| isNode(line)) {
continue;
}
if (isHarness(line)) {
if (harnessFrameCount >= maxHarnessFrames) {
continue;
}
harnessFrameCount++;
}
line = line.replace(/\bfile:\/\/\/(.*?)(?=(:\d+)*($|\)))/, (_, path) => ts.sys.resolvePath(path));
frameCount++;
}
filtered.push(line);
}
(<any>error).stack = filtered.join(ts.sys.newLine);
}
return error;
}
function isStackFrame(line: string) {
return /^\s+at\s/.test(line);
}
function isMocha(line: string) {
return /[\\/](node_modules|components)[\\/]mocha(js)?[\\/]|[\\/]mocha\.js/.test(line);
}
function isNode(line: string) {
return /\((timers|events|node|module)\.js:/.test(line);
}
function isHarness(line: string) {
return /[\\/]src[\\/]harness[\\/]|[\\/]run\.js/.test(line);
}
}
namespace Harness.Path {
@@ -747,13 +801,15 @@ namespace Harness {
namespace Harness {
export const libFolder = "built/local/";
const tcServicesFileName = ts.combinePaths(libFolder, Utils.getExecutionEnvironment() === Utils.ExecutionEnvironment.Browser ? "typescriptServicesInBrowserTest.js" : "typescriptServices.js");
export const tcServicesFile = IO.readFile(tcServicesFileName);
export const tcServicesFile = IO.readFile(tcServicesFileName) + (Utils.getExecutionEnvironment() !== Utils.ExecutionEnvironment.Browser
? IO.newLine() + `//# sourceURL=${IO.resolvePath(tcServicesFileName)}`
: "");
export interface SourceMapEmitterCallback {
(emittedFile: string, emittedLine: number, emittedColumn: number, sourceFile: string, sourceLine: number, sourceColumn: number, sourceName: string): void;
}
// Settings
// Settings
export let userSpecifiedRoot = "";
export let lightMode = false;
@@ -792,7 +848,7 @@ namespace Harness {
fileName: string,
sourceText: string,
languageVersion: ts.ScriptTarget) {
// We'll only assert invariants outside of light mode.
// We'll only assert invariants outside of light mode.
const shouldAssertInvariants = !Harness.lightMode;
// Only set the parent nodes if we're asserting invariants. We don't need them otherwise.
@@ -887,7 +943,7 @@ namespace Harness {
libFiles?: string;
}
// Additional options not already in ts.optionDeclarations
// Additional options not already in ts.optionDeclarations
const harnessOptionDeclarations: ts.CommandLineOption[] = [
{ name: "allowNonTsExtensions", type: "boolean" },
{ name: "useCaseSensitiveFileNames", type: "boolean" },
@@ -1135,7 +1191,7 @@ namespace Harness {
errLines.forEach(e => outputLines.push(e));
// do not count errors from lib.d.ts here, they are computed separately as numLibraryDiagnostics
// if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers)
// if lib.d.ts is explicitly included in input files and there are some errors in it (i.e. because of duplicate identifiers)
// then they will be added twice thus triggering 'total errors' assertion with condition
// 'totalErrorsReportedInNonLibraryFiles + numLibraryDiagnostics + numTest262HarnessDiagnostics, diagnostics.length
@@ -1445,7 +1501,7 @@ namespace Harness {
};
testUnitData.push(newTestFile2);
// unit tests always list files explicitly
// unit tests always list files explicitly
const parseConfigHost: ts.ParseConfigHost = {
readDirectory: (name) => []
};
@@ -1590,17 +1646,21 @@ namespace Harness {
let actual = <string>undefined;
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
try {
if (runImmediately) {
actual = generateActual(actualFileName, generateContent);
const comparison = compareToBaseline(actual, relativeFileName, opts);
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
}
else {
actual = generateActual(actualFileName, generateContent);
if (runImmediately) {
actual = generateActual(actualFileName, generateContent);
const comparison = compareToBaseline(actual, relativeFileName, opts);
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
const comparison = compareToBaseline(actual, relativeFileName, opts);
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
}
}
else {
actual = generateActual(actualFileName, generateContent);
const comparison = compareToBaseline(actual, relativeFileName, opts);
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, descriptionForDescribe);
catch (e) {
throw Utils.filterStack(e);
}
}
}
@@ -1621,5 +1681,9 @@ namespace Harness {
if (Error) (<any>Error).stackTraceLimit = 1;
}
if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) {
ts.sys.tryEnableSourceMapsForHost();
}
// TODO: not sure why Utils.evalFile isn't working with this, eventually will concat it like old compiler instead of eval
eval(Harness.tcServicesFile);

View File

@@ -46,6 +46,13 @@ if (testConfigFile !== "") {
Harness.lightMode = true;
}
if (testConfig.stackTraceLimit === "full") {
(<any>Error).stackTraceLimit = Infinity;
}
else if ((testConfig.stackTraceLimit | 0) > 0) {
(<any>Error).stackTraceLimit = testConfig.stackTraceLimit;
}
if (testConfig.test && testConfig.test.length > 0) {
for (const option of testConfig.test) {
if (!option) {

View File

@@ -22,8 +22,8 @@ System.register(["foo"], function (exports_1, context_1) {
var foo_1, cls, cls2, x, y, z, M;
return {
setters: [
function (_1) {
foo_1 = _1;
function (foo_1_1) {
foo_1 = foo_1_1;
}
],
execute: function () {

View File

@@ -10,13 +10,13 @@ export class Foo {
}
//// [b.js]
System.register([], function(exports_1, context_1) {
System.register([], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var Foo;
return {
setters:[],
execute: function() {
setters: [],
execute: function () {
Foo = (function () {
function Foo() {
}
@@ -24,21 +24,21 @@ System.register([], function(exports_1, context_1) {
}());
exports_1("Foo", Foo);
}
}
};
});
//// [a.js]
System.register(["./b"], function(exports_1, context_1) {
System.register(["./b"], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var b_1;
var x;
var b_1, x;
return {
setters:[
setters: [
function (b_1_1) {
b_1 = b_1_1;
}],
execute: function() {
}
],
execute: function () {
exports_1("x", x = new b_1["default"].Foo());
}
}
};
});

View File

@@ -11,13 +11,13 @@ export class Foo {
//// [b.js]
System.register([], function(exports_1, context_1) {
System.register([], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var Foo;
return {
setters:[],
execute: function() {
setters: [],
execute: function () {
Foo = (function () {
function Foo() {
}
@@ -25,21 +25,21 @@ System.register([], function(exports_1, context_1) {
}());
exports_1("Foo", Foo);
}
}
};
});
//// [a.js]
System.register(["./b"], function(exports_1, context_1) {
System.register(["./b"], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var b_1;
var x;
var b_1, x;
return {
setters:[
setters: [
function (b_1_1) {
b_1 = b_1_1;
}],
execute: function() {
}
],
execute: function () {
exports_1("x", x = new b_1["default"].Foo());
}
}
};
});

View File

@@ -12,18 +12,18 @@ export var x = new Foo();
//// [a.js]
System.register(["./b"], function(exports_1, context_1) {
System.register(["./b"], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var b_1;
var x;
var b_1, x;
return {
setters:[
setters: [
function (b_1_1) {
b_1 = b_1_1;
}],
execute: function() {
}
],
execute: function () {
exports_1("x", x = new b_1["default"]());
}
}
};
});

View File

@@ -12,18 +12,18 @@ export var x = new Foo();
//// [a.js]
System.register(["./b"], function(exports_1, context_1) {
System.register(["./b"], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var b_1;
var x;
var b_1, x;
return {
setters:[
setters: [
function (b_1_1) {
b_1 = b_1_1;
}],
execute: function() {
}
],
execute: function () {
exports_1("x", x = new b_1["default"]());
}
}
};
});

View File

@@ -3,5 +3,4 @@ export declare module "M" { }
//// [ambientExternalModuleInsideNonAmbientExternalModule.js]
define(["require", "exports"], function (require, exports) {
"use strict";
});

View File

@@ -7,5 +7,4 @@ export declare module M { }
//// [ambientInsideNonAmbientExternalModule.js]
define(["require", "exports"], function (require, exports) {
"use strict";
});

View File

@@ -10,14 +10,14 @@ export {n2}
export {n2 as n3}
//// [systemModule10.js]
System.register(["file1", "file2"], function (exports_1, context_1) {
System.register(['file1', 'file2'], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var file1_1, n2;
return {
setters: [
function (_1) {
file1_1 = _1;
function (file1_1_1) {
file1_1 = file1_1_1;
},
function (n2_1) {
n2 = n2_1;

View File

@@ -10,14 +10,14 @@ export {n2}
export {n2 as n3}
//// [systemModule10_ES5.js]
System.register(["file1", "file2"], function (exports_1, context_1) {
System.register(['file1', 'file2'], function (exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var file1_1, n2;
return {
setters: [
function (_1) {
file1_1 = _1;
function (file1_1_1) {
file1_1 = file1_1_1;
},
function (n2_1) {
n2 = n2_1;

View File

@@ -20,8 +20,8 @@ System.register(["foo"], function (exports_1, context_1) {
var foo_1, x;
return {
setters: [
function (_1) {
foo_1 = _1;
function (foo_1_1) {
foo_1 = foo_1_1;
}
],
execute: function () {

View File

@@ -43,22 +43,22 @@ System.register(["file1", "file2", "file3", "file4", "file5", "file6", "file7"],
function (ns_1) {
ns = ns_1;
},
function (file2_1_1) {
file2_1 = file2_1_1;
},
function (file3_1_1) {
file3_1 = file3_1_1;
},
function (_1) {
file2_1 = _1;
},
function (_2) {
file3_1 = _2;
},
function (_3) {
},
function (_4) {
file5_1 = _4;
function (file5_1_1) {
file5_1 = file5_1_1;
},
function (ns3_1) {
ns3 = ns3_1;
},
function (_5) {
exportStar_1(_5);
function (file7_1_1) {
exportStar_1(file7_1_1);
}
],
execute: function () {