From 0eba61c1c35ba7865c99ac903ad50bd97f3bd5c7 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Thu, 18 Feb 2016 12:14:35 -0800 Subject: [PATCH 1/2] Prototype UMD support --- src/compiler/binder.ts | 7 ++++ src/compiler/checker.ts | 9 +++++ src/compiler/parser.ts | 31 +++++++++++++++- src/compiler/program.ts | 21 +++++++---- src/compiler/types.ts | 10 +++++ src/compiler/utilities.ts | 1 + src/harness/compilerRunner.ts | 2 +- src/harness/harness.ts | 3 +- 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 +++++++++++++ .../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 ++++++++ 26 files changed, 503 insertions(+), 11 deletions(-) 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/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 1f19d01b9cbfc..757312a268eec 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1345,6 +1345,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: @@ -1394,6 +1396,11 @@ namespace ts { } } + function bindGlobalModuleExportDeclaration(node: GlobalModuleExportDeclaration) { + 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 692b6ea848bf0..eddd656a6e15c 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); } } @@ -16298,6 +16304,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/parser.ts b/src/compiler/parser.ts index db9639156a58e..67cbc60441eed 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: @@ -4418,7 +4421,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(); @@ -4604,6 +4608,12 @@ namespace ts { case SyntaxKind.EnumKeyword: return parseEnumDeclaration(fullStart, decorators, modifiers); case SyntaxKind.GlobalKeyword: + if (lookAhead(isGlobalModuleExportDeclaration)) { + return parseGlobalModuleExportDeclaration(fullStart, decorators, modifiers); + } + else { + return parseModuleDeclaration(fullStart, decorators, modifiers); + } case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: return parseModuleDeclaration(fullStart, decorators, modifiers); @@ -4627,6 +4637,11 @@ namespace ts { } } + function isGlobalModuleExportDeclaration() { + nextToken(); + return token === SyntaxKind.ExportKeyword; + } + function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral); @@ -5282,6 +5297,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.GlobalKeyword); + parseExpected(SyntaxKind.ExportKeyword); + + 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..b11f41d220649 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, true); } function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean { @@ -1376,7 +1376,7 @@ namespace ts { } } - function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) { + 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 +1384,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 +1394,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 +1429,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 +1438,10 @@ namespace ts { reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd); } + if (file) { + file.wasReferenced = file.wasReferenced || isReference; + } + return file; } @@ -1454,6 +1458,7 @@ namespace ts { filesByName.set(path, file); if (file) { + file.wasReferenced = file.wasReferenced || isReference; file.path = path; if (host.useCaseSensitiveFileNames()) { @@ -1491,7 +1496,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 +1522,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 c065478a20ae1..1d3f1562760df 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 + wasReferenced?: boolean; /* @internal */ identifiers: Map; /* @internal */ nodeCount: number; @@ -1994,6 +2003,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 9c598da906901..d198c3930bc0f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1475,6 +1475,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/umd1.js b/tests/baselines/reference/umd1.js new file mode 100644 index 0000000000000..fc84ed0f89ffd --- /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 } +declare global export 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..12f44be8b4b6b --- /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)) + +declare global export Foo; + diff --git a/tests/baselines/reference/umd1.types b/tests/baselines/reference/umd1.types new file mode 100644 index 0000000000000..0162bee0aaf02 --- /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 + +declare global export 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..3c8ba9800496d --- /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; + declare global export 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..937205d68dd35 --- /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; +declare global export 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..f5f229ca82944 --- /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 } +declare global export 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..0be4177b438a1 --- /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)) + +declare global export Foo; + diff --git a/tests/baselines/reference/umd3.types b/tests/baselines/reference/umd3.types new file mode 100644 index 0000000000000..fcec460da018a --- /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 + +declare global export Foo; +>Foo : any + diff --git a/tests/baselines/reference/umd4.js b/tests/baselines/reference/umd4.js new file mode 100644 index 0000000000000..8004359da93c2 --- /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 } +declare global export 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..7cbae61bc6ab7 --- /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)) + +declare global export Foo; + diff --git a/tests/baselines/reference/umd4.types b/tests/baselines/reference/umd4.types new file mode 100644 index 0000000000000..e12f6474b024d --- /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 + +declare global export 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..8ddc245b85946 --- /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 } + declare global export 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..5af8f79e572e4 --- /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 } +declare global export 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/umd1.ts b/tests/cases/conformance/externalModules/umd1.ts new file mode 100644 index 0000000000000..f964dd8b246c8 --- /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 } +declare global export 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..905a09819f2fd --- /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; +declare global export 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..b446549b955b2 --- /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 } +declare global export 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..7a35b090ff161 --- /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 } +declare global export 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..2a7a6c80ea376 --- /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 } +declare global export 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 96a304766a25b96d0ebfdfb9b14c2b1cdbedad06 Mon Sep 17 00:00:00 2001 From: Ryan Cavanaugh Date: Mon, 29 Feb 2016 17:44:04 -0800 Subject: [PATCH 2/2] Update for new syntax --- src/compiler/binder.ts | 4 ++ src/compiler/checker.ts | 19 ++++++ src/compiler/diagnosticMessages.json | 12 ++++ src/compiler/parser.ts | 33 +++++----- src/compiler/program.ts | 2 +- .../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 | 2 +- tests/baselines/reference/umd1.symbols | 2 +- tests/baselines/reference/umd1.types | 2 +- tests/baselines/reference/umd2.errors.txt | 2 +- tests/baselines/reference/umd2.js | 2 +- tests/baselines/reference/umd3.js | 2 +- tests/baselines/reference/umd3.symbols | 2 +- tests/baselines/reference/umd3.types | 2 +- tests/baselines/reference/umd4.js | 2 +- tests/baselines/reference/umd4.symbols | 2 +- tests/baselines/reference/umd4.types | 2 +- tests/baselines/reference/umd5.errors.txt | 2 +- tests/baselines/reference/umd5.js | 2 +- .../conformance/externalModules/umd-errors.ts | 31 ++++++++++ .../cases/conformance/externalModules/umd1.ts | 2 +- .../cases/conformance/externalModules/umd2.ts | 2 +- .../cases/conformance/externalModules/umd3.ts | 2 +- .../cases/conformance/externalModules/umd4.ts | 2 +- .../cases/conformance/externalModules/umd5.ts | 2 +- 28 files changed, 213 insertions(+), 37 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/cases/conformance/externalModules/umd-errors.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 757312a268eec..1b8c9ae0e2013 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1397,6 +1397,10 @@ 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); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index eddd656a6e15c..ed32fad5a8811 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15201,6 +15201,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: missing external module indicator case checked in binder + if (parent.externalModuleIndicator && !parent.isDeclarationFile) { + error(node, Diagnostics.Global_module_exports_may_only_appear_in_declaration_files); + } + } + + } function checkSourceElement(node: Node): void { if (!node) { @@ -15318,6 +15335,8 @@ 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/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f2da96b133bb7..85eb9c139ef2d 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 67cbc60441eed..690a97f907ba0 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -1146,7 +1146,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(); @@ -4431,7 +4431,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; @@ -4608,12 +4609,7 @@ namespace ts { case SyntaxKind.EnumKeyword: return parseEnumDeclaration(fullStart, decorators, modifiers); case SyntaxKind.GlobalKeyword: - if (lookAhead(isGlobalModuleExportDeclaration)) { - return parseGlobalModuleExportDeclaration(fullStart, decorators, modifiers); - } - else { - return parseModuleDeclaration(fullStart, decorators, modifiers); - } + return parseModuleDeclaration(fullStart, decorators, modifiers); case SyntaxKind.ModuleKeyword: case SyntaxKind.NamespaceKeyword: return parseModuleDeclaration(fullStart, decorators, modifiers); @@ -4621,9 +4617,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 @@ -4637,11 +4639,6 @@ namespace ts { } } - function isGlobalModuleExportDeclaration() { - nextToken(); - return token === SyntaxKind.ExportKeyword; - } - function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral); @@ -5301,8 +5298,8 @@ namespace ts { const exportDeclaration = createNode(SyntaxKind.GlobalModuleExportDeclaration, fullStart); exportDeclaration.decorators = decorators; exportDeclaration.modifiers = modifiers; - parseExpected(SyntaxKind.GlobalKeyword); - parseExpected(SyntaxKind.ExportKeyword); + parseExpected(SyntaxKind.AsKeyword); + parseExpected(SyntaxKind.NamespaceKeyword); exportDeclaration.name = parseIdentifier(); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index b11f41d220649..65a5d26f74209 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, true); + processSourceFile(normalizePath(fileName), isDefaultLib, /*isReference*/ true); } function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean { 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 index fc84ed0f89ffd..9b059da488774 100644 --- a/tests/baselines/reference/umd1.js +++ b/tests/baselines/reference/umd1.js @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; //// [a.ts] /// diff --git a/tests/baselines/reference/umd1.symbols b/tests/baselines/reference/umd1.symbols index 12f44be8b4b6b..cccc777e3e375 100644 --- a/tests/baselines/reference/umd1.symbols +++ b/tests/baselines/reference/umd1.symbols @@ -29,5 +29,5 @@ export interface Thing { n: typeof x } >n : Symbol(n, Decl(foo.d.ts, 3, 24)) >x : Symbol(x, Decl(foo.d.ts, 1, 10)) -declare global export Foo; +export as namespace Foo; diff --git a/tests/baselines/reference/umd1.types b/tests/baselines/reference/umd1.types index 0162bee0aaf02..1767f3b5a899d 100644 --- a/tests/baselines/reference/umd1.types +++ b/tests/baselines/reference/umd1.types @@ -30,6 +30,6 @@ export interface Thing { n: typeof x } >n : number >x : number -declare global export Foo; +export as namespace Foo; >Foo : any diff --git a/tests/baselines/reference/umd2.errors.txt b/tests/baselines/reference/umd2.errors.txt index 3c8ba9800496d..76a4d33f65ac1 100644 --- a/tests/baselines/reference/umd2.errors.txt +++ b/tests/baselines/reference/umd2.errors.txt @@ -15,5 +15,5 @@ tests/cases/conformance/externalModules/a.ts(2,8): error TS2503: Cannot find nam export var x: number; export function fn(): void; - declare global export Foo; + export as namespace Foo; \ No newline at end of file diff --git a/tests/baselines/reference/umd2.js b/tests/baselines/reference/umd2.js index 937205d68dd35..2737856dcfde5 100644 --- a/tests/baselines/reference/umd2.js +++ b/tests/baselines/reference/umd2.js @@ -4,7 +4,7 @@ export var x: number; export function fn(): void; -declare global export Foo; +export as namespace Foo; //// [a.ts] Foo.fn(); diff --git a/tests/baselines/reference/umd3.js b/tests/baselines/reference/umd3.js index f5f229ca82944..5e869148bebec 100644 --- a/tests/baselines/reference/umd3.js +++ b/tests/baselines/reference/umd3.js @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; //// [a.ts] import * as Foo from './foo'; diff --git a/tests/baselines/reference/umd3.symbols b/tests/baselines/reference/umd3.symbols index 0be4177b438a1..82db9e0b29a9c 100644 --- a/tests/baselines/reference/umd3.symbols +++ b/tests/baselines/reference/umd3.symbols @@ -31,5 +31,5 @@ export interface Thing { n: typeof x } >n : Symbol(n, Decl(foo.d.ts, 3, 24)) >x : Symbol(x, Decl(foo.d.ts, 1, 10)) -declare global export Foo; +export as namespace Foo; diff --git a/tests/baselines/reference/umd3.types b/tests/baselines/reference/umd3.types index fcec460da018a..85ee6bafe5ec1 100644 --- a/tests/baselines/reference/umd3.types +++ b/tests/baselines/reference/umd3.types @@ -32,6 +32,6 @@ export interface Thing { n: typeof x } >n : number >x : number -declare global export Foo; +export as namespace Foo; >Foo : any diff --git a/tests/baselines/reference/umd4.js b/tests/baselines/reference/umd4.js index 8004359da93c2..b7a7d1da0e281 100644 --- a/tests/baselines/reference/umd4.js +++ b/tests/baselines/reference/umd4.js @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; //// [a.ts] import * as Bar from './foo'; diff --git a/tests/baselines/reference/umd4.symbols b/tests/baselines/reference/umd4.symbols index 7cbae61bc6ab7..8ad987a127226 100644 --- a/tests/baselines/reference/umd4.symbols +++ b/tests/baselines/reference/umd4.symbols @@ -31,5 +31,5 @@ export interface Thing { n: typeof x } >n : Symbol(n, Decl(foo.d.ts, 3, 24)) >x : Symbol(x, Decl(foo.d.ts, 1, 10)) -declare global export Foo; +export as namespace Foo; diff --git a/tests/baselines/reference/umd4.types b/tests/baselines/reference/umd4.types index e12f6474b024d..579599f56619b 100644 --- a/tests/baselines/reference/umd4.types +++ b/tests/baselines/reference/umd4.types @@ -32,6 +32,6 @@ export interface Thing { n: typeof x } >n : number >x : number -declare global export Foo; +export as namespace Foo; >Foo : any diff --git a/tests/baselines/reference/umd5.errors.txt b/tests/baselines/reference/umd5.errors.txt index 8ddc245b85946..19529ce195a6c 100644 --- a/tests/baselines/reference/umd5.errors.txt +++ b/tests/baselines/reference/umd5.errors.txt @@ -16,5 +16,5 @@ tests/cases/conformance/externalModules/a.ts(6,9): error TS2304: Cannot find nam export var x: number; export function fn(): void; export interface Thing { n: typeof x } - declare global export Foo; + export as namespace Foo; \ No newline at end of file diff --git a/tests/baselines/reference/umd5.js b/tests/baselines/reference/umd5.js index 5af8f79e572e4..d054daf93fd61 100644 --- a/tests/baselines/reference/umd5.js +++ b/tests/baselines/reference/umd5.js @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; //// [a.ts] import * as Bar from './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 index f964dd8b246c8..5ceb7fa59ba2b 100644 --- a/tests/cases/conformance/externalModules/umd1.ts +++ b/tests/cases/conformance/externalModules/umd1.ts @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; // @filename: a.ts /// diff --git a/tests/cases/conformance/externalModules/umd2.ts b/tests/cases/conformance/externalModules/umd2.ts index 905a09819f2fd..2fb98491ebf66 100644 --- a/tests/cases/conformance/externalModules/umd2.ts +++ b/tests/cases/conformance/externalModules/umd2.ts @@ -4,7 +4,7 @@ // @filename: foo.d.ts export var x: number; export function fn(): void; -declare global export Foo; +export as namespace Foo; // @filename: a.ts Foo.fn(); diff --git a/tests/cases/conformance/externalModules/umd3.ts b/tests/cases/conformance/externalModules/umd3.ts index b446549b955b2..dad0dfc644d6d 100644 --- a/tests/cases/conformance/externalModules/umd3.ts +++ b/tests/cases/conformance/externalModules/umd3.ts @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; // @filename: a.ts import * as Foo from './foo'; diff --git a/tests/cases/conformance/externalModules/umd4.ts b/tests/cases/conformance/externalModules/umd4.ts index 7a35b090ff161..e927d21f1ccdd 100644 --- a/tests/cases/conformance/externalModules/umd4.ts +++ b/tests/cases/conformance/externalModules/umd4.ts @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; // @filename: a.ts import * as Bar from './foo'; diff --git a/tests/cases/conformance/externalModules/umd5.ts b/tests/cases/conformance/externalModules/umd5.ts index 2a7a6c80ea376..b6d949c2d0a76 100644 --- a/tests/cases/conformance/externalModules/umd5.ts +++ b/tests/cases/conformance/externalModules/umd5.ts @@ -5,7 +5,7 @@ export var x: number; export function fn(): void; export interface Thing { n: typeof x } -declare global export Foo; +export as namespace Foo; // @filename: a.ts import * as Bar from './foo';