Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix assertion functions accessed via wildcard imports #51324

Merged
merged 4 commits into from Oct 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/compiler/checker.ts
Expand Up @@ -24490,6 +24490,7 @@ namespace ts {
}

function getExplicitTypeOfSymbol(symbol: Symbol, diagnostic?: Diagnostic) {
symbol = resolveSymbol(symbol);
if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.ValueModule)) {
return getTypeOfSymbol(symbol);
}
Expand Down Expand Up @@ -24529,7 +24530,7 @@ namespace ts {
switch (node.kind) {
case SyntaxKind.Identifier:
const symbol = getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(node as Identifier));
return getExplicitTypeOfSymbol(symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol, diagnostic);
return getExplicitTypeOfSymbol(symbol, diagnostic);
case SyntaxKind.ThisKeyword:
return getExplicitThisType(node);
case SyntaxKind.SuperKeyword:
Expand Down
71 changes: 71 additions & 0 deletions tests/baselines/reference/assertionFunctionWildcardImport1.js
@@ -0,0 +1,71 @@
//// [tests/cases/compiler/assertionFunctionWildcardImport1.ts] ////

//// [ts.ts]
import * as Debug from "../debug";
export { Debug };

//// [debug.ts]
export declare function assert(expression: unknown): asserts expression;


//// [foo.ts]
import * as ts from "./_namespaces/ts";
import { Debug } from "./_namespaces/ts";

ts.Debug.assert(true);
Debug.assert(true);


//// [ts.ts]
export * from "../../core/_namespaces/ts"


//// [bar.ts]
import * as ts from "./_namespaces/ts";
import { Debug } from "./_namespaces/ts";

ts.Debug.assert(true);
Debug.assert(true);


//// [debug.js]
"use strict";
exports.__esModule = true;
//// [ts.js]
"use strict";
exports.__esModule = true;
exports.Debug = void 0;
var Debug = require("../debug");
exports.Debug = Debug;
//// [foo.js]
"use strict";
exports.__esModule = true;
var ts = require("./_namespaces/ts");
var ts_1 = require("./_namespaces/ts");
ts.Debug.assert(true);
ts_1.Debug.assert(true);
//// [ts.js]
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
exports.__esModule = true;
__exportStar(require("../../core/_namespaces/ts"), exports);
//// [bar.js]
"use strict";
exports.__esModule = true;
var ts = require("./_namespaces/ts");
var ts_1 = require("./_namespaces/ts");
ts.Debug.assert(true);
ts_1.Debug.assert(true);
58 changes: 58 additions & 0 deletions tests/baselines/reference/assertionFunctionWildcardImport1.symbols
@@ -0,0 +1,58 @@
=== tests/cases/compiler/src/core/_namespaces/ts.ts ===
import * as Debug from "../debug";
>Debug : Symbol(Debug, Decl(ts.ts, 0, 6))

export { Debug };
>Debug : Symbol(Debug, Decl(ts.ts, 1, 8))

=== tests/cases/compiler/src/core/debug.ts ===
export declare function assert(expression: unknown): asserts expression;
>assert : Symbol(assert, Decl(debug.ts, 0, 0))
>expression : Symbol(expression, Decl(debug.ts, 0, 31))
>expression : Symbol(expression, Decl(debug.ts, 0, 31))


=== tests/cases/compiler/src/core/foo.ts ===
import * as ts from "./_namespaces/ts";
>ts : Symbol(ts, Decl(foo.ts, 0, 6))

import { Debug } from "./_namespaces/ts";
>Debug : Symbol(Debug, Decl(foo.ts, 1, 8))

ts.Debug.assert(true);
>ts.Debug.assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))
>ts.Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
>ts : Symbol(ts, Decl(foo.ts, 0, 6))
>Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
>assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))

Debug.assert(true);
>Debug.assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))
>Debug : Symbol(Debug, Decl(foo.ts, 1, 8))
>assert : Symbol(ts.Debug.assert, Decl(debug.ts, 0, 0))


=== tests/cases/compiler/src/other/_namespaces/ts.ts ===

export * from "../../core/_namespaces/ts"


=== tests/cases/compiler/src/other/bar.ts ===
import * as ts from "./_namespaces/ts";
>ts : Symbol(ts, Decl(bar.ts, 0, 6))

import { Debug } from "./_namespaces/ts";
>Debug : Symbol(Debug, Decl(bar.ts, 1, 8))

ts.Debug.assert(true);
>ts.Debug.assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))
>ts.Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
>ts : Symbol(ts, Decl(bar.ts, 0, 6))
>Debug : Symbol(ts.Debug, Decl(ts.ts, 1, 8))
>assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))

Debug.assert(true);
>Debug.assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))
>Debug : Symbol(Debug, Decl(bar.ts, 1, 8))
>assert : Symbol(Debug.assert, Decl(debug.ts, 0, 0))

65 changes: 65 additions & 0 deletions tests/baselines/reference/assertionFunctionWildcardImport1.types
@@ -0,0 +1,65 @@
=== tests/cases/compiler/src/core/_namespaces/ts.ts ===
import * as Debug from "../debug";
>Debug : typeof Debug

export { Debug };
>Debug : typeof Debug

=== tests/cases/compiler/src/core/debug.ts ===
export declare function assert(expression: unknown): asserts expression;
>assert : (expression: unknown) => asserts expression
>expression : unknown


=== tests/cases/compiler/src/core/foo.ts ===
import * as ts from "./_namespaces/ts";
>ts : typeof ts

import { Debug } from "./_namespaces/ts";
>Debug : typeof ts.Debug

ts.Debug.assert(true);
>ts.Debug.assert(true) : void
>ts.Debug.assert : (expression: unknown) => asserts expression
>ts.Debug : typeof ts.Debug
>ts : typeof ts
>Debug : typeof ts.Debug
>assert : (expression: unknown) => asserts expression
>true : true

Debug.assert(true);
>Debug.assert(true) : void
>Debug.assert : (expression: unknown) => asserts expression
>Debug : typeof ts.Debug
>assert : (expression: unknown) => asserts expression
>true : true


=== tests/cases/compiler/src/other/_namespaces/ts.ts ===

export * from "../../core/_namespaces/ts"


=== tests/cases/compiler/src/other/bar.ts ===
import * as ts from "./_namespaces/ts";
>ts : typeof ts

import { Debug } from "./_namespaces/ts";
>Debug : typeof ts.Debug

ts.Debug.assert(true);
>ts.Debug.assert(true) : void
>ts.Debug.assert : (expression: unknown) => asserts expression
>ts.Debug : typeof ts.Debug
>ts : typeof ts
>Debug : typeof ts.Debug
>assert : (expression: unknown) => asserts expression
>true : true

Debug.assert(true);
>Debug.assert(true) : void
>Debug.assert : (expression: unknown) => asserts expression
>Debug : typeof ts.Debug
>assert : (expression: unknown) => asserts expression
>true : true

40 changes: 40 additions & 0 deletions tests/baselines/reference/assertionFunctionWildcardImport2.js
@@ -0,0 +1,40 @@
//// [tests/cases/compiler/assertionFunctionWildcardImport2.ts] ////

//// [asserts.ts]
function isNonNullable<T>(obj: T): asserts obj is NonNullable<T> {
if (obj === undefined || obj === null) {
throw new Error("Must not be a nullable value");
}
}

export {
isNonNullable
};

//// [test.ts]
import * as asserts from "./asserts";

function test(obj: string | null): void {
asserts.isNonNullable(obj);
obj.trim();
}


//// [asserts.js]
"use strict";
exports.__esModule = true;
exports.isNonNullable = void 0;
function isNonNullable(obj) {
if (obj === undefined || obj === null) {
throw new Error("Must not be a nullable value");
}
}
exports.isNonNullable = isNonNullable;
//// [test.js]
"use strict";
exports.__esModule = true;
var asserts = require("./asserts");
function test(obj) {
asserts.isNonNullable(obj);
obj.trim();
}
46 changes: 46 additions & 0 deletions tests/baselines/reference/assertionFunctionWildcardImport2.symbols
@@ -0,0 +1,46 @@
=== tests/cases/compiler/asserts.ts ===
function isNonNullable<T>(obj: T): asserts obj is NonNullable<T> {
>isNonNullable : Symbol(isNonNullable, Decl(asserts.ts, 0, 0))
>T : Symbol(T, Decl(asserts.ts, 0, 23))
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))
>T : Symbol(T, Decl(asserts.ts, 0, 23))
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))
>NonNullable : Symbol(NonNullable, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(asserts.ts, 0, 23))

if (obj === undefined || obj === null) {
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))
>undefined : Symbol(undefined)
>obj : Symbol(obj, Decl(asserts.ts, 0, 26))

throw new Error("Must not be a nullable value");
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
}
}

export {
isNonNullable
>isNonNullable : Symbol(isNonNullable, Decl(asserts.ts, 6, 8))

};

=== tests/cases/compiler/test.ts ===
import * as asserts from "./asserts";
>asserts : Symbol(asserts, Decl(test.ts, 0, 6))

function test(obj: string | null): void {
>test : Symbol(test, Decl(test.ts, 0, 37))
>obj : Symbol(obj, Decl(test.ts, 2, 14))

asserts.isNonNullable(obj);
>asserts.isNonNullable : Symbol(asserts.isNonNullable, Decl(asserts.ts, 6, 8))
>asserts : Symbol(asserts, Decl(test.ts, 0, 6))
>isNonNullable : Symbol(asserts.isNonNullable, Decl(asserts.ts, 6, 8))
>obj : Symbol(obj, Decl(test.ts, 2, 14))

obj.trim();
>obj.trim : Symbol(String.trim, Decl(lib.es5.d.ts, --, --))
>obj : Symbol(obj, Decl(test.ts, 2, 14))
>trim : Symbol(String.trim, Decl(lib.es5.d.ts, --, --))
}

50 changes: 50 additions & 0 deletions tests/baselines/reference/assertionFunctionWildcardImport2.types
@@ -0,0 +1,50 @@
=== tests/cases/compiler/asserts.ts ===
function isNonNullable<T>(obj: T): asserts obj is NonNullable<T> {
>isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>
>obj : T

if (obj === undefined || obj === null) {
>obj === undefined || obj === null : boolean
>obj === undefined : boolean
>obj : T
>undefined : undefined
>obj === null : boolean
>obj : T & ({} | null)
>null : null

throw new Error("Must not be a nullable value");
>new Error("Must not be a nullable value") : Error
>Error : ErrorConstructor
>"Must not be a nullable value" : "Must not be a nullable value"
}
}

export {
isNonNullable
>isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>

};

=== tests/cases/compiler/test.ts ===
import * as asserts from "./asserts";
>asserts : typeof asserts

function test(obj: string | null): void {
>test : (obj: string | null) => void
>obj : string | null
>null : null

asserts.isNonNullable(obj);
>asserts.isNonNullable(obj) : void
>asserts.isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>
>asserts : typeof asserts
>isNonNullable : <T>(obj: T) => asserts obj is NonNullable<T>
>obj : string | null

obj.trim();
>obj.trim() : string
>obj.trim : () => string
>obj : string
>trim : () => string
}

28 changes: 28 additions & 0 deletions tests/cases/compiler/assertionFunctionWildcardImport1.ts
@@ -0,0 +1,28 @@
// @strict: true

// @filename: src/core/_namespaces/ts.ts
import * as Debug from "../debug";
export { Debug };

// @filename: src/core/debug.ts
export declare function assert(expression: unknown): asserts expression;


// @filename: src/core/foo.ts
import * as ts from "./_namespaces/ts";
import { Debug } from "./_namespaces/ts";

ts.Debug.assert(true);
Debug.assert(true);


// @filename: src/other/_namespaces/ts.ts
export * from "../../core/_namespaces/ts"


// @filename: src/other/bar.ts
import * as ts from "./_namespaces/ts";
import { Debug } from "./_namespaces/ts";

ts.Debug.assert(true);
Debug.assert(true);