diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index db956cca647..73e382ea434 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -53,7 +53,8 @@ namespace ts { return state; } else if (node.kind === SyntaxKind.ModuleDeclaration) { - return getModuleInstanceState((node).body); + const body = (node).body; + return body ? getModuleInstanceState(body) : ModuleInstanceState.Instantiated; } else { return ModuleInstanceState.Instantiated; @@ -1258,7 +1259,7 @@ namespace ts { function hasExportDeclarations(node: ModuleDeclaration | SourceFile): boolean { const body = node.kind === SyntaxKind.SourceFile ? node : (node).body; - if (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock) { + if (body && (body.kind === SyntaxKind.SourceFile || body.kind === SyntaxKind.ModuleBlock)) { for (const stat of (body).statements) { if (stat.kind === SyntaxKind.ExportDeclaration || stat.kind === SyntaxKind.ExportAssignment) { return true; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 044f42414b7..28082914256 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -992,7 +992,9 @@ namespace ts { const moduleSymbol = resolveExternalModuleName(node, (node.parent).moduleSpecifier); if (moduleSymbol) { - const exportDefaultSymbol = moduleSymbol.exports["export="] ? + const exportDefaultSymbol = isShorthandAmbientModule(moduleSymbol.valueDeclaration) ? + moduleSymbol : + moduleSymbol.exports["export="] ? getPropertyOfType(getTypeOfSymbol(moduleSymbol.exports["export="]), "default") : resolveSymbol(moduleSymbol.exports["default"]); @@ -1066,6 +1068,10 @@ namespace ts { if (targetSymbol) { const name = specifier.propertyName || specifier.name; if (name.text) { + if (isShorthandAmbientModule(moduleSymbol.valueDeclaration)) { + return moduleSymbol; + } + let symbolFromVariable: Symbol; // First check if module was specified with "export=". If so, get the member from the resolved type if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports["export="]) { @@ -3234,9 +3240,14 @@ namespace ts { function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { const links = getSymbolLinks(symbol); if (!links.type) { - const type = createObjectType(TypeFlags.Anonymous, symbol); - links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? - addTypeKind(type, TypeFlags.Undefined) : type; + if (symbol.valueDeclaration.kind === SyntaxKind.ModuleDeclaration && isShorthandAmbientModule(symbol.valueDeclaration)) { + links.type = anyType; + } + else { + const type = createObjectType(TypeFlags.Anonymous, symbol); + links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? + addTypeKind(type, TypeFlags.Undefined) : type; + } } return links.type; } @@ -16052,7 +16063,7 @@ namespace ts { // - augmentation for a global scope is always applied // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module). const checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & SymbolFlags.Merged); - if (checkBody) { + if (checkBody && node.body) { // body of ambient external module is always a module block for (const statement of (node.body).statements) { checkModuleAugmentationElement(statement, isGlobalAugmentation); @@ -16079,7 +16090,15 @@ namespace ts { } } } - checkSourceElement(node.body); + + if (compilerOptions.noImplicitAny && !node.body) { + // Ambient shorthand module is an implicit any + reportImplicitAnyError(node, anyType); + } + + if (node.body) { + checkSourceElement(node.body); + } } function checkModuleAugmentationElement(node: Node, isGlobalAugmentation: boolean): void { diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index bda1c7c0cb6..2708833a13f 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -853,21 +853,26 @@ namespace ts { writeTextOfNode(currentText, node.name); } } - while (node.body.kind !== SyntaxKind.ModuleBlock) { + while (node.body && node.body.kind !== SyntaxKind.ModuleBlock) { node = node.body; write("."); writeTextOfNode(currentText, node.name); } const prevEnclosingDeclaration = enclosingDeclaration; - enclosingDeclaration = node; - write(" {"); - writeLine(); - increaseIndent(); - emitLines((node.body).statements); - decreaseIndent(); - write("}"); - writeLine(); - enclosingDeclaration = prevEnclosingDeclaration; + if (node.body) { + enclosingDeclaration = node; + write(" {"); + writeLine(); + increaseIndent(); + emitLines((node.body).statements); + decreaseIndent(); + write("}"); + writeLine(); + enclosingDeclaration = prevEnclosingDeclaration; + } + else { + write(";"); + } } function writeTypeAliasDeclaration(node: TypeAliasDeclaration) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 610551cdbb8..4f65d8bd16d 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6300,7 +6300,7 @@ const _super = (function (geti, seti) { } function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration: ModuleDeclaration): ModuleDeclaration { - if (moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) { + if (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) { const recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body); return recursiveInnerModule || moduleDeclaration.body; } @@ -6349,6 +6349,7 @@ const _super = (function (geti, seti) { write(getGeneratedNameForNode(node)); emitEnd(node.name); write(") "); + Debug.assert(node.body !== undefined); // node.body must exist, as this is a non-ambient module if (node.body.kind === SyntaxKind.ModuleBlock) { const saveConvertedLoopState = convertedLoopState; const saveTempFlags = tempFlags; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b24dd85f2f0..a31cf0cbe93 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5337,7 +5337,14 @@ namespace ts { else { node.name = parseLiteralNode(/*internName*/ true); } - node.body = parseModuleBlock(); + + if (token === SyntaxKind.OpenBraceToken) { + node.body = parseModuleBlock(); + } + else { + parseSemicolon(); + } + return finishNode(node); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 2535afb93a6..1f7bdc3966c 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1775,9 +1775,12 @@ namespace ts { // The StringLiteral must specify a top - level external module name. // Relative external module names are not permitted - // NOTE: body of ambient module is always a module block - for (const statement of ((node).body).statements) { - collectModuleReferences(statement, /*inAmbientModule*/ true); + // NOTE: body of ambient module is always a module block, if it exists + const body = (node).body; + if (body) { + for (const statement of body.statements) { + collectModuleReferences(statement, /*inAmbientModule*/ true); + } } } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b6b4f532da5..bc5b3b5dfd3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1301,7 +1301,7 @@ namespace ts { // @kind(SyntaxKind.ModuleDeclaration) export interface ModuleDeclaration extends DeclarationStatement { name: Identifier | LiteralExpression; - body: ModuleBlock | ModuleDeclaration; + body?: ModuleBlock | ModuleDeclaration; } // @kind(SyntaxKind.ModuleBlock) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index c54775ad2af..bf163b47c05 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -372,6 +372,11 @@ namespace ts { ((node).name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(node)); } + export function isShorthandAmbientModule(node: Node): boolean { + // The only kind of module that can be missing a body is a shorthand ambient module. + return node.kind === SyntaxKind.ModuleDeclaration && (!(node).body); + } + export function isBlockScopedContainerTopLevel(node: Node): boolean { return node.kind === SyntaxKind.SourceFile || node.kind === SyntaxKind.ModuleDeclaration || diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 92cf64eac94..59dc4a38283 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -188,7 +188,10 @@ namespace ts.NavigationBar { case SyntaxKind.ModuleDeclaration: let moduleDeclaration = node; topLevelNodes.push(node); - addTopLevelNodes((getInnermostModule(moduleDeclaration).body).statements, topLevelNodes); + const inner = getInnermostModule(moduleDeclaration); + if (inner.body) { + addTopLevelNodes((inner.body).statements, topLevelNodes); + } break; case SyntaxKind.FunctionDeclaration: @@ -453,7 +456,8 @@ namespace ts.NavigationBar { function createModuleItem(node: ModuleDeclaration): NavigationBarItem { const moduleName = getModuleName(node); - const childItems = getItemsWorker(getChildNodes((getInnermostModule(node).body).statements), createChildItem); + const body = getInnermostModule(node).body; + const childItems = body ? getItemsWorker(getChildNodes(body.statements), createChildItem) : []; return getNavigationBarItem(moduleName, ts.ScriptElementKind.moduleElement, @@ -611,7 +615,7 @@ namespace ts.NavigationBar { } function getInnermostModule(node: ModuleDeclaration): ModuleDeclaration { - while (node.body.kind === SyntaxKind.ModuleDeclaration) { + while (node.body && node.body.kind === SyntaxKind.ModuleDeclaration) { node = node.body; } diff --git a/src/services/services.ts b/src/services/services.ts index cae2af356a0..13df3a54a30 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -414,7 +414,7 @@ namespace ts { } // If this is left side of dotted module declaration, there is no doc comments associated with this node - if (declaration.kind === SyntaxKind.ModuleDeclaration && (declaration).body.kind === SyntaxKind.ModuleDeclaration) { + if (declaration.kind === SyntaxKind.ModuleDeclaration && (declaration).body && (declaration).body.kind === SyntaxKind.ModuleDeclaration) { return; } diff --git a/tests/baselines/reference/ambientShorthand.js b/tests/baselines/reference/ambientShorthand.js new file mode 100644 index 00000000000..109264fc91b --- /dev/null +++ b/tests/baselines/reference/ambientShorthand.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/ambient/ambientShorthand.ts] //// + +//// [declarations.d.ts] +declare module "jquery" +// Semicolon is optional +declare module "fs"; + +//// [user.ts] +/// +import foo, {bar} from "jquery"; +import * as baz from "fs"; +import boom = require("jquery"); +foo(bar, baz, boom); + + +//// [user.js] +"use strict"; +/// +var jquery_1 = require("jquery"); +var baz = require("fs"); +var boom = require("jquery"); +jquery_1["default"](jquery_1.bar, baz, boom); diff --git a/tests/baselines/reference/ambientShorthand.symbols b/tests/baselines/reference/ambientShorthand.symbols new file mode 100644 index 00000000000..6747fd65173 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand.symbols @@ -0,0 +1,24 @@ +=== tests/cases/conformance/ambient/user.ts === +/// +import foo, {bar} from "jquery"; +>foo : Symbol(foo, Decl(user.ts, 1, 6)) +>bar : Symbol(bar, Decl(user.ts, 1, 13)) + +import * as baz from "fs"; +>baz : Symbol(baz, Decl(user.ts, 2, 6)) + +import boom = require("jquery"); +>boom : Symbol(boom, Decl(user.ts, 2, 26)) + +foo(bar, baz, boom); +>foo : Symbol(foo, Decl(user.ts, 1, 6)) +>bar : Symbol(bar, Decl(user.ts, 1, 13)) +>baz : Symbol(baz, Decl(user.ts, 2, 6)) +>boom : Symbol(boom, Decl(user.ts, 2, 26)) + +=== tests/cases/conformance/ambient/declarations.d.ts === +declare module "jquery" +No type information for this code.// Semicolon is optional +No type information for this code.declare module "fs"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand.types b/tests/baselines/reference/ambientShorthand.types new file mode 100644 index 00000000000..054349b1a6a --- /dev/null +++ b/tests/baselines/reference/ambientShorthand.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/ambient/user.ts === +/// +import foo, {bar} from "jquery"; +>foo : any +>bar : any + +import * as baz from "fs"; +>baz : any + +import boom = require("jquery"); +>boom : any + +foo(bar, baz, boom); +>foo(bar, baz, boom) : any +>foo : any +>bar : any +>baz : any +>boom : any + +=== tests/cases/conformance/ambient/declarations.d.ts === +declare module "jquery" +No type information for this code.// Semicolon is optional +No type information for this code.declare module "fs"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_declarationEmit.js b/tests/baselines/reference/ambientShorthand_declarationEmit.js new file mode 100644 index 00000000000..d758b57efd2 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_declarationEmit.js @@ -0,0 +1,9 @@ +//// [ambientShorthand_declarationEmit.ts] +declare module "foo"; + + +//// [ambientShorthand_declarationEmit.js] + + +//// [ambientShorthand_declarationEmit.d.ts] +declare module "foo"; \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_declarationEmit.symbols b/tests/baselines/reference/ambientShorthand_declarationEmit.symbols new file mode 100644 index 00000000000..f1b3284b0f2 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_declarationEmit.symbols @@ -0,0 +1,4 @@ +=== tests/cases/conformance/ambient/ambientShorthand_declarationEmit.ts === +declare module "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_declarationEmit.types b/tests/baselines/reference/ambientShorthand_declarationEmit.types new file mode 100644 index 00000000000..f1b3284b0f2 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_declarationEmit.types @@ -0,0 +1,4 @@ +=== tests/cases/conformance/ambient/ambientShorthand_declarationEmit.ts === +declare module "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_duplicate.js b/tests/baselines/reference/ambientShorthand_duplicate.js new file mode 100644 index 00000000000..d99eb3d27dc --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_duplicate.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/ambient/ambientShorthand_duplicate.ts] //// + +//// [declarations1.d.ts] +declare module "foo"; + +//// [declarations2.d.ts] +declare module "foo"; + +//// [user.ts] +/// +/// +import foo from "foo"; + + +//// [user.js] +"use strict"; diff --git a/tests/baselines/reference/ambientShorthand_duplicate.symbols b/tests/baselines/reference/ambientShorthand_duplicate.symbols new file mode 100644 index 00000000000..05856b47b92 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_duplicate.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/ambient/user.ts === +/// +/// +import foo from "foo"; +>foo : Symbol(foo, Decl(user.ts, 2, 6)) + +=== tests/cases/conformance/ambient/declarations1.d.ts === +declare module "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_duplicate.types b/tests/baselines/reference/ambientShorthand_duplicate.types new file mode 100644 index 00000000000..1520c5447ec --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_duplicate.types @@ -0,0 +1,10 @@ +=== tests/cases/conformance/ambient/user.ts === +/// +/// +import foo from "foo"; +>foo : any + +=== tests/cases/conformance/ambient/declarations1.d.ts === +declare module "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_isImplicitAny.errors.txt b/tests/baselines/reference/ambientShorthand_isImplicitAny.errors.txt new file mode 100644 index 00000000000..875a656202d --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_isImplicitAny.errors.txt @@ -0,0 +1,8 @@ +tests/cases/conformance/ambient/ambientShorthand_isImplicitAny.ts(1,16): error TS7005: Variable '"jquery"' implicitly has an 'any' type. + + +==== tests/cases/conformance/ambient/ambientShorthand_isImplicitAny.ts (1 errors) ==== + declare module "jquery"; + ~~~~~~~~ +!!! error TS7005: Variable '"jquery"' implicitly has an 'any' type. + \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_isImplicitAny.js b/tests/baselines/reference/ambientShorthand_isImplicitAny.js new file mode 100644 index 00000000000..ab05d2a9979 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_isImplicitAny.js @@ -0,0 +1,5 @@ +//// [ambientShorthand_isImplicitAny.ts] +declare module "jquery"; + + +//// [ambientShorthand_isImplicitAny.js] diff --git a/tests/baselines/reference/ambientShorthand_merging.js b/tests/baselines/reference/ambientShorthand_merging.js new file mode 100644 index 00000000000..f0aaefc6366 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_merging.js @@ -0,0 +1,18 @@ +//// [tests/cases/conformance/ambient/ambientShorthand_merging.ts] //// + +//// [declarations1.d.ts] +declare module "foo"; + +//// [declarations2.d.ts] +declare module "foo" { + export const bar: number; +} + +//// [user.ts] +/// +/// +import foo, {bar} from "foo"; + + +//// [user.js] +"use strict"; diff --git a/tests/baselines/reference/ambientShorthand_merging.symbols b/tests/baselines/reference/ambientShorthand_merging.symbols new file mode 100644 index 00000000000..8a0ca5acb74 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_merging.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/ambient/user.ts === +/// +/// +import foo, {bar} from "foo"; +>foo : Symbol(foo, Decl(user.ts, 2, 6)) +>bar : Symbol(bar, Decl(user.ts, 2, 13)) + +=== tests/cases/conformance/ambient/declarations1.d.ts === +declare module "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_merging.types b/tests/baselines/reference/ambientShorthand_merging.types new file mode 100644 index 00000000000..78390a35dd8 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_merging.types @@ -0,0 +1,11 @@ +=== tests/cases/conformance/ambient/user.ts === +/// +/// +import foo, {bar} from "foo"; +>foo : any +>bar : any + +=== tests/cases/conformance/ambient/declarations1.d.ts === +declare module "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/ambientShorthand_reExport.js b/tests/baselines/reference/ambientShorthand_reExport.js new file mode 100644 index 00000000000..d0433e5d478 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_reExport.js @@ -0,0 +1,30 @@ +//// [tests/cases/conformance/ambient/ambientShorthand_reExport.ts] //// + +//// [declarations.d.ts] +declare module "jquery"; + +//// [reExportX.ts] +export {x} from "jquery"; + +//// [reExportAll.ts] +export * from "jquery"; + +//// [reExportUser.ts] +import {x} from "./reExportX"; +import * as $ from "./reExportAll"; +// '$' is not callable, it is an object. +x($); + + +//// [reExportX.js] +"use strict"; +var jquery_1 = require("jquery"); +exports.x = jquery_1.x; +//// [reExportAll.js] +"use strict"; +//// [reExportUser.js] +"use strict"; +var reExportX_1 = require("./reExportX"); +var $ = require("./reExportAll"); +// '$' is not callable, it is an object. +reExportX_1.x($); diff --git a/tests/baselines/reference/ambientShorthand_reExport.symbols b/tests/baselines/reference/ambientShorthand_reExport.symbols new file mode 100644 index 00000000000..1e8d5318011 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_reExport.symbols @@ -0,0 +1,22 @@ +=== tests/cases/conformance/ambient/declarations.d.ts === +declare module "jquery"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/ambient/reExportX.ts === +export {x} from "jquery"; +>x : Symbol(x, Decl(reExportX.ts, 0, 8)) + +=== tests/cases/conformance/ambient/reExportAll.ts === +export * from "jquery"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/ambient/reExportUser.ts === +import {x} from "./reExportX"; +>x : Symbol(x, Decl(reExportUser.ts, 0, 8)) + +import * as $ from "./reExportAll"; +>$ : Symbol($, Decl(reExportUser.ts, 1, 6)) + +// '$' is not callable, it is an object. +x($); +>x : Symbol(x, Decl(reExportUser.ts, 0, 8)) +>$ : Symbol($, Decl(reExportUser.ts, 1, 6)) + diff --git a/tests/baselines/reference/ambientShorthand_reExport.types b/tests/baselines/reference/ambientShorthand_reExport.types new file mode 100644 index 00000000000..5765c7e0331 --- /dev/null +++ b/tests/baselines/reference/ambientShorthand_reExport.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/ambient/declarations.d.ts === +declare module "jquery"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/ambient/reExportX.ts === +export {x} from "jquery"; +>x : any + +=== tests/cases/conformance/ambient/reExportAll.ts === +export * from "jquery"; +No type information for this code. +No type information for this code.=== tests/cases/conformance/ambient/reExportUser.ts === +import {x} from "./reExportX"; +>x : any + +import * as $ from "./reExportAll"; +>$ : typeof $ + +// '$' is not callable, it is an object. +x($); +>x($) : any +>x : any +>$ : typeof $ + diff --git a/tests/cases/conformance/ambient/ambientShorthand.ts b/tests/cases/conformance/ambient/ambientShorthand.ts new file mode 100644 index 00000000000..35bb53a92cf --- /dev/null +++ b/tests/cases/conformance/ambient/ambientShorthand.ts @@ -0,0 +1,11 @@ +// @Filename: declarations.d.ts +declare module "jquery" +// Semicolon is optional +declare module "fs"; + +// @Filename: user.ts +/// +import foo, {bar} from "jquery"; +import * as baz from "fs"; +import boom = require("jquery"); +foo(bar, baz, boom); diff --git a/tests/cases/conformance/ambient/ambientShorthand_declarationEmit.ts b/tests/cases/conformance/ambient/ambientShorthand_declarationEmit.ts new file mode 100644 index 00000000000..13053868e5b --- /dev/null +++ b/tests/cases/conformance/ambient/ambientShorthand_declarationEmit.ts @@ -0,0 +1,2 @@ +// @declaration: true +declare module "foo"; diff --git a/tests/cases/conformance/ambient/ambientShorthand_duplicate.ts b/tests/cases/conformance/ambient/ambientShorthand_duplicate.ts new file mode 100644 index 00000000000..03a0dd72249 --- /dev/null +++ b/tests/cases/conformance/ambient/ambientShorthand_duplicate.ts @@ -0,0 +1,10 @@ +// @Filename: declarations1.d.ts +declare module "foo"; + +// @Filename: declarations2.d.ts +declare module "foo"; + +// @Filename: user.ts +/// +/// +import foo from "foo"; diff --git a/tests/cases/conformance/ambient/ambientShorthand_isImplicitAny.ts b/tests/cases/conformance/ambient/ambientShorthand_isImplicitAny.ts new file mode 100644 index 00000000000..bf7de709ef2 --- /dev/null +++ b/tests/cases/conformance/ambient/ambientShorthand_isImplicitAny.ts @@ -0,0 +1,2 @@ +// @noImplicitAny: true +declare module "jquery"; diff --git a/tests/cases/conformance/ambient/ambientShorthand_merging.ts b/tests/cases/conformance/ambient/ambientShorthand_merging.ts new file mode 100644 index 00000000000..a7bd7784d43 --- /dev/null +++ b/tests/cases/conformance/ambient/ambientShorthand_merging.ts @@ -0,0 +1,12 @@ +// @Filename: declarations1.d.ts +declare module "foo"; + +// @Filename: declarations2.d.ts +declare module "foo" { + export const bar: number; +} + +// @Filename: user.ts +/// +/// +import foo, {bar} from "foo"; diff --git a/tests/cases/conformance/ambient/ambientShorthand_reExport.ts b/tests/cases/conformance/ambient/ambientShorthand_reExport.ts new file mode 100644 index 00000000000..b78afe42675 --- /dev/null +++ b/tests/cases/conformance/ambient/ambientShorthand_reExport.ts @@ -0,0 +1,14 @@ +// @Filename: declarations.d.ts +declare module "jquery"; + +// @Filename: reExportX.ts +export {x} from "jquery"; + +// @Filename: reExportAll.ts +export * from "jquery"; + +// @Filename: reExportUser.ts +import {x} from "./reExportX"; +import * as $ from "./reExportAll"; +// '$' is not callable, it is an object. +x($); diff --git a/tests/cases/fourslash/ambientShorthandFindAllRefs.ts b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts new file mode 100644 index 00000000000..16fddd1869d --- /dev/null +++ b/tests/cases/fourslash/ambientShorthandFindAllRefs.ts @@ -0,0 +1,21 @@ +/// + +// @Filename: declarations.d.ts +////declare module "jquery"; + +// @Filename: user.ts +////import {[|x|]} from "jquery"; + +// @Filename: user2.ts +////import {[|x|]} from "jquery"; + +let ranges = test.ranges(); +for (let range of ranges) { + goTo.file(range.fileName); + goTo.position(range.start); + + verify.referencesCountIs(ranges.length); + for (let expectedRange of ranges) { + verify.referencesAtPositionContains(expectedRange); + } +} diff --git a/tests/cases/fourslash/ambientShorthandGotoDefinition.ts b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts new file mode 100644 index 00000000000..970b87f8ec2 --- /dev/null +++ b/tests/cases/fourslash/ambientShorthandGotoDefinition.ts @@ -0,0 +1,39 @@ +/// + +// @Filename: declarations.d.ts +/////*module*/declare module "jquery" + +// @Filename: user.ts +/////// +////import /*importFoo*/foo, {bar} from "jquery"; +////import /*importBaz*/* as /*idBaz*/baz from "jquery"; +/////*importBang*/import /*idBang*/bang = require("jquery"); +////foo/*useFoo*/(bar/*useBar*/, baz/*useBaz*/, bang/*useBang*/); + +goTo.marker("useFoo"); +verify.quickInfoIs("import foo"); +goTo.definition(); +verify.caretAtMarker("importFoo"); +goTo.definition(); +verify.caretAtMarker("module"); + +goTo.marker("useBar"); +verify.quickInfoIs("import bar"); +goTo.definition(); +verify.caretAtMarker("module"); + +goTo.marker("useBaz"); +verify.quickInfoIs("import baz"); +goTo.definition(); +verify.caretAtMarker("importBaz"); +goTo.marker("idBaz"); +goTo.definition(); +verify.caretAtMarker("module"); + +goTo.marker("useBang"); +verify.quickInfoIs("import bang = require(\"jquery\")"); +goTo.definition(); +verify.caretAtMarker("importBang"); +goTo.marker("idBang"); +goTo.definition(); +verify.caretAtMarker("module");