From 44aa7388eaf234abff335fa8606c0fd032ca5601 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 2 Mar 2016 10:52:16 -0800 Subject: [PATCH 01/11] UMD support --- src/compiler/binder.ts | 11 ++++ src/compiler/checker.ts | 28 +++++++++ src/compiler/diagnosticMessages.json | 12 ++++ src/compiler/parser.ts | 38 ++++++++++-- src/compiler/program.ts | 24 +++++--- src/compiler/types.ts | 10 ++++ src/compiler/utilities.ts | 1 + src/harness/compilerRunner.ts | 2 +- src/harness/harness.ts | 3 +- .../baselines/reference/umd-errors.errors.txt | 60 +++++++++++++++++++ tests/baselines/reference/umd-errors.js | 36 +++++++++++ tests/baselines/reference/umd-errors.symbols | 8 +++ tests/baselines/reference/umd-errors.types | 9 +++ tests/baselines/reference/umd1.js | 21 +++++++ tests/baselines/reference/umd1.symbols | 33 ++++++++++ tests/baselines/reference/umd1.types | 35 +++++++++++ tests/baselines/reference/umd2.errors.txt | 19 ++++++ tests/baselines/reference/umd2.js | 18 ++++++ tests/baselines/reference/umd3.js | 22 +++++++ tests/baselines/reference/umd3.symbols | 35 +++++++++++ tests/baselines/reference/umd3.types | 37 ++++++++++++ tests/baselines/reference/umd4.js | 22 +++++++ tests/baselines/reference/umd4.symbols | 35 +++++++++++ tests/baselines/reference/umd4.types | 37 ++++++++++++ tests/baselines/reference/umd5.errors.txt | 20 +++++++ tests/baselines/reference/umd5.js | 26 ++++++++ .../conformance/externalModules/umd-errors.ts | 31 ++++++++++ .../cases/conformance/externalModules/umd1.ts | 14 +++++ .../cases/conformance/externalModules/umd2.ts | 12 ++++ .../cases/conformance/externalModules/umd3.ts | 14 +++++ .../cases/conformance/externalModules/umd4.ts | 14 +++++ .../cases/conformance/externalModules/umd5.ts | 16 +++++ 32 files changed, 687 insertions(+), 16 deletions(-) create mode 100644 tests/baselines/reference/umd-errors.errors.txt create mode 100644 tests/baselines/reference/umd-errors.js create mode 100644 tests/baselines/reference/umd-errors.symbols create mode 100644 tests/baselines/reference/umd-errors.types create mode 100644 tests/baselines/reference/umd1.js create mode 100644 tests/baselines/reference/umd1.symbols create mode 100644 tests/baselines/reference/umd1.types create mode 100644 tests/baselines/reference/umd2.errors.txt create mode 100644 tests/baselines/reference/umd2.js create mode 100644 tests/baselines/reference/umd3.js create mode 100644 tests/baselines/reference/umd3.symbols create mode 100644 tests/baselines/reference/umd3.types create mode 100644 tests/baselines/reference/umd4.js create mode 100644 tests/baselines/reference/umd4.symbols create mode 100644 tests/baselines/reference/umd4.types create mode 100644 tests/baselines/reference/umd5.errors.txt create mode 100644 tests/baselines/reference/umd5.js create mode 100644 tests/cases/conformance/externalModules/umd-errors.ts create mode 100644 tests/cases/conformance/externalModules/umd1.ts create mode 100644 tests/cases/conformance/externalModules/umd2.ts create mode 100644 tests/cases/conformance/externalModules/umd3.ts create mode 100644 tests/cases/conformance/externalModules/umd4.ts create mode 100644 tests/cases/conformance/externalModules/umd5.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9363a8796ee6b..0a2cb25bd3f06 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1355,6 +1355,8 @@ namespace ts { case SyntaxKind.ImportSpecifier: case SyntaxKind.ExportSpecifier: return declareSymbolAndAddToSymbolTable(node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + case SyntaxKind.GlobalModuleExportDeclaration: + return bindGlobalModuleExportDeclaration(node); case SyntaxKind.ImportClause: return bindImportClause(node); case SyntaxKind.ExportDeclaration: @@ -1404,6 +1406,15 @@ namespace ts { } } + function bindGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration) { + if (!file.externalModuleIndicator) { + file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files)); + return; + } + file.symbol.globalExports = file.symbol.globalExports || {}; + declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); + } + function bindExportDeclaration(node: ExportDeclaration) { if (!container.symbol || !container.symbol.exports) { // Export * in some sort of block construct diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 14fec7bb976da..fde042eaaba2c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -981,6 +981,10 @@ namespace ts { return getExternalModuleMember(node.parent.parent.parent, node); } + function getTargetOfGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration): Symbol { + return node.parent.symbol; + } + function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol { return (node.parent.parent).moduleSpecifier ? getExternalModuleMember(node.parent.parent, node) : @@ -1005,6 +1009,8 @@ namespace ts { return getTargetOfExportSpecifier(node); case SyntaxKind.ExportAssignment: return getTargetOfExportAssignment(node); + case SyntaxKind.GlobalModuleExportDeclaration: + return getTargetOfGlobalModuleExportDeclaration(node); } } @@ -15220,6 +15226,23 @@ namespace ts { } } + function checkGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration) { + if (node.modifiers && node.modifiers.length) { + error(node, Diagnostics.Modifiers_cannot_appear_here); + } + + if (node.parent.kind !== SyntaxKind.SourceFile) { + error(node, Diagnostics.Global_module_exports_may_only_appear_at_top_level); + } + else { + const parent = node.parent as SourceFile; + // Note: the binder handles the case where the declaration isn't in an external module + if (parent.externalModuleIndicator && !parent.isDeclarationFile) { + error(node, Diagnostics.Global_module_exports_may_only_appear_in_declaration_files); + } + } + + } function checkSourceElement(node: Node): void { if (!node) { @@ -15337,6 +15360,8 @@ namespace ts { return checkExportDeclaration(node); case SyntaxKind.ExportAssignment: return checkExportAssignment(node); + case SyntaxKind.GlobalModuleExportDeclaration: + return checkGlobalModuleExportDeclaration(node); case SyntaxKind.EmptyStatement: checkGrammarStatementInAmbientContext(node); return; @@ -16331,6 +16356,9 @@ namespace ts { if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } + if (file.wasReferenced && file.symbol && file.symbol.globalExports) { + mergeSymbolTable(globals, file.symbol.globalExports); + } }); if (augmentations) { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 4ffbca3bb501e..15a3a4e5ef474 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -831,6 +831,18 @@ "category": "Error", "code": 1313 }, + "Global module exports may only appear in module files.": { + "category": "Error", + "code": 1314 + }, + "Global module exports may only appear in declaration files.": { + "category": "Error", + "code": 1315 + }, + "Global module exports may only appear at top level.": { + "category": "Error", + "code": 1316 + }, "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5487d1a47c304..4489185d0eaae 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -301,6 +301,9 @@ namespace ts { case SyntaxKind.ImportClause: return visitNode(cbNode, (node).name) || visitNode(cbNode, (node).namedBindings); + case SyntaxKind.GlobalModuleExportDeclaration: + return visitNode(cbNode, (node).name); + case SyntaxKind.NamespaceImport: return visitNode(cbNode, (node).name); case SyntaxKind.NamedImports: @@ -1125,7 +1128,7 @@ namespace ts { if (token === SyntaxKind.DefaultKeyword) { return lookAhead(nextTokenIsClassOrFunction); } - return token !== SyntaxKind.AsteriskToken && token !== SyntaxKind.OpenBraceToken && canFollowModifier(); + return token !== SyntaxKind.AsteriskToken && token !== SyntaxKind.AsKeyword && token !== SyntaxKind.OpenBraceToken && canFollowModifier(); } if (token === SyntaxKind.DefaultKeyword) { return nextTokenIsClassOrFunction(); @@ -4400,7 +4403,8 @@ namespace ts { continue; case SyntaxKind.GlobalKeyword: - return nextToken() === SyntaxKind.OpenBraceToken; + nextToken(); + return token === SyntaxKind.OpenBraceToken || token === SyntaxKind.Identifier || token === SyntaxKind.ExportKeyword; case SyntaxKind.ImportKeyword: nextToken(); @@ -4409,7 +4413,8 @@ namespace ts { case SyntaxKind.ExportKeyword: nextToken(); if (token === SyntaxKind.EqualsToken || token === SyntaxKind.AsteriskToken || - token === SyntaxKind.OpenBraceToken || token === SyntaxKind.DefaultKeyword) { + token === SyntaxKind.OpenBraceToken || token === SyntaxKind.DefaultKeyword || + token === SyntaxKind.AsKeyword) { return true; } continue; @@ -4586,6 +4591,7 @@ namespace ts { case SyntaxKind.EnumKeyword: return parseEnumDeclaration(fullStart, decorators, modifiers); case SyntaxKind.GlobalKeyword: + return parseModuleDeclaration(fullStart, decorators, modifiers); case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: return parseModuleDeclaration(fullStart, decorators, modifiers); @@ -4593,9 +4599,15 @@ namespace ts { return parseImportDeclarationOrImportEqualsDeclaration(fullStart, decorators, modifiers); case SyntaxKind.ExportKeyword: nextToken(); - return token === SyntaxKind.DefaultKeyword || token === SyntaxKind.EqualsToken ? - parseExportAssignment(fullStart, decorators, modifiers) : - parseExportDeclaration(fullStart, decorators, modifiers); + switch (token) { + case SyntaxKind.DefaultKeyword: + case SyntaxKind.EqualsToken: + return parseExportAssignment(fullStart, decorators, modifiers); + case SyntaxKind.AsKeyword: + return parseGlobalModuleExportDeclaration(fullStart, decorators, modifiers); + default: + return parseExportDeclaration(fullStart, decorators, modifiers); + } default: if (decorators || modifiers) { // We reached this point because we encountered decorators and/or modifiers and assumed a declaration @@ -5264,6 +5276,20 @@ namespace ts { return nextToken() === SyntaxKind.SlashToken; } + function parseGlobalModuleExportDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): GlobalModuleExportDeclaration { + const exportDeclaration = createNode(SyntaxKind.GlobalModuleExportDeclaration, fullStart); + exportDeclaration.decorators = decorators; + exportDeclaration.modifiers = modifiers; + parseExpected(SyntaxKind.AsKeyword); + parseExpected(SyntaxKind.NamespaceKeyword); + + exportDeclaration.name = parseIdentifier(); + + parseExpected(SyntaxKind.SemicolonToken); + + return finishNode(exportDeclaration); + } + function parseImportDeclarationOrImportEqualsDeclaration(fullStart: number, decorators: NodeArray, modifiers: ModifiersArray): ImportEqualsDeclaration | ImportDeclaration { parseExpected(SyntaxKind.ImportKeyword); const afterImportPos = scanner.getStartPos(); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b051c0f5bccbf..e4b16fdf5f6d2 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1282,7 +1282,7 @@ namespace ts { } function processRootFile(fileName: string, isDefaultLib: boolean) { - processSourceFile(normalizePath(fileName), isDefaultLib); + processSourceFile(normalizePath(fileName), isDefaultLib, /*isReference*/ true); } function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean { @@ -1376,7 +1376,10 @@ namespace ts { } } - function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) { + /** + * 'isReference' indicates whether the file was brought in via a reference directive (rather than an import declaration) + */ + function processSourceFile(fileName: string, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) { let diagnosticArgument: string[]; let diagnostic: DiagnosticMessage; if (hasExtension(fileName)) { @@ -1384,7 +1387,7 @@ namespace ts { diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1; diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"]; } - else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd)) { + else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd)) { diagnostic = Diagnostics.File_0_not_found; diagnosticArgument = [fileName]; } @@ -1394,13 +1397,13 @@ namespace ts { } } else { - const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd); + const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd); if (!nonTsFile) { if (options.allowNonTsExtensions) { diagnostic = Diagnostics.File_0_not_found; diagnosticArgument = [fileName]; } - else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd))) { + else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd))) { diagnostic = Diagnostics.File_0_not_found; fileName += ".ts"; diagnosticArgument = [fileName]; @@ -1429,7 +1432,7 @@ namespace ts { } // Get source file from normalized fileName - function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile { + function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile { if (filesByName.contains(path)) { const file = filesByName.get(path); // try to check if we've already seen this file but with a different casing in path @@ -1438,6 +1441,10 @@ namespace ts { reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd); } + if (file) { + file.wasReferenced = file.wasReferenced || isReference; + } + return file; } @@ -1454,6 +1461,7 @@ namespace ts { filesByName.set(path, file); if (file) { + file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { @@ -1491,7 +1499,7 @@ namespace ts { function processReferencedFiles(file: SourceFile, basePath: string) { forEach(file.referencedFiles, ref => { const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName); - processSourceFile(referencedFileName, /*isDefaultLib*/ false, file, ref.pos, ref.end); + processSourceFile(referencedFileName, /*isDefaultLib*/ false, /*isReference*/ true, file, ref.pos, ref.end); }); } @@ -1517,7 +1525,7 @@ namespace ts { i < file.imports.length; if (shouldAddFile) { - const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); + const importedFile = findSourceFile(resolution.resolvedFileName, toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName), /*isDefaultLib*/ false, /*isReference*/ false, file, skipTrivia(file.text, file.imports[i].pos), file.imports[i].end); if (importedFile && resolution.isExternalLibraryImport) { // Since currently irrespective of allowJs, we only look for supportedTypeScript extension external module files, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 10cae6e6ee34a..9d461d8f9fac8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -274,6 +274,7 @@ namespace ts { ModuleDeclaration, ModuleBlock, CaseBlock, + GlobalModuleExportDeclaration, ImportEqualsDeclaration, ImportDeclaration, ImportClause, @@ -1324,6 +1325,12 @@ namespace ts { name: Identifier; } + // @kind(SyntaxKind.GlobalModuleImport) + export interface GlobalModuleExportDeclaration extends DeclarationStatement { + name: Identifier; + moduleReference: LiteralLikeNode; + } + // @kind(SyntaxKind.ExportDeclaration) export interface ExportDeclaration extends DeclarationStatement { exportClause?: NamedExports; @@ -1537,6 +1544,8 @@ namespace ts { /* @internal */ externalModuleIndicator: Node; // The first node that causes this file to be a CommonJS module /* @internal */ commonJsModuleIndicator: Node; + // True if the file was a root file in a compilation or a /// reference targets + /* @internal */ wasReferenced?: boolean; /* @internal */ identifiers: Map; /* @internal */ nodeCount: number; @@ -1995,6 +2004,7 @@ namespace ts { members?: SymbolTable; // Class, interface or literal instance members exports?: SymbolTable; // Module exports + globalExports?: SymbolTable; // Conditional global UMD exports /* @internal */ id?: number; // Unique id (used to look up SymbolLinks) /* @internal */ mergeId?: number; // Merge id (used to look up merged symbol) /* @internal */ parent?: Symbol; // Parent symbol diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3916d0022c8b4..b70c770ef6250 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1471,6 +1471,7 @@ namespace ts { // export default ... export function isAliasSymbolDeclaration(node: Node): boolean { return node.kind === SyntaxKind.ImportEqualsDeclaration || + node.kind === SyntaxKind.GlobalModuleExportDeclaration || node.kind === SyntaxKind.ImportClause && !!(node).name || node.kind === SyntaxKind.NamespaceImport || node.kind === SyntaxKind.ImportSpecifier || diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 473840d69cc18..3362cb1d375be 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -88,7 +88,7 @@ class CompilerBaselineRunner extends RunnerBase { toBeCompiled = []; otherFiles = []; - if (/require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) { + if (testCaseContent.settings["noImplicitReferences"] || /require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) { toBeCompiled.push({ unitName: this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content }); units.forEach(unit => { if (unit.name !== lastUnit.name) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index df64cf61277a9..4020bcd821b8d 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -896,7 +896,8 @@ namespace Harness { { name: "fileName", type: "string" }, { name: "libFiles", type: "string" }, { name: "noErrorTruncation", type: "boolean" }, - { name: "suppressOutputPathCheck", type: "boolean" } + { name: "suppressOutputPathCheck", type: "boolean" }, + { name: "noImplicitReferences", type: "boolean" } ]; let optionsIndex: ts.Map; diff --git a/tests/baselines/reference/umd-errors.errors.txt b/tests/baselines/reference/umd-errors.errors.txt new file mode 100644 index 0000000000000..e2af49f5d5370 --- /dev/null +++ b/tests/baselines/reference/umd-errors.errors.txt @@ -0,0 +1,60 @@ +tests/cases/conformance/externalModules/err1.d.ts(3,1): error TS1314: Global module exports may only appear in module files. +tests/cases/conformance/externalModules/err2.d.ts(3,2): error TS1314: Global module exports may only appear in module files. +tests/cases/conformance/externalModules/err2.d.ts(3,2): error TS1316: Global module exports may only appear at top level. +tests/cases/conformance/externalModules/err3.d.ts(3,1): error TS1184: Modifiers cannot appear here. +tests/cases/conformance/externalModules/err3.d.ts(4,1): error TS1184: Modifiers cannot appear here. +tests/cases/conformance/externalModules/err3.d.ts(5,1): error TS1184: Modifiers cannot appear here. +tests/cases/conformance/externalModules/err3.d.ts(6,7): error TS1134: Variable declaration expected. +tests/cases/conformance/externalModules/err4.d.ts(3,2): error TS1316: Global module exports may only appear at top level. +tests/cases/conformance/externalModules/err5.ts(3,1): error TS1315: Global module exports may only appear in declaration files. + + +==== tests/cases/conformance/externalModules/err1.d.ts (1 errors) ==== + + // Illegal, can't be in script file + export as namespace Foo; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1314: Global module exports may only appear in module files. + +==== tests/cases/conformance/externalModules/err2.d.ts (2 errors) ==== + // Illegal, can't be in external ambient module + declare module "Foo" { + export as namespace Bar; + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1314: Global module exports may only appear in module files. + ~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1316: Global module exports may only appear at top level. + } + +==== tests/cases/conformance/externalModules/err3.d.ts (4 errors) ==== + // Illegal, can't have modifiers + export var p; + static export as namespace oo1; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + declare export as namespace oo2; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + public export as namespace oo3; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1184: Modifiers cannot appear here. + const export as namespace oo4; + ~~~~~~ +!!! error TS1134: Variable declaration expected. + +==== tests/cases/conformance/externalModules/err4.d.ts (1 errors) ==== + // Illegal, must be at top-level + export namespace B { + export as namespace C1; + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1316: Global module exports may only appear at top level. + } + +==== tests/cases/conformance/externalModules/err5.ts (1 errors) ==== + // Illegal, may not appear in implementation files + export var v; + export as namespace C2; + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS1315: Global module exports may only appear in declaration files. + + \ No newline at end of file diff --git a/tests/baselines/reference/umd-errors.js b/tests/baselines/reference/umd-errors.js new file mode 100644 index 0000000000000..7423c81f9ed29 --- /dev/null +++ b/tests/baselines/reference/umd-errors.js @@ -0,0 +1,36 @@ +//// [tests/cases/conformance/externalModules/umd-errors.ts] //// + +//// [err1.d.ts] + +// Illegal, can't be in script file +export as namespace Foo; + +//// [err2.d.ts] +// Illegal, can't be in external ambient module +declare module "Foo" { + export as namespace Bar; +} + +//// [err3.d.ts] +// Illegal, can't have modifiers +export var p; +static export as namespace oo1; +declare export as namespace oo2; +public export as namespace oo3; +const export as namespace oo4; + +//// [err4.d.ts] +// Illegal, must be at top-level +export namespace B { + export as namespace C1; +} + +//// [err5.ts] +// Illegal, may not appear in implementation files +export var v; +export as namespace C2; + + + +//// [err5.js] +"use strict"; diff --git a/tests/baselines/reference/umd-errors.symbols b/tests/baselines/reference/umd-errors.symbols new file mode 100644 index 0000000000000..043e92ad9db74 --- /dev/null +++ b/tests/baselines/reference/umd-errors.symbols @@ -0,0 +1,8 @@ +=== tests/cases/conformance/externalModules/err5.d.ts === +// Illegal, may not appear in implementation files +export var v; +>v : Symbol(v, Decl(err5.d.ts, 1, 10)) + +export as namespace C; + + diff --git a/tests/baselines/reference/umd-errors.types b/tests/baselines/reference/umd-errors.types new file mode 100644 index 0000000000000..9138dd49a4490 --- /dev/null +++ b/tests/baselines/reference/umd-errors.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/externalModules/err5.d.ts === +// Illegal, may not appear in implementation files +export var v; +>v : any + +export as namespace C; +>C : any + + diff --git a/tests/baselines/reference/umd1.js b/tests/baselines/reference/umd1.js new file mode 100644 index 0000000000000..9b059da488774 --- /dev/null +++ b/tests/baselines/reference/umd1.js @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/externalModules/umd1.ts] //// + +//// [foo.d.ts] + +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +//// [a.ts] +/// +Foo.fn(); +let x: Foo.Thing; +let y: number = x.n; + + +//// [a.js] +/// +exports.Foo.fn(); +var x; +var y = x.n; diff --git a/tests/baselines/reference/umd1.symbols b/tests/baselines/reference/umd1.symbols new file mode 100644 index 0000000000000..cccc777e3e375 --- /dev/null +++ b/tests/baselines/reference/umd1.symbols @@ -0,0 +1,33 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +Foo.fn(); +>Foo.fn : Symbol(Foo.fn, Decl(foo.d.ts, 1, 21)) +>Foo : Symbol(Foo, Decl(foo.d.ts, 3, 38)) +>fn : Symbol(Foo.fn, Decl(foo.d.ts, 1, 21)) + +let x: Foo.Thing; +>x : Symbol(x, Decl(a.ts, 2, 3)) +>Foo : Symbol(Foo, Decl(foo.d.ts, 3, 38)) +>Thing : Symbol(Foo.Thing, Decl(foo.d.ts, 2, 27)) + +let y: number = x.n; +>y : Symbol(y, Decl(a.ts, 3, 3)) +>x.n : Symbol(Foo.Thing.n, Decl(foo.d.ts, 3, 24)) +>x : Symbol(x, Decl(a.ts, 2, 3)) +>n : Symbol(Foo.Thing.n, Decl(foo.d.ts, 3, 24)) + +=== tests/cases/conformance/externalModules/foo.d.ts === + +export var x: number; +>x : Symbol(x, Decl(foo.d.ts, 1, 10)) + +export function fn(): void; +>fn : Symbol(fn, Decl(foo.d.ts, 1, 21)) + +export interface Thing { n: typeof x } +>Thing : Symbol(Thing, Decl(foo.d.ts, 2, 27)) +>n : Symbol(n, Decl(foo.d.ts, 3, 24)) +>x : Symbol(x, Decl(foo.d.ts, 1, 10)) + +export as namespace Foo; + diff --git a/tests/baselines/reference/umd1.types b/tests/baselines/reference/umd1.types new file mode 100644 index 0000000000000..1767f3b5a899d --- /dev/null +++ b/tests/baselines/reference/umd1.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +Foo.fn(); +>Foo.fn() : void +>Foo.fn : () => void +>Foo : typeof Foo +>fn : () => void + +let x: Foo.Thing; +>x : Foo.Thing +>Foo : any +>Thing : Foo.Thing + +let y: number = x.n; +>y : number +>x.n : number +>x : Foo.Thing +>n : number + +=== tests/cases/conformance/externalModules/foo.d.ts === + +export var x: number; +>x : number + +export function fn(): void; +>fn : () => void + +export interface Thing { n: typeof x } +>Thing : Thing +>n : number +>x : number + +export as namespace Foo; +>Foo : any + diff --git a/tests/baselines/reference/umd2.errors.txt b/tests/baselines/reference/umd2.errors.txt new file mode 100644 index 0000000000000..76a4d33f65ac1 --- /dev/null +++ b/tests/baselines/reference/umd2.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/externalModules/a.ts(1,1): error TS2304: Cannot find name 'Foo'. +tests/cases/conformance/externalModules/a.ts(2,8): error TS2503: Cannot find namespace 'Foo'. + + +==== tests/cases/conformance/externalModules/a.ts (2 errors) ==== + Foo.fn(); + ~~~ +!!! error TS2304: Cannot find name 'Foo'. + let x: Foo.Thing; + ~~~ +!!! error TS2503: Cannot find namespace 'Foo'. + let y: number = x.n; + +==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ==== + + export var x: number; + export function fn(): void; + export as namespace Foo; + \ No newline at end of file diff --git a/tests/baselines/reference/umd2.js b/tests/baselines/reference/umd2.js new file mode 100644 index 0000000000000..2737856dcfde5 --- /dev/null +++ b/tests/baselines/reference/umd2.js @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/externalModules/umd2.ts] //// + +//// [foo.d.ts] + +export var x: number; +export function fn(): void; +export as namespace Foo; + +//// [a.ts] +Foo.fn(); +let x: Foo.Thing; +let y: number = x.n; + + +//// [a.js] +Foo.fn(); +var x; +var y = x.n; diff --git a/tests/baselines/reference/umd3.js b/tests/baselines/reference/umd3.js new file mode 100644 index 0000000000000..5e869148bebec --- /dev/null +++ b/tests/baselines/reference/umd3.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/externalModules/umd3.ts] //// + +//// [foo.d.ts] + +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +//// [a.ts] +import * as Foo from './foo'; +Foo.fn(); +let x: Foo.Thing; +let y: number = x.n; + + +//// [a.js] +"use strict"; +var Foo = require('./foo'); +Foo.fn(); +var x; +var y = x.n; diff --git a/tests/baselines/reference/umd3.symbols b/tests/baselines/reference/umd3.symbols new file mode 100644 index 0000000000000..82db9e0b29a9c --- /dev/null +++ b/tests/baselines/reference/umd3.symbols @@ -0,0 +1,35 @@ +=== tests/cases/conformance/externalModules/a.ts === +import * as Foo from './foo'; +>Foo : Symbol(Foo, Decl(a.ts, 0, 6)) + +Foo.fn(); +>Foo.fn : Symbol(Foo.fn, Decl(foo.d.ts, 1, 21)) +>Foo : Symbol(Foo, Decl(a.ts, 0, 6)) +>fn : Symbol(Foo.fn, Decl(foo.d.ts, 1, 21)) + +let x: Foo.Thing; +>x : Symbol(x, Decl(a.ts, 2, 3)) +>Foo : Symbol(Foo, Decl(a.ts, 0, 6)) +>Thing : Symbol(Foo.Thing, Decl(foo.d.ts, 2, 27)) + +let y: number = x.n; +>y : Symbol(y, Decl(a.ts, 3, 3)) +>x.n : Symbol(Foo.Thing.n, Decl(foo.d.ts, 3, 24)) +>x : Symbol(x, Decl(a.ts, 2, 3)) +>n : Symbol(Foo.Thing.n, Decl(foo.d.ts, 3, 24)) + +=== tests/cases/conformance/externalModules/foo.d.ts === + +export var x: number; +>x : Symbol(x, Decl(foo.d.ts, 1, 10)) + +export function fn(): void; +>fn : Symbol(fn, Decl(foo.d.ts, 1, 21)) + +export interface Thing { n: typeof x } +>Thing : Symbol(Thing, Decl(foo.d.ts, 2, 27)) +>n : Symbol(n, Decl(foo.d.ts, 3, 24)) +>x : Symbol(x, Decl(foo.d.ts, 1, 10)) + +export as namespace Foo; + diff --git a/tests/baselines/reference/umd3.types b/tests/baselines/reference/umd3.types new file mode 100644 index 0000000000000..85ee6bafe5ec1 --- /dev/null +++ b/tests/baselines/reference/umd3.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/externalModules/a.ts === +import * as Foo from './foo'; +>Foo : typeof Foo + +Foo.fn(); +>Foo.fn() : void +>Foo.fn : () => void +>Foo : typeof Foo +>fn : () => void + +let x: Foo.Thing; +>x : Foo.Thing +>Foo : any +>Thing : Foo.Thing + +let y: number = x.n; +>y : number +>x.n : number +>x : Foo.Thing +>n : number + +=== tests/cases/conformance/externalModules/foo.d.ts === + +export var x: number; +>x : number + +export function fn(): void; +>fn : () => void + +export interface Thing { n: typeof x } +>Thing : Thing +>n : number +>x : number + +export as namespace Foo; +>Foo : any + diff --git a/tests/baselines/reference/umd4.js b/tests/baselines/reference/umd4.js new file mode 100644 index 0000000000000..b7a7d1da0e281 --- /dev/null +++ b/tests/baselines/reference/umd4.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/externalModules/umd4.ts] //// + +//// [foo.d.ts] + +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +//// [a.ts] +import * as Bar from './foo'; +Bar.fn(); +let x: Bar.Thing; +let y: number = x.n; + + +//// [a.js] +"use strict"; +var Bar = require('./foo'); +Bar.fn(); +var x; +var y = x.n; diff --git a/tests/baselines/reference/umd4.symbols b/tests/baselines/reference/umd4.symbols new file mode 100644 index 0000000000000..8ad987a127226 --- /dev/null +++ b/tests/baselines/reference/umd4.symbols @@ -0,0 +1,35 @@ +=== tests/cases/conformance/externalModules/a.ts === +import * as Bar from './foo'; +>Bar : Symbol(Bar, Decl(a.ts, 0, 6)) + +Bar.fn(); +>Bar.fn : Symbol(Bar.fn, Decl(foo.d.ts, 1, 21)) +>Bar : Symbol(Bar, Decl(a.ts, 0, 6)) +>fn : Symbol(Bar.fn, Decl(foo.d.ts, 1, 21)) + +let x: Bar.Thing; +>x : Symbol(x, Decl(a.ts, 2, 3)) +>Bar : Symbol(Bar, Decl(a.ts, 0, 6)) +>Thing : Symbol(Bar.Thing, Decl(foo.d.ts, 2, 27)) + +let y: number = x.n; +>y : Symbol(y, Decl(a.ts, 3, 3)) +>x.n : Symbol(Bar.Thing.n, Decl(foo.d.ts, 3, 24)) +>x : Symbol(x, Decl(a.ts, 2, 3)) +>n : Symbol(Bar.Thing.n, Decl(foo.d.ts, 3, 24)) + +=== tests/cases/conformance/externalModules/foo.d.ts === + +export var x: number; +>x : Symbol(x, Decl(foo.d.ts, 1, 10)) + +export function fn(): void; +>fn : Symbol(fn, Decl(foo.d.ts, 1, 21)) + +export interface Thing { n: typeof x } +>Thing : Symbol(Thing, Decl(foo.d.ts, 2, 27)) +>n : Symbol(n, Decl(foo.d.ts, 3, 24)) +>x : Symbol(x, Decl(foo.d.ts, 1, 10)) + +export as namespace Foo; + diff --git a/tests/baselines/reference/umd4.types b/tests/baselines/reference/umd4.types new file mode 100644 index 0000000000000..579599f56619b --- /dev/null +++ b/tests/baselines/reference/umd4.types @@ -0,0 +1,37 @@ +=== tests/cases/conformance/externalModules/a.ts === +import * as Bar from './foo'; +>Bar : typeof Bar + +Bar.fn(); +>Bar.fn() : void +>Bar.fn : () => void +>Bar : typeof Bar +>fn : () => void + +let x: Bar.Thing; +>x : Bar.Thing +>Bar : any +>Thing : Bar.Thing + +let y: number = x.n; +>y : number +>x.n : number +>x : Bar.Thing +>n : number + +=== tests/cases/conformance/externalModules/foo.d.ts === + +export var x: number; +>x : number + +export function fn(): void; +>fn : () => void + +export interface Thing { n: typeof x } +>Thing : Thing +>n : number +>x : number + +export as namespace Foo; +>Foo : any + diff --git a/tests/baselines/reference/umd5.errors.txt b/tests/baselines/reference/umd5.errors.txt new file mode 100644 index 0000000000000..19529ce195a6c --- /dev/null +++ b/tests/baselines/reference/umd5.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/externalModules/a.ts(6,9): error TS2304: Cannot find name 'Foo'. + + +==== tests/cases/conformance/externalModules/a.ts (1 errors) ==== + import * as Bar from './foo'; + Bar.fn(); + let x: Bar.Thing; + let y: number = x.n; + // should error + let z = Foo; + ~~~ +!!! error TS2304: Cannot find name 'Foo'. + +==== tests/cases/conformance/externalModules/foo.d.ts (0 errors) ==== + + export var x: number; + export function fn(): void; + export interface Thing { n: typeof x } + export as namespace Foo; + \ No newline at end of file diff --git a/tests/baselines/reference/umd5.js b/tests/baselines/reference/umd5.js new file mode 100644 index 0000000000000..d054daf93fd61 --- /dev/null +++ b/tests/baselines/reference/umd5.js @@ -0,0 +1,26 @@ +//// [tests/cases/conformance/externalModules/umd5.ts] //// + +//// [foo.d.ts] + +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +//// [a.ts] +import * as Bar from './foo'; +Bar.fn(); +let x: Bar.Thing; +let y: number = x.n; +// should error +let z = Foo; + + +//// [a.js] +"use strict"; +var Bar = require('./foo'); +Bar.fn(); +var x; +var y = x.n; +// should error +var z = Foo; diff --git a/tests/cases/conformance/externalModules/umd-errors.ts b/tests/cases/conformance/externalModules/umd-errors.ts new file mode 100644 index 0000000000000..95e6cb7c7a451 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd-errors.ts @@ -0,0 +1,31 @@ +// @module: commonjs + +// @filename: err1.d.ts +// Illegal, can't be in script file +export as namespace Foo; + +// @filename: err2.d.ts +// Illegal, can't be in external ambient module +declare module "Foo" { + export as namespace Bar; +} + +// @filename: err3.d.ts +// Illegal, can't have modifiers +export var p; +static export as namespace oo1; +declare export as namespace oo2; +public export as namespace oo3; +const export as namespace oo4; + +// @filename: err4.d.ts +// Illegal, must be at top-level +export namespace B { + export as namespace C1; +} + +// @filename: err5.ts +// Illegal, may not appear in implementation files +export var v; +export as namespace C2; + diff --git a/tests/cases/conformance/externalModules/umd1.ts b/tests/cases/conformance/externalModules/umd1.ts new file mode 100644 index 0000000000000..5ceb7fa59ba2b --- /dev/null +++ b/tests/cases/conformance/externalModules/umd1.ts @@ -0,0 +1,14 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +// @filename: a.ts +/// +Foo.fn(); +let x: Foo.Thing; +let y: number = x.n; diff --git a/tests/cases/conformance/externalModules/umd2.ts b/tests/cases/conformance/externalModules/umd2.ts new file mode 100644 index 0000000000000..2fb98491ebf66 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd2.ts @@ -0,0 +1,12 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +export var x: number; +export function fn(): void; +export as namespace Foo; + +// @filename: a.ts +Foo.fn(); +let x: Foo.Thing; +let y: number = x.n; diff --git a/tests/cases/conformance/externalModules/umd3.ts b/tests/cases/conformance/externalModules/umd3.ts new file mode 100644 index 0000000000000..dad0dfc644d6d --- /dev/null +++ b/tests/cases/conformance/externalModules/umd3.ts @@ -0,0 +1,14 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +// @filename: a.ts +import * as Foo from './foo'; +Foo.fn(); +let x: Foo.Thing; +let y: number = x.n; diff --git a/tests/cases/conformance/externalModules/umd4.ts b/tests/cases/conformance/externalModules/umd4.ts new file mode 100644 index 0000000000000..e927d21f1ccdd --- /dev/null +++ b/tests/cases/conformance/externalModules/umd4.ts @@ -0,0 +1,14 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +// @filename: a.ts +import * as Bar from './foo'; +Bar.fn(); +let x: Bar.Thing; +let y: number = x.n; diff --git a/tests/cases/conformance/externalModules/umd5.ts b/tests/cases/conformance/externalModules/umd5.ts new file mode 100644 index 0000000000000..b6d949c2d0a76 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd5.ts @@ -0,0 +1,16 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +export var x: number; +export function fn(): void; +export interface Thing { n: typeof x } +export as namespace Foo; + +// @filename: a.ts +import * as Bar from './foo'; +Bar.fn(); +let x: Bar.Thing; +let y: number = x.n; +// should error +let z = Foo; From e9f4bef3ac36fc032a365ad481439eb907edf377 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 2 Mar 2016 10:53:41 -0800 Subject: [PATCH 02/11] Address CR feedback --- src/compiler/parser.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4489185d0eaae..4f8d246911058 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4591,7 +4591,6 @@ namespace ts { case SyntaxKind.EnumKeyword: return parseEnumDeclaration(fullStart, decorators, modifiers); case SyntaxKind.GlobalKeyword: - return parseModuleDeclaration(fullStart, decorators, modifiers); case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: return parseModuleDeclaration(fullStart, decorators, modifiers); From 887adb0146bed4505af1719c525a37f136192b54 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 3 Mar 2016 13:12:26 -0800 Subject: [PATCH 03/11] Move checks from checker to binder --- src/compiler/binder.ts | 22 +++++++++++++++++-- src/compiler/checker.ts | 20 ----------------- .../baselines/reference/umd-errors.errors.txt | 5 +---- tests/baselines/reference/umd-errors.symbols | 8 ------- tests/baselines/reference/umd-errors.types | 9 -------- 5 files changed, 21 insertions(+), 43 deletions(-) delete mode 100644 tests/baselines/reference/umd-errors.symbols delete mode 100644 tests/baselines/reference/umd-errors.types diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 0a2cb25bd3f06..7777b30bdd1d3 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1407,10 +1407,28 @@ namespace ts { } function bindGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration) { - if (!file.externalModuleIndicator) { - file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files)); + if (node.modifiers && node.modifiers.length) { + file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Modifiers_cannot_appear_here)); + } + + if (node.parent.kind !== SyntaxKind.SourceFile) { + file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_at_top_level)); return; } + else { + const parent = node.parent as SourceFile; + + if (!isExternalModule(node.parent)) { + file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files)); + return; + } + + if (!parent.isDeclarationFile) { + file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_declaration_files)); + return; + } + } + file.symbol.globalExports = file.symbol.globalExports || {}; declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fde042eaaba2c..746b3236cf3da 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15226,24 +15226,6 @@ namespace ts { } } - function checkGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration) { - if (node.modifiers && node.modifiers.length) { - error(node, Diagnostics.Modifiers_cannot_appear_here); - } - - if (node.parent.kind !== SyntaxKind.SourceFile) { - error(node, Diagnostics.Global_module_exports_may_only_appear_at_top_level); - } - else { - const parent = node.parent as SourceFile; - // Note: the binder handles the case where the declaration isn't in an external module - if (parent.externalModuleIndicator && !parent.isDeclarationFile) { - error(node, Diagnostics.Global_module_exports_may_only_appear_in_declaration_files); - } - } - - } - function checkSourceElement(node: Node): void { if (!node) { return; @@ -15360,8 +15342,6 @@ namespace ts { return checkExportDeclaration(node); case SyntaxKind.ExportAssignment: return checkExportAssignment(node); - case SyntaxKind.GlobalModuleExportDeclaration: - return checkGlobalModuleExportDeclaration(node); case SyntaxKind.EmptyStatement: checkGrammarStatementInAmbientContext(node); return; diff --git a/tests/baselines/reference/umd-errors.errors.txt b/tests/baselines/reference/umd-errors.errors.txt index e2af49f5d5370..a957566527753 100644 --- a/tests/baselines/reference/umd-errors.errors.txt +++ b/tests/baselines/reference/umd-errors.errors.txt @@ -1,5 +1,4 @@ tests/cases/conformance/externalModules/err1.d.ts(3,1): error TS1314: Global module exports may only appear in module files. -tests/cases/conformance/externalModules/err2.d.ts(3,2): error TS1314: Global module exports may only appear in module files. tests/cases/conformance/externalModules/err2.d.ts(3,2): error TS1316: Global module exports may only appear at top level. tests/cases/conformance/externalModules/err3.d.ts(3,1): error TS1184: Modifiers cannot appear here. tests/cases/conformance/externalModules/err3.d.ts(4,1): error TS1184: Modifiers cannot appear here. @@ -16,13 +15,11 @@ tests/cases/conformance/externalModules/err5.ts(3,1): error TS1315: Global modul ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS1314: Global module exports may only appear in module files. -==== tests/cases/conformance/externalModules/err2.d.ts (2 errors) ==== +==== tests/cases/conformance/externalModules/err2.d.ts (1 errors) ==== // Illegal, can't be in external ambient module declare module "Foo" { export as namespace Bar; ~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS1314: Global module exports may only appear in module files. - ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS1316: Global module exports may only appear at top level. } diff --git a/tests/baselines/reference/umd-errors.symbols b/tests/baselines/reference/umd-errors.symbols deleted file mode 100644 index 043e92ad9db74..0000000000000 --- a/tests/baselines/reference/umd-errors.symbols +++ /dev/null @@ -1,8 +0,0 @@ -=== tests/cases/conformance/externalModules/err5.d.ts === -// Illegal, may not appear in implementation files -export var v; ->v : Symbol(v, Decl(err5.d.ts, 1, 10)) - -export as namespace C; - - diff --git a/tests/baselines/reference/umd-errors.types b/tests/baselines/reference/umd-errors.types deleted file mode 100644 index 9138dd49a4490..0000000000000 --- a/tests/baselines/reference/umd-errors.types +++ /dev/null @@ -1,9 +0,0 @@ -=== tests/cases/conformance/externalModules/err5.d.ts === -// Illegal, may not appear in implementation files -export var v; ->v : any - -export as namespace C; ->C : any - - From 34cf10542c996eab58ac8769286b7eb90373dd02 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 3 Mar 2016 14:58:17 -0800 Subject: [PATCH 04/11] Lint --- src/compiler/binder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 7777b30bdd1d3..2cc48c02947ae 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1417,7 +1417,7 @@ namespace ts { } else { const parent = node.parent as SourceFile; - + if (!isExternalModule(node.parent)) { file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files)); return; From 132d75c26721f7b11d137c2a3c3139faaa09d94f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 7 Mar 2016 12:30:57 -0800 Subject: [PATCH 05/11] Support UMD when targeted module uses `export = ` --- src/compiler/checker.ts | 8 ++++++- tests/baselines/reference/umd6.js | 18 +++++++++++++++ tests/baselines/reference/umd6.symbols | 19 +++++++++++++++ tests/baselines/reference/umd6.types | 23 +++++++++++++++++++ .../cases/conformance/externalModules/umd6.ts | 13 +++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/umd6.js create mode 100644 tests/baselines/reference/umd6.symbols create mode 100644 tests/baselines/reference/umd6.types create mode 100644 tests/cases/conformance/externalModules/umd6.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 746b3236cf3da..6bf47ba4b9876 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -982,7 +982,13 @@ namespace ts { } function getTargetOfGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration): Symbol { - return node.parent.symbol; + const moduleSymbol = node.parent.symbol; + if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports["export="]) { + return moduleSymbol.exports["export="].exportSymbol; + } + else { + return moduleSymbol; + } } function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol { diff --git a/tests/baselines/reference/umd6.js b/tests/baselines/reference/umd6.js new file mode 100644 index 0000000000000..d4d84fd0384ce --- /dev/null +++ b/tests/baselines/reference/umd6.js @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/externalModules/umd6.ts] //// + +//// [foo.d.ts] + +declare namespace Thing { + export function fn(): number; +} +export = Thing; +export as namespace Foo; + +//// [a.ts] +/// +let y: number = Foo.fn(); + + +//// [a.js] +/// +var y = exports.Foo.fn(); diff --git a/tests/baselines/reference/umd6.symbols b/tests/baselines/reference/umd6.symbols new file mode 100644 index 0000000000000..3b417e005d6fb --- /dev/null +++ b/tests/baselines/reference/umd6.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +let y: number = Foo.fn(); +>y : Symbol(y, Decl(a.ts, 1, 3)) +>Foo : Symbol(Foo, Decl(foo.d.ts, 4, 15)) + +=== tests/cases/conformance/externalModules/foo.d.ts === + +declare namespace Thing { +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + + export function fn(): number; +>fn : Symbol(fn, Decl(foo.d.ts, 1, 25)) +} +export = Thing; +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + +export as namespace Foo; + diff --git a/tests/baselines/reference/umd6.types b/tests/baselines/reference/umd6.types new file mode 100644 index 0000000000000..dc0f45846c2d8 --- /dev/null +++ b/tests/baselines/reference/umd6.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +let y: number = Foo.fn(); +>y : number +>Foo.fn() : any +>Foo.fn : any +>Foo : any +>fn : any + +=== tests/cases/conformance/externalModules/foo.d.ts === + +declare namespace Thing { +>Thing : typeof Thing + + export function fn(): number; +>fn : () => number +} +export = Thing; +>Thing : typeof Thing + +export as namespace Foo; +>Foo : any + diff --git a/tests/cases/conformance/externalModules/umd6.ts b/tests/cases/conformance/externalModules/umd6.ts new file mode 100644 index 0000000000000..2f9e49072cf36 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd6.ts @@ -0,0 +1,13 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +declare namespace Thing { + export function fn(): number; +} +export = Thing; +export as namespace Foo; + +// @filename: a.ts +/// +let y: number = Foo.fn(); From 3d948be4c603dd87749f4dd4dc722a3c286bf44f Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 8 Mar 2016 13:41:50 -0800 Subject: [PATCH 06/11] Support module augmentation --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6bf47ba4b9876..e1173a55aaa64 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -984,10 +984,10 @@ namespace ts { function getTargetOfGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration): Symbol { const moduleSymbol = node.parent.symbol; if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports["export="]) { - return moduleSymbol.exports["export="].exportSymbol; + return getMergedSymbol(moduleSymbol.exports["export="].exportSymbol); } else { - return moduleSymbol; + return getMergedSymbol(moduleSymbol); } } From 2875326735c810a3e8b43c9c52e3bcb603d33efc Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Tue, 8 Mar 2016 14:56:40 -0800 Subject: [PATCH 07/11] Use existing function to resolve export= declarations --- src/compiler/checker.ts | 8 +------- tests/baselines/reference/umd6.symbols | 2 ++ tests/baselines/reference/umd6.types | 8 ++++---- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e1173a55aaa64..9ba35313e4835 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -982,13 +982,7 @@ namespace ts { } function getTargetOfGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration): Symbol { - const moduleSymbol = node.parent.symbol; - if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports["export="]) { - return getMergedSymbol(moduleSymbol.exports["export="].exportSymbol); - } - else { - return getMergedSymbol(moduleSymbol); - } + return resolveExternalModuleSymbol(node.parent.symbol); } function getTargetOfExportSpecifier(node: ExportSpecifier): Symbol { diff --git a/tests/baselines/reference/umd6.symbols b/tests/baselines/reference/umd6.symbols index 3b417e005d6fb..d08507f1ea2e7 100644 --- a/tests/baselines/reference/umd6.symbols +++ b/tests/baselines/reference/umd6.symbols @@ -2,7 +2,9 @@ /// let y: number = Foo.fn(); >y : Symbol(y, Decl(a.ts, 1, 3)) +>Foo.fn : Symbol(Foo.fn, Decl(foo.d.ts, 1, 25)) >Foo : Symbol(Foo, Decl(foo.d.ts, 4, 15)) +>fn : Symbol(Foo.fn, Decl(foo.d.ts, 1, 25)) === tests/cases/conformance/externalModules/foo.d.ts === diff --git a/tests/baselines/reference/umd6.types b/tests/baselines/reference/umd6.types index dc0f45846c2d8..7318a43057a4e 100644 --- a/tests/baselines/reference/umd6.types +++ b/tests/baselines/reference/umd6.types @@ -2,10 +2,10 @@ /// let y: number = Foo.fn(); >y : number ->Foo.fn() : any ->Foo.fn : any ->Foo : any ->fn : any +>Foo.fn() : number +>Foo.fn : () => number +>Foo : typeof Foo +>fn : () => number === tests/cases/conformance/externalModules/foo.d.ts === From 14941f26a05962b6e838f59c6359f0b046765128 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 9 Mar 2016 14:35:03 -0800 Subject: [PATCH 08/11] Add tests for each variant of UMD augmentation --- .../baselines/reference/umd-augmentation-1.js | 50 ++++++++ .../reference/umd-augmentation-1.symbols | 95 +++++++++++++++ .../reference/umd-augmentation-1.types | 105 ++++++++++++++++ .../baselines/reference/umd-augmentation-2.js | 49 ++++++++ .../reference/umd-augmentation-2.symbols | 93 ++++++++++++++ .../reference/umd-augmentation-2.types | 103 ++++++++++++++++ .../baselines/reference/umd-augmentation-3.js | 56 +++++++++ .../reference/umd-augmentation-3.symbols | 104 ++++++++++++++++ .../reference/umd-augmentation-3.types | 114 ++++++++++++++++++ .../baselines/reference/umd-augmentation-4.js | 55 +++++++++ .../reference/umd-augmentation-4.symbols | 102 ++++++++++++++++ .../reference/umd-augmentation-4.types | 112 +++++++++++++++++ .../externalModules/umd-augmentation-1.ts | 39 ++++++ .../externalModules/umd-augmentation-2.ts | 39 ++++++ .../externalModules/umd-augmentation-3.ts | 45 +++++++ .../externalModules/umd-augmentation-4.ts | 45 +++++++ 16 files changed, 1206 insertions(+) create mode 100644 tests/baselines/reference/umd-augmentation-1.js create mode 100644 tests/baselines/reference/umd-augmentation-1.symbols create mode 100644 tests/baselines/reference/umd-augmentation-1.types create mode 100644 tests/baselines/reference/umd-augmentation-2.js create mode 100644 tests/baselines/reference/umd-augmentation-2.symbols create mode 100644 tests/baselines/reference/umd-augmentation-2.types create mode 100644 tests/baselines/reference/umd-augmentation-3.js create mode 100644 tests/baselines/reference/umd-augmentation-3.symbols create mode 100644 tests/baselines/reference/umd-augmentation-3.types create mode 100644 tests/baselines/reference/umd-augmentation-4.js create mode 100644 tests/baselines/reference/umd-augmentation-4.symbols create mode 100644 tests/baselines/reference/umd-augmentation-4.types create mode 100644 tests/cases/conformance/externalModules/umd-augmentation-1.ts create mode 100644 tests/cases/conformance/externalModules/umd-augmentation-2.ts create mode 100644 tests/cases/conformance/externalModules/umd-augmentation-3.ts create mode 100644 tests/cases/conformance/externalModules/umd-augmentation-4.ts diff --git a/tests/baselines/reference/umd-augmentation-1.js b/tests/baselines/reference/umd-augmentation-1.js new file mode 100644 index 0000000000000..b3ffcf670a8cb --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-1.js @@ -0,0 +1,50 @@ +//// [tests/cases/conformance/externalModules/umd-augmentation-1.ts] //// + +//// [index.d.ts] + +export as namespace Math2d; + +export interface Point { + x: number; + y: number; +} + +export class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; +} + +export function getLength(p: Vector): number; + +//// [math2d-augment.d.ts] +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +//// [b.ts] +/// +import * as m from 'math2d'; +let v = new m.Vector(3, 2); +let magnitude = m.getLength(v); +let p: m.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; + + +//// [b.js] +"use strict"; +/// +var m = require('math2d'); +var v = new m.Vector(3, 2); +var magnitude = m.getLength(v); +var p = v.translate(5, 5); +p = v.reverse(); +var t = p.x; diff --git a/tests/baselines/reference/umd-augmentation-1.symbols b/tests/baselines/reference/umd-augmentation-1.symbols new file mode 100644 index 0000000000000..15dab071bb4a5 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-1.symbols @@ -0,0 +1,95 @@ +=== tests/cases/conformance/externalModules/b.ts === +/// +import * as m from 'math2d'; +>m : Symbol(m, Decl(b.ts, 1, 6)) + +let v = new m.Vector(3, 2); +>v : Symbol(v, Decl(b.ts, 2, 3)) +>m.Vector : Symbol(m.Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) +>m : Symbol(m, Decl(b.ts, 1, 6)) +>Vector : Symbol(m.Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) + +let magnitude = m.getLength(v); +>magnitude : Symbol(magnitude, Decl(b.ts, 3, 3)) +>m.getLength : Symbol(m.getLength, Decl(index.d.ts, 14, 1)) +>m : Symbol(m, Decl(b.ts, 1, 6)) +>getLength : Symbol(m.getLength, Decl(index.d.ts, 14, 1)) +>v : Symbol(v, Decl(b.ts, 2, 3)) + +let p: m.Point = v.translate(5, 5); +>p : Symbol(p, Decl(b.ts, 4, 3)) +>m : Symbol(m, Decl(b.ts, 1, 6)) +>Point : Symbol(m.Point, Decl(index.d.ts, 1, 27)) +>v.translate : Symbol(m.Vector.translate, Decl(index.d.ts, 11, 35)) +>v : Symbol(v, Decl(b.ts, 2, 3)) +>translate : Symbol(m.Vector.translate, Decl(index.d.ts, 11, 35)) + +p = v.reverse(); +>p : Symbol(p, Decl(b.ts, 4, 3)) +>v.reverse : Symbol(m.Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) +>v : Symbol(v, Decl(b.ts, 2, 3)) +>reverse : Symbol(m.Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) + +var t = p.x; +>t : Symbol(t, Decl(b.ts, 6, 3)) +>p.x : Symbol(m.Point.x, Decl(index.d.ts, 3, 24)) +>p : Symbol(p, Decl(b.ts, 4, 3)) +>x : Symbol(m.Point.x, Decl(index.d.ts, 3, 24)) + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; + +export interface Point { +>Point : Symbol(Point, Decl(index.d.ts, 1, 27)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 3, 24)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 4, 11)) +} + +export class Vector implements Point { +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) +>Point : Symbol(Point, Decl(index.d.ts, 1, 27)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 8, 38)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 9, 11)) + + constructor(x: number, y: number); +>x : Symbol(x, Decl(index.d.ts, 11, 13)) +>y : Symbol(y, Decl(index.d.ts, 11, 23)) + + translate(dx: number, dy: number): Vector; +>translate : Symbol(translate, Decl(index.d.ts, 11, 35)) +>dx : Symbol(dx, Decl(index.d.ts, 13, 11)) +>dy : Symbol(dy, Decl(index.d.ts, 13, 22)) +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) +} + +export function getLength(p: Vector): number; +>getLength : Symbol(getLength, Decl(index.d.ts, 14, 1)) +>p : Symbol(p, Decl(index.d.ts, 16, 26)) +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) + + reverse(): Math2d.Point; +>reverse : Symbol(reverse, Decl(math2d-augment.d.ts, 4, 19)) +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) +>Point : Symbol(Point, Decl(index.d.ts, 1, 27)) + } +} + diff --git a/tests/baselines/reference/umd-augmentation-1.types b/tests/baselines/reference/umd-augmentation-1.types new file mode 100644 index 0000000000000..31ac43fe85557 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-1.types @@ -0,0 +1,105 @@ +=== tests/cases/conformance/externalModules/b.ts === +/// +import * as m from 'math2d'; +>m : typeof m + +let v = new m.Vector(3, 2); +>v : m.Vector +>new m.Vector(3, 2) : m.Vector +>m.Vector : typeof m.Vector +>m : typeof m +>Vector : typeof m.Vector +>3 : number +>2 : number + +let magnitude = m.getLength(v); +>magnitude : number +>m.getLength(v) : number +>m.getLength : (p: m.Vector) => number +>m : typeof m +>getLength : (p: m.Vector) => number +>v : m.Vector + +let p: m.Point = v.translate(5, 5); +>p : m.Point +>m : any +>Point : m.Point +>v.translate(5, 5) : m.Vector +>v.translate : (dx: number, dy: number) => m.Vector +>v : m.Vector +>translate : (dx: number, dy: number) => m.Vector +>5 : number +>5 : number + +p = v.reverse(); +>p = v.reverse() : m.Point +>p : m.Point +>v.reverse() : m.Point +>v.reverse : () => m.Point +>v : m.Vector +>reverse : () => m.Point + +var t = p.x; +>t : number +>p.x : number +>p : m.Point +>x : number + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; +>Math2d : any + +export interface Point { +>Point : Point + + x: number; +>x : number + + y: number; +>y : number +} + +export class Vector implements Point { +>Vector : Vector +>Point : Point + + x: number; +>x : number + + y: number; +>y : number + + constructor(x: number, y: number); +>x : number +>y : number + + translate(dx: number, dy: number): Vector; +>translate : (dx: number, dy: number) => Vector +>dx : number +>dy : number +>Vector : Vector +} + +export function getLength(p: Vector): number; +>getLength : (p: Vector) => number +>p : Vector +>Vector : Vector + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : typeof Math2d + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Vector + + reverse(): Math2d.Point; +>reverse : () => Point +>Math2d : any +>Point : Point + } +} + diff --git a/tests/baselines/reference/umd-augmentation-2.js b/tests/baselines/reference/umd-augmentation-2.js new file mode 100644 index 0000000000000..a4a98690b523e --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-2.js @@ -0,0 +1,49 @@ +//// [tests/cases/conformance/externalModules/umd-augmentation-2.ts] //// + +//// [index.d.ts] + +export as namespace Math2d; + +export interface Point { + x: number; + y: number; +} + +export class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; +} + +export function getLength(p: Vector): number; + +//// [math2d-augment.d.ts] +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +//// [a.ts] +/// +/// +let v = new Math2d.Vector(3, 2); +let magnitude = Math2d.getLength(v); +let p: Math2d.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; + + +//// [a.js] +/// +/// +var v = new exports.Math2d.Vector(3, 2); +var magnitude = exports.Math2d.getLength(v); +var p = v.translate(5, 5); +p = v.reverse(); +var t = p.x; diff --git a/tests/baselines/reference/umd-augmentation-2.symbols b/tests/baselines/reference/umd-augmentation-2.symbols new file mode 100644 index 0000000000000..4e5163f7499a5 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-2.symbols @@ -0,0 +1,93 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +/// +let v = new Math2d.Vector(3, 2); +>v : Symbol(v, Decl(a.ts, 2, 3)) +>Math2d.Vector : Symbol(Math2d.Vector, Decl(index.d.ts, 6, 1)) +>Math2d : Symbol(Math2d, Decl(index.d.ts, 0, 0)) +>Vector : Symbol(Math2d.Vector, Decl(index.d.ts, 6, 1)) + +let magnitude = Math2d.getLength(v); +>magnitude : Symbol(magnitude, Decl(a.ts, 3, 3)) +>Math2d.getLength : Symbol(Math2d.getLength, Decl(index.d.ts, 14, 1)) +>Math2d : Symbol(Math2d, Decl(index.d.ts, 0, 0)) +>getLength : Symbol(Math2d.getLength, Decl(index.d.ts, 14, 1)) +>v : Symbol(v, Decl(a.ts, 2, 3)) + +let p: Math2d.Point = v.translate(5, 5); +>p : Symbol(p, Decl(a.ts, 4, 3)) +>Math2d : Symbol(Math2d, Decl(index.d.ts, 0, 0)) +>Point : Symbol(Math2d.Point, Decl(index.d.ts, 1, 27)) +>v.translate : Symbol(Vector.translate, Decl(index.d.ts, 11, 35)) +>v : Symbol(v, Decl(a.ts, 2, 3)) +>translate : Symbol(Vector.translate, Decl(index.d.ts, 11, 35)) + +p = v.reverse(); +>p : Symbol(p, Decl(a.ts, 4, 3)) +>v.reverse : Symbol(Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) +>v : Symbol(v, Decl(a.ts, 2, 3)) +>reverse : Symbol(Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) + +var t = p.x; +>t : Symbol(t, Decl(a.ts, 6, 3)) +>p.x : Symbol(Math2d.Point.x, Decl(index.d.ts, 3, 24)) +>p : Symbol(p, Decl(a.ts, 4, 3)) +>x : Symbol(Math2d.Point.x, Decl(index.d.ts, 3, 24)) + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; + +export interface Point { +>Point : Symbol(Point, Decl(index.d.ts, 1, 27)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 3, 24)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 4, 11)) +} + +export class Vector implements Point { +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) +>Point : Symbol(Point, Decl(index.d.ts, 1, 27)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 8, 38)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 9, 11)) + + constructor(x: number, y: number); +>x : Symbol(x, Decl(index.d.ts, 11, 13)) +>y : Symbol(y, Decl(index.d.ts, 11, 23)) + + translate(dx: number, dy: number): Vector; +>translate : Symbol(translate, Decl(index.d.ts, 11, 35)) +>dx : Symbol(dx, Decl(index.d.ts, 13, 11)) +>dy : Symbol(dy, Decl(index.d.ts, 13, 22)) +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) +} + +export function getLength(p: Vector): number; +>getLength : Symbol(getLength, Decl(index.d.ts, 14, 1)) +>p : Symbol(p, Decl(index.d.ts, 16, 26)) +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Symbol(Vector, Decl(index.d.ts, 6, 1), Decl(math2d-augment.d.ts, 2, 25)) + + reverse(): Math2d.Point; +>reverse : Symbol(reverse, Decl(math2d-augment.d.ts, 4, 19)) +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) +>Point : Symbol(Point, Decl(index.d.ts, 1, 27)) + } +} + diff --git a/tests/baselines/reference/umd-augmentation-2.types b/tests/baselines/reference/umd-augmentation-2.types new file mode 100644 index 0000000000000..20bba09190314 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-2.types @@ -0,0 +1,103 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +/// +let v = new Math2d.Vector(3, 2); +>v : Vector +>new Math2d.Vector(3, 2) : Vector +>Math2d.Vector : typeof Math2d.Vector +>Math2d : typeof Math2d +>Vector : typeof Math2d.Vector +>3 : number +>2 : number + +let magnitude = Math2d.getLength(v); +>magnitude : number +>Math2d.getLength(v) : number +>Math2d.getLength : (p: Vector) => number +>Math2d : typeof Math2d +>getLength : (p: Vector) => number +>v : Vector + +let p: Math2d.Point = v.translate(5, 5); +>p : Math2d.Point +>Math2d : any +>Point : Math2d.Point +>v.translate(5, 5) : Vector +>v.translate : (dx: number, dy: number) => Vector +>v : Vector +>translate : (dx: number, dy: number) => Vector +>5 : number +>5 : number + +p = v.reverse(); +>p = v.reverse() : Math2d.Point +>p : Math2d.Point +>v.reverse() : Math2d.Point +>v.reverse : () => Math2d.Point +>v : Vector +>reverse : () => Math2d.Point + +var t = p.x; +>t : number +>p.x : number +>p : Math2d.Point +>x : number + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; +>Math2d : any + +export interface Point { +>Point : Point + + x: number; +>x : number + + y: number; +>y : number +} + +export class Vector implements Point { +>Vector : Vector +>Point : Point + + x: number; +>x : number + + y: number; +>y : number + + constructor(x: number, y: number); +>x : number +>y : number + + translate(dx: number, dy: number): Vector; +>translate : (dx: number, dy: number) => Vector +>dx : number +>dy : number +>Vector : Vector +} + +export function getLength(p: Vector): number; +>getLength : (p: Vector) => number +>p : Vector +>Vector : Vector + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : typeof Math2d + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Vector + + reverse(): Math2d.Point; +>reverse : () => Point +>Math2d : any +>Point : Point + } +} + diff --git a/tests/baselines/reference/umd-augmentation-3.js b/tests/baselines/reference/umd-augmentation-3.js new file mode 100644 index 0000000000000..2b8eac7bf6377 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-3.js @@ -0,0 +1,56 @@ +//// [tests/cases/conformance/externalModules/umd-augmentation-3.ts] //// + +//// [index.d.ts] + +export as namespace Math2d; + +export = M2D; + +declare namespace M2D { + interface Point { + x: number; + y: number; + } + + class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; + } + + function getLength(p: Vector): number; + +} + + +//// [math2d-augment.d.ts] +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +//// [b.ts] +/// +import * as m from 'math2d'; +let v = new m.Vector(3, 2); +let magnitude = m.getLength(v); +let p: m.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; + + +//// [b.js] +"use strict"; +/// +var m = require('math2d'); +var v = new m.Vector(3, 2); +var magnitude = m.getLength(v); +var p = v.translate(5, 5); +p = v.reverse(); +var t = p.x; diff --git a/tests/baselines/reference/umd-augmentation-3.symbols b/tests/baselines/reference/umd-augmentation-3.symbols new file mode 100644 index 0000000000000..049630e647a73 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-3.symbols @@ -0,0 +1,104 @@ +=== tests/cases/conformance/externalModules/b.ts === +/// +import * as m from 'math2d'; +>m : Symbol(m, Decl(b.ts, 1, 6)) + +let v = new m.Vector(3, 2); +>v : Symbol(v, Decl(b.ts, 2, 3)) +>m.Vector : Symbol(m.Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) +>m : Symbol(m, Decl(b.ts, 1, 6)) +>Vector : Symbol(m.Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + +let magnitude = m.getLength(v); +>magnitude : Symbol(magnitude, Decl(b.ts, 3, 3)) +>m.getLength : Symbol(m.getLength, Decl(index.d.ts, 17, 2)) +>m : Symbol(m, Decl(b.ts, 1, 6)) +>getLength : Symbol(m.getLength, Decl(index.d.ts, 17, 2)) +>v : Symbol(v, Decl(b.ts, 2, 3)) + +let p: m.Point = v.translate(5, 5); +>p : Symbol(p, Decl(b.ts, 4, 3)) +>m : Symbol(m, Decl(b.ts, 1, 6)) +>Point : Symbol(m.Point, Decl(index.d.ts, 5, 23)) +>v.translate : Symbol(m.Vector.translate, Decl(index.d.ts, 14, 36)) +>v : Symbol(v, Decl(b.ts, 2, 3)) +>translate : Symbol(m.Vector.translate, Decl(index.d.ts, 14, 36)) + +p = v.reverse(); +>p : Symbol(p, Decl(b.ts, 4, 3)) +>v.reverse : Symbol(m.Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) +>v : Symbol(v, Decl(b.ts, 2, 3)) +>reverse : Symbol(m.Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) + +var t = p.x; +>t : Symbol(t, Decl(b.ts, 6, 3)) +>p.x : Symbol(m.Point.x, Decl(index.d.ts, 6, 18)) +>p : Symbol(p, Decl(b.ts, 4, 3)) +>x : Symbol(m.Point.x, Decl(index.d.ts, 6, 18)) + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; + +export = M2D; +>M2D : Symbol(M2D, Decl(index.d.ts, 3, 13)) + +declare namespace M2D { +>M2D : Symbol(, Decl(index.d.ts, 3, 13), Decl(math2d-augment.d.ts, 0, 33)) + + interface Point { +>Point : Symbol(Point, Decl(index.d.ts, 5, 23)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 6, 18)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 7, 12)) + } + + class Vector implements Point { +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) +>Point : Symbol(Point, Decl(index.d.ts, 5, 23)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 11, 32)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 12, 12)) + + constructor(x: number, y: number); +>x : Symbol(x, Decl(index.d.ts, 14, 14)) +>y : Symbol(y, Decl(index.d.ts, 14, 24)) + + translate(dx: number, dy: number): Vector; +>translate : Symbol(translate, Decl(index.d.ts, 14, 36)) +>dx : Symbol(dx, Decl(index.d.ts, 16, 12)) +>dy : Symbol(dy, Decl(index.d.ts, 16, 23)) +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + } + + function getLength(p: Vector): number; +>getLength : Symbol(getLength, Decl(index.d.ts, 17, 2)) +>p : Symbol(p, Decl(index.d.ts, 19, 20)) +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + +} + + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + + reverse(): Math2d.Point; +>reverse : Symbol(reverse, Decl(math2d-augment.d.ts, 4, 19)) +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) +>Point : Symbol(Point, Decl(index.d.ts, 5, 23)) + } +} + diff --git a/tests/baselines/reference/umd-augmentation-3.types b/tests/baselines/reference/umd-augmentation-3.types new file mode 100644 index 0000000000000..09a383dc881d8 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-3.types @@ -0,0 +1,114 @@ +=== tests/cases/conformance/externalModules/b.ts === +/// +import * as m from 'math2d'; +>m : typeof m + +let v = new m.Vector(3, 2); +>v : m.Vector +>new m.Vector(3, 2) : m.Vector +>m.Vector : typeof m.Vector +>m : typeof m +>Vector : typeof m.Vector +>3 : number +>2 : number + +let magnitude = m.getLength(v); +>magnitude : number +>m.getLength(v) : number +>m.getLength : (p: m.Vector) => number +>m : typeof m +>getLength : (p: m.Vector) => number +>v : m.Vector + +let p: m.Point = v.translate(5, 5); +>p : m.Point +>m : any +>Point : m.Point +>v.translate(5, 5) : m.Vector +>v.translate : (dx: number, dy: number) => m.Vector +>v : m.Vector +>translate : (dx: number, dy: number) => m.Vector +>5 : number +>5 : number + +p = v.reverse(); +>p = v.reverse() : m.Point +>p : m.Point +>v.reverse() : m.Point +>v.reverse : () => m.Point +>v : m.Vector +>reverse : () => m.Point + +var t = p.x; +>t : number +>p.x : number +>p : m.Point +>x : number + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; +>Math2d : any + +export = M2D; +>M2D : typeof M2D + +declare namespace M2D { +>M2D : typeof + + interface Point { +>Point : Point + + x: number; +>x : number + + y: number; +>y : number + } + + class Vector implements Point { +>Vector : Vector +>Point : Point + + x: number; +>x : number + + y: number; +>y : number + + constructor(x: number, y: number); +>x : number +>y : number + + translate(dx: number, dy: number): Vector; +>translate : (dx: number, dy: number) => Vector +>dx : number +>dy : number +>Vector : Vector + } + + function getLength(p: Vector): number; +>getLength : (p: Vector) => number +>p : Vector +>Vector : Vector + +} + + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : typeof Math2d + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Vector + + reverse(): Math2d.Point; +>reverse : () => Point +>Math2d : any +>Point : Point + } +} + diff --git a/tests/baselines/reference/umd-augmentation-4.js b/tests/baselines/reference/umd-augmentation-4.js new file mode 100644 index 0000000000000..da0f2ec177762 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-4.js @@ -0,0 +1,55 @@ +//// [tests/cases/conformance/externalModules/umd-augmentation-4.ts] //// + +//// [index.d.ts] + +export as namespace Math2d; + +export = M2D; + +declare namespace M2D { + interface Point { + x: number; + y: number; + } + + class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; + } + + function getLength(p: Vector): number; + +} + + +//// [math2d-augment.d.ts] +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +//// [a.ts] +/// +/// +let v = new Math2d.Vector(3, 2); +let magnitude = Math2d.getLength(v); +let p: Math2d.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; + + +//// [a.js] +/// +/// +var v = new exports.Math2d.Vector(3, 2); +var magnitude = exports.Math2d.getLength(v); +var p = v.translate(5, 5); +p = v.reverse(); +var t = p.x; diff --git a/tests/baselines/reference/umd-augmentation-4.symbols b/tests/baselines/reference/umd-augmentation-4.symbols new file mode 100644 index 0000000000000..ea36e0c7992a2 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-4.symbols @@ -0,0 +1,102 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +/// +let v = new Math2d.Vector(3, 2); +>v : Symbol(v, Decl(a.ts, 2, 3)) +>Math2d.Vector : Symbol(Math2d.Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) +>Math2d : Symbol(Math2d, Decl(index.d.ts, 0, 0)) +>Vector : Symbol(Math2d.Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + +let magnitude = Math2d.getLength(v); +>magnitude : Symbol(magnitude, Decl(a.ts, 3, 3)) +>Math2d.getLength : Symbol(Math2d.getLength, Decl(index.d.ts, 17, 2)) +>Math2d : Symbol(Math2d, Decl(index.d.ts, 0, 0)) +>getLength : Symbol(Math2d.getLength, Decl(index.d.ts, 17, 2)) +>v : Symbol(v, Decl(a.ts, 2, 3)) + +let p: Math2d.Point = v.translate(5, 5); +>p : Symbol(p, Decl(a.ts, 4, 3)) +>Math2d : Symbol(Math2d, Decl(index.d.ts, 0, 0)) +>Point : Symbol(Math2d.Point, Decl(index.d.ts, 5, 23)) +>v.translate : Symbol(Math2d.Vector.translate, Decl(index.d.ts, 14, 36)) +>v : Symbol(v, Decl(a.ts, 2, 3)) +>translate : Symbol(Math2d.Vector.translate, Decl(index.d.ts, 14, 36)) + +p = v.reverse(); +>p : Symbol(p, Decl(a.ts, 4, 3)) +>v.reverse : Symbol(Math2d.Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) +>v : Symbol(v, Decl(a.ts, 2, 3)) +>reverse : Symbol(Math2d.Vector.reverse, Decl(math2d-augment.d.ts, 4, 19)) + +var t = p.x; +>t : Symbol(t, Decl(a.ts, 6, 3)) +>p.x : Symbol(Math2d.Point.x, Decl(index.d.ts, 6, 18)) +>p : Symbol(p, Decl(a.ts, 4, 3)) +>x : Symbol(Math2d.Point.x, Decl(index.d.ts, 6, 18)) + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; + +export = M2D; +>M2D : Symbol(M2D, Decl(index.d.ts, 3, 13)) + +declare namespace M2D { +>M2D : Symbol(Math2d, Decl(index.d.ts, 3, 13), Decl(math2d-augment.d.ts, 0, 33)) + + interface Point { +>Point : Symbol(Point, Decl(index.d.ts, 5, 23)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 6, 18)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 7, 12)) + } + + class Vector implements Point { +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) +>Point : Symbol(Point, Decl(index.d.ts, 5, 23)) + + x: number; +>x : Symbol(x, Decl(index.d.ts, 11, 32)) + + y: number; +>y : Symbol(y, Decl(index.d.ts, 12, 12)) + + constructor(x: number, y: number); +>x : Symbol(x, Decl(index.d.ts, 14, 14)) +>y : Symbol(y, Decl(index.d.ts, 14, 24)) + + translate(dx: number, dy: number): Vector; +>translate : Symbol(translate, Decl(index.d.ts, 14, 36)) +>dx : Symbol(dx, Decl(index.d.ts, 16, 12)) +>dy : Symbol(dy, Decl(index.d.ts, 16, 23)) +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + } + + function getLength(p: Vector): number; +>getLength : Symbol(getLength, Decl(index.d.ts, 17, 2)) +>p : Symbol(p, Decl(index.d.ts, 19, 20)) +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + +} + + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Symbol(Vector, Decl(index.d.ts, 9, 2), Decl(math2d-augment.d.ts, 2, 25)) + + reverse(): Math2d.Point; +>reverse : Symbol(reverse, Decl(math2d-augment.d.ts, 4, 19)) +>Math2d : Symbol(Math2d, Decl(math2d-augment.d.ts, 0, 6)) +>Point : Symbol(Point, Decl(index.d.ts, 5, 23)) + } +} + diff --git a/tests/baselines/reference/umd-augmentation-4.types b/tests/baselines/reference/umd-augmentation-4.types new file mode 100644 index 0000000000000..71783d0301260 --- /dev/null +++ b/tests/baselines/reference/umd-augmentation-4.types @@ -0,0 +1,112 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +/// +let v = new Math2d.Vector(3, 2); +>v : Math2d.Vector +>new Math2d.Vector(3, 2) : Math2d.Vector +>Math2d.Vector : typeof Math2d.Vector +>Math2d : typeof Math2d +>Vector : typeof Math2d.Vector +>3 : number +>2 : number + +let magnitude = Math2d.getLength(v); +>magnitude : number +>Math2d.getLength(v) : number +>Math2d.getLength : (p: Math2d.Vector) => number +>Math2d : typeof Math2d +>getLength : (p: Math2d.Vector) => number +>v : Math2d.Vector + +let p: Math2d.Point = v.translate(5, 5); +>p : Math2d.Point +>Math2d : any +>Point : Math2d.Point +>v.translate(5, 5) : Math2d.Vector +>v.translate : (dx: number, dy: number) => Math2d.Vector +>v : Math2d.Vector +>translate : (dx: number, dy: number) => Math2d.Vector +>5 : number +>5 : number + +p = v.reverse(); +>p = v.reverse() : Math2d.Point +>p : Math2d.Point +>v.reverse() : Math2d.Point +>v.reverse : () => Math2d.Point +>v : Math2d.Vector +>reverse : () => Math2d.Point + +var t = p.x; +>t : number +>p.x : number +>p : Math2d.Point +>x : number + +=== tests/cases/conformance/externalModules/node_modules/math2d/index.d.ts === + +export as namespace Math2d; +>Math2d : any + +export = M2D; +>M2D : typeof M2D + +declare namespace M2D { +>M2D : typeof Math2d + + interface Point { +>Point : Point + + x: number; +>x : number + + y: number; +>y : number + } + + class Vector implements Point { +>Vector : Vector +>Point : Point + + x: number; +>x : number + + y: number; +>y : number + + constructor(x: number, y: number); +>x : number +>y : number + + translate(dx: number, dy: number): Vector; +>translate : (dx: number, dy: number) => Vector +>dx : number +>dy : number +>Vector : Vector + } + + function getLength(p: Vector): number; +>getLength : (p: Vector) => number +>p : Vector +>Vector : Vector + +} + + +=== tests/cases/conformance/externalModules/math2d-augment.d.ts === +import * as Math2d from 'math2d'; +>Math2d : typeof Math2d + +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { +>Vector : Vector + + reverse(): Math2d.Point; +>reverse : () => Point +>Math2d : any +>Point : Point + } +} + diff --git a/tests/cases/conformance/externalModules/umd-augmentation-1.ts b/tests/cases/conformance/externalModules/umd-augmentation-1.ts new file mode 100644 index 0000000000000..312f21846e65f --- /dev/null +++ b/tests/cases/conformance/externalModules/umd-augmentation-1.ts @@ -0,0 +1,39 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: node_modules/math2d/index.d.ts +export as namespace Math2d; + +export interface Point { + x: number; + y: number; +} + +export class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; +} + +export function getLength(p: Vector): number; + +// @filename: math2d-augment.d.ts +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +// @filename: b.ts +/// +import * as m from 'math2d'; +let v = new m.Vector(3, 2); +let magnitude = m.getLength(v); +let p: m.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; diff --git a/tests/cases/conformance/externalModules/umd-augmentation-2.ts b/tests/cases/conformance/externalModules/umd-augmentation-2.ts new file mode 100644 index 0000000000000..2f8330e7fa275 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd-augmentation-2.ts @@ -0,0 +1,39 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: node_modules/math2d/index.d.ts +export as namespace Math2d; + +export interface Point { + x: number; + y: number; +} + +export class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; +} + +export function getLength(p: Vector): number; + +// @filename: math2d-augment.d.ts +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +// @filename: a.ts +/// +/// +let v = new Math2d.Vector(3, 2); +let magnitude = Math2d.getLength(v); +let p: Math2d.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; diff --git a/tests/cases/conformance/externalModules/umd-augmentation-3.ts b/tests/cases/conformance/externalModules/umd-augmentation-3.ts new file mode 100644 index 0000000000000..1524d7128de62 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd-augmentation-3.ts @@ -0,0 +1,45 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: node_modules/math2d/index.d.ts +export as namespace Math2d; + +export = M2D; + +declare namespace M2D { + interface Point { + x: number; + y: number; + } + + class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; + } + + function getLength(p: Vector): number; + +} + + +// @filename: math2d-augment.d.ts +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +// @filename: b.ts +/// +import * as m from 'math2d'; +let v = new m.Vector(3, 2); +let magnitude = m.getLength(v); +let p: m.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; diff --git a/tests/cases/conformance/externalModules/umd-augmentation-4.ts b/tests/cases/conformance/externalModules/umd-augmentation-4.ts new file mode 100644 index 0000000000000..729465504c140 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd-augmentation-4.ts @@ -0,0 +1,45 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: node_modules/math2d/index.d.ts +export as namespace Math2d; + +export = M2D; + +declare namespace M2D { + interface Point { + x: number; + y: number; + } + + class Vector implements Point { + x: number; + y: number; + constructor(x: number, y: number); + + translate(dx: number, dy: number): Vector; + } + + function getLength(p: Vector): number; + +} + + +// @filename: math2d-augment.d.ts +import * as Math2d from 'math2d'; +// Augment the module +declare module 'math2d' { + // Add a method to the class + interface Vector { + reverse(): Math2d.Point; + } +} + +// @filename: a.ts +/// +/// +let v = new Math2d.Vector(3, 2); +let magnitude = Math2d.getLength(v); +let p: Math2d.Point = v.translate(5, 5); +p = v.reverse(); +var t = p.x; From c72f1c354bf3cf4e6801362e94d1feb388e84029 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 9 Mar 2016 16:08:08 -0800 Subject: [PATCH 09/11] Reuse existing var --- src/compiler/binder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 2cc48c02947ae..b038a699b4761 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1418,7 +1418,7 @@ namespace ts { else { const parent = node.parent as SourceFile; - if (!isExternalModule(node.parent)) { + if (!isExternalModule(parent)) { file.bindDiagnostics.push(createDiagnosticForNode(node, Diagnostics.Global_module_exports_may_only_appear_in_module_files)); return; } From 8cef251b14eab8826a895bdf47b09904dcd6a7cc Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Wed, 9 Mar 2016 16:24:54 -0800 Subject: [PATCH 10/11] Add test for function export --- tests/baselines/reference/umd7.js | 16 ++++++++++++++++ tests/baselines/reference/umd7.symbols | 16 ++++++++++++++++ tests/baselines/reference/umd7.types | 18 ++++++++++++++++++ .../cases/conformance/externalModules/umd7.ts | 11 +++++++++++ 4 files changed, 61 insertions(+) create mode 100644 tests/baselines/reference/umd7.js create mode 100644 tests/baselines/reference/umd7.symbols create mode 100644 tests/baselines/reference/umd7.types create mode 100644 tests/cases/conformance/externalModules/umd7.ts diff --git a/tests/baselines/reference/umd7.js b/tests/baselines/reference/umd7.js new file mode 100644 index 0000000000000..12d0a8651fc8b --- /dev/null +++ b/tests/baselines/reference/umd7.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/externalModules/umd7.ts] //// + +//// [foo.d.ts] + +declare function Thing(): number; +export = Thing; +export as namespace Foo; + +//// [a.ts] +/// +let y: number = Foo(); + + +//// [a.js] +/// +var y = exports.Foo(); diff --git a/tests/baselines/reference/umd7.symbols b/tests/baselines/reference/umd7.symbols new file mode 100644 index 0000000000000..0b3ef17fb7b72 --- /dev/null +++ b/tests/baselines/reference/umd7.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +let y: number = Foo(); +>y : Symbol(y, Decl(a.ts, 1, 3)) +>Foo : Symbol(Foo, Decl(foo.d.ts, 2, 15)) + +=== tests/cases/conformance/externalModules/foo.d.ts === + +declare function Thing(): number; +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + +export = Thing; +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + +export as namespace Foo; + diff --git a/tests/baselines/reference/umd7.types b/tests/baselines/reference/umd7.types new file mode 100644 index 0000000000000..60782543710bc --- /dev/null +++ b/tests/baselines/reference/umd7.types @@ -0,0 +1,18 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +let y: number = Foo(); +>y : number +>Foo() : number +>Foo : () => number + +=== tests/cases/conformance/externalModules/foo.d.ts === + +declare function Thing(): number; +>Thing : () => number + +export = Thing; +>Thing : () => number + +export as namespace Foo; +>Foo : any + diff --git a/tests/cases/conformance/externalModules/umd7.ts b/tests/cases/conformance/externalModules/umd7.ts new file mode 100644 index 0000000000000..9b9a9959efc67 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd7.ts @@ -0,0 +1,11 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +declare function Thing(): number; +export = Thing; +export as namespace Foo; + +// @filename: a.ts +/// +let y: number = Foo(); From 043b3380248509193dae8fe49a1c908d158869ed Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 10 Mar 2016 10:11:48 -0800 Subject: [PATCH 11/11] Add `export = class` scenario --- tests/baselines/reference/umd8.js | 21 +++++++++++++++ tests/baselines/reference/umd8.symbols | 25 +++++++++++++++++ tests/baselines/reference/umd8.types | 27 +++++++++++++++++++ .../cases/conformance/externalModules/umd8.ts | 15 +++++++++++ 4 files changed, 88 insertions(+) create mode 100644 tests/baselines/reference/umd8.js create mode 100644 tests/baselines/reference/umd8.symbols create mode 100644 tests/baselines/reference/umd8.types create mode 100644 tests/cases/conformance/externalModules/umd8.ts diff --git a/tests/baselines/reference/umd8.js b/tests/baselines/reference/umd8.js new file mode 100644 index 0000000000000..b4c6e0fa76b3d --- /dev/null +++ b/tests/baselines/reference/umd8.js @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/externalModules/umd8.ts] //// + +//// [foo.d.ts] + +declare class Thing { + foo(): number; +} +export = Thing; +export as namespace Foo; + +//// [a.ts] +/// +let y: Foo; +y.foo(); + + + +//// [a.js] +/// +var y; +y.foo(); diff --git a/tests/baselines/reference/umd8.symbols b/tests/baselines/reference/umd8.symbols new file mode 100644 index 0000000000000..347038e6b33f6 --- /dev/null +++ b/tests/baselines/reference/umd8.symbols @@ -0,0 +1,25 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +let y: Foo; +>y : Symbol(y, Decl(a.ts, 1, 3)) +>Foo : Symbol(Foo, Decl(foo.d.ts, 4, 15)) + +y.foo(); +>y.foo : Symbol(Foo.foo, Decl(foo.d.ts, 1, 21)) +>y : Symbol(y, Decl(a.ts, 1, 3)) +>foo : Symbol(Foo.foo, Decl(foo.d.ts, 1, 21)) + + +=== tests/cases/conformance/externalModules/foo.d.ts === + +declare class Thing { +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + + foo(): number; +>foo : Symbol(foo, Decl(foo.d.ts, 1, 21)) +} +export = Thing; +>Thing : Symbol(Thing, Decl(foo.d.ts, 0, 0)) + +export as namespace Foo; + diff --git a/tests/baselines/reference/umd8.types b/tests/baselines/reference/umd8.types new file mode 100644 index 0000000000000..0e66a49b9630e --- /dev/null +++ b/tests/baselines/reference/umd8.types @@ -0,0 +1,27 @@ +=== tests/cases/conformance/externalModules/a.ts === +/// +let y: Foo; +>y : Foo +>Foo : Foo + +y.foo(); +>y.foo() : number +>y.foo : () => number +>y : Foo +>foo : () => number + + +=== tests/cases/conformance/externalModules/foo.d.ts === + +declare class Thing { +>Thing : Thing + + foo(): number; +>foo : () => number +} +export = Thing; +>Thing : Thing + +export as namespace Foo; +>Foo : any + diff --git a/tests/cases/conformance/externalModules/umd8.ts b/tests/cases/conformance/externalModules/umd8.ts new file mode 100644 index 0000000000000..caab734f5e0d0 --- /dev/null +++ b/tests/cases/conformance/externalModules/umd8.ts @@ -0,0 +1,15 @@ +// @module: commonjs +// @noImplicitReferences: true + +// @filename: foo.d.ts +declare class Thing { + foo(): number; +} +export = Thing; +export as namespace Foo; + +// @filename: a.ts +/// +let y: Foo; +y.foo(); +