diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 09836c4b43e..05c031c73b9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17385,6 +17385,11 @@ namespace ts { function isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean { node = getParseTreeNode(node); + // Purely synthesized nodes are always emitted. + if (node === undefined) { + return true; + } + if (isAliasSymbolDeclaration(node)) { const symbol = getSymbolOfNode(node); if (symbol && getSymbolLinks(symbol).referenced) { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index d9272fb2b62..aba9d1c037b 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -415,6 +415,11 @@ namespace ts { name: "strictNullChecks", type: "boolean", description: Diagnostics.Enable_strict_null_checks + }, + { + name: "importHelpers", + type: "boolean", + description: Diagnostics.Import_emit_helpers_from_tslib } ]; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 034bd27b147..085a1043456 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2772,6 +2772,10 @@ "category": "Error", "code": 6131 }, + "Import emit helpers from 'tslib'.": { + "category": "Message", + "code": 6132 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 868ede1b0a8..a3b76996844 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2106,48 +2106,56 @@ const _super = (function (geti, seti) { } function emitEmitHelpers(node: SourceFile) { + // Only emit helpers if the user did not say otherwise. + if (compilerOptions.noEmitHelpers) { + return false; + } + + // Don't emit helpers if we can import them. + if (compilerOptions.importHelpers + && (isExternalModule(node) || compilerOptions.isolatedModules)) { + return false; + } + let helpersEmitted = false; - // Only emit helpers if the user did not say otherwise. - if (!compilerOptions.noEmitHelpers) { - // Only Emit __extends function when target ES5. - // For target ES6 and above, we can emit classDeclaration as is. - if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) { - writeLines(extendsHelper); - extendsEmitted = true; - helpersEmitted = true; + // Only Emit __extends function when target ES5. + // For target ES6 and above, we can emit classDeclaration as is. + if ((languageVersion < ScriptTarget.ES6) && (!extendsEmitted && node.flags & NodeFlags.HasClassExtends)) { + writeLines(extendsHelper); + extendsEmitted = true; + helpersEmitted = true; + } + + if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasJsxSpreadAttribute)) { + writeLines(assignHelper); + assignEmitted = true; + } + + if (!decorateEmitted && node.flags & NodeFlags.HasDecorators) { + writeLines(decorateHelper); + if (compilerOptions.emitDecoratorMetadata) { + writeLines(metadataHelper); } - if (compilerOptions.jsx !== JsxEmit.Preserve && !assignEmitted && (node.flags & NodeFlags.HasJsxSpreadAttribute)) { - writeLines(assignHelper); - assignEmitted = true; - } + decorateEmitted = true; + helpersEmitted = true; + } - if (!decorateEmitted && node.flags & NodeFlags.HasDecorators) { - writeLines(decorateHelper); - if (compilerOptions.emitDecoratorMetadata) { - writeLines(metadataHelper); - } + if (!paramEmitted && node.flags & NodeFlags.HasParamDecorators) { + writeLines(paramHelper); + paramEmitted = true; + helpersEmitted = true; + } - decorateEmitted = true; - helpersEmitted = true; - } + if (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions) { + writeLines(awaiterHelper); + awaiterEmitted = true; + helpersEmitted = true; + } - if (!paramEmitted && node.flags & NodeFlags.HasParamDecorators) { - writeLines(paramHelper); - paramEmitted = true; - helpersEmitted = true; - } - - if (!awaiterEmitted && node.flags & NodeFlags.HasAsyncFunctions) { - writeLines(awaiterHelper); - awaiterEmitted = true; - helpersEmitted = true; - } - - if (helpersEmitted) { - writeLine(); - } + if (helpersEmitted) { + writeLine(); } return helpersEmitted; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 2ea5de24901..d5f4699248d 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -800,30 +800,31 @@ namespace ts { updated.fileName = node.fileName; updated.path = node.path; updated.text = node.text; - updated.amdDependencies = node.amdDependencies; - updated.moduleName = node.moduleName; - updated.referencedFiles = node.referencedFiles; - updated.typeReferenceDirectives = node.typeReferenceDirectives; - updated.languageVariant = node.languageVariant; - updated.isDeclarationFile = node.isDeclarationFile; - updated.renamedDependencies = node.renamedDependencies; - updated.hasNoDefaultLib = node.hasNoDefaultLib; - updated.languageVersion = node.languageVersion; - updated.scriptKind = node.scriptKind; - updated.externalModuleIndicator = node.externalModuleIndicator; - updated.commonJsModuleIndicator = node.commonJsModuleIndicator; - updated.identifiers = node.identifiers; - updated.nodeCount = node.nodeCount; - updated.identifierCount = node.identifierCount; - updated.symbolCount = node.symbolCount; - updated.parseDiagnostics = node.parseDiagnostics; - updated.bindDiagnostics = node.bindDiagnostics; - updated.lineMap = node.lineMap; - updated.classifiableNames = node.classifiableNames; - updated.resolvedModules = node.resolvedModules; - updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames; - updated.imports = node.imports; - updated.moduleAugmentations = node.moduleAugmentations; + if (node.amdDependencies !== undefined) updated.amdDependencies = node.amdDependencies; + if (node.moduleName !== undefined) updated.moduleName = node.moduleName; + if (node.referencedFiles !== undefined) updated.referencedFiles = node.referencedFiles; + if (node.typeReferenceDirectives !== undefined) updated.typeReferenceDirectives = node.typeReferenceDirectives; + if (node.languageVariant !== undefined) updated.languageVariant = node.languageVariant; + if (node.isDeclarationFile !== undefined) updated.isDeclarationFile = node.isDeclarationFile; + if (node.renamedDependencies !== undefined) updated.renamedDependencies = node.renamedDependencies; + if (node.hasNoDefaultLib !== undefined) updated.hasNoDefaultLib = node.hasNoDefaultLib; + if (node.languageVersion !== undefined) updated.languageVersion = node.languageVersion; + if (node.scriptKind !== undefined) updated.scriptKind = node.scriptKind; + if (node.externalModuleIndicator !== undefined) updated.externalModuleIndicator = node.externalModuleIndicator; + if (node.commonJsModuleIndicator !== undefined) updated.commonJsModuleIndicator = node.commonJsModuleIndicator; + if (node.identifiers !== undefined) updated.identifiers = node.identifiers; + if (node.nodeCount !== undefined) updated.nodeCount = node.nodeCount; + if (node.identifierCount !== undefined) updated.identifierCount = node.identifierCount; + if (node.symbolCount !== undefined) updated.symbolCount = node.symbolCount; + if (node.parseDiagnostics !== undefined) updated.parseDiagnostics = node.parseDiagnostics; + if (node.bindDiagnostics !== undefined) updated.bindDiagnostics = node.bindDiagnostics; + if (node.lineMap !== undefined) updated.lineMap = node.lineMap; + if (node.classifiableNames !== undefined) updated.classifiableNames = node.classifiableNames; + if (node.resolvedModules !== undefined) updated.resolvedModules = node.resolvedModules; + if (node.resolvedTypeReferenceDirectiveNames !== undefined) updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames; + if (node.imports !== undefined) updated.imports = node.imports; + if (node.moduleAugmentations !== undefined) updated.moduleAugmentations = node.moduleAugmentations; + if (node.tslib !== undefined) updated.tslib = node.tslib; return updateNode(updated, node); } @@ -923,6 +924,12 @@ namespace ts { return node; } + export function createNamespaceImport(name: Identifier): NamespaceImport { + const node = createNode(SyntaxKind.NamespaceImport); + node.name = name; + return node; + } + export function createNamedImports(elements: NodeArray, location?: TextRange): NamedImports { const node = createNode(SyntaxKind.NamedImports, location); node.elements = elements; @@ -1058,9 +1065,15 @@ namespace ts { // Helpers - export function createExtendsHelper(name: Identifier) { + export function createHelperName(tslib: Identifier, name: string) { + return tslib + ? createPropertyAccess(tslib, name) + : createIdentifier(name); + } + + export function createExtendsHelper(tslib: Identifier, name: Identifier) { return createCall( - createIdentifier("__extends"), + createHelperName(tslib, "__extends"), /*typeArguments*/ undefined, [ name, @@ -1069,17 +1082,17 @@ namespace ts { ); } - export function createAssignHelper(attributesSegments: Expression[]) { + export function createAssignHelper(tslib: Identifier, attributesSegments: Expression[]) { return createCall( - createIdentifier("__assign"), + createHelperName(tslib, "__assign"), /*typeArguments*/ undefined, attributesSegments ); } - export function createParamHelper(expression: Expression, parameterOffset: number, location?: TextRange) { + export function createParamHelper(tslib: Identifier, expression: Expression, parameterOffset: number, location?: TextRange) { return createCall( - createIdentifier("__param"), + createHelperName(tslib, "__param"), /*typeArguments*/ undefined, [ createLiteral(parameterOffset), @@ -1089,9 +1102,9 @@ namespace ts { ); } - export function createMetadataHelper(metadataKey: string, metadataValue: Expression) { + export function createMetadataHelper(tslib: Identifier, metadataKey: string, metadataValue: Expression) { return createCall( - createIdentifier("__metadata"), + createHelperName(tslib, "__metadata"), /*typeArguments*/ undefined, [ createLiteral(metadataKey), @@ -1100,7 +1113,7 @@ namespace ts { ); } - export function createDecorateHelper(decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) { + export function createDecorateHelper(tslib: Identifier, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) { const argumentsArray: Expression[] = []; argumentsArray.push(createArrayLiteral(decoratorExpressions, /*location*/ undefined, /*multiLine*/ true)); argumentsArray.push(target); @@ -1111,12 +1124,12 @@ namespace ts { } } - return createCall(createIdentifier("__decorate"), /*typeArguments*/ undefined, argumentsArray, location); + return createCall(createHelperName(tslib, "__decorate"), /*typeArguments*/ undefined, argumentsArray, location); } - export function createAwaiterHelper(hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) { + export function createAwaiterHelper(tslib: Identifier, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) { return createCall( - createIdentifier("__awaiter"), + createHelperName(tslib, "__awaiter"), /*typeArguments*/ undefined, [ createThis(), @@ -1920,7 +1933,8 @@ namespace ts { export function getLocalNameForExternalImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration, sourceFile: SourceFile): Identifier { const namespaceDeclaration = getNamespaceDeclarationNode(node); if (namespaceDeclaration && !isDefaultImport(node)) { - return createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name)); + const name = namespaceDeclaration.name; + return isGeneratedIdentifier(name) ? name : createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, namespaceDeclaration.name)); } if (node.kind === SyntaxKind.ImportDeclaration && (node).importClause) { return getGeneratedNameForNode(node); diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 2f4f090a02e..cd8878b8a71 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -702,7 +702,7 @@ namespace ts { if (extendsClauseElement) { statements.push( createStatement( - createExtendsHelper(getDeclarationName(node)), + createExtendsHelper(currentSourceFile.tslib, getDeclarationName(node)), /*location*/ extendsClauseElement ) ); diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 6a90fd0ecaf..969b1bf0904 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -7,6 +7,7 @@ namespace ts { export function transformJsx(context: TransformationContext) { const compilerOptions = context.getCompilerOptions(); + let currentSourceFile: SourceFile; return transformSourceFile; /** @@ -15,7 +16,10 @@ namespace ts { * @param node A SourceFile node. */ function transformSourceFile(node: SourceFile) { - return visitEachChild(node, visitor, context); + currentSourceFile = node; + node = visitEachChild(node, visitor, context); + currentSourceFile = undefined; + return node; } function visitor(node: Node): VisitResult { @@ -102,7 +106,7 @@ namespace ts { // Either emit one big object literal (no spread attribs), or // a call to the __assign helper. objectProperties = singleOrUndefined(segments) - || createAssignHelper(segments); + || createAssignHelper(currentSourceFile.tslib, segments); } const element = createReactCreateElement( diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 4df58376b3c..a6879e75edc 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -51,6 +51,7 @@ namespace ts { let currentNamespace: ModuleDeclaration; let currentNamespaceContainerName: Identifier; let currentScope: SourceFile | Block | ModuleBlock | CaseBlock; + let currentSourceFileTslib: Identifier; /** * Keeps track of whether expression substitution has been enabled for specific edge cases. @@ -90,11 +91,7 @@ namespace ts { * @param node A SourceFile node. */ function transformSourceFile(node: SourceFile) { - currentSourceFile = node; - currentScope = node; - const visited = visitEachChild(node, visitor, context); - setNodeEmitFlags(visited, NodeEmitFlags.EmitEmitHelpers | getNodeEmitFlags(node)); - return visited; + return visitNode(node, visitor, isSourceFile); } /** @@ -132,7 +129,10 @@ namespace ts { * @param node The node to visit. */ function visitorWorker(node: Node): VisitResult { - if (node.transformFlags & TransformFlags.TypeScript) { + if (node.kind === SyntaxKind.SourceFile) { + return visitSourceFile(node); + } + else if (node.transformFlags & TransformFlags.TypeScript) { // This node is explicitly marked as TypeScript, so we should transform the node. return visitTypeScript(node); } @@ -420,6 +420,43 @@ namespace ts { } } + function visitSourceFile(node: SourceFile) { + currentSourceFile = node; + + // If the source file requires any helpers and is an external module, and + // the importHelpers compiler option is enabled, emit a synthesized import + // statement for the helpers library. + if (node.flags & NodeFlags.EmitHelperFlags + && compilerOptions.importHelpers + && (isExternalModule(node) || compilerOptions.isolatedModules)) { + startLexicalEnvironment(); + const statements: Statement[] = []; + const statementOffset = addPrologueDirectives(statements, node.statements); + const tslib = createUniqueName("tslib"); + const tslibImport = createImportDeclaration( + createImportClause(/*name*/ undefined, createNamespaceImport(tslib)), + createLiteral("tslib") + ); + tslibImport.parent = node; + tslibImport.flags &= ~NodeFlags.Synthesized; + statements.push(tslibImport); + + currentSourceFileTslib = tslib; + addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset)); + addRange(statements, endLexicalEnvironment()); + currentSourceFileTslib = undefined; + + node = updateSourceFileNode(node, createNodeArray(statements, node.statements)); + node.tslib = tslib; + } + else { + node = visitEachChild(node, visitor, context); + } + + setNodeEmitFlags(node, NodeEmitFlags.EmitEmitHelpers | node.emitFlags); + return node; + } + /** * Tests whether we should emit a __decorate call for a class declaration. */ @@ -1345,6 +1382,7 @@ namespace ts { : undefined; const helper = createDecorateHelper( + currentSourceFileTslib, decoratorExpressions, prefix, memberName, @@ -1394,6 +1432,7 @@ namespace ts { const expression = createAssignment( decoratedClassAlias, createDecorateHelper( + currentSourceFileTslib, decoratorExpressions, getDeclarationName(node) ) @@ -1417,6 +1456,7 @@ namespace ts { const result = createAssignment( getDeclarationName(node), createDecorateHelper( + currentSourceFileTslib, decoratorExpressions, getDeclarationName(node) ), @@ -1448,7 +1488,11 @@ namespace ts { if (decorators) { expressions = []; for (const decorator of decorators) { - const helper = createParamHelper(transformDecorator(decorator), parameterOffset, /*location*/ decorator.expression); + const helper = createParamHelper( + currentSourceFileTslib, + transformDecorator(decorator), + parameterOffset, + /*location*/ decorator.expression); setNodeEmitFlags(helper, NodeEmitFlags.NoComments); expressions.push(helper); } @@ -1475,13 +1519,13 @@ namespace ts { function addOldTypeMetadata(node: Declaration, decoratorExpressions: Expression[]) { if (compilerOptions.emitDecoratorMetadata) { if (shouldAddTypeMetadata(node)) { - decoratorExpressions.push(createMetadataHelper("design:type", serializeTypeOfNode(node))); + decoratorExpressions.push(createMetadataHelper(currentSourceFileTslib,"design:type", serializeTypeOfNode(node))); } if (shouldAddParamTypesMetadata(node)) { - decoratorExpressions.push(createMetadataHelper("design:paramtypes", serializeParameterTypesOfNode(node))); + decoratorExpressions.push(createMetadataHelper(currentSourceFileTslib,"design:paramtypes", serializeParameterTypesOfNode(node))); } if (shouldAddReturnTypeMetadata(node)) { - decoratorExpressions.push(createMetadataHelper("design:returntype", serializeReturnTypeOfNode(node))); + decoratorExpressions.push(createMetadataHelper(currentSourceFileTslib,"design:returntype", serializeReturnTypeOfNode(node))); } } } @@ -1499,7 +1543,7 @@ namespace ts { (properties || (properties = [])).push(createPropertyAssignment("returnType", createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, serializeReturnTypeOfNode(node)))); } if (properties) { - decoratorExpressions.push(createMetadataHelper("design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true))); + decoratorExpressions.push(createMetadataHelper(currentSourceFileTslib,"design:typeinfo", createObjectLiteral(properties, /*location*/ undefined, /*multiLine*/ true))); } } } @@ -2190,6 +2234,7 @@ namespace ts { statements.push( createReturn( createAwaiterHelper( + currentSourceFileTslib, hasLexicalArguments, promiseConstructor, transformFunctionBodyWorker(node.body) @@ -2216,6 +2261,7 @@ namespace ts { } else { return createAwaiterHelper( + currentSourceFileTslib, hasLexicalArguments, promiseConstructor, transformConciseBodyWorker(node.body, /*forceBlockFunctionBody*/ true) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b38450c7af3..957c9371460 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -415,7 +415,7 @@ namespace ts { BlockScoped = Let | Const, ReachabilityCheckFlags = HasImplicitReturn | HasExplicitReturn, - EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions, + EmitHelperFlags = HasClassExtends | HasDecorators | HasParamDecorators | HasAsyncFunctions | HasJsxSpreadAttribute, ReachabilityAndEmitFlags = ReachabilityCheckFlags | EmitHelperFlags, // Parsing context flags @@ -1725,6 +1725,8 @@ namespace ts { /* @internal */ resolvedTypeReferenceDirectiveNames: Map; /* @internal */ imports: LiteralExpression[]; /* @internal */ moduleAugmentations: LiteralExpression[]; + // The synthesized identifier for an imported tslib helpers runtime. + /* @internal */ tslib?: Identifier; } export interface ScriptReferenceHost { @@ -2558,6 +2560,7 @@ namespace ts { init?: boolean; inlineSourceMap?: boolean; inlineSources?: boolean; + importHelpers?: boolean; jsx?: JsxEmit; reactNamespace?: string; listFiles?: boolean; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c504af01c6f..325b1a7c15f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -117,7 +117,7 @@ namespace ts { } export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean { - return sourceFile.resolvedModules && hasProperty(sourceFile.resolvedModules, moduleNameText); + return sourceFile && sourceFile.resolvedModules && hasProperty(sourceFile.resolvedModules, moduleNameText); } export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModule { diff --git a/tests/baselines/reference/importHelpers.js b/tests/baselines/reference/importHelpers.js new file mode 100644 index 00000000000..52e07fb98bb --- /dev/null +++ b/tests/baselines/reference/importHelpers.js @@ -0,0 +1,107 @@ +//// [tests/cases/compiler/importHelpers.ts] //// + +//// [external.ts] +export class A { } +export class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} + +//// [script.ts] +class A { } +class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} + +//// [external.js] +"use strict"; +var tslib_1 = require("tslib"); +var A = (function () { + function A() { + } + return A; +}()); +exports.A = A; +var B = (function (_super) { + tslib_1.__extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; +}(A)); +exports.B = B; +var C = (function () { + function C() { + } + C.prototype.method = function (x) { + }; + return C; +}()); +tslib_1.__decorate([ + tslib_1.__param(0, dec), + tslib_1.__metadata("design:type", Function), + tslib_1.__metadata("design:paramtypes", [Number]), + tslib_1.__metadata("design:returntype", void 0) +], C.prototype, "method", null); +C = tslib_1.__decorate([ + dec, + tslib_1.__metadata("design:paramtypes", []) +], C); +//// [script.js] +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var __param = (this && this.__param) || function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } +}; +var A = (function () { + function A() { + } + return A; +}()); +var B = (function (_super) { + __extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; +}(A)); +var C = (function () { + function C() { + } + C.prototype.method = function (x) { + }; + return C; +}()); +__decorate([ + __param(0, dec), + __metadata("design:type", Function), + __metadata("design:paramtypes", [Number]), + __metadata("design:returntype", void 0) +], C.prototype, "method", null); +C = __decorate([ + dec, + __metadata("design:paramtypes", []) +], C); diff --git a/tests/baselines/reference/importHelpers.symbols b/tests/baselines/reference/importHelpers.symbols new file mode 100644 index 00000000000..cb852ab286c --- /dev/null +++ b/tests/baselines/reference/importHelpers.symbols @@ -0,0 +1,47 @@ +=== tests/cases/compiler/external.ts === +export class A { } +>A : Symbol(A, Decl(external.ts, 0, 0)) + +export class B extends A { } +>B : Symbol(B, Decl(external.ts, 0, 18)) +>A : Symbol(A, Decl(external.ts, 0, 0)) + +declare var dec: any; +>dec : Symbol(dec, Decl(external.ts, 3, 11)) + +@dec +>dec : Symbol(dec, Decl(external.ts, 3, 11)) + +class C { +>C : Symbol(C, Decl(external.ts, 3, 21)) + + method(@dec x: number) { +>method : Symbol(C.method, Decl(external.ts, 6, 9)) +>dec : Symbol(dec, Decl(external.ts, 3, 11)) +>x : Symbol(x, Decl(external.ts, 7, 11)) + } +} + +=== tests/cases/compiler/script.ts === +class A { } +>A : Symbol(A, Decl(script.ts, 0, 0)) + +class B extends A { } +>B : Symbol(B, Decl(script.ts, 0, 11)) +>A : Symbol(A, Decl(script.ts, 0, 0)) + +declare var dec: any; +>dec : Symbol(dec, Decl(script.ts, 3, 11)) + +@dec +>dec : Symbol(dec, Decl(script.ts, 3, 11)) + +class C { +>C : Symbol(C, Decl(script.ts, 3, 21)) + + method(@dec x: number) { +>method : Symbol(C.method, Decl(script.ts, 6, 9)) +>dec : Symbol(dec, Decl(script.ts, 3, 11)) +>x : Symbol(x, Decl(script.ts, 7, 11)) + } +} diff --git a/tests/baselines/reference/importHelpers.types b/tests/baselines/reference/importHelpers.types new file mode 100644 index 00000000000..0d1cda653e8 --- /dev/null +++ b/tests/baselines/reference/importHelpers.types @@ -0,0 +1,47 @@ +=== tests/cases/compiler/external.ts === +export class A { } +>A : A + +export class B extends A { } +>B : B +>A : A + +declare var dec: any; +>dec : any + +@dec +>dec : any + +class C { +>C : C + + method(@dec x: number) { +>method : (x: number) => void +>dec : any +>x : number + } +} + +=== tests/cases/compiler/script.ts === +class A { } +>A : A + +class B extends A { } +>B : B +>A : A + +declare var dec: any; +>dec : any + +@dec +>dec : any + +class C { +>C : C + + method(@dec x: number) { +>method : (x: number) => void +>dec : any +>x : number + } +} diff --git a/tests/baselines/reference/importHelpersAmd.js b/tests/baselines/reference/importHelpersAmd.js new file mode 100644 index 00000000000..e5f6bdce278 --- /dev/null +++ b/tests/baselines/reference/importHelpersAmd.js @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/importHelpersAmd.ts] //// + +//// [a.ts] +export class A { } +//// [b.ts] +import { A } from "./a"; +export class B extends A { } + + +//// [a.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + var A = (function () { + function A() { + } + return A; + }()); + exports.A = A; +}); +//// [b.js] +define(["require", "exports", "tslib", "./a"], function (require, exports, tslib_1, a_1) { + "use strict"; + var B = (function (_super) { + tslib_1.__extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; + }(a_1.A)); + exports.B = B; +}); diff --git a/tests/baselines/reference/importHelpersAmd.symbols b/tests/baselines/reference/importHelpersAmd.symbols new file mode 100644 index 00000000000..d4155c4bf52 --- /dev/null +++ b/tests/baselines/reference/importHelpersAmd.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/a.ts === +export class A { } +>A : Symbol(A, Decl(a.ts, 0, 0)) + +=== tests/cases/compiler/b.ts === +import { A } from "./a"; +>A : Symbol(A, Decl(b.ts, 0, 8)) + +export class B extends A { } +>B : Symbol(B, Decl(b.ts, 0, 24)) +>A : Symbol(A, Decl(b.ts, 0, 8)) + diff --git a/tests/baselines/reference/importHelpersAmd.types b/tests/baselines/reference/importHelpersAmd.types new file mode 100644 index 00000000000..7f313d87cd6 --- /dev/null +++ b/tests/baselines/reference/importHelpersAmd.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/a.ts === +export class A { } +>A : A + +=== tests/cases/compiler/b.ts === +import { A } from "./a"; +>A : typeof A + +export class B extends A { } +>B : B +>A : A + diff --git a/tests/baselines/reference/importHelpersES6.js b/tests/baselines/reference/importHelpersES6.js new file mode 100644 index 00000000000..c9709986853 --- /dev/null +++ b/tests/baselines/reference/importHelpersES6.js @@ -0,0 +1,14 @@ +//// [a.ts] +declare var dec: any; +@dec export class A { + +} + +//// [a.js] +import * as tslib_1 from "tslib"; +let A = class A { +}; +A = tslib_1.__decorate([ + dec +], A); +export { A }; diff --git a/tests/baselines/reference/importHelpersES6.symbols b/tests/baselines/reference/importHelpersES6.symbols new file mode 100644 index 00000000000..66d3cd62c41 --- /dev/null +++ b/tests/baselines/reference/importHelpersES6.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/a.ts === +declare var dec: any; +>dec : Symbol(dec, Decl(a.ts, 0, 11)) + +@dec export class A { +>dec : Symbol(dec, Decl(a.ts, 0, 11)) +>A : Symbol(A, Decl(a.ts, 0, 21)) + +} diff --git a/tests/baselines/reference/importHelpersES6.types b/tests/baselines/reference/importHelpersES6.types new file mode 100644 index 00000000000..d54a768ea7f --- /dev/null +++ b/tests/baselines/reference/importHelpersES6.types @@ -0,0 +1,9 @@ +=== tests/cases/compiler/a.ts === +declare var dec: any; +>dec : any + +@dec export class A { +>dec : any +>A : A + +} diff --git a/tests/baselines/reference/importHelpersInIsolatedModules.errors.txt b/tests/baselines/reference/importHelpersInIsolatedModules.errors.txt new file mode 100644 index 00000000000..9005078fada --- /dev/null +++ b/tests/baselines/reference/importHelpersInIsolatedModules.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/script.ts(1,1): error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + + +==== tests/cases/compiler/external.ts (0 errors) ==== + export class A { } + export class B extends A { } + + declare var dec: any; + + @dec + class C { + method(@dec x: number) { + } + } + +==== tests/cases/compiler/script.ts (1 errors) ==== + class A { } + ~~~~~ +!!! error TS1208: Cannot compile namespaces when the '--isolatedModules' flag is provided. + class B extends A { } + + declare var dec: any; + + @dec + class C { + method(@dec x: number) { + } + } \ No newline at end of file diff --git a/tests/baselines/reference/importHelpersInIsolatedModules.js b/tests/baselines/reference/importHelpersInIsolatedModules.js new file mode 100644 index 00000000000..f9aa4cfa1b9 --- /dev/null +++ b/tests/baselines/reference/importHelpersInIsolatedModules.js @@ -0,0 +1,92 @@ +//// [tests/cases/compiler/importHelpersInIsolatedModules.ts] //// + +//// [external.ts] +export class A { } +export class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} + +//// [script.ts] +class A { } +class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} + +//// [external.js] +"use strict"; +var tslib_1 = require("tslib"); +var A = (function () { + function A() { + } + return A; +}()); +exports.A = A; +var B = (function (_super) { + tslib_1.__extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; +}(A)); +exports.B = B; +var C = (function () { + function C() { + } + C.prototype.method = function (x) { + }; + return C; +}()); +tslib_1.__decorate([ + tslib_1.__param(0, dec), + tslib_1.__metadata("design:type", Function), + tslib_1.__metadata("design:paramtypes", [Number]), + tslib_1.__metadata("design:returntype", void 0) +], C.prototype, "method", null); +C = tslib_1.__decorate([ + dec, + tslib_1.__metadata("design:paramtypes", []) +], C); +//// [script.js] +"use strict"; +var tslib_1 = require("tslib"); +var A = (function () { + function A() { + } + return A; +}()); +var B = (function (_super) { + tslib_1.__extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; +}(A)); +var C = (function () { + function C() { + } + C.prototype.method = function (x) { + }; + return C; +}()); +tslib_1.__decorate([ + tslib_1.__param(0, dec), + tslib_1.__metadata("design:type", Function), + tslib_1.__metadata("design:paramtypes", [Number]), + tslib_1.__metadata("design:returntype", void 0) +], C.prototype, "method", null); +C = tslib_1.__decorate([ + dec, + tslib_1.__metadata("design:paramtypes", []) +], C); diff --git a/tests/baselines/reference/importHelpersInTsx.js b/tests/baselines/reference/importHelpersInTsx.js new file mode 100644 index 00000000000..2d0ae56793f --- /dev/null +++ b/tests/baselines/reference/importHelpersInTsx.js @@ -0,0 +1,26 @@ +//// [tests/cases/compiler/importHelpersInTsx.tsx] //// + +//// [external.tsx] +declare var React: any; +declare var o: any; +export const x = + +//// [internal.tsx] +declare var React: any; +declare var o: any; +const x = + +//// [external.js] +"use strict"; +var tslib_1 = require("tslib"); +exports.x = React.createElement("span", tslib_1.__assign({}, o)); +//// [internal.js] +var __assign = (this && this.__assign) || Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; +}; +var x = React.createElement("span", __assign({}, o)); diff --git a/tests/baselines/reference/importHelpersInTsx.symbols b/tests/baselines/reference/importHelpersInTsx.symbols new file mode 100644 index 00000000000..16ca20e0fe4 --- /dev/null +++ b/tests/baselines/reference/importHelpersInTsx.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/external.tsx === +declare var React: any; +>React : Symbol(React, Decl(external.tsx, 0, 11)) + +declare var o: any; +>o : Symbol(o, Decl(external.tsx, 1, 11)) + +export const x = +>x : Symbol(x, Decl(external.tsx, 2, 12)) +>span : Symbol(unknown) +>o : Symbol(o, Decl(external.tsx, 1, 11)) + +=== tests/cases/compiler/internal.tsx === +declare var React: any; +>React : Symbol(React, Decl(internal.tsx, 0, 11)) + +declare var o: any; +>o : Symbol(o, Decl(internal.tsx, 1, 11)) + +const x = +>x : Symbol(x, Decl(internal.tsx, 2, 5)) +>span : Symbol(unknown) +>o : Symbol(o, Decl(internal.tsx, 1, 11)) + diff --git a/tests/baselines/reference/importHelpersInTsx.types b/tests/baselines/reference/importHelpersInTsx.types new file mode 100644 index 00000000000..2e833e78c19 --- /dev/null +++ b/tests/baselines/reference/importHelpersInTsx.types @@ -0,0 +1,26 @@ +=== tests/cases/compiler/external.tsx === +declare var React: any; +>React : any + +declare var o: any; +>o : any + +export const x = +>x : any +> : any +>span : any +>o : any + +=== tests/cases/compiler/internal.tsx === +declare var React: any; +>React : any + +declare var o: any; +>o : any + +const x = +>x : any +> : any +>span : any +>o : any + diff --git a/tests/baselines/reference/importHelpersOutFile.js b/tests/baselines/reference/importHelpersOutFile.js new file mode 100644 index 00000000000..6071c78416e --- /dev/null +++ b/tests/baselines/reference/importHelpersOutFile.js @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/importHelpersOutFile.ts] //// + +//// [a.ts] +export class A { } +//// [b.ts] +import { A } from "./a"; +export class B extends A { } +//// [c.ts] +import { A } from "./a"; +export class C extends A { } + + +//// [out.js] +define("a", ["require", "exports"], function (require, exports) { + "use strict"; + var A = (function () { + function A() { + } + return A; + }()); + exports.A = A; +}); +define("b", ["require", "exports", "tslib", "a"], function (require, exports, tslib_1, a_1) { + "use strict"; + var B = (function (_super) { + tslib_1.__extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; + }(a_1.A)); + exports.B = B; +}); +define("c", ["require", "exports", "tslib", "a"], function (require, exports, tslib_2, a_2) { + "use strict"; + var C = (function (_super) { + tslib_2.__extends(C, _super); + function C() { + _super.apply(this, arguments); + } + return C; + }(a_2.A)); + exports.C = C; +}); diff --git a/tests/baselines/reference/importHelpersOutFile.symbols b/tests/baselines/reference/importHelpersOutFile.symbols new file mode 100644 index 00000000000..cd65e3dcd69 --- /dev/null +++ b/tests/baselines/reference/importHelpersOutFile.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/a.ts === +export class A { } +>A : Symbol(A, Decl(a.ts, 0, 0)) + +=== tests/cases/compiler/b.ts === +import { A } from "./a"; +>A : Symbol(A, Decl(b.ts, 0, 8)) + +export class B extends A { } +>B : Symbol(B, Decl(b.ts, 0, 24)) +>A : Symbol(A, Decl(b.ts, 0, 8)) + +=== tests/cases/compiler/c.ts === +import { A } from "./a"; +>A : Symbol(A, Decl(c.ts, 0, 8)) + +export class C extends A { } +>C : Symbol(C, Decl(c.ts, 0, 24)) +>A : Symbol(A, Decl(c.ts, 0, 8)) + diff --git a/tests/baselines/reference/importHelpersOutFile.types b/tests/baselines/reference/importHelpersOutFile.types new file mode 100644 index 00000000000..94726de43e5 --- /dev/null +++ b/tests/baselines/reference/importHelpersOutFile.types @@ -0,0 +1,20 @@ +=== tests/cases/compiler/a.ts === +export class A { } +>A : A + +=== tests/cases/compiler/b.ts === +import { A } from "./a"; +>A : typeof A + +export class B extends A { } +>B : B +>A : A + +=== tests/cases/compiler/c.ts === +import { A } from "./a"; +>A : typeof A + +export class C extends A { } +>C : C +>A : A + diff --git a/tests/baselines/reference/importHelpersSystem.js b/tests/baselines/reference/importHelpersSystem.js new file mode 100644 index 00000000000..664edef5248 --- /dev/null +++ b/tests/baselines/reference/importHelpersSystem.js @@ -0,0 +1,52 @@ +//// [tests/cases/compiler/importHelpersSystem.ts] //// + +//// [a.ts] +export class A { } +//// [b.ts] +import { A } from "./a"; +export class B extends A { } + + +//// [a.js] +System.register([], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var A; + return { + setters: [], + execute: function () { + A = (function () { + function A() { + } + return A; + }()); + exports_1("A", A); + } + }; +}); +//// [b.js] +System.register(["tslib", "./a"], function (exports_1, context_1) { + "use strict"; + var __moduleName = context_1 && context_1.id; + var tslib_1, a_1, B; + return { + setters: [ + function (tslib_1_1) { + tslib_1 = tslib_1_1; + }, + function (a_1_1) { + a_1 = a_1_1; + } + ], + execute: function () { + B = (function (_super) { + tslib_1.__extends(B, _super); + function B() { + _super.apply(this, arguments); + } + return B; + }(a_1.A)); + exports_1("B", B); + } + }; +}); diff --git a/tests/baselines/reference/importHelpersSystem.symbols b/tests/baselines/reference/importHelpersSystem.symbols new file mode 100644 index 00000000000..d4155c4bf52 --- /dev/null +++ b/tests/baselines/reference/importHelpersSystem.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/a.ts === +export class A { } +>A : Symbol(A, Decl(a.ts, 0, 0)) + +=== tests/cases/compiler/b.ts === +import { A } from "./a"; +>A : Symbol(A, Decl(b.ts, 0, 8)) + +export class B extends A { } +>B : Symbol(B, Decl(b.ts, 0, 24)) +>A : Symbol(A, Decl(b.ts, 0, 8)) + diff --git a/tests/baselines/reference/importHelpersSystem.types b/tests/baselines/reference/importHelpersSystem.types new file mode 100644 index 00000000000..7f313d87cd6 --- /dev/null +++ b/tests/baselines/reference/importHelpersSystem.types @@ -0,0 +1,12 @@ +=== tests/cases/compiler/a.ts === +export class A { } +>A : A + +=== tests/cases/compiler/b.ts === +import { A } from "./a"; +>A : typeof A + +export class B extends A { } +>B : B +>A : A + diff --git a/tests/cases/compiler/importHelpers.ts b/tests/cases/compiler/importHelpers.ts new file mode 100644 index 00000000000..7a578fa70f3 --- /dev/null +++ b/tests/cases/compiler/importHelpers.ts @@ -0,0 +1,28 @@ +// @importHelpers: true +// @target: es5 +// @module: commonjs +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @filename: external.ts +export class A { } +export class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} + +// @filename: script.ts +class A { } +class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} \ No newline at end of file diff --git a/tests/cases/compiler/importHelpersAmd.ts b/tests/cases/compiler/importHelpersAmd.ts new file mode 100644 index 00000000000..6d21a380178 --- /dev/null +++ b/tests/cases/compiler/importHelpersAmd.ts @@ -0,0 +1,8 @@ +// @importHelpers: true +// @target: es5 +// @module: amd +// @filename: a.ts +export class A { } +// @filename: b.ts +import { A } from "./a"; +export class B extends A { } diff --git a/tests/cases/compiler/importHelpersES6.ts b/tests/cases/compiler/importHelpersES6.ts new file mode 100644 index 00000000000..7dfa70e2325 --- /dev/null +++ b/tests/cases/compiler/importHelpersES6.ts @@ -0,0 +1,8 @@ +// @importHelpers: true +// @target: es6 +// @experimentalDecorators: true +// @filename: a.ts +declare var dec: any; +@dec export class A { + +} \ No newline at end of file diff --git a/tests/cases/compiler/importHelpersInIsolatedModules.ts b/tests/cases/compiler/importHelpersInIsolatedModules.ts new file mode 100644 index 00000000000..c55ba6e52e4 --- /dev/null +++ b/tests/cases/compiler/importHelpersInIsolatedModules.ts @@ -0,0 +1,29 @@ +// @importHelpers: true +// @isolatedModules: true +// @target: es5 +// @module: commonjs +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @filename: external.ts +export class A { } +export class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} + +// @filename: script.ts +class A { } +class B extends A { } + +declare var dec: any; + +@dec +class C { + method(@dec x: number) { + } +} \ No newline at end of file diff --git a/tests/cases/compiler/importHelpersInTsx.tsx b/tests/cases/compiler/importHelpersInTsx.tsx new file mode 100644 index 00000000000..b1ab98ec5db --- /dev/null +++ b/tests/cases/compiler/importHelpersInTsx.tsx @@ -0,0 +1,15 @@ +// @importHelpers: true +// @target: es5 +// @module: commonjs +// @jsx: react +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @filename: external.tsx +declare var React: any; +declare var o: any; +export const x = + +// @filename: internal.tsx +declare var React: any; +declare var o: any; +const x = \ No newline at end of file diff --git a/tests/cases/compiler/importHelpersOutFile.ts b/tests/cases/compiler/importHelpersOutFile.ts new file mode 100644 index 00000000000..471f363c65d --- /dev/null +++ b/tests/cases/compiler/importHelpersOutFile.ts @@ -0,0 +1,12 @@ +// @importHelpers: true +// @target: es5 +// @module: amd +// @outfile: out.js +// @filename: a.ts +export class A { } +// @filename: b.ts +import { A } from "./a"; +export class B extends A { } +// @filename: c.ts +import { A } from "./a"; +export class C extends A { } diff --git a/tests/cases/compiler/importHelpersSystem.ts b/tests/cases/compiler/importHelpersSystem.ts new file mode 100644 index 00000000000..1b81e748ff0 --- /dev/null +++ b/tests/cases/compiler/importHelpersSystem.ts @@ -0,0 +1,8 @@ +// @importHelpers: true +// @target: es5 +// @module: system +// @filename: a.ts +export class A { } +// @filename: b.ts +import { A } from "./a"; +export class B extends A { }