Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 15 additions & 20 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2264,9 +2264,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
var identityRelation = new Map<string, RelationComparisonResult>();
var enumRelation = new Map<string, RelationComparisonResult>();

var builtinGlobals = createSymbolTable();
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);

// Extensions suggested for path imports when module resolution is node16 or higher.
// The first element of each tuple is the extension a file has.
// The second element of each tuple is the extension that should be used in a path import.
Expand Down Expand Up @@ -2729,20 +2726,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

function addToSymbolTable(target: SymbolTable, source: SymbolTable, message: DiagnosticMessage) {
source.forEach((sourceSymbol, id) => {
const targetSymbol = target.get(id);
if (targetSymbol) {
// Error on redeclarations
forEach(targetSymbol.declarations, addDeclarationDiagnostic(unescapeLeadingUnderscores(id), message));
}
else {
target.set(id, sourceSymbol);
}
});

function addDeclarationDiagnostic(id: string, message: DiagnosticMessage) {
return (declaration: Declaration) => diagnostics.add(createDiagnosticForNode(declaration, message, id));
function addUndefinedToGlobalsOrErrorOnRedeclaration() {
const name = undefinedSymbol.escapedName;
const targetSymbol = globals.get(name);
if (targetSymbol) {
forEach(targetSymbol.declarations, declaration => {
// checkTypeNameIsReserved will have added better diagnostics for undefined.
if (!isTypeDeclaration(declaration)) {
diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0, unescapeLeadingUnderscores(name)));
}
});
}
else {
globals.set(name, undefinedSymbol);
}
}

Expand Down Expand Up @@ -44347,6 +44343,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
case "symbol":
case "void":
case "object":
case "undefined":
error(name, message, name.escapedText as string);
}
}
Expand Down Expand Up @@ -48836,7 +48833,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
if (!isExternalOrCommonJsModule(file)) {
// It is an error for a non-external-module (i.e. script) to declare its own `globalThis`.
// We can't use `builtinGlobals` for this due to synthetic expando-namespace generation in JS files.
const fileGlobalThisSymbol = file.locals!.get("globalThis" as __String);
if (fileGlobalThisSymbol?.declarations) {
for (const declaration of fileGlobalThisSymbol.declarations) {
Expand Down Expand Up @@ -48882,8 +48878,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

// Setup global builtins
addToSymbolTable(globals, builtinGlobals, Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0);
addUndefinedToGlobalsOrErrorOnRedeclaration();

getSymbolLinks(undefinedSymbol).type = undefinedWideningType;
getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments" as __String, /*arity*/ 0, /*reportErrors*/ true);
Expand Down
23 changes: 23 additions & 0 deletions tests/baselines/reference/typeNamedUndefined1.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
typeNamedUndefined1.ts(3,17): error TS2457: Type alias name cannot be 'undefined'.
typeNamedUndefined1.ts(13,13): error TS2457: Type alias name cannot be 'undefined'.


==== typeNamedUndefined1.ts (2 errors) ====
export namespace ns {
const s = Symbol();
export type undefined = typeof s;
~~~~~~~~~
!!! error TS2457: Type alias name cannot be 'undefined'.
export function x(p: undefined): undefined { // global undefined
return p;
}
}

export function x(p: ns.undefined) { // undefined from the namespace
return p;
}

export type undefined = "";
~~~~~~~~~
!!! error TS2457: Type alias name cannot be 'undefined'.

30 changes: 30 additions & 0 deletions tests/baselines/reference/typeNamedUndefined1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//// [tests/cases/compiler/typeNamedUndefined1.ts] ////

//// [typeNamedUndefined1.ts]
export namespace ns {
const s = Symbol();
export type undefined = typeof s;
export function x(p: undefined): undefined { // global undefined
return p;
}
}

export function x(p: ns.undefined) { // undefined from the namespace
return p;
}

export type undefined = "";


//// [typeNamedUndefined1.js]
export var ns;
(function (ns) {
const s = Symbol();
function x(p) {
return p;
}
ns.x = x;
})(ns || (ns = {}));
export function x(p) {
return p;
}
36 changes: 36 additions & 0 deletions tests/baselines/reference/typeNamedUndefined1.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//// [tests/cases/compiler/typeNamedUndefined1.ts] ////

=== typeNamedUndefined1.ts ===
export namespace ns {
>ns : Symbol(ns, Decl(typeNamedUndefined1.ts, 0, 0))

const s = Symbol();
>s : Symbol(s, Decl(typeNamedUndefined1.ts, 1, 9))
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))

export type undefined = typeof s;
>undefined : Symbol(undefined, Decl(typeNamedUndefined1.ts, 1, 23))
>s : Symbol(s, Decl(typeNamedUndefined1.ts, 1, 9))

export function x(p: undefined): undefined { // global undefined
>x : Symbol(x, Decl(typeNamedUndefined1.ts, 2, 37))
>p : Symbol(p, Decl(typeNamedUndefined1.ts, 3, 22))

return p;
>p : Symbol(p, Decl(typeNamedUndefined1.ts, 3, 22))
}
}

export function x(p: ns.undefined) { // undefined from the namespace
>x : Symbol(x, Decl(typeNamedUndefined1.ts, 6, 1))
>p : Symbol(p, Decl(typeNamedUndefined1.ts, 8, 18))
>ns : Symbol(ns, Decl(typeNamedUndefined1.ts, 0, 0))
>undefined : Symbol(ns.undefined, Decl(typeNamedUndefined1.ts, 1, 23))

return p;
>p : Symbol(p, Decl(typeNamedUndefined1.ts, 8, 18))
}

export type undefined = "";
>undefined : Symbol(undefined, Decl(typeNamedUndefined1.ts, 10, 1))

36 changes: 36 additions & 0 deletions tests/baselines/reference/typeNamedUndefined1.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//// [tests/cases/compiler/typeNamedUndefined1.ts] ////

=== typeNamedUndefined1.ts ===
export namespace ns {
>ns : typeof ns

const s = Symbol();
>s : unique symbol
>Symbol() : unique symbol
>Symbol : SymbolConstructor

export type undefined = typeof s;
>undefined : unique symbol
>s : unique symbol

export function x(p: undefined): undefined { // global undefined
>x : (p: undefined) => undefined
>p : undefined

return p;
>p : undefined
}
}

export function x(p: ns.undefined) { // undefined from the namespace
>x : (p: ns.undefined) => symbol
>p : unique symbol
>ns : any

return p;
>p : unique symbol
}

export type undefined = "";
>undefined : ""

28 changes: 28 additions & 0 deletions tests/baselines/reference/typeNamedUndefined2.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
typeNamedUndefined2.ts(4,21): error TS2457: Type alias name cannot be 'undefined'.
typeNamedUndefined2.ts(17,17): error TS2457: Type alias name cannot be 'undefined'.


==== typeNamedUndefined2.ts (2 errors) ====
export namespace ns {
export namespace undefined {
export const s = Symbol();
export type undefined = typeof s;
~~~~~~~~~
!!! error TS2457: Type alias name cannot be 'undefined'.
};
export function x(p: undefined): undefined {
return p;
}
}

export function x(p: ns.undefined.undefined) {
return p;
}

export namespace undefined {
export const s = Symbol();
export type undefined = typeof s;
~~~~~~~~~
!!! error TS2457: Type alias name cannot be 'undefined'.
};

44 changes: 44 additions & 0 deletions tests/baselines/reference/typeNamedUndefined2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//// [tests/cases/compiler/typeNamedUndefined2.ts] ////

//// [typeNamedUndefined2.ts]
export namespace ns {
export namespace undefined {
export const s = Symbol();
export type undefined = typeof s;
};
export function x(p: undefined): undefined {
return p;
}
}

export function x(p: ns.undefined.undefined) {
return p;
}

export namespace undefined {
export const s = Symbol();
export type undefined = typeof s;
};


//// [typeNamedUndefined2.js]
export var ns;
(function (ns) {
let undefined;
(function (undefined) {
undefined.s = Symbol();
})(undefined = ns.undefined || (ns.undefined = {}));
;
function x(p) {
return p;
}
ns.x = x;
})(ns || (ns = {}));
export function x(p) {
return p;
}
export var undefined;
(function (undefined) {
undefined.s = Symbol();
})(undefined || (undefined = {}));
;
51 changes: 51 additions & 0 deletions tests/baselines/reference/typeNamedUndefined2.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//// [tests/cases/compiler/typeNamedUndefined2.ts] ////

=== typeNamedUndefined2.ts ===
export namespace ns {
>ns : Symbol(ns, Decl(typeNamedUndefined2.ts, 0, 0))

export namespace undefined {
>undefined : Symbol(undefined, Decl(typeNamedUndefined2.ts, 0, 21))

export const s = Symbol();
>s : Symbol(s, Decl(typeNamedUndefined2.ts, 2, 20))
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))

export type undefined = typeof s;
>undefined : Symbol(undefined, Decl(typeNamedUndefined2.ts, 2, 34))
>s : Symbol(s, Decl(typeNamedUndefined2.ts, 2, 20))

};
export function x(p: undefined): undefined {
>x : Symbol(x, Decl(typeNamedUndefined2.ts, 4, 6))
>p : Symbol(p, Decl(typeNamedUndefined2.ts, 5, 22))

return p;
>p : Symbol(p, Decl(typeNamedUndefined2.ts, 5, 22))
}
}

export function x(p: ns.undefined.undefined) {
>x : Symbol(x, Decl(typeNamedUndefined2.ts, 8, 1))
>p : Symbol(p, Decl(typeNamedUndefined2.ts, 10, 18))
>ns : Symbol(ns, Decl(typeNamedUndefined2.ts, 0, 0))
>undefined : Symbol(ns.undefined, Decl(typeNamedUndefined2.ts, 0, 21))
>undefined : Symbol(ns.undefined.undefined, Decl(typeNamedUndefined2.ts, 2, 34))

return p;
>p : Symbol(p, Decl(typeNamedUndefined2.ts, 10, 18))
}

export namespace undefined {
>undefined : Symbol(undefined, Decl(typeNamedUndefined2.ts, 12, 1))

export const s = Symbol();
>s : Symbol(s, Decl(typeNamedUndefined2.ts, 15, 16))
>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --))

export type undefined = typeof s;
>undefined : Symbol(undefined, Decl(typeNamedUndefined2.ts, 15, 30))
>s : Symbol(s, Decl(typeNamedUndefined2.ts, 15, 16))

};

52 changes: 52 additions & 0 deletions tests/baselines/reference/typeNamedUndefined2.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//// [tests/cases/compiler/typeNamedUndefined2.ts] ////

=== typeNamedUndefined2.ts ===
export namespace ns {
>ns : typeof ns

export namespace undefined {
>undefined : typeof undefined

export const s = Symbol();
>s : unique symbol
>Symbol() : unique symbol
>Symbol : SymbolConstructor

export type undefined = typeof s;
>undefined : unique symbol
>s : unique symbol

};
export function x(p: undefined): undefined {
>x : (p: undefined) => undefined
>p : undefined

return p;
>p : undefined
}
}

export function x(p: ns.undefined.undefined) {
>x : (p: ns.undefined.undefined) => symbol
>p : unique symbol
>ns : any
>undefined : any

return p;
>p : unique symbol
}

export namespace undefined {
>undefined : typeof undefined

export const s = Symbol();
>s : unique symbol
>Symbol() : unique symbol
>Symbol : SymbolConstructor

export type undefined = typeof s;
>undefined : unique symbol
>s : unique symbol

};

4 changes: 2 additions & 2 deletions tests/baselines/reference/undefinedTypeAssignment1.errors.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
undefinedTypeAssignment1.ts(1,6): error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
undefinedTypeAssignment1.ts(1,6): error TS2457: Type alias name cannot be 'undefined'.


==== undefinedTypeAssignment1.ts (1 errors) ====
type undefined = string;
~~~~~~~~~
!!! error TS2397: Declaration name conflicts with built-in global identifier 'undefined'.
!!! error TS2457: Type alias name cannot be 'undefined'.
function p(undefined = "wat") {
return undefined;
}
Expand Down
Loading