Merge branch 'transforms-transformer-jsx' into transforms-transformer-es7

This commit is contained in:
Ron Buckton
2016-03-01 15:43:37 -08:00
179 changed files with 1641 additions and 1567 deletions
-8
View File
@@ -239,7 +239,6 @@ function concatenateFiles(destinationFile, sourceFiles) {
var useDebugMode = true;
var useTransforms = process.env.USE_TRANSFORMS || false;
var useTransformCompat = false;
var host = (process.env.host || process.env.TYPESCRIPT_HOST || "node");
var compilerFilename = "tsc.js";
var LKGCompiler = path.join(LKGDirectory, compilerFilename);
@@ -302,9 +301,6 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu
if (useBuiltCompiler && useTransforms) {
options += " --experimentalTransforms"
}
else if (useBuiltCompiler && useTransformCompat) {
options += " --transformCompatibleEmit"
}
var cmd = host + " " + compilerPath + " " + options + " ";
cmd = cmd + sources.join(" ");
@@ -433,10 +429,6 @@ task("setTransforms", function() {
useTransforms = true;
});
task("setTransformCompat", function() {
useTransformCompat = true;
});
task("configure-nightly", [configureNightlyJs], function() {
var cmd = host + " " + configureNightlyJs + " " + packageJson + " " + programTs;
console.log(cmd);
+3 -3
View File
@@ -4846,7 +4846,7 @@ namespace ts {
const parent = container && container.parent;
if (parent && (isClassLike(parent) || parent.kind === SyntaxKind.InterfaceDeclaration)) {
if (!(container.flags & NodeFlags.Static) &&
(container.kind !== SyntaxKind.Constructor || isNodeDescendentOf(node, (<ConstructorDeclaration>container).body))) {
(container.kind !== SyntaxKind.Constructor || isNodeDescendantOf(node, (<ConstructorDeclaration>container).body))) {
return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType;
}
}
@@ -7206,8 +7206,8 @@ namespace ts {
let container = getContainingClass(node);
while (container !== undefined) {
if (container === localOrExportSymbol.valueDeclaration && container.name !== node) {
getNodeLinks(container).flags |= NodeCheckFlags.ClassWithBodyScopedClassBinding;
getNodeLinks(node).flags |= NodeCheckFlags.BodyScopedClassBinding;
getNodeLinks(container).flags |= NodeCheckFlags.DecoratedClassWithSelfReference;
getNodeLinks(node).flags |= NodeCheckFlags.SelfReferenceInDecoratedClass;
break;
}
-7
View File
@@ -327,13 +327,6 @@ namespace ts {
name: "experimentalTransforms",
type: "boolean",
experimental: true
},
{
// this option will be removed when this is merged with master and exists solely
// to enable the tree transforming emitter side-by-side with the existing emitter.
name: "transformCompatibleEmit",
type: "boolean",
experimental: true
}
];
+84 -8
View File
@@ -172,25 +172,101 @@ namespace ts {
}
/**
* Maps an array. If the mapped value is an array, it is spread into the result.
* Flattens an array containing a mix of array or non-array elements.
*
* @param array The array to flatten.
*/
export function flatMap<T, U>(array: T[], f: (x: T, i: number) => U | U[]): U[] {
export function flatten<T>(array: (T | T[])[]): T[] {
let result: T[];
if (array) {
result = [];
for (const v of array) {
if (v) {
if (isArray(v)) {
addRange(result, v);
}
else {
result.push(v);
}
}
}
}
return result;
}
/**
* Maps an array. If the mapped value is an array, it is spread into the result.
*
* @param array The array to map.
* @param mapfn The callback used to map the result into one or more values.
*/
export function flatMap<T, U>(array: T[], mapfn: (x: T, i: number) => U | U[]): U[] {
let result: U[];
if (array) {
result = [];
for (let i = 0; i < array.length; i++) {
const v = array[i];
const ar = f(v, i);
if (ar) {
// We cast to <U> here to leverage the behavior of Array#concat
// which will append a single value here.
result = result.concat(<U[]>ar);
const v = mapfn(array[i], i);
if (v) {
if (isArray(v)) {
addRange(result, v);
}
else {
result.push(v);
}
}
}
}
return result;
}
/**
* Maps contiguous spans of values with the same key.
*
* @param array The array to map.
* @param keyfn A callback used to select the key for an element.
* @param mapfn A callback used to map a contiguous chunk of values to a single value.
*/
export function spanMap<T, K, U>(array: T[], keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K) => U): U[] {
let result: U[];
if (array) {
result = [];
const len = array.length;
let previousKey: K;
let key: K;
let start = 0;
let pos = 0;
while (start < len) {
while (pos < len) {
const value = array[pos];
key = keyfn(value, pos);
if (pos === 0) {
previousKey = key;
}
else if (key !== previousKey) {
break;
}
pos++;
}
if (start < pos) {
const v = mapfn(array.slice(start, pos), previousKey);
if (v) {
result.push(v);
}
start = pos;
}
previousKey = key;
pos++;
}
}
return result;
}
export function concatenate<T>(array1: T[], array2: T[]): T[] {
if (!array2 || !array2.length) return array1;
if (!array1 || !array1.length) return array2;
+10 -23
View File
@@ -346,7 +346,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
};
function isUniqueLocalName(name: string, container: Node): boolean {
for (let node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
if (node.locals && hasProperty(node.locals, name)) {
// We conservatively include alias symbols to cover cases where they're emitted as locals
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
@@ -1529,7 +1529,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
return;
}
}
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.BodyScopedClassBinding) {
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.SelfReferenceInDecoratedClass) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
@@ -1915,9 +1915,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
if (multiLine) {
decreaseIndent();
if (!compilerOptions.transformCompatibleEmit) {
writeLine();
}
}
write(")");
@@ -2237,7 +2234,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
return forEach(elements, e => e.kind === SyntaxKind.SpreadElementExpression);
}
function skipParentheses(node: Expression): Expression {
function skipParenthesesAndAssertions(node: Expression): Expression {
while (node.kind === SyntaxKind.ParenthesizedExpression || node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression) {
node = (<ParenthesizedExpression | AssertionExpression>node).expression;
}
@@ -2268,7 +2265,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
function emitCallWithSpread(node: CallExpression) {
let target: Expression;
const expr = skipParentheses(node.expression);
const expr = skipParenthesesAndAssertions(node.expression);
if (expr.kind === SyntaxKind.PropertyAccessExpression) {
// Target will be emitted as "this" argument
target = emitCallTarget((<PropertyAccessExpression>expr).expression);
@@ -4334,9 +4331,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
writeLine();
emitStart(restParam);
emitNodeWithCommentsAndWithoutSourcemap(restParam.name);
write(restIndex > 0 || !compilerOptions.transformCompatibleEmit
? `[${tempName} - ${restIndex}] = arguments[${tempName}];`
: `[${tempName}] = arguments[${tempName}];`);
write(`[${tempName} - ${restIndex}] = arguments[${tempName}];`);
emitEnd(restParam);
decreaseIndent();
writeLine();
@@ -5208,7 +5203,7 @@ const _super = (function (geti, seti) {
// [Example 4]
//
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithBodyScopedClassBinding) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.DecoratedClassWithSelfReference) {
decoratedClassAlias = unescapeIdentifier(makeUniqueName(node.name ? node.name.text : "default"));
decoratedClassAliases[getNodeId(node)] = decoratedClassAlias;
write(`let ${decoratedClassAlias};`);
@@ -5356,7 +5351,7 @@ const _super = (function (geti, seti) {
const isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === SyntaxKind.ClassExpression;
let tempVariable: Identifier;
if (isClassExpressionWithStaticProperties && compilerOptions.transformCompatibleEmit) {
if (isClassExpressionWithStaticProperties) {
tempVariable = createAndRecordTempVariable(TempFlags.Auto);
write("(");
increaseIndent();
@@ -5393,11 +5388,6 @@ const _super = (function (geti, seti) {
writeLine();
emitConstructor(node, baseTypeNode);
emitMemberFunctionsForES5AndLower(node);
if (!compilerOptions.transformCompatibleEmit) {
emitPropertyDeclarations(node, staticProperties);
writeLine();
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
}
writeLine();
emitToken(SyntaxKind.CloseBraceToken, node.members.end, () => {
write("return ");
@@ -5424,13 +5414,10 @@ const _super = (function (geti, seti) {
write("))");
if (node.kind === SyntaxKind.ClassDeclaration) {
write(";");
if (compilerOptions.transformCompatibleEmit) {
emitPropertyDeclarations(node, staticProperties);
writeLine();
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
}
emitPropertyDeclarations(node, staticProperties);
emitDecoratorsOfClass(node, /*decoratedClassAlias*/ undefined);
}
else if (isClassExpressionWithStaticProperties && compilerOptions.transformCompatibleEmit) {
else if (isClassExpressionWithStaticProperties) {
for (const property of staticProperties) {
write(",");
writeLine();
+39 -15
View File
@@ -153,7 +153,21 @@ namespace ts {
* Creates a shallow, memberwise clone of a node for mutation.
*/
export function getMutableNode<T extends Node>(node: T): T {
return cloneNode<T>(node, node, node.flags, node.parent, node);
return cloneNode(node, /*location*/ node, node.flags, /*parent*/ undefined, /*original*/ node);
}
/**
* Creates a shallow, memberwise clone of a node with no source map location.
*/
export function getSynthesizedClone<T extends Node>(node: T): T {
return nodeIsSynthesized(node) ? node : cloneNode(node, /*location*/ undefined, node.flags, /*parent*/ undefined, /*original*/ node);
}
/**
* Creates a shallow, memberwise clone of a node at the specified source map location.
*/
export function getRelocatedClone<T extends Node>(node: T, location: TextRange): T {
return cloneNode(node, location, node.flags, /*parent*/ undefined, /*original*/ node);
}
export function createNodeArrayNode<T extends Node>(elements: T[]): NodeArrayNode<T> {
@@ -185,24 +199,38 @@ namespace ts {
// Identifiers
export function createIdentifier(text: string): Identifier {
const node = <Identifier>createNode(SyntaxKind.Identifier);
export function createIdentifier(text: string, location?: TextRange): Identifier {
const node = <Identifier>createNode(SyntaxKind.Identifier, location);
node.text = text;
return node;
}
export function createTempVariable(): Identifier {
const name = <Identifier>createNode(SyntaxKind.Identifier);
name.text = undefined;
name.tempKind = TempVariableKind.Auto;
export function createTempVariable(location?: TextRange): Identifier {
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
name.autoGenerateKind = GeneratedIdentifierKind.Auto;
getNodeId(name);
return name;
}
export function createLoopVariable(): Identifier {
const name = <Identifier>createNode(SyntaxKind.Identifier);
name.text = undefined;
name.tempKind = TempVariableKind.Loop;
export function createLoopVariable(location?: TextRange): Identifier {
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
name.autoGenerateKind = GeneratedIdentifierKind.Loop;
getNodeId(name);
return name;
}
export function createUniqueName(text: string, location?: TextRange): Identifier {
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
name.text = text;
name.autoGenerateKind = GeneratedIdentifierKind.Unique;
getNodeId(name);
return name;
}
export function getGeneratedNameForNode(node: Node, location?: TextRange): Identifier {
const name = <Identifier>createNode(SyntaxKind.Identifier, location);
name.autoGenerateKind = GeneratedIdentifierKind.Node;
name.original = node;
getNodeId(name);
return name;
}
@@ -1326,8 +1354,4 @@ namespace ts {
node.flags = flags;
return node;
}
export function getSynthesizedNode<T extends Node>(node: T): T {
return nodeIsSynthesized(node) ? node : cloneNode(node, /*location*/ undefined, node.flags, /*parent*/ undefined, /*original*/ node);
}
}
+123 -39
View File
@@ -121,7 +121,6 @@ const _super = (function (geti, seti) {
const writer = createTextWriter(newLine);
const {
write,
writeTextOfNode,
writeLine,
increaseIndent,
decreaseIndent
@@ -154,11 +153,12 @@ const _super = (function (geti, seti) {
let identifierSubstitution: (node: Identifier) => Identifier;
let onBeforeEmitNode: (node: Node) => void;
let onAfterEmitNode: (node: Node) => void;
let isUniqueName: (name: string) => boolean;
let temporaryVariables: string[] = [];
let nodeToGeneratedName: string[];
let generatedNameSet: Map<string>;
let tempFlags: TempFlags;
let currentSourceFile: SourceFile;
let currentText: string;
let currentFileIdentifiers: Map<string>;
let extendsEmitted: boolean;
let decorateEmitted: boolean;
let paramEmitted: boolean;
@@ -169,6 +169,8 @@ const _super = (function (geti, seti) {
function doPrint(jsFilePath: string, sourceMapFilePath: string, sourceFiles: SourceFile[], isBundledEmit: boolean) {
sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFiles, isBundledEmit);
nodeToGeneratedName = [];
generatedNameSet = {};
isOwnFileEmit = !isBundledEmit;
// Emit helpers from all the files
@@ -213,8 +215,6 @@ const _super = (function (geti, seti) {
identifierSubstitution = undefined;
onBeforeEmitNode = undefined;
onAfterEmitNode = undefined;
isUniqueName = undefined;
temporaryVariables = undefined;
tempFlags = TempFlags.Auto;
currentSourceFile = undefined;
currentText = undefined;
@@ -236,13 +236,13 @@ const _super = (function (geti, seti) {
identifierSubstitution = context.identifierSubstitution;
onBeforeEmitNode = context.onBeforeEmitNode;
onAfterEmitNode = context.onAfterEmitNode;
isUniqueName = context.isUniqueName;
return printSourceFile;
}
function printSourceFile(node: SourceFile) {
currentSourceFile = node;
currentText = node.text;
currentFileIdentifiers = node.identifiers;
sourceMap.setSourceFile(node);
comments.setSourceFile(node);
emitWorker(node);
@@ -659,22 +659,11 @@ const _super = (function (geti, seti) {
//
function emitIdentifier(node: Identifier) {
if (node.text === undefined) {
// Emit a temporary variable name for this node.
const nodeId = getOriginalNodeId(node);
const text = temporaryVariables[nodeId] || (temporaryVariables[nodeId] = makeTempVariableName(tempKindToFlags(node.tempKind)));
write(text);
}
else if (nodeIsSynthesized(node) || !node.parent) {
if (getNodeEmitFlags(node) & NodeEmitFlags.UMDDefine) {
writeLines(umdHelper);
}
else {
write(node.text);
}
if (getNodeEmitFlags(node) && NodeEmitFlags.UMDDefine) {
writeLines(umdHelper);
}
else {
writeTextOfNode(currentText, node);
write(getTextOfNode(node, /*includeTrivia*/ false));
}
}
@@ -1720,7 +1709,6 @@ const _super = (function (geti, seti) {
emitExpression(node.expression);
write(":");
debugger;
emitCaseOrDefaultClauseStatements(node, node.statements);
}
@@ -1763,14 +1751,14 @@ const _super = (function (geti, seti) {
function emitPropertyAssignment(node: PropertyAssignment) {
emit(node.name);
write(": ");
// // This is to ensure that we emit comment in the following case:
// // For example:
// // obj = {
// // id: /*comment1*/ ()=>void
// // }
// // "comment1" is not considered to be leading comment for node.initializer
// // but rather a trailing comment on the previous node.
// emitTrailingCommentsOfPosition(node.initializer.pos);
// This is to ensure that we emit comment in the following case:
// For example:
// obj = {
// id: /*comment1*/ ()=>void
// }
// "comment1" is not considered to be leading comment for node.initializer
// but rather a trailing comment on the previous node.
emitLeadingComments(node.initializer, getTrailingComments(collapseTextRange(node.initializer, TextRangeCollapse.CollapseToStart)));
emitExpression(node.initializer);
}
@@ -1951,11 +1939,8 @@ const _super = (function (geti, seti) {
}
function emitModifiers(node: Node, modifiers: ModifiersArray) {
const startingPos = writer.getTextPos();
emitList(node, modifiers, ListFormat.SingleLine);
const endingPos = writer.getTextPos();
if (startingPos !== endingPos) {
if (modifiers && modifiers.length) {
emitList(node, modifiers, ListFormat.SingleLine);
write(" ");
}
}
@@ -2345,7 +2330,15 @@ const _super = (function (geti, seti) {
}
function getTextOfNode(node: Node, includeTrivia?: boolean) {
if (nodeIsSynthesized(node) && (isLiteralExpression(node) || isIdentifier(node))) {
if (isIdentifier(node)) {
if (node.autoGenerateKind) {
return getGeneratedIdentifier(node);
}
else if (nodeIsSynthesized(node) || !node.parent) {
return node.text;
}
}
else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) {
return node.text;
}
@@ -2368,10 +2361,22 @@ const _super = (function (geti, seti) {
&& rangeEndIsOnSameLineAsRangeStart(block, block);
}
function tempKindToFlags(kind: TempVariableKind) {
return kind === TempVariableKind.Loop
? TempFlags._i
: TempFlags.Auto;
function isUniqueName(name: string): boolean {
return !resolver.hasGlobalName(name) &&
!hasProperty(currentFileIdentifiers, name) &&
!hasProperty(generatedNameSet, name);
}
function isUniqueLocalName(name: string, container: Node): boolean {
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
if (node.locals && hasProperty(node.locals, name)) {
// We conservatively include alias symbols to cover cases where they're emitted as locals
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
return false;
}
}
}
return true;
}
/**
@@ -2401,6 +2406,85 @@ const _super = (function (geti, seti) {
}
}
}
// Generate a name that is unique within the current file and doesn't conflict with any names
// in global scope. The name is formed by adding an '_n' suffix to the specified base name,
// where n is a positive integer. Note that names generated by makeTempVariableName and
// makeUniqueName are guaranteed to never conflict.
function makeUniqueName(baseName: string): string {
// Find the first unique 'name_n', where n is a positive number
if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) {
baseName += "_";
}
let i = 1;
while (true) {
const generatedName = baseName + i;
if (isUniqueName(generatedName)) {
return generatedNameSet[generatedName] = generatedName;
}
i++;
}
}
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
const name = node.name.text;
// Use module/enum name itself if it is unique, otherwise make a unique variation
return isUniqueLocalName(name, node) ? name : makeUniqueName(name);
}
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
const expr = getExternalModuleName(node);
const baseName = expr.kind === SyntaxKind.StringLiteral ?
escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text)) : "module";
return makeUniqueName(baseName);
}
function generateNameForExportDefault() {
return makeUniqueName("default");
}
function generateNameForClassExpression() {
return makeUniqueName("class");
}
function generateNameForNode(node: Node) {
switch (node.kind) {
case SyntaxKind.Identifier:
return makeUniqueName((<Identifier>node).text);
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.EnumDeclaration:
return generateNameForModuleOrEnum(<ModuleDeclaration | EnumDeclaration>node);
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ExportDeclaration:
return generateNameForImportOrExportDeclaration(<ImportDeclaration | ExportDeclaration>node);
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ExportAssignment:
return generateNameForExportDefault();
case SyntaxKind.ClassExpression:
return generateNameForClassExpression();
default:
return makeTempVariableName(TempFlags.Auto);
}
}
function generateIdentifier(node: Identifier) {
switch (node.autoGenerateKind) {
case GeneratedIdentifierKind.Auto:
return makeTempVariableName(TempFlags.Auto);
case GeneratedIdentifierKind.Loop:
return makeTempVariableName(TempFlags._i);
case GeneratedIdentifierKind.Unique:
return makeUniqueName(node.text);
case GeneratedIdentifierKind.Node:
return generateNameForNode(getOriginalNode(node));
}
}
function getGeneratedIdentifier(node: Identifier) {
const id = getOriginalNodeId(node);
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = unescapeIdentifier(generateIdentifier(node)));
}
}
}
-118
View File
@@ -54,8 +54,6 @@ namespace ts {
* @param transforms An array of Transformers.
*/
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]) {
const nodeToGeneratedName: Identifier[] = [];
const generatedNameSet: Map<string> = {};
const nodeEmitFlags: NodeEmitFlags[] = [];
const lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
const lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
@@ -72,10 +70,6 @@ namespace ts {
getEmitResolver: () => resolver,
getNodeEmitFlags,
setNodeEmitFlags,
isUniqueName,
getGeneratedNameForNode,
nodeHasGeneratedName,
makeUniqueName,
hoistVariableDeclaration,
hoistFunctionDeclaration,
startLexicalEnvironment,
@@ -151,118 +145,6 @@ namespace ts {
return node;
}
/**
* Generate a name that is unique within the current file and doesn't conflict with any names
* in global scope. The name is formed by adding an '_n' suffix to the specified base name,
* where n is a positive integer. Note that names generated by makeTempVariableName and
* makeUniqueName are guaranteed to never conflict.
*/
function makeUniqueName(baseName: string): Identifier {
// Find the first unique 'name_n', where n is a positive number
if (baseName.charCodeAt(baseName.length - 1) !== CharacterCodes._) {
baseName += "_";
}
let i = 1;
while (true) {
const generatedName = baseName + i;
if (isUniqueName(generatedName)) {
return createIdentifier(generatedNameSet[generatedName] = generatedName);
}
i++;
}
}
/**
* Gets the generated name for a node.
*/
function getGeneratedNameForNode(node: Node) {
const id = getNodeId(node);
return nodeToGeneratedName[id] || (nodeToGeneratedName[id] = generateNameForNode(node));
}
/**
* Gets a value indicating whether a node has a generated name.
*/
function nodeHasGeneratedName(node: Node) {
const id = getNodeId(node);
return nodeToGeneratedName[id] !== undefined;
}
/**
* Tests whether the provided name is unique.
*/
function isUniqueName(name: string): boolean {
return !resolver.hasGlobalName(name)
&& !hasProperty(currentSourceFile.identifiers, name)
&& !hasProperty(generatedNameSet, name);
}
/**
* Tests whether the provided name is unique within a container.
*/
function isUniqueLocalName(name: string, container: Node): boolean {
container = getOriginalNode(container);
for (let node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
if (node.locals && hasProperty(node.locals, name)) {
// We conservatively include alias symbols to cover cases where they're emitted as locals
if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
return false;
}
}
}
return true;
}
/**
* Generates a name for a node.
*/
function generateNameForNode(node: Node): Identifier {
switch (node.kind) {
case SyntaxKind.Identifier:
return makeUniqueName((<Identifier>node).text);
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.EnumDeclaration:
return generateNameForModuleOrEnum(<ModuleDeclaration | EnumDeclaration>node);
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ExportDeclaration:
return generateNameForImportOrExportDeclaration(<ImportDeclaration | ExportDeclaration>node);
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
Debug.assert((node.flags & NodeFlags.Default) !== 0, "Can only generate a name for a default export.");
return generateNameForExportDefault();
case SyntaxKind.ExportAssignment:
return generateNameForExportDefault();
case SyntaxKind.ClassExpression:
return generateNameForClassExpression();
default:
return createTempVariable();
}
}
function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) {
const name = node.name;
// Use module/enum name itself if it is unique, otherwise make a unique variation
return isUniqueLocalName(name.text, node) ? name : makeUniqueName(name.text);
}
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
const expr = getExternalModuleName(node);
const baseName = expr.kind === SyntaxKind.StringLiteral
? escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text))
: "module";
return makeUniqueName(baseName);
}
function generateNameForExportDefault() {
return makeUniqueName("default");
}
function generateNameForClassExpression() {
return makeUniqueName("class");
}
/**
* Records a hoisted variable declaration for the provided name within a lexical environment.
*/
+130 -127
View File
@@ -9,6 +9,11 @@ namespace ts {
const compilerOptions = context.getCompilerOptions();
return transformSourceFile;
/**
* Transform JSX-specific syntax in a SourceFile.
*
* @param node A SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
return visitEachChild(node, visitor, context);
}
@@ -64,52 +69,41 @@ namespace ts {
}
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[]) {
// We must the node onto the node stack if it is not already at the top.
const tagName = getTagName(node);
let objectProperties: Expression;
if (node.attributes.length === 0) {
const attrs = node.attributes;
if (attrs.length === 0) {
// When there are no attributes, React wants "null"
objectProperties = createNull();
}
else {
// Map spans of JsxAttribute nodes into object literals and spans
// of JsxSpreadAttribute nodes into expressions.
const segments = flatten(
spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread
? map(attrs, transformJsxSpreadAttributeToExpression)
: createObjectLiteral(map(attrs, transformJsxAttributeToObjectLiteralElement))
)
);
if (isJsxSpreadAttribute(attrs[0])) {
// We must always emit at least one object literal before a spread
// argument.
segments.unshift(createObjectLiteral());
}
// Either emit one big object literal (no spread attribs), or
// a call to React.__spread
const attrs = node.attributes;
if (forEach(attrs, isJsxSpreadAttribute)) {
const segments: Expression[] = [];
let properties: ObjectLiteralElement[] = [];
for (const attr of attrs) {
if (isJsxSpreadAttribute(attr)) {
if (properties) {
segments.push(createObjectLiteral(properties));
properties = undefined;
}
addNode(segments, transformJsxSpreadAttributeToExpression(attr));
}
else {
if (!properties) {
properties = [];
}
addNode(properties, transformJsxAttributeToObjectLiteralElement(attr));
}
}
if (properties) {
segments.push(createObjectLiteral(properties));
}
objectProperties = createJsxSpread(compilerOptions.reactNamespace, segments);
}
else {
const properties = map(node.attributes, transformJsxAttributeToObjectLiteralElement);
objectProperties = createObjectLiteral(properties);
}
objectProperties = singleOrUndefined(segments)
|| createJsxSpread(compilerOptions.reactNamespace, segments);
}
const childExpressions = filter(map(children, transformJsxChildToExpression), isDefined);
return createJsxCreateElement(compilerOptions.reactNamespace, tagName, objectProperties, childExpressions);
return createJsxCreateElement(
compilerOptions.reactNamespace,
tagName,
objectProperties,
filter(map(children, transformJsxChildToExpression), isDefined)
);
}
function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) {
@@ -125,39 +119,29 @@ namespace ts {
}
function visitJsxText(node: JsxText) {
const text = getTextToEmit(node);
if (text !== undefined) {
return createLiteral(text);
}
return undefined;
}
function getTextToEmit(node: JsxText) {
const text = trimReactWhitespaceAndApplyEntities(node);
if (text === undefined || text.length === 0) {
return undefined;
}
else {
return text;
}
}
function trimReactWhitespaceAndApplyEntities(node: JsxText): string {
const text = getTextOfNode(node, /*includeTrivia*/ true);
let result: string = undefined;
let parts: Expression[];
let firstNonWhitespace = 0;
let lastNonWhitespace = -1;
// JSX trims whitespace at the end and beginning of lines, except that the
// start/end of a tag is considered a start/end of a line only if that line is
// on the same line as the closing tag. See examples in tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
// on the same line as the closing tag. See examples in
// tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx
for (let i = 0; i < text.length; i++) {
const c = text.charCodeAt(i);
if (isLineBreak(c)) {
if (firstNonWhitespace !== -1 && (lastNonWhitespace - firstNonWhitespace + 1 > 0)) {
const part = text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1);
result = (result ? result + "\" + ' ' + \"" : "") + part;
if (!parts) {
parts = [];
}
// We do not escape the string here as that is handled by the printer
// when it emits the literal. We do, however, need to decode JSX entities.
parts.push(createLiteral(decodeEntities(part)));
}
firstNonWhitespace = -1;
}
else if (!isWhiteSpace(c)) {
@@ -170,22 +154,41 @@ namespace ts {
if (firstNonWhitespace !== -1) {
const part = text.substr(firstNonWhitespace);
result = (result ? result + "\" + ' ' + \"" : "") + part;
if (!parts) {
parts = [];
}
// We do not escape the string here as that is handled by the printer
// when it emits the literal. We do, however, need to decode JSX entities.
parts.push(createLiteral(decodeEntities(part)));
}
if (result) {
// Replace entities like &nbsp;
result = result.replace(/&(\w+);/g, function(s: any, m: string) {
if (entities[m] !== undefined) {
return String.fromCharCode(entities[m]);
}
else {
return s;
}
});
if (parts) {
return reduceLeft(parts, aggregateJsxTextParts);
}
return result;
return undefined;
}
/**
* Aggregates two expressions by interpolating them with a whitespace literal.
*/
function aggregateJsxTextParts(left: Expression, right: Expression) {
return createAdd(createAdd(left, createLiteral(" ")), right);
}
/**
* Decodes JSX entities.
*/
function decodeEntities(text: string) {
return text.replace(/&(\w+);/g, function(s: any, m: string) {
if (entities[m] !== undefined) {
return String.fromCharCode(entities[m]);
}
else {
return s;
}
});
}
function getTagName(node: JsxElement | JsxOpeningLikeElement): Expression {
@@ -210,7 +213,7 @@ namespace ts {
*/
function getAttributeName(node: JsxAttribute): StringLiteral | Identifier {
const name = node.name;
if (/[A-Za-z_]+[\w*]/.test(name.text)) {
if (/^[A-Za-z_]\w*$/.test(name.text)) {
return createLiteral(name.text);
}
else {
@@ -422,62 +425,62 @@ namespace ts {
"uarr": 0x2191,
"rarr": 0x2192,
"darr": 0x2193,
"harr": 0x2194,
"crarr": 0x21B5,
"lArr": 0x21D0,
"uArr": 0x21D1,
"rArr": 0x21D2,
"dArr": 0x21D3,
"hArr": 0x21D4,
"forall": 0x2200,
"part": 0x2202,
"exist": 0x2203,
"empty": 0x2205,
"nabla": 0x2207,
"isin": 0x2208,
"notin": 0x2209,
"ni": 0x220B,
"prod": 0x220F,
"sum": 0x2211,
"minus": 0x2212,
"lowast": 0x2217,
"radic": 0x221A,
"prop": 0x221D,
"infin": 0x221E,
"ang": 0x2220,
"and": 0x2227,
"or": 0x2228,
"cap": 0x2229,
"cup": 0x222A,
"int": 0x222B,
"there4": 0x2234,
"sim": 0x223C,
"cong": 0x2245,
"asymp": 0x2248,
"ne": 0x2260,
"equiv": 0x2261,
"le": 0x2264,
"ge": 0x2265,
"sub": 0x2282,
"sup": 0x2283,
"nsub": 0x2284,
"sube": 0x2286,
"supe": 0x2287,
"oplus": 0x2295,
"otimes": 0x2297,
"perp": 0x22A5,
"sdot": 0x22C5,
"lceil": 0x2308,
"rceil": 0x2309,
"lfloor": 0x230A,
"rfloor": 0x230B,
"lang": 0x2329,
"rang": 0x232A,
"loz": 0x25CA,
"spades": 0x2660,
"clubs": 0x2663,
"hearts": 0x2665,
"diams": 0x2666
};
"harr": 0x2194,
"crarr": 0x21B5,
"lArr": 0x21D0,
"uArr": 0x21D1,
"rArr": 0x21D2,
"dArr": 0x21D3,
"hArr": 0x21D4,
"forall": 0x2200,
"part": 0x2202,
"exist": 0x2203,
"empty": 0x2205,
"nabla": 0x2207,
"isin": 0x2208,
"notin": 0x2209,
"ni": 0x220B,
"prod": 0x220F,
"sum": 0x2211,
"minus": 0x2212,
"lowast": 0x2217,
"radic": 0x221A,
"prop": 0x221D,
"infin": 0x221E,
"ang": 0x2220,
"and": 0x2227,
"or": 0x2228,
"cap": 0x2229,
"cup": 0x222A,
"int": 0x222B,
"there4": 0x2234,
"sim": 0x223C,
"cong": 0x2245,
"asymp": 0x2248,
"ne": 0x2260,
"equiv": 0x2261,
"le": 0x2264,
"ge": 0x2265,
"sub": 0x2282,
"sup": 0x2283,
"nsub": 0x2284,
"sube": 0x2286,
"supe": 0x2287,
"oplus": 0x2295,
"otimes": 0x2297,
"perp": 0x22A5,
"sdot": 0x22C5,
"lceil": 0x2308,
"rceil": 0x2309,
"lfloor": 0x230A,
"rfloor": 0x230B,
"lang": 0x2329,
"rang": 0x232A,
"loz": 0x25CA,
"spades": 0x2660,
"clubs": 0x2663,
"hearts": 0x2665,
"diams": 0x2666
};
}
}
+286 -219
View File
@@ -6,10 +6,17 @@
namespace ts {
type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration;
const enum TypeScriptSubstitutionFlags {
/** Enables substitutions for decorated classes. */
DecoratedClasses = 1 << 0,
/** Enables substitutions for namespace exports. */
NamespaceExports = 1 << 1,
/** Enables substitutions for async methods with `super` calls. */
AsyncMethodsWithSuper = 1 << 2,
}
export function transformTypeScript(context: TransformationContext) {
const {
getGeneratedNameForNode,
makeUniqueName,
setNodeEmitFlags,
startLexicalEnvironment,
endLexicalEnvironment,
@@ -21,14 +28,14 @@ namespace ts {
const languageVersion = getEmitScriptTarget(compilerOptions);
// Save the previous transformation hooks.
const previousExpressionSubstitution = context.expressionSubstitution;
const previousOnBeforeEmitNode = context.onBeforeEmitNode;
const previousOnAfterEmitNode = context.onAfterEmitNode;
const previousExpressionSubstitution = context.expressionSubstitution;
// Set new transformation hooks.
context.expressionSubstitution = substituteExpression;
context.onBeforeEmitNode = onBeforeEmitNode;
context.onAfterEmitNode = onAfterEmitNode;
context.expressionSubstitution = substituteExpression;
// These variables contain state that changes as we descend into the tree.
let currentSourceFile: SourceFile;
@@ -38,31 +45,46 @@ namespace ts {
let currentParent: Node;
let currentNode: Node;
// These variables keep track of whether expression substitution has been enabled for
// specific edge cases. They are persisted between each SourceFile transformation and
// should not be reset.
let hasEnabledExpressionSubstitutionForDecoratedClasses = false;
let hasEnabledExpressionSubstitutionForNamespaceExports = false;
let hasEnabledExpressionSubstitutionForAsyncMethodsWithSuper = false;
/**
* Keeps track of whether expression substitution has been enabled for specific edge cases.
* They are persisted between each SourceFile transformation and should not be reset.
*/
let enabledSubstitutions: TypeScriptSubstitutionFlags;
// This map keeps track of aliases created for classes with decorators to avoid issues
// with the double-binding behavior of classes.
/**
* A map that keeps track of aliases created for classes with decorators to avoid issues
* with the double-binding behavior of classes.
*/
let decoratedClassAliases: Map<Identifier>;
// This map keeps track of currently active aliases defined in `decoratedClassAliases`
// when just-in-time substitution occurs while printing an expression identifier.
/**
* A map that keeps track of currently active aliases defined in `decoratedClassAliases`
* when just-in-time substitution occurs while printing an expression identifier.
*/
let currentDecoratedClassAliases: Map<Identifier>;
// This value keeps track of how deeply nested we are within any containing namespaces
// when performing just-in-time substitution while printing an expression identifier.
/**
* Keeps track of how deeply nested we are within any containing namespaces
* when performing just-in-time substitution while printing an expression identifier.
* If the nest level is greater than zero, then we are performing a substitution
* inside of a namespace and we should perform the more costly checks to determine
* whether the identifier points to an exported declaration.
*/
let namespaceNestLevel: number;
// This array keeps track of containers where `super` is valid, for use with
// just-in-time substitution for `super` expressions inside of async methods.
/**
* This array keeps track of containers where `super` is valid, for use with
* just-in-time substitution for `super` expressions inside of async methods.
*/
let superContainerStack: SuperContainer[];
return transformSourceFile;
/**
* Transform TypeScript-specific syntax in a SourceFile.
*
* @param node A SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
currentSourceFile = node;
node = visitEachChild(node, visitor, context);
@@ -138,8 +160,7 @@ namespace ts {
* @param node The node to visit.
*/
function namespaceElementVisitorWorker(node: Node): Node {
if (node.transformFlags & TransformFlags.TypeScript
|| node.flags & NodeFlags.Export) {
if (node.transformFlags & TransformFlags.TypeScript || isExported(node)) {
// This node is explicitly marked as TypeScript, or is exported at the namespace
// level, so we should transform the node.
node = visitTypeScript(node);
@@ -167,12 +188,25 @@ namespace ts {
* @param node The node to visit.
*/
function classElementVisitorWorker(node: Node) {
if (node.kind === SyntaxKind.Constructor) {
// TypeScript constructors are elided.
return undefined;
}
switch (node.kind) {
case SyntaxKind.Constructor:
// TypeScript constructors are transformed in `transformClassDeclaration`.
// We elide them here as `visitorWorker` checks transform flags, which could
// erronously include an ES6 constructor without TypeScript syntax.
return undefined;
return visitorWorker(node);
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.IndexSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
case SyntaxKind.MethodDeclaration:
// Fallback to the default visit behavior.
return visitorWorker(node);
default:
Debug.fail("Unexpected node.");
break;
}
}
/**
@@ -181,9 +215,9 @@ namespace ts {
* @param node The node to visit.
*/
function visitTypeScript(node: Node): Node {
// TypeScript ambient declarations are elided.
if (node.flags & NodeFlags.Ambient) {
return;
// TypeScript ambient declarations are elided.
return undefined;
}
switch (node.kind) {
@@ -235,8 +269,7 @@ namespace ts {
// TypeScript property declarations are elided.
case SyntaxKind.Constructor:
// TypeScript constructors are elided. The constructor of a class will be
// transformed as part of `transformClassDeclaration`.
// TypeScript constructors are transformed in `transformClassDeclaration`.
return undefined;
case SyntaxKind.ClassDeclaration:
@@ -378,11 +411,7 @@ namespace ts {
*/
function visitClassDeclaration(node: ClassDeclaration): NodeArrayNode<Statement> {
const staticProperties = getInitializedProperties(node, /*isStatic*/ true);
const statements: Statement[] = [];
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
const heritageClauses = visitNodes(node.heritageClauses, visitor, isHeritageClause);
const members = transformClassMembers(node, heritageClauses !== undefined);
let decoratedClassAlias: Identifier;
const hasExtendsClause = getClassExtendsHeritageClauseElement(node) !== undefined;
// emit name if
// - node has a name
@@ -393,166 +422,28 @@ namespace ts {
name = getGeneratedNameForNode(node);
}
if (node.decorators) {
// When we emit an ES6 class that has a class decorator, we must tailor the
// emit to certain specific cases.
//
// In the simplest case, we emit the class declaration as a let declaration, and
// evaluate decorators after the close of the class body:
//
// [Example 1]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C = class C {
// class C { | }
// } | C = __decorate([dec], C);
// ---------------------------------------------------------------------
// @dec | let C = class C {
// export class C { | }
// } | C = __decorate([dec], C);
// | export { C };
// ---------------------------------------------------------------------
//
// If a class declaration contains a reference to itself *inside* of the class body,
// this introduces two bindings to the class: One outside of the class body, and one
// inside of the class body. If we apply decorators as in [Example 1] above, there
// is the possibility that the decorator `dec` will return a new value for the
// constructor, which would result in the binding inside of the class no longer
// pointing to the same reference as the binding outside of the class.
//
// As a result, we must instead rewrite all references to the class *inside* of the
// class body to instead point to a local temporary alias for the class:
//
// [Example 2]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C_1;
// class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// ---------------------------------------------------------------------
// @dec | let C_1;
// export class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// | export { C };
// ---------------------------------------------------------------------
//
// If a class declaration is the default export of a module, we instead emit
// the export after the decorated declaration:
//
// [Example 3]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let default_1 = class {
// export default class { | }
// } | default_1 = __decorate([dec], default_1);
// | export default default_1;
// ---------------------------------------------------------------------
// @dec | let C = class C {
// export default class C { | }
// } | C = __decorate([dec], C);
// | export default C;
// ---------------------------------------------------------------------
//
// If the class declaration is the default export and a reference to itself
// inside of the class body, we must emit both an alias for the class *and*
// move the export after the declaration:
//
// [Example 4]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C_1;
// export default class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// | export default C;
// ---------------------------------------------------------------------
//
// class ${name} ${heritageClauses} {
// ${members}
// }
let classExpression: Expression = setOriginalNode(
createClassExpression(
name,
heritageClauses,
members,
/*location*/ node
),
node
);
// Record an alias to avoid class double-binding.
if (resolver.getNodeCheckFlags(getOriginalNode(node)) & NodeCheckFlags.ClassWithBodyScopedClassBinding) {
enableExpressionSubstitutionForDecoratedClasses();
decoratedClassAlias = makeUniqueName(node.name ? node.name.text : "default");
decoratedClassAliases[getOriginalNodeId(node)] = decoratedClassAlias;
// We emit the class alias as a `let` declaration here so that it has the same
// TDZ as the class.
// let ${decoratedClassAlias};
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(decoratedClassAlias)
],
/*location*/ undefined,
NodeFlags.Let)
)
);
// ${decoratedClassAlias} = ${classExpression}
classExpression = createAssignment(
cloneNode(decoratedClassAlias),
classExpression,
/*location*/ node);
}
// let ${name} = ${classExpression};
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
name,
classExpression
)
],
/*location*/ undefined,
NodeFlags.Let)
)
);
}
else {
let decoratedClassAlias: Identifier;
const statements: Statement[] = [];
if (!node.decorators) {
// ${modifiers} class ${name} ${heritageClauses} {
// ${members}
// }
addNode(statements,
setOriginalNode(
createClassDeclaration(
modifiers,
visitNodes(node.modifiers, visitor, isModifier),
name,
heritageClauses,
members,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
/*location*/ node
),
node
)
);
}
else {
decoratedClassAlias = addClassDeclarationHeadWithDecorators(statements, node, name, hasExtendsClause);
}
// Emit static property assignment. Because classDeclaration is lexically evaluated,
// it is safe to emit static property assignment after classDeclaration
@@ -577,13 +468,168 @@ namespace ts {
addNode(statements, createExportDefault(name));
}
else if (isNamedExternalModuleExport(node)) {
addNode(statements, createModuleExport(name));
addNode(statements, createExternalModuleExport(name));
}
}
return createNodeArrayNode(statements);
}
/**
* Transforms a decorated class declaration and appends the resulting statements. If
* the class requires an alias to avoid issues with double-binding, the alias is returned.
*
* @param node A ClassDeclaration node.
* @param name The name of the class.
* @param hasExtendsClause A value indicating whether
*/
function addClassDeclarationHeadWithDecorators(statements: Statement[], node: ClassDeclaration, name: Identifier, hasExtendsClause: boolean) {
// When we emit an ES6 class that has a class decorator, we must tailor the
// emit to certain specific cases.
//
// In the simplest case, we emit the class declaration as a let declaration, and
// evaluate decorators after the close of the class body:
//
// [Example 1]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C = class C {
// class C { | }
// } | C = __decorate([dec], C);
// ---------------------------------------------------------------------
// @dec | let C = class C {
// export class C { | }
// } | C = __decorate([dec], C);
// | export { C };
// ---------------------------------------------------------------------
//
// If a class declaration contains a reference to itself *inside* of the class body,
// this introduces two bindings to the class: One outside of the class body, and one
// inside of the class body. If we apply decorators as in [Example 1] above, there
// is the possibility that the decorator `dec` will return a new value for the
// constructor, which would result in the binding inside of the class no longer
// pointing to the same reference as the binding outside of the class.
//
// As a result, we must instead rewrite all references to the class *inside* of the
// class body to instead point to a local temporary alias for the class:
//
// [Example 2]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C_1;
// class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// ---------------------------------------------------------------------
// @dec | let C_1;
// export class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// | export { C };
// ---------------------------------------------------------------------
//
// If a class declaration is the default export of a module, we instead emit
// the export after the decorated declaration:
//
// [Example 3]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let default_1 = class {
// export default class { | }
// } | default_1 = __decorate([dec], default_1);
// | export default default_1;
// ---------------------------------------------------------------------
// @dec | let C = class C {
// export default class C { | }
// } | C = __decorate([dec], C);
// | export default C;
// ---------------------------------------------------------------------
//
// If the class declaration is the default export and a reference to itself
// inside of the class body, we must emit both an alias for the class *and*
// move the export after the declaration:
//
// [Example 4]
// ---------------------------------------------------------------------
// TypeScript | Javascript
// ---------------------------------------------------------------------
// @dec | let C_1;
// export default class C { | let C = C_1 = class C {
// static x() { return C.y; } | static x() { return C_1.y; }
// static y = 1; | }
// } | C.y = 1;
// | C = C_1 = __decorate([dec], C);
// | export default C;
// ---------------------------------------------------------------------
//
// ... = class ${name} ${heritageClauses} {
// ${members}
// }
let classExpression: Expression = setOriginalNode(
createClassExpression(
name,
visitNodes(node.heritageClauses, visitor, isHeritageClause),
transformClassMembers(node, hasExtendsClause),
/*location*/ node
),
node
);
// Record an alias to avoid class double-binding.
let decoratedClassAlias: Identifier;
if (resolver.getNodeCheckFlags(getOriginalNode(node)) & NodeCheckFlags.DecoratedClassWithSelfReference) {
enableExpressionSubstitutionForDecoratedClasses();
decoratedClassAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? node.name.text : "default");
decoratedClassAliases[getOriginalNodeId(node)] = decoratedClassAlias;
// We emit the class alias as a `let` declaration here so that it has the same
// TDZ as the class.
// let ${decoratedClassAlias};
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(decoratedClassAlias)
],
/*location*/ undefined,
NodeFlags.Let)
)
);
// ${decoratedClassAlias} = ${classExpression}
classExpression = createAssignment(
decoratedClassAlias,
classExpression,
/*location*/ node);
}
// let ${name} = ${classExpression};
addNode(statements,
createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([
createVariableDeclaration(
name,
classExpression
)
],
/*location*/ undefined,
NodeFlags.Let)
)
);
return decoratedClassAlias;
}
/**
* Transforms a class expression with TypeScript syntax into compatible ES6.
*
@@ -640,7 +686,7 @@ namespace ts {
const members: ClassElement[] = [];
addNode(members, transformConstructor(node, hasExtendsClause));
addNodes(members, visitNodes(node.members, classElementVisitor, isClassElement));
return members;
return createNodeArray(members, /*location*/ node.members);
}
/**
@@ -691,7 +737,7 @@ namespace ts {
function transformConstructorParameters(constructor: ConstructorDeclaration, hasExtendsClause: boolean) {
return constructor
? visitNodes(constructor.parameters, visitor, isParameter)
: hasExtendsClause ? [createRestParameter(makeUniqueName("args"))] : [];
: hasExtendsClause ? [createRestParameter(createUniqueName("args"))] : [];
}
/**
@@ -1646,7 +1692,7 @@ namespace ts {
return createLiteral(name.text);
}
else {
return getSynthesizedNode(name);
return getSynthesizedClone(name);
}
}
@@ -1815,7 +1861,7 @@ namespace ts {
if (isNamespaceExport(node)) {
return createNodeArrayNode([
func,
createNamespaceExport(getSynthesizedNode(node.name), getSynthesizedNode(node.name))
createNamespaceExport(getSynthesizedClone(node.name), getSynthesizedClone(node.name))
]);
}
@@ -2103,14 +2149,15 @@ namespace ts {
}
const savedCurrentNamespaceLocalName = currentNamespaceLocalName;
const modifiers = visitNodes(node.modifiers, visitor, isModifier);
const statements: Statement[] = [];
let location: TextRange = node;
if (!isNamespaceExport(node)) {
if (!isExported(node) || (isExternalModuleExport(node) && isFirstDeclarationOfKind(node, SyntaxKind.EnumDeclaration))) {
// Emit a VariableStatement if the enum is not exported, or is the first enum
// with the same name exported from an external module.
addNode(statements,
createVariableStatement(
modifiers,
visitNodes(node.modifiers, visitor, isModifier),
createVariableDeclarationList([
createVariableDeclaration(node.name)
]),
@@ -2179,7 +2226,7 @@ namespace ts {
*
* @param member The enum member node.
*/
function transformEnumMember(member: EnumMember) {
function transformEnumMember(member: EnumMember): Statement {
const name = getExpressionForPropertyName(member);
return createStatement(
createAssignment(
@@ -2421,7 +2468,7 @@ namespace ts {
// exports.${name} = ${moduleReference};
return setOriginalNode(
createNamespaceExport(
getSynthesizedNode(node.name),
getSynthesizedClone(node.name),
moduleReference,
node
),
@@ -2443,14 +2490,31 @@ namespace ts {
&& (isExternalModule(currentSourceFile) || !resolver.isTopLevelValueImportEqualsWithEntityName(node));
}
/**
* Gets a value indicating whether the node is exported.
*
* @param node The node to test.
*/
function isExported(node: Node) {
return (node.flags & NodeFlags.Export) !== 0;
}
/**
* Gets a value indicating whether the node is exported from a namespace.
*
* @param node The node to test.
*/
function isNamespaceExport(node: Node) {
return currentNamespace !== undefined && isExported(node);
}
/**
* Gets a value indicating whether the node is exported from an external module.
*
* @param node The node to test.
*/
function isExternalModuleExport(node: Node) {
return currentNamespace === undefined
&& (node.flags & NodeFlags.Export) !== 0;
return currentNamespace === undefined && isExported(node);
}
/**
@@ -2474,13 +2538,14 @@ namespace ts {
}
/**
* Gets a value indicating whether the node is exported from a namespace.
* Gets a value indicating whether a node is the first declaration of its kind.
*
* @param node The node to test.
* @param node A Declaration node.
* @param kind The SyntaxKind to find among related declarations.
*/
function isNamespaceExport(node: Node) {
return currentNamespace !== undefined
&& (node.flags & NodeFlags.Export) !== 0;
function isFirstDeclarationOfKind(node: Declaration, kind: SyntaxKind) {
const original = getOriginalNode(node);
return original.symbol && getDeclarationOfKind(original.symbol, kind) === original;
}
/**
@@ -2500,7 +2565,7 @@ namespace ts {
);
}
function createModuleExport(exportName: Identifier) {
function createExternalModuleExport(exportName: Identifier) {
return createExportDeclaration(
createNamedExports([
createExportSpecifier(exportName)
@@ -2509,14 +2574,14 @@ namespace ts {
}
function getNamespaceMemberName(name: Identifier): Expression {
name = getSynthesizedNode(name);
name = getSynthesizedClone(name);
return currentNamespaceLocalName
? createPropertyAccess(currentNamespaceLocalName, name)
: name;
}
function getDeclarationName(node: ClassExpression | ClassDeclaration | FunctionDeclaration) {
return node.name ? getSynthesizedNode(node.name) : getGeneratedNameForNode(node);
return node.name ? getSynthesizedClone(node.name) : getGeneratedNameForNode(node);
}
function getClassPrototype(node: ClassExpression | ClassDeclaration) {
@@ -2533,12 +2598,13 @@ namespace ts {
previousOnBeforeEmitNode(node);
const kind = node.kind;
if (hasEnabledExpressionSubstitutionForDecoratedClasses
&& kind === SyntaxKind.ClassDeclaration && node.decorators) {
if (enabledSubstitutions & TypeScriptSubstitutionFlags.DecoratedClasses
&& kind === SyntaxKind.ClassDeclaration
&& node.decorators) {
currentDecoratedClassAliases[getOriginalNodeId(node)] = decoratedClassAliases[getOriginalNodeId(node)];
}
if (hasEnabledExpressionSubstitutionForAsyncMethodsWithSuper
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports
&& (kind === SyntaxKind.ClassDeclaration
|| kind === SyntaxKind.Constructor
|| kind === SyntaxKind.MethodDeclaration
@@ -2552,7 +2618,7 @@ namespace ts {
superContainerStack.push(<SuperContainer>node);
}
if (hasEnabledExpressionSubstitutionForNamespaceExports
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports
&& kind === SyntaxKind.ModuleDeclaration) {
namespaceNestLevel++;
}
@@ -2562,12 +2628,13 @@ namespace ts {
previousOnAfterEmitNode(node);
const kind = node.kind;
if (hasEnabledExpressionSubstitutionForDecoratedClasses
&& kind === SyntaxKind.ClassDeclaration && node.decorators) {
if (enabledSubstitutions & TypeScriptSubstitutionFlags.DecoratedClasses
&& kind === SyntaxKind.ClassDeclaration
&& node.decorators) {
currentDecoratedClassAliases[getOriginalNodeId(node)] = undefined;
}
if (hasEnabledExpressionSubstitutionForAsyncMethodsWithSuper
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports
&& (kind === SyntaxKind.ClassDeclaration
|| kind === SyntaxKind.Constructor
|| kind === SyntaxKind.MethodDeclaration
@@ -2579,7 +2646,7 @@ namespace ts {
}
}
if (hasEnabledExpressionSubstitutionForNamespaceExports
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports
&& kind === SyntaxKind.ModuleDeclaration) {
namespaceNestLevel--;
}
@@ -2593,7 +2660,7 @@ namespace ts {
return substituteExpressionIdentifier(<Identifier>node);
}
if (hasEnabledExpressionSubstitutionForAsyncMethodsWithSuper) {
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports) {
switch (node.kind) {
case SyntaxKind.CallExpression:
return substituteCallExpression(<CallExpression>node);
@@ -2608,9 +2675,9 @@ namespace ts {
}
function substituteExpressionIdentifier(node: Identifier): Expression {
if (hasEnabledExpressionSubstitutionForDecoratedClasses
if (enabledSubstitutions & TypeScriptSubstitutionFlags.DecoratedClasses
&& !nodeIsSynthesized(node)
&& resolver.getNodeCheckFlags(node) & NodeCheckFlags.BodyScopedClassBinding) {
&& resolver.getNodeCheckFlags(node) & NodeCheckFlags.SelfReferenceInDecoratedClass) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
@@ -2624,7 +2691,7 @@ namespace ts {
}
}
if (hasEnabledExpressionSubstitutionForNamespaceExports
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports
&& namespaceNestLevel > 0) {
// If we are nested within a namespace declaration, we may need to qualifiy
// an identifier that is exported from a merged namespace.
@@ -2691,8 +2758,8 @@ namespace ts {
}
function enableExpressionSubstitutionForAsyncMethodsWithSuper() {
if (!hasEnabledExpressionSubstitutionForAsyncMethodsWithSuper) {
hasEnabledExpressionSubstitutionForAsyncMethodsWithSuper = true;
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports) === 0) {
enabledSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports;
// We need to enable substitutions for call, property access, and element access
// if we need to rewrite super calls.
@@ -2710,8 +2777,8 @@ namespace ts {
}
function enableExpressionSubstitutionForDecoratedClasses() {
if (!hasEnabledExpressionSubstitutionForDecoratedClasses) {
hasEnabledExpressionSubstitutionForDecoratedClasses = true;
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.DecoratedClasses) === 0) {
enabledSubstitutions |= TypeScriptSubstitutionFlags.DecoratedClasses;
// We need to enable substitutions for identifiers. This allows us to
// substitute class names inside of a class declaration.
@@ -2724,8 +2791,8 @@ namespace ts {
}
function enableExpressionSubstitutionForNamespaceExports() {
if (!hasEnabledExpressionSubstitutionForNamespaceExports) {
hasEnabledExpressionSubstitutionForNamespaceExports = true;
if ((enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports) === 0) {
enabledSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports;
// We need to enable substitutions for identifiers. This allows us to
// substitute the names of exported members of a namespace.
+10 -12
View File
@@ -497,16 +497,19 @@ namespace ts {
// @kind(SyntaxKind.StaticKeyword)
export interface Modifier extends Node { }
export const enum TempVariableKind {
Auto, // Automatically generated identifier
Loop, // Automatically generated identifier with a preference for '_i'
export const enum GeneratedIdentifierKind {
None, // Not automatically generated.
Auto, // Automatically generated identifier.
Loop, // Automatically generated identifier with a preference for '_i'.
Unique, // Unique name based on the 'text' property.
Node, // Unique name based on the node in the 'original' property.
}
// @kind(SyntaxKind.Identifier)
export interface Identifier extends PrimaryExpression {
text: string; // Text of identifier (with escapes converted to characters)
tempKind?: TempVariableKind; // Specifies whether to auto-generate the text for an identifier.
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.
}
// @kind(SyntaxKind.QualifiedName)
@@ -2088,8 +2091,8 @@ namespace ts {
CapturedBlockScopedBinding = 0x00020000, // Block-scoped binding that is captured in some function
BlockScopedBindingInLoop = 0x00040000, // Block-scoped binding with declaration nested inside iteration statement
HasSeenSuperCall = 0x00080000, // Set during the binding when encounter 'super'
ClassWithBodyScopedClassBinding = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
BodyScopedClassBinding = 0x00200000, // Binding to a decorated class inside of the class's body.
DecoratedClassWithSelfReference = 0x00100000, // Decorated class that contains a binding to itself inside of the class body.
SelfReferenceInDecoratedClass = 0x00200000, // Binding to a decorated class inside of the class's body.
}
/* @internal */
@@ -2470,7 +2473,6 @@ namespace ts {
allowJs?: boolean;
/* @internal */ stripInternal?: boolean;
/* @internal */ experimentalTransforms?: boolean;
/* @internal */ transformCompatibleEmit?: boolean;
// Skip checking lib.d.ts to help speed up tests.
/* @internal */ skipDefaultLibCheck?: boolean;
@@ -2805,7 +2807,7 @@ namespace ts {
SingleLine = 1 << 6, // The contents of this node should be emit on a single line.
AdviseOnEmitNode = 1 << 7, // The node printer should invoke the onBeforeEmitNode and onAfterEmitNode callbacks when printing this node.
IsNotEmittedNode = 1 << 8, // Is a node that is not emitted but whose comments should be preserved if possible.
EmitCommentsOfNotEmittedParent = 1 << 8, // Emits comments of missing parent nodes.
EmitCommentsOfNotEmittedParent = 1 << 9, // Emits comments of missing parent nodes.
}
/** Additional context provided to `visitEachChild` */
@@ -2825,10 +2827,6 @@ namespace ts {
setNodeEmitFlags<T extends Node>(node: T, flags: NodeEmitFlags): T;
hoistFunctionDeclaration(node: FunctionDeclaration): void;
hoistVariableDeclaration(node: Identifier): void;
isUniqueName(name: string): boolean;
getGeneratedNameForNode(node: Node): Identifier;
nodeHasGeneratedName(node: Node): boolean;
makeUniqueName(baseName: string): Identifier;
/**
* Hook used by transformers to substitute non-expression identifiers
+16 -7
View File
@@ -1352,7 +1352,7 @@ namespace ts {
export function isNodeDescendentOf(node: Node, ancestor: Node): boolean {
export function isNodeDescendantOf(node: Node, ancestor: Node): boolean {
while (node) {
if (node === ancestor) return true;
node = node.parent;
@@ -2318,11 +2318,11 @@ namespace ts {
writer.write(" ");
}
let emitInterveningSeperator = false;
let emitInterveningSeparator = false;
for (const comment of comments) {
if (emitInterveningSeperator) {
if (emitInterveningSeparator) {
writer.write(" ");
emitInterveningSeperator = false;
emitInterveningSeparator = false;
}
writeComment(text, lineMap, writer, comment, newLine);
@@ -2330,11 +2330,11 @@ namespace ts {
writer.writeLine();
}
else {
emitInterveningSeperator = true;
emitInterveningSeparator = true;
}
}
if (emitInterveningSeperator && trailingSeparator) {
if (emitInterveningSeparator && trailingSeparator) {
writer.write(" ");
}
}
@@ -2744,7 +2744,7 @@ namespace ts {
}
return collapse === TextRangeCollapse.CollapseToStart
? { pos: range.pos, end: range.end }
? { pos: range.pos, end: range.pos }
: { pos: range.end, end: range.end };
}
@@ -2865,6 +2865,11 @@ namespace ts {
return node.kind === SyntaxKind.Identifier;
}
export function isGeneratedIdentifier(node: Node): node is Identifier {
// Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`.
return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None;
}
// Keywords
export function isModifier(node: Node): node is Modifier {
@@ -3263,6 +3268,10 @@ namespace ts {
return node.kind === SyntaxKind.JsxSpreadAttribute;
}
export function isJsxAttribute(node: Node): node is JsxAttribute {
return node.kind === SyntaxKind.JsxAttribute;
}
// Clauses
export function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause {
@@ -28,9 +28,9 @@ var Point = (function () {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
var Point;
(function (Point) {
Point.Origin = ""; //expected duplicate identifier error
@@ -42,9 +42,9 @@ var A;
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
A.Point = Point;
var Point;
(function (Point) {
@@ -28,9 +28,9 @@ var Point = (function () {
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
var Point;
(function (Point) {
var Origin = ""; // not an error, since not exported
@@ -42,9 +42,9 @@ var A;
this.x = x;
this.y = y;
}
Point.Origin = { x: 0, y: 0 };
return Point;
}());
Point.Origin = { x: 0, y: 0 };
A.Point = Point;
var Point;
(function (Point) {
@@ -7,6 +7,6 @@ class AtomicNumbers {
var AtomicNumbers = (function () {
function AtomicNumbers() {
}
AtomicNumbers.H = 1;
return AtomicNumbers;
}());
AtomicNumbers.H = 1;
@@ -14,7 +14,6 @@ obj[Symbol.foo];
var Symbol;
var obj = (_a = {},
_a[Symbol.foo] = 0,
_a
);
_a);
obj[Symbol.foo];
var _a;
@@ -38,9 +38,9 @@ define(["require", "exports"], function (require, exports) {
function C1() {
this.m1 = 42;
}
C1.s1 = true;
return C1;
}());
C1.s1 = true;
exports.C1 = C1;
(function (E1) {
E1[E1["A"] = 0] = "A";
+1 -1
View File
@@ -37,9 +37,9 @@ var Point = (function () {
Point.prototype.getDist = function () {
return Math.sqrt(this.x * this.x + this.y * this.y);
};
Point.origin = new Point(0, 0);
return Point;
}());
Point.origin = new Point(0, 0);
var Point3D = (function (_super) {
__extends(Point3D, _super);
function Point3D(x, y, z, m) {
@@ -163,31 +163,35 @@ function foo8() {
var x;
}
function foo9() {
var y = (function () {
function class_3() {
}
class_3.a = x;
return class_3;
}());
var y = (_a = (function () {
function class_3() {
}
return class_3;
}()),
_a.a = x,
_a);
var x;
var _a;
}
function foo10() {
var A = (function () {
function A() {
}
A.a = x;
return A;
}());
A.a = x;
var x;
}
function foo11() {
function f() {
var y = (function () {
function class_4() {
}
class_4.a = x;
return class_4;
}());
var y = (_a = (function () {
function class_4() {
}
return class_4;
}()),
_a.a = x,
_a);
var _a;
}
var x;
}
+1 -1
View File
@@ -5,6 +5,6 @@ class foo { constructor() { static f = 3; } }
var foo = (function () {
function foo() {
}
foo.f = 3;
return foo;
}());
foo.f = 3;
@@ -12,10 +12,10 @@ var v = ;
var C = (function () {
function C() {
}
C.p = 1;
C = __decorate([
decorate
], C);
return C;
}());
C.p = 1;
C = __decorate([
decorate
], C);
;
@@ -2,10 +2,12 @@
var v = class C { static a = 1; static b = 2 };
//// [classExpressionWithStaticProperties1.js]
var v = (function () {
function C() {
}
C.a = 1;
C.b = 2;
return C;
}());
var v = (_a = (function () {
function C() {
}
return C;
}()),
_a.a = 1,
_a.b = 2,
_a);
var _a;
@@ -2,9 +2,11 @@
var v = class C { static a = 1; static b };
//// [classExpressionWithStaticProperties2.js]
var v = (function () {
function C() {
}
C.a = 1;
return C;
}());
var v = (_a = (function () {
function C() {
}
return C;
}()),
_a.a = 1,
_a);
var _a;
@@ -27,9 +27,9 @@ var CCC = (function () {
this.y = aaa;
this.y = ''; // was: error, cannot assign string to number
}
CCC.staticY = aaa; // This shouldnt be error
return CCC;
}());
CCC.staticY = aaa; // This shouldnt be error
// above is equivalent to this:
var aaaa = 1;
var CCCC = (function () {
@@ -40,12 +40,12 @@ var Test = (function () {
console.log(field); // Using field here shouldnt be error
};
}
Test.staticMessageHandler = function () {
var field = Test.field;
console.log(field); // Using field here shouldnt be error
};
return Test;
}());
Test.staticMessageHandler = function () {
var field = Test.field;
console.log(field); // Using field here shouldnt be error
};
var field1;
var Test1 = (function () {
function Test1(field1) {
@@ -56,8 +56,8 @@ var Test1 = (function () {
// it would resolve to private field1 and thats not what user intended here.
};
}
Test1.staticMessageHandler = function () {
console.log(field1); // This shouldnt be error as its a static property
};
return Test1;
}());
Test1.staticMessageHandler = function () {
console.log(field1); // This shouldnt be error as its a static property
};
@@ -32,9 +32,9 @@ var C = (function () {
}
C.prototype.c = function () { return ''; };
C.f = function () { return ''; };
C.g = function () { return ''; };
return C;
}());
C.g = function () { return ''; };
var c = new C();
var r1 = c.x;
var r2 = c.a;
@@ -42,9 +42,9 @@ var C = (function () {
}
C.prototype.c = function () { return ''; };
C.f = function () { return ''; };
C.g = function () { return ''; };
return C;
}());
C.g = function () { return ''; };
var D = (function (_super) {
__extends(D, _super);
function D() {
@@ -30,9 +30,9 @@ var C = (function () {
}
C.prototype.c = function () { return ''; };
C.f = function () { return ''; };
C.g = function () { return ''; };
return C;
}());
C.g = function () { return ''; };
// all of these are valid
var c = new C();
var r1 = c.x;
@@ -16,10 +16,10 @@ module Clod {
var Clod = (function () {
function Clod() {
}
Clod.x = 10;
Clod.y = 10;
return Clod;
}());
Clod.x = 10;
Clod.y = 10;
var Clod;
(function (Clod) {
var p = Clod.x;
@@ -24,13 +24,13 @@ class test {
var test = (function () {
function test() {
}
/**
* p1 comment appears in output
*/
test.p1 = "";
/**
* p3 comment appears in output
*/
test.p3 = "";
return test;
}());
/**
* p1 comment appears in output
*/
test.p1 = "";
/**
* p3 comment appears in output
*/
test.p3 = "";
@@ -19,9 +19,9 @@ var C1 = (function () {
function C1() {
this.m1 = 42;
}
C1.s1 = true;
return C1;
}());
C1.s1 = true;
exports.C1 = C1;
//// [foo_1.js]
"use strict";
@@ -37,9 +37,9 @@ var C1 = (function () {
function C1() {
this.m1 = 42;
}
C1.s1 = true;
return C1;
}());
C1.s1 = true;
exports.C1 = C1;
(function (E1) {
E1[E1["A"] = 0] = "A";
@@ -32,6 +32,5 @@ var v = (_a = {},
_a[true] = function () { },
_a["hello bye"] = function () { },
_a["hello " + a + " bye"] = function () { },
_a
);
_a);
var _a;
@@ -68,6 +68,5 @@ var v = (_a = {},
enumerable: true,
configurable: true
}),
_a
);
_a);
var _a;
@@ -26,6 +26,6 @@ var C = (function () {
this[s + n] = 2;
this["hello bye"] = 0;
}
C["hello " + a + " bye"] = 0;
return C;
}());
C["hello " + a + " bye"] = 0;
@@ -9,7 +9,6 @@ function foo() {
function foo() {
var obj = (_a = {},
_a[this.bar] = 0,
_a
);
_a);
var _a;
}
@@ -10,7 +10,6 @@ var M;
(function (M) {
var obj = (_a = {},
_a[this.bar] = 0,
_a
);
_a);
var _a;
})(M || (M = {}));
@@ -17,6 +17,5 @@ var v = (_a = {},
enumerable: true,
configurable: true
}),
_a
);
_a);
var _a;
@@ -6,6 +6,5 @@ var obj = {
//// [computedPropertyNames20_ES5.js]
var obj = (_a = {},
_a[this.bar] = 0,
_a
);
_a);
var _a;
@@ -15,8 +15,7 @@ var C = (function () {
C.prototype.bar = function () {
var obj = (_a = {},
_a[this.bar()] = function () { },
_a
);
_a);
return 0;
var _a;
};
@@ -35,8 +35,7 @@ var C = (function (_super) {
C.prototype.foo = function () {
var obj = (_a = {},
_a[_super.prototype.bar.call(this)] = function () { },
_a
);
_a);
return 0;
var _a;
};
@@ -27,8 +27,7 @@ var C = (function (_super) {
_super.call(this);
var obj = (_a = {},
_a[(_super.call(this), "prop")] = function () { },
_a
);
_a);
var _a;
}
return C;
@@ -19,8 +19,7 @@ var C = (function () {
(function () {
var obj = (_a = {},
_a[_this.bar()] = function () { },
_a
);
_a);
var _a;
});
return 0;
@@ -36,8 +36,7 @@ var C = (function (_super) {
// illegal, and not capturing this is consistent with
//treatment of other similar violations.
_a[(_super.call(this), "prop")] = function () { },
_a
);
_a);
var _a;
});
}
@@ -39,8 +39,7 @@ var C = (function (_super) {
(function () {
var obj = (_a = {},
_a[_super.prototype.bar.call(_this)] = function () { },
_a
);
_a);
var _a;
});
return 0;
@@ -17,8 +17,7 @@ var C = (function () {
C.prototype.bar = function () {
var obj = (_a = {},
_a[foo()] = function () { },
_a
);
_a);
return 0;
var _a;
};
@@ -17,8 +17,7 @@ var C = (function () {
C.bar = function () {
var obj = (_a = {},
_a[foo()] = function () { },
_a
);
_a);
return 0;
var _a;
};
@@ -6,6 +6,5 @@ var o = {
//// [computedPropertyNames46_ES5.js]
var o = (_a = {},
_a["" || 0] = 0,
_a
);
_a);
var _a;
@@ -16,6 +16,5 @@ var E2;
})(E2 || (E2 = {}));
var o = (_a = {},
_a[E1.x || E2.x] = 0,
_a
);
_a);
var _a;
@@ -25,14 +25,11 @@ var E;
var a;
extractIndexer((_a = {},
_a[a] = "",
_a
)); // Should return string
_a)); // Should return string
extractIndexer((_b = {},
_b[E.x] = "",
_b
)); // Should return string
_b)); // Should return string
extractIndexer((_c = {},
_c["" || 0] = "",
_c
)); // Should return any (widened form of undefined)
_c)); // Should return any (widened form of undefined)
var _a, _b, _c;
@@ -62,6 +62,5 @@ var x = (_a = {
}),
,
_a.p2 = 20,
_a
);
_a);
var _a;
@@ -32,6 +32,5 @@ var v = (_a = {},
_a[true] = 0,
_a["hello bye"] = 0,
_a["hello " + a + " bye"] = 0,
_a
);
_a);
var _a;
@@ -58,6 +58,5 @@ var x = (_a = {
}),
,
_a.p2 = 20,
_a
);
_a);
var _a;
@@ -18,6 +18,5 @@ var v = (_a = {},
_a[{}] = 0,
_a[undefined] = undefined,
_a[null] = null,
_a
);
_a);
var _a;
@@ -16,6 +16,5 @@ var v = (_a = {},
_a[p1] = 0,
_a[p2] = 1,
_a[p3] = 2,
_a
);
_a);
var _a;
@@ -13,6 +13,5 @@ var E;
})(E || (E = {}));
var v = (_a = {},
_a[E.member] = 0,
_a
);
_a);
var _a;
@@ -15,7 +15,6 @@ function f() {
var v = (_a = {},
_a[t] = 0,
_a[u] = 1,
_a
);
_a);
var _a;
}
@@ -16,6 +16,5 @@ var v = (_a = {},
_a[f("")] = 0,
_a[f(0)] = 0,
_a[f(true)] = 0,
_a
);
_a);
var _a;
@@ -12,6 +12,5 @@ var o: I = {
var o = (_a = {},
_a[+"foo"] = "",
_a[+"bar"] = 0,
_a
);
_a);
var _a;
@@ -13,6 +13,5 @@ var o: I = {
var o = (_a = {},
_a["" + 0] = function (y) { return y.length; },
_a["" + 1] = function (y) { return y.length; },
_a
);
_a);
var _a;
@@ -13,6 +13,5 @@ var o: I = {
var o = (_a = {},
_a[+"foo"] = function (y) { return y.length; },
_a[+"bar"] = function (y) { return y.length; },
_a
);
_a);
var _a;
@@ -12,6 +12,5 @@ var o: I = {
var o = (_a = {},
_a[+"foo"] = function (y) { return y.length; },
_a[+"bar"] = function (y) { return y.length; },
_a
);
_a);
var _a;
@@ -13,6 +13,5 @@ var o: I = {
var o = (_a = {},
_a["" + "foo"] = "",
_a["" + "bar"] = 0,
_a
);
_a);
var _a;
@@ -13,6 +13,5 @@ var o: I = {
var o = (_a = {},
_a[+"foo"] = "",
_a[+"bar"] = 0,
_a
);
_a);
var _a;
@@ -21,6 +21,5 @@ foo((_a = {
_a["hi" + "bye"] = true,
_a[0 + 1] = 0,
_a[+"hi"] = [0],
_a
));
_a));
var _a;
@@ -21,6 +21,5 @@ foo((_a = {
_a["hi" + "bye"] = true,
_a[0 + 1] = 0,
_a[+"hi"] = [0],
_a
));
_a));
var _a;
@@ -13,6 +13,5 @@ var o: I = {
var o = (_a = {},
_a["" + "foo"] = "",
_a["" + "bar"] = 0,
_a
);
_a);
var _a;
@@ -13,6 +13,5 @@ var o: I = {
var o = (_a = {},
_a[+"foo"] = "",
_a[+"bar"] = 0,
_a
);
_a);
var _a;
@@ -20,8 +20,7 @@ var v = (_a = {},
enumerable: true,
configurable: true
}),
_a
);
_a);
var _a;
@@ -10,7 +10,6 @@ var v = (_a = {},
_a["hello"] = function () {
debugger;
},
_a
);
_a);
var _a;
//# sourceMappingURL=computedPropertyNamesSourceMap2_ES5.js.map
@@ -1,2 +1,2 @@
//// [computedPropertyNamesSourceMap2_ES5.js.map]
{"version":3,"file":"computedPropertyNamesSourceMap2_ES5.js","sourceRoot":"","sources":["computedPropertyNamesSourceMap2_ES5.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG;IACJ,GAAC,OAAO,CAAC,GAAT;QACI,QAAQ,CAAC;IACb,CAAC;;CACJ,CAAA"}
{"version":3,"file":"computedPropertyNamesSourceMap2_ES5.js","sourceRoot":"","sources":["computedPropertyNamesSourceMap2_ES5.ts"],"names":[],"mappings":"AAAA,IAAI,CAAC,GAAG;IACJ,GAAC,OAAO,CAAC,GAAT;QACI,QAAQ,CAAC;IACb,CAAC;OACJ,CAAA"}
@@ -56,23 +56,21 @@ sourceFile:computedPropertyNamesSourceMap2_ES5.ts
>>> },
1 >^^^^
2 > ^
3 > ^^->
3 > ^^^^->
1 >
>
2 > }
1 >Emitted(4, 5) Source(4, 5) + SourceIndex(0)
2 >Emitted(4, 6) Source(4, 6) + SourceIndex(0)
---
>>> _a
>>>);
1->^
2 > ^
3 > ^^^^^^->
>>> _a);
1->^^^^^^^
2 > ^
1->
>}
2 >
1->Emitted(6, 2) Source(5, 2) + SourceIndex(0)
2 >Emitted(6, 3) Source(5, 2) + SourceIndex(0)
2 >
1->Emitted(5, 8) Source(5, 2) + SourceIndex(0)
2 >Emitted(5, 9) Source(5, 2) + SourceIndex(0)
---
>>>var _a;
>>>//# sourceMappingURL=computedPropertyNamesSourceMap2_ES5.js.map
@@ -61,28 +61,32 @@ function getFoo1() {
}());
}
function getFoo2() {
return (function () {
function class_2() {
}
class_2.method1 = function (arg) {
return (_a = (function () {
function class_2() {
}
return class_2;
}()),
_a.method1 = function (arg) {
arg.numProp = 10;
};
class_2.method2 = function (arg) {
},
_a.method2 = function (arg) {
arg.strProp = "hello";
};
return class_2;
}());
},
_a);
var _a;
}
function getFoo3() {
return (function () {
function class_3() {
}
class_3.method1 = function (arg) {
return (_a = (function () {
function class_3() {
}
return class_3;
}()),
_a.method1 = function (arg) {
arg.numProp = 10;
};
class_3.method2 = function (arg) {
},
_a.method2 = function (arg) {
arg.strProp = "hello";
};
return class_3;
}());
},
_a);
var _a;
}
@@ -40,10 +40,10 @@ var C = (function () {
enumerable: true,
configurable: true
});
C.x = 1;
C.y = 1;
return C;
}());
C.x = 1;
C.y = 1;
//// [declFilePrivateStatic.d.ts]
@@ -24,8 +24,8 @@ var C = (function () {
function C() {
}
C.m = function () { };
C = __decorate([
dec
], C);
return C;
}());
C = __decorate([
dec
], C);
@@ -30,12 +30,12 @@ var A = (function () {
}
A.prototype.m = function () {
};
__decorate([
(function (x, p) {
var a = 3;
func(a);
return x;
})
], A.prototype, "m", null);
return A;
}());
__decorate([
(function (x, p) {
var a = 3;
func(a);
return x;
})
], A.prototype, "m", null);
@@ -45,8 +45,8 @@ var Wat = (function () {
Wat.whatever = function () {
// ...
};
__decorate([
filter(function () { return a_1.test == 'abc'; })
], Wat, "whatever", null);
return Wat;
}());
__decorate([
filter(function () { return a_1.test == 'abc'; })
], Wat, "whatever", null);
+10 -10
View File
@@ -45,15 +45,15 @@ var MyComponent = (function () {
}
MyComponent.prototype.method = function (x) {
};
__decorate([
decorator,
__metadata('design:type', Function),
__metadata('design:paramtypes', [Object]),
__metadata('design:returntype', void 0)
], MyComponent.prototype, "method", null);
MyComponent = __decorate([
decorator,
__metadata('design:paramtypes', [service_1.default])
], MyComponent);
return MyComponent;
}());
__decorate([
decorator,
__metadata('design:type', Function),
__metadata('design:paramtypes', [Object]),
__metadata('design:returntype', void 0)
], MyComponent.prototype, "method", null);
MyComponent = __decorate([
decorator,
__metadata('design:paramtypes', [service_1.default])
], MyComponent);
@@ -20,11 +20,11 @@ var MyClass = (function () {
}
MyClass.prototype.doSomething = function () {
};
__decorate([
decorator,
__metadata('design:type', Function),
__metadata('design:paramtypes', []),
__metadata('design:returntype', void 0)
], MyClass.prototype, "doSomething", null);
return MyClass;
}());
__decorate([
decorator,
__metadata('design:type', Function),
__metadata('design:paramtypes', []),
__metadata('design:returntype', void 0)
], MyClass.prototype, "doSomething", null);
@@ -31,10 +31,10 @@ var B = (function () {
function B() {
this.x = new A();
}
__decorate([
decorator,
__metadata('design:type', Object)
], B.prototype, "x", void 0);
return B;
}());
__decorate([
decorator,
__metadata('design:type', Object)
], B.prototype, "x", void 0);
exports.B = B;
@@ -31,10 +31,10 @@ var B = (function () {
function B() {
this.x = new A();
}
__decorate([
decorator,
__metadata('design:type', A)
], B.prototype, "x", void 0);
return B;
}());
__decorate([
decorator,
__metadata('design:type', A)
], B.prototype, "x", void 0);
exports.B = B;
@@ -44,10 +44,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.db])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.db])
], MyClass);
exports.MyClass = MyClass;
@@ -44,10 +44,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.db])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.db])
], MyClass);
exports.MyClass = MyClass;
@@ -44,10 +44,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db.db])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db.db])
], MyClass);
exports.MyClass = MyClass;
@@ -44,10 +44,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [Object])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [Object])
], MyClass);
exports.MyClass = MyClass;
@@ -45,10 +45,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.default])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.default])
], MyClass);
exports.MyClass = MyClass;
@@ -45,10 +45,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.default])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [db_1.default])
], MyClass);
exports.MyClass = MyClass;
@@ -45,10 +45,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [Object])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [Object])
], MyClass);
exports.MyClass = MyClass;
@@ -44,10 +44,10 @@ var MyClass = (function () {
this.db = db;
this.db.doSomething();
}
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [database.db])
], MyClass);
return MyClass;
}());
MyClass = __decorate([
someDecorator,
__metadata('design:paramtypes', [database.db])
], MyClass);
exports.MyClass = MyClass;
@@ -15,8 +15,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var C = (function () {
function C() {
}
C = __decorate([
dec
], C);
return C;
}());
C = __decorate([
dec
], C);
@@ -16,9 +16,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var C = (function () {
function C() {
}
C = __decorate([
dec
], C);
return C;
}());
C = __decorate([
dec
], C);
exports.C = C;
@@ -16,8 +16,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var C = (function () {
function C() {
}
C = __decorate([
dec
], C);
return C;
}());
C = __decorate([
dec
], C);
@@ -15,8 +15,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var C = (function () {
function C() {
}
C = __decorate([
dec()
], C);
return C;
}());
C = __decorate([
dec()
], C);
@@ -15,8 +15,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var C = (function () {
function C() {
}
C = __decorate([
dec()
], C);
return C;
}());
C = __decorate([
dec()
], C);
@@ -15,8 +15,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
var C = (function () {
function C() {
}
C = __decorate([
dec()
], C);
return C;
}());
C = __decorate([
dec()
], C);
@@ -20,8 +20,8 @@ var C = (function () {
enumerable: true,
configurable: true
});
__decorate([
dec
], C.prototype, "accessor", null);
return C;
}());
__decorate([
dec
], C.prototype, "accessor", null);
@@ -20,8 +20,8 @@ var C = (function () {
enumerable: true,
configurable: true
});
__decorate([
dec
], C.prototype, "accessor", null);
return C;
}());
__decorate([
dec
], C.prototype, "accessor", null);
@@ -20,8 +20,8 @@ var C = (function () {
enumerable: true,
configurable: true
});
__decorate([
dec
], C.prototype, "accessor", null);
return C;
}());
__decorate([
dec
], C.prototype, "accessor", null);
@@ -20,8 +20,8 @@ var C = (function () {
enumerable: true,
configurable: true
});
__decorate([
dec
], C.prototype, "accessor", null);
return C;
}());
__decorate([
dec
], C.prototype, "accessor", null);
@@ -20,8 +20,8 @@ var C = (function () {
enumerable: true,
configurable: true
});
__decorate([
dec
], C.prototype, "accessor", null);
return C;
}());
__decorate([
dec
], C.prototype, "accessor", null);

Some files were not shown because too many files have changed in this diff Show More