use 'declare global' to define augmentations for the global scope

This commit is contained in:
Vladimir Matveev
2015-12-28 12:03:54 -08:00
parent 3e1bc01a86
commit 7f2ebf928a
55 changed files with 554 additions and 79 deletions
+3 -3
View File
@@ -192,8 +192,8 @@ namespace ts {
// unless it is a well known Symbol.
function getDeclarationName(node: Declaration): string {
if (node.name) {
if (node.kind === SyntaxKind.ModuleDeclaration && node.name.kind === SyntaxKind.StringLiteral) {
return `"${(<LiteralExpression>node.name).text}"`;
if (isAmbientModule(node)) {
return isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${(<LiteralExpression>node.name).text}"`;
}
if (node.name.kind === SyntaxKind.ComputedPropertyName) {
const nameExpression = (<ComputedPropertyName>node.name).expression;
@@ -849,7 +849,7 @@ namespace ts {
function bindModuleDeclaration(node: ModuleDeclaration) {
setExportContextFlag(node);
if (node.name.kind === SyntaxKind.StringLiteral) {
if (isAmbientModule(node)) {
if (node.flags & NodeFlags.Export) {
errorOnFirstToken(node, Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible);
}
+37 -34
View File
@@ -378,7 +378,7 @@ namespace ts {
return;
}
if (isNameOfGlobalAugmentation(moduleName)) {
if (isGlobalScopeAugmentation(moduleAugmentation)) {
mergeSymbolTable(globals, moduleAugmentation.symbol.exports);
}
else {
@@ -597,8 +597,7 @@ namespace ts {
if (!isExternalOrCommonJsModule(<SourceFile>location)) break;
case SyntaxKind.ModuleDeclaration:
const moduleExports = getSymbolOfNode(location).exports;
if (location.kind === SyntaxKind.SourceFile ||
(location.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>location).name.kind === SyntaxKind.StringLiteral)) {
if (location.kind === SyntaxKind.SourceFile || isAmbientModule(location)) {
// It's an external module. First see if the module has an export default and if the local
// name of that export default matches.
@@ -1552,8 +1551,7 @@ namespace ts {
}
function hasExternalModuleSymbol(declaration: Node) {
return (declaration.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>declaration).name.kind === SyntaxKind.StringLiteral) ||
(declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(<SourceFile>declaration));
return isAmbientModule(declaration) || (declaration.kind === SyntaxKind.SourceFile && isExternalOrCommonJsModule(<SourceFile>declaration));
}
function hasVisibleDeclarations(symbol: Symbol): SymbolVisibilityResult {
@@ -11995,7 +11993,7 @@ namespace ts {
case SyntaxKind.InterfaceDeclaration:
return SymbolFlags.ExportType;
case SyntaxKind.ModuleDeclaration:
return (<ModuleDeclaration>d).name.kind === SyntaxKind.StringLiteral || getModuleInstanceState(d) !== ModuleInstanceState.NonInstantiated
return isAmbientModule(d) || getModuleInstanceState(d) !== ModuleInstanceState.NonInstantiated
? SymbolFlags.ExportNamespace | SymbolFlags.ExportValue
: SymbolFlags.ExportNamespace;
case SyntaxKind.ClassDeclaration:
@@ -14134,7 +14132,13 @@ namespace ts {
function checkModuleDeclaration(node: ModuleDeclaration) {
if (produceDiagnostics) {
// Grammar checking
const isAmbientExternalModule = node.name.kind === SyntaxKind.StringLiteral;
const isGlobalAugmentation = isGlobalScopeAugmentation(node);
const inAmbientContext = isInAmbientContext(node);
if (isGlobalAugmentation && !inAmbientContext) {
error(node.name, Diagnostics.Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context);
}
const isAmbientExternalModule = isAmbientModule(node);
const contextErrorMessage = isAmbientExternalModule
? Diagnostics.An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file
: Diagnostics.A_namespace_declaration_is_only_allowed_in_a_namespace_or_module;
@@ -14144,7 +14148,7 @@ namespace ts {
}
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node)) {
if (!isInAmbientContext(node) && node.name.kind === SyntaxKind.StringLiteral) {
if (!inAmbientContext && node.name.kind === SyntaxKind.StringLiteral) {
grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names);
}
}
@@ -14157,7 +14161,7 @@ namespace ts {
// The following checks only apply on a non-ambient instantiated module declaration.
if (symbol.flags & SymbolFlags.ValueModule
&& symbol.declarations.length > 1
&& !isInAmbientContext(node)
&& !inAmbientContext
&& isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) {
const firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol);
if (firstNonAmbientClassOrFunc) {
@@ -14180,41 +14184,42 @@ namespace ts {
if (isAmbientExternalModule) {
if (isExternalModuleAugmentation(node)) {
// if symbol of augmentation is not merged this means that either
// - this is an augmentation of the global scope
// or
// - this augmentation was not merged with main definition of the module
// error should already be reported so all errors in the body of augmentation can be ignored.
const checkBody = isNameOfGlobalAugmentation(<LiteralExpression>node.name) || (getSymbolOfNode(node).flags & SymbolFlags.Merged);
// body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module)
// otherwise we'll be swamped in cascading errors.
// We can detect if augmentation was applied using following rules:
// - 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) {
const globalAugmentation = isNameOfGlobalAugmentation(<LiteralExpression>node.name);
// body of ambient external module is always a module block
for (const statement of (<ModuleBlock>node.body).statements) {
checkBodyOfModuleAugmentation(statement, globalAugmentation);
checkBodyOfModuleAugmentation(statement, isGlobalAugmentation);
}
}
}
else if (isGlobalSourceFile(node.parent)) {
if (isExternalModuleNameRelative(node.name.text)) {
if (isGlobalAugmentation) {
error(node.name, Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
}
else if (isExternalModuleNameRelative(node.name.text)) {
error(node.name, Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name);
}
}
else {
// Node is not an augmentation and is not located on the script level.
// This means that this is declaration of ambient module that is located in other module or namespace which is prohibited.
error(node.name, Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces);
if (isGlobalAugmentation) {
error(node.name, Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations);
}
else {
// Node is not an augmentation and is not located on the script level.
// This means that this is declaration of ambient module that is located in other module or namespace which is prohibited.
error(node.name, Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces);
}
}
}
}
checkSourceElement(node.body);
}
function isNameOfGlobalAugmentation(node: LiteralExpression): boolean {
// global augmentation
// TODO: fix to use 'declare global' syntax.
return node.text === "/";
}
function checkBodyOfModuleAugmentation(node: Node, isGlobalAugmentation: boolean): void {
switch (node.kind) {
case SyntaxKind.VariableStatement:
@@ -14294,7 +14299,7 @@ namespace ts {
error(moduleName, Diagnostics.String_literal_expected);
return false;
}
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && (<ModuleDeclaration>node.parent.parent).name.kind === SyntaxKind.StringLiteral;
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(<ModuleDeclaration>node.parent.parent);
if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule) {
error(moduleName, node.kind === SyntaxKind.ExportDeclaration ?
Diagnostics.Export_declarations_are_not_permitted_in_a_namespace :
@@ -14417,7 +14422,7 @@ namespace ts {
// export { x, y } from "foo"
forEach(node.exportClause.elements, checkExportSpecifier);
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && (<ModuleDeclaration>node.parent.parent).name.kind === SyntaxKind.StringLiteral;
const inAmbientExternalModule = node.parent.kind === SyntaxKind.ModuleBlock && isAmbientModule(node.parent.parent);
if (node.parent.kind !== SyntaxKind.SourceFile && !inAmbientExternalModule) {
error(node, Diagnostics.Export_declarations_are_not_permitted_in_a_namespace);
}
@@ -14452,7 +14457,7 @@ namespace ts {
}
const container = node.parent.kind === SyntaxKind.SourceFile ? <SourceFile>node.parent : <ModuleDeclaration>node.parent.parent;
if (container.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>container).name.kind === SyntaxKind.Identifier) {
if (container.kind === SyntaxKind.ModuleDeclaration && !isAmbientModule(container)) {
error(node, Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace);
return;
}
@@ -15616,10 +15621,8 @@ namespace ts {
// merge module augmentations.
// this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed
for (const file of host.getSourceFiles()) {
if (file.moduleAugmentations.length) {
for (const augmentation of file.moduleAugmentations) {
mergeModuleAugmentation(augmentation);
}
for (const augmentation of file.moduleAugmentations) {
mergeModuleAugmentation(augmentation);
}
}
}
+15 -10
View File
@@ -731,7 +731,7 @@ namespace ts {
}
function emitExternalModuleSpecifier(parent: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration | ModuleDeclaration) {
// emitExternalModuleSpecifier is usualyl called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
// emitExternalModuleSpecifier is usually called when we emit something in the.d.ts file that will make it an external module (i.e. import/export declarations).
// the only case when it is not true is when we call it to emit correct name for module augmentation - d.ts files with just module augmentations are not considered
// external modules since they are indistingushable from script files with ambient modules. To fix this in such d.ts files we'll emit top level 'export {}'
// so compiler will treat them as external modules.
@@ -802,17 +802,22 @@ namespace ts {
function writeModuleDeclaration(node: ModuleDeclaration) {
emitJsDocComments(node);
emitModuleElementDeclarationFlags(node);
if (node.flags & NodeFlags.Namespace) {
write("namespace ");
if (isGlobalScopeAugmentation(node)) {
write("global ");
}
else {
write("module ");
}
if (isExternalModuleAugmentation(node)) {
emitExternalModuleSpecifier(node);
}
else {
writeTextOfNode(currentText, node.name);
if (node.flags & NodeFlags.Namespace) {
write("namespace ");
}
else {
write("module ");
}
if (isExternalModuleAugmentation(node)) {
emitExternalModuleSpecifier(node);
}
else {
writeTextOfNode(currentText, node.name);
}
}
while (node.body.kind !== SyntaxKind.ModuleBlock) {
node = <ModuleDeclaration>node.body;
+8
View File
@@ -1791,6 +1791,14 @@
"category": "Error",
"code": 2665
},
"Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.": {
"category": "Error",
"code": 2666
},
"Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.": {
"category": "Error",
"code": 2667
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000
+19 -2
View File
@@ -4387,6 +4387,9 @@ namespace ts {
}
continue;
case SyntaxKind.GlobalKeyword:
return nextToken() === SyntaxKind.OpenBraceToken;
case SyntaxKind.ImportKeyword:
nextToken();
return token === SyntaxKind.StringLiteral || token === SyntaxKind.AsteriskToken ||
@@ -4451,6 +4454,7 @@ namespace ts {
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
case SyntaxKind.TypeKeyword:
case SyntaxKind.GlobalKeyword:
// When these don't start a declaration, they're an identifier in an expression statement
return true;
@@ -4539,6 +4543,7 @@ namespace ts {
case SyntaxKind.PublicKeyword:
case SyntaxKind.AbstractKeyword:
case SyntaxKind.StaticKeyword:
case SyntaxKind.GlobalKeyword:
if (isStartOfDeclaration()) {
return parseDeclaration();
}
@@ -4566,6 +4571,7 @@ namespace ts {
return parseTypeAliasDeclaration(fullStart, decorators, modifiers);
case SyntaxKind.EnumKeyword:
return parseEnumDeclaration(fullStart, decorators, modifiers);
case SyntaxKind.GlobalKeyword:
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
return parseModuleDeclaration(fullStart, decorators, modifiers);
@@ -5200,14 +5206,25 @@ namespace ts {
const node = <ModuleDeclaration>createNode(SyntaxKind.ModuleDeclaration, fullStart);
node.decorators = decorators;
setModifiers(node, modifiers);
node.name = parseLiteralNode(/*internName*/ true);
if (token === SyntaxKind.GlobalKeyword) {
// parse 'global' as name of global scope augmentation
node.name = parseIdentifier();
node.flags |= NodeFlags.GlobalAugmentation;
}
else {
node.name = parseLiteralNode(/*internName*/ true);
}
node.body = parseModuleBlock();
return finishNode(node);
}
function parseModuleDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ModuleDeclaration {
let flags = modifiers ? modifiers.flags : 0;
if (parseOptional(SyntaxKind.NamespaceKeyword)) {
if (token === SyntaxKind.GlobalKeyword) {
// global augmentation
return parseAmbientExternalModuleDeclaration(fullStart, decorators, modifiers);
}
else if (parseOptional(SyntaxKind.NamespaceKeyword)) {
flags |= NodeFlags.Namespace;
}
else {
+1 -1
View File
@@ -952,7 +952,7 @@ namespace ts {
}
break;
case SyntaxKind.ModuleDeclaration:
if ((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral && (inAmbientModule || node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || node.flags & NodeFlags.Ambient || isDeclarationFile(file))) {
const moduleName = <LiteralExpression>(<ModuleDeclaration>node).name;
// Ambient module declarations can be interpreted as augmentations for some existing external modules.
// This will happen in two cases:
+1
View File
@@ -94,6 +94,7 @@ namespace ts {
"protected": SyntaxKind.ProtectedKeyword,
"public": SyntaxKind.PublicKeyword,
"require": SyntaxKind.RequireKeyword,
"global": SyntaxKind.GlobalKeyword,
"return": SyntaxKind.ReturnKeyword,
"set": SyntaxKind.SetKeyword,
"static": SyntaxKind.StaticKeyword,
+2
View File
@@ -170,6 +170,7 @@ namespace ts {
SymbolKeyword,
TypeKeyword,
FromKeyword,
GlobalKeyword,
OfKeyword, // LastKeyword and LastToken
// Parse tree nodes
@@ -389,6 +390,7 @@ namespace ts {
ContainsThis = 1 << 18, // Interface contains references to "this"
HasImplicitReturn = 1 << 19, // If function implicitly returns on one of codepaths (initialized by binding)
HasExplicitReturn = 1 << 20, // If function has explicit reachable return on one of codepaths (initialized by binding)
GlobalAugmentation = 1 << 21, // Set if module declaration is an augmentation for the global scope
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
AccessibilityModifier = Public | Private | Protected,
BlockScoped = Let | Const,
+6 -1
View File
@@ -252,7 +252,12 @@ namespace ts {
}
export function isAmbientModule(node: Node): boolean {
return node && node.kind === SyntaxKind.ModuleDeclaration && (<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral;
return node && node.kind === SyntaxKind.ModuleDeclaration &&
((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(<ModuleDeclaration>node));
}
export function isGlobalScopeAugmentation(module: ModuleDeclaration): boolean {
return !!(module.flags & NodeFlags.GlobalAugmentation);
}
export function isExternalModuleAugmentation(node: Node): boolean {
+1 -1
View File
@@ -387,7 +387,7 @@ namespace ts.NavigationBar {
function getModuleName(moduleDeclaration: ModuleDeclaration): string {
// We want to maintain quotation marks.
if (moduleDeclaration.name.kind === SyntaxKind.StringLiteral) {
if (isAmbientModule(moduleDeclaration)) {
return getTextOfNode(moduleDeclaration.name);
}
+1 -1
View File
@@ -6229,7 +6229,7 @@ namespace ts {
return SemanticMeaning.Value | SemanticMeaning.Type;
case SyntaxKind.ModuleDeclaration:
if ((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral) {
if (isAmbientModule(<ModuleDeclaration>node)) {
return SemanticMeaning.Namespace | SemanticMeaning.Value;
}
else if (getModuleInstanceState(node) === ModuleInstanceState.Instantiated) {
@@ -8,7 +8,7 @@ export class A {x: number;}
import {A} from "./f1";
// change the shape of Array<T>
declare module "/" {
declare global {
interface Array<T> {
getA(): A;
}
@@ -38,7 +38,7 @@ export declare class A {
}
//// [f2.d.ts]
import { A } from "./f1";
declare module "/" {
declare global {
interface Array<T> {
getA(): A;
}
@@ -9,9 +9,11 @@ import {A} from "./f1";
>A : Symbol(A, Decl(f2.ts, 0, 8))
// change the shape of Array<T>
declare module "/" {
declare global {
>global : Symbol(, Decl(f2.ts, 0, 23))
interface Array<T> {
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(f2.ts, 3, 20))
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(f2.ts, 3, 16))
>T : Symbol(T, Decl(lib.d.ts, --, --), Decl(f2.ts, 4, 20))
getA(): A;
@@ -9,7 +9,9 @@ import {A} from "./f1";
>A : typeof A
// change the shape of Array<T>
declare module "/" {
declare global {
>global : typeof
interface Array<T> {
>Array : T[]
>T : T
@@ -8,7 +8,7 @@ export class A {};
// change the shape of Array<T>
import {A} from "./f1";
declare module "/" {
declare global {
interface Array<T> {
getCountAsString(): string;
}
@@ -37,7 +37,7 @@ var y = x.getCountAsString().toLowerCase();
export declare class A {
}
//// [f2.d.ts]
declare module "/" {
declare global {
interface Array<T> {
getCountAsString(): string;
}
@@ -9,9 +9,11 @@ export class A {};
import {A} from "./f1";
>A : Symbol(A, Decl(f2.ts, 2, 8))
declare module "/" {
declare global {
>global : Symbol(, Decl(f2.ts, 2, 23))
interface Array<T> {
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(f2.ts, 4, 20))
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(f2.ts, 4, 16))
>T : Symbol(T, Decl(lib.d.ts, --, --), Decl(f2.ts, 5, 20))
getCountAsString(): string;
@@ -9,7 +9,9 @@ export class A {};
import {A} from "./f1";
>A : typeof A
declare module "/" {
declare global {
>global : typeof
interface Array<T> {
>Array : T[]
>T : T
@@ -8,7 +8,7 @@ export class A {};
// change the shape of Array<T>
import {A} from "./f1";
declare module "/" {
declare global {
interface Array<T> {
getCountAsString(): string;
}
@@ -43,7 +43,7 @@ var y = x.getCountAsString().toLowerCase();
export declare class A {
}
//// [f2.d.ts]
declare module "/" {
declare global {
interface Array<T> {
getCountAsString(): string;
}
@@ -9,9 +9,11 @@ export class A {};
import {A} from "./f1";
>A : Symbol(A, Decl(f2.ts, 2, 8))
declare module "/" {
declare global {
>global : Symbol(, Decl(f2.ts, 2, 23))
interface Array<T> {
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(f2.ts, 4, 20))
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(f2.ts, 4, 16))
>T : Symbol(T, Decl(lib.d.ts, --, --), Decl(f2.ts, 5, 20))
getCountAsString(): string;
@@ -9,7 +9,9 @@ export class A {};
import {A} from "./f1";
>A : typeof A
declare module "/" {
declare global {
>global : typeof
interface Array<T> {
>Array : T[]
>T : T
@@ -4,7 +4,7 @@ tests/cases/compiler/f2.ts(3,15): error TS2662: Module augmentation cannot intro
==== tests/cases/compiler/f1.ts (1 errors) ====
declare module "/" {
declare global {
interface Something {x}
~~~~~~~~~
!!! error TS2662: Module augmentation cannot introduce new names in the top level scope.
@@ -12,7 +12,7 @@ tests/cases/compiler/f2.ts(3,15): error TS2662: Module augmentation cannot intro
export {};
==== tests/cases/compiler/f2.ts (1 errors) ====
declare module "/" {
declare global {
interface Something {y}
~~~~~~~~~
!!! error TS2662: Module augmentation cannot introduce new names in the top level scope.
@@ -2,13 +2,13 @@
//// [f1.ts]
declare module "/" {
declare global {
interface Something {x}
}
export {};
//// [f2.ts]
declare module "/" {
declare global {
interface Something {y}
}
export {};
@@ -29,7 +29,7 @@ require("./f2");
//// [f1.d.ts]
declare module "/" {
declare global {
interface Something {
x: any;
}
@@ -37,7 +37,7 @@ declare module "/" {
export { };
export {};
//// [f2.d.ts]
declare module "/" {
declare global {
interface Something {
y: any;
}
@@ -0,0 +1,28 @@
tests/cases/compiler/f1.d.ts(4,19): error TS2662: Module augmentation cannot introduce new names in the top level scope.
tests/cases/compiler/f2.d.ts(3,19): error TS2662: Module augmentation cannot introduce new names in the top level scope.
==== tests/cases/compiler/f3.ts (0 errors) ====
/// <reference path="f1.d.ts"/>
/// <reference path="f2.d.ts"/>
import "A";
import "B";
==== tests/cases/compiler/f1.d.ts (1 errors) ====
declare module "A" {
global {
interface Something {x}
~~~~~~~~~
!!! error TS2662: Module augmentation cannot introduce new names in the top level scope.
}
}
==== tests/cases/compiler/f2.d.ts (1 errors) ====
declare module "B" {
global {
interface Something {y}
~~~~~~~~~
!!! error TS2662: Module augmentation cannot introduce new names in the top level scope.
}
}
@@ -0,0 +1,34 @@
//// [tests/cases/compiler/moduleAugmentationGlobal5.ts] ////
//// [f1.d.ts]
declare module "A" {
global {
interface Something {x}
}
}
//// [f2.d.ts]
declare module "B" {
global {
interface Something {y}
}
}
//// [f3.ts]
/// <reference path="f1.d.ts"/>
/// <reference path="f2.d.ts"/>
import "A";
import "B";
//// [f3.js]
"use strict";
/// <reference path="f1.d.ts"/>
/// <reference path="f2.d.ts"/>
require("A");
require("B");
//// [f3.d.ts]
/// <reference path="f1.d.ts" />
/// <reference path="f2.d.ts" />
@@ -0,0 +1,9 @@
tests/cases/compiler/moduleAugmentationGlobal6.ts(1,9): error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
==== tests/cases/compiler/moduleAugmentationGlobal6.ts (1 errors) ====
declare global {
~~~~~~
!!! error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
interface Array<T> { x }
}
@@ -0,0 +1,6 @@
//// [moduleAugmentationGlobal6.ts]
declare global {
interface Array<T> { x }
}
//// [moduleAugmentationGlobal6.js]
@@ -0,0 +1,12 @@
tests/cases/compiler/moduleAugmentationGlobal6_1.ts(1,1): error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
tests/cases/compiler/moduleAugmentationGlobal6_1.ts(1,1): error TS2667: Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.
==== tests/cases/compiler/moduleAugmentationGlobal6_1.ts (2 errors) ====
global {
~~~~~~
!!! error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
~~~~~~
!!! error TS2667: Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.
interface Array<T> { x }
}
@@ -0,0 +1,6 @@
//// [moduleAugmentationGlobal6_1.ts]
global {
interface Array<T> { x }
}
//// [moduleAugmentationGlobal6_1.js]
@@ -0,0 +1,11 @@
tests/cases/compiler/moduleAugmentationGlobal7.ts(2,13): error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
==== tests/cases/compiler/moduleAugmentationGlobal7.ts (1 errors) ====
namespace A {
declare global {
~~~~~~
!!! error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
interface Array<T> { x }
}
}
@@ -0,0 +1,8 @@
//// [moduleAugmentationGlobal7.ts]
namespace A {
declare global {
interface Array<T> { x }
}
}
//// [moduleAugmentationGlobal7.js]
@@ -0,0 +1,14 @@
tests/cases/compiler/moduleAugmentationGlobal7_1.ts(2,5): error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
tests/cases/compiler/moduleAugmentationGlobal7_1.ts(2,5): error TS2667: Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.
==== tests/cases/compiler/moduleAugmentationGlobal7_1.ts (2 errors) ====
namespace A {
global {
~~~~~~
!!! error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
~~~~~~
!!! error TS2667: Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.
interface Array<T> { x }
}
}
@@ -0,0 +1,8 @@
//// [moduleAugmentationGlobal7_1.ts]
namespace A {
global {
interface Array<T> { x }
}
}
//// [moduleAugmentationGlobal7_1.js]
@@ -0,0 +1,13 @@
tests/cases/compiler/moduleAugmentationGlobal8.ts(2,13): error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
==== tests/cases/compiler/moduleAugmentationGlobal8.ts (1 errors) ====
namespace A {
declare global {
~~~~~~
!!! error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
interface Array<T> { x }
}
}
export {}
@@ -0,0 +1,13 @@
//// [moduleAugmentationGlobal8.ts]
namespace A {
declare global {
interface Array<T> { x }
}
}
export {}
//// [moduleAugmentationGlobal8.js]
define(["require", "exports"], function (require, exports) {
"use strict";
});
@@ -0,0 +1,16 @@
tests/cases/compiler/moduleAugmentationGlobal8_1.ts(2,5): error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
tests/cases/compiler/moduleAugmentationGlobal8_1.ts(2,5): error TS2667: Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.
==== tests/cases/compiler/moduleAugmentationGlobal8_1.ts (2 errors) ====
namespace A {
global {
~~~~~~
!!! error TS2666: Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.
~~~~~~
!!! error TS2667: Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context.
interface Array<T> { x }
}
}
export {}
@@ -0,0 +1,13 @@
//// [moduleAugmentationGlobal8_1.ts]
namespace A {
global {
interface Array<T> { x }
}
}
export {}
//// [moduleAugmentationGlobal8_1.js]
define(["require", "exports"], function (require, exports) {
"use strict";
});
@@ -0,0 +1,35 @@
//// [tests/cases/compiler/moduleAugmentationInAmbientModule5.ts] ////
//// [array.d.ts]
declare module "A" {
class A { x: number; }
}
declare module "array" {
import {A} from "A";
global {
interface Array<T> {
getA(): A;
}
}
}
//// [f.ts]
/// <reference path="array.d.ts"/>
import "array";
let x = [1];
let y = x.getA().x;
//// [f.js]
"use strict";
/// <reference path="array.d.ts"/>
require("array");
var x = [1];
var y = x.getA().x;
//// [f.d.ts]
/// <reference path="array.d.ts" />
@@ -0,0 +1,41 @@
=== tests/cases/compiler/f.ts ===
/// <reference path="array.d.ts"/>
import "array";
let x = [1];
>x : Symbol(x, Decl(f.ts, 3, 3))
let y = x.getA().x;
>y : Symbol(y, Decl(f.ts, 4, 3))
>x.getA().x : Symbol(A.x, Decl(array.d.ts, 2, 13))
>x.getA : Symbol(Array.getA, Decl(array.d.ts, 8, 28))
>x : Symbol(x, Decl(f.ts, 3, 3))
>getA : Symbol(Array.getA, Decl(array.d.ts, 8, 28))
>x : Symbol(A.x, Decl(array.d.ts, 2, 13))
=== tests/cases/compiler/array.d.ts ===
declare module "A" {
class A { x: number; }
>A : Symbol(A, Decl(array.d.ts, 1, 20))
>x : Symbol(x, Decl(array.d.ts, 2, 13))
}
declare module "array" {
import {A} from "A";
>A : Symbol(A, Decl(array.d.ts, 6, 12))
global {
>global : Symbol(, Decl(array.d.ts, 6, 24))
interface Array<T> {
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --), Decl(array.d.ts, 7, 12))
>T : Symbol(T, Decl(lib.d.ts, --, --), Decl(array.d.ts, 8, 24))
getA(): A;
>getA : Symbol(getA, Decl(array.d.ts, 8, 28))
>A : Symbol(A, Decl(array.d.ts, 6, 12))
}
}
}
@@ -0,0 +1,44 @@
=== tests/cases/compiler/f.ts ===
/// <reference path="array.d.ts"/>
import "array";
let x = [1];
>x : number[]
>[1] : number[]
>1 : number
let y = x.getA().x;
>y : number
>x.getA().x : number
>x.getA() : A
>x.getA : () => A
>x : number[]
>getA : () => A
>x : number
=== tests/cases/compiler/array.d.ts ===
declare module "A" {
class A { x: number; }
>A : A
>x : number
}
declare module "array" {
import {A} from "A";
>A : typeof A
global {
>global : typeof
interface Array<T> {
>Array : T[]
>T : T
getA(): A;
>getA : () => A
>A : A
}
}
}
@@ -8,7 +8,7 @@ export class A {x: number;}
import {A} from "./f1";
// change the shape of Array<T>
declare module "/" {
declare global {
interface Array<T> {
getA(): A;
}
@@ -8,7 +8,7 @@ export class A {};
// change the shape of Array<T>
import {A} from "./f1";
declare module "/" {
declare global {
interface Array<T> {
getCountAsString(): string;
}
@@ -8,7 +8,7 @@ export class A {};
// change the shape of Array<T>
import {A} from "./f1";
declare module "/" {
declare global {
interface Array<T> {
getCountAsString(): string;
}
@@ -2,13 +2,13 @@
// @declaration: true
// @filename: f1.ts
declare module "/" {
declare global {
interface Something {x}
}
export {};
// @filename: f2.ts
declare module "/" {
declare global {
interface Something {y}
}
export {};
@@ -0,0 +1,21 @@
// @module: commonjs
// @declaration: true
// @filename: f1.d.ts
declare module "A" {
global {
interface Something {x}
}
}
// @filename: f2.d.ts
declare module "B" {
global {
interface Something {y}
}
}
// @filename: f3.ts
/// <reference path="f1.d.ts"/>
/// <reference path="f2.d.ts"/>
import "A";
import "B";
@@ -0,0 +1,3 @@
declare global {
interface Array<T> { x }
}
@@ -0,0 +1,3 @@
global {
interface Array<T> { x }
}
@@ -0,0 +1,5 @@
namespace A {
declare global {
interface Array<T> { x }
}
}
@@ -0,0 +1,5 @@
namespace A {
global {
interface Array<T> { x }
}
}
@@ -0,0 +1,8 @@
// @target: es5
// @module: amd
namespace A {
declare global {
interface Array<T> { x }
}
}
export {}
@@ -0,0 +1,8 @@
// @target: es5
// @module: amd
namespace A {
global {
interface Array<T> { x }
}
}
export {}
@@ -0,0 +1,23 @@
// @module: commonjs
// @declaration: true
// @filename: array.d.ts
declare module "A" {
class A { x: number; }
}
declare module "array" {
import {A} from "A";
global {
interface Array<T> {
getA(): A;
}
}
}
// @filename: f.ts
/// <reference path="array.d.ts"/>
import "array";
let x = [1];
let y = x.getA().x;
@@ -0,0 +1,8 @@
/// <reference path="fourslash.ts"/>
/////*1*/declare global {
////}
format.document();
goTo.marker("1");
verify.currentLineContentIs("declare global {");
@@ -0,0 +1,10 @@
/// <reference path="fourslash.ts"/>
////declare module "A" {
/////*1*/ global {
//// }
////}
format.document();
goTo.marker("1");
verify.currentLineContentIs(" global {");
@@ -0,0 +1,9 @@
/// <reference path="fourslash.ts"/>
// @module: amd
//// export {}
//// declare global {/*1*/
goTo.marker("1");
edit.insertLine("");
verify.indentationIs(4);
@@ -0,0 +1,8 @@
/// <reference path="fourslash.ts"/>
//// declare module "A" {
//// global {/*1*/
goTo.marker("1");
edit.insertLine("");
verify.indentationIs(8);