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

fix53287 mergeSymbol checks if the resolved target can merge with the source #58326

Merged
merged 4 commits into from May 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
19 changes: 16 additions & 3 deletions src/compiler/checker.ts
Expand Up @@ -2606,7 +2606,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (resolvedTarget === unknownSymbol) {
return source;
}
target = cloneSymbol(resolvedTarget);
if (
!(resolvedTarget.flags & getExcludedSymbolFlags(source.flags)) ||
(source.flags | resolvedTarget.flags) & SymbolFlags.Assignment
) {
target = cloneSymbol(resolvedTarget);
}
else {
reportMergeSymbolError(target, source);
return source;
}
}
// Javascript static-property-assignment declarations always merge, even though they are also values
if (source.flags & SymbolFlags.ValueModule && target.flags & SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
Expand Down Expand Up @@ -2642,7 +2651,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}
}
else { // error
else {
reportMergeSymbolError(target, source);
}
return target;

function reportMergeSymbolError(target: Symbol, source: Symbol) {
const isEitherEnum = !!(target.flags & SymbolFlags.Enum || source.flags & SymbolFlags.Enum);
const isEitherBlockScoped = !!(target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable);
const message = isEitherEnum ? Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations
Expand All @@ -2669,7 +2683,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!isTargetPlainJs) addDuplicateDeclarationErrorsForSymbols(target, message, symbolName, source);
}
}
return target;

function addDuplicateLocations(locs: Declaration[], symbol: Symbol): void {
if (symbol.declarations) {
Expand Down
12 changes: 8 additions & 4 deletions tests/baselines/reference/checkMergedGlobalUMDSymbol.errors.txt
@@ -1,21 +1,25 @@
global.d.ts(6,16): error TS2403: Subsequent variable declarations must have the same type. Variable 'THREE' must be of type 'typeof import("global")', but here has type 'typeof import("three")'.
global.d.ts(3,21): error TS2451: Cannot redeclare block-scoped variable 'THREE'.
global.d.ts(6,16): error TS2451: Cannot redeclare block-scoped variable 'THREE'.


==== three.d.ts (0 errors) ====
export namespace THREE {
export class Vector2 {}
}

==== global.d.ts (1 errors) ====
==== global.d.ts (2 errors) ====
import * as _three from './three';

export as namespace THREE;
~~~~~
!!! error TS2451: Cannot redeclare block-scoped variable 'THREE'.
!!! related TS6203 global.d.ts:6:16: 'THREE' was also declared here.

declare global {
export const THREE: typeof _three;
~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'THREE' must be of type 'typeof import("global")', but here has type 'typeof import("three")'.
!!! related TS6203 global.d.ts:1:1: 'THREE' was also declared here.
!!! error TS2451: Cannot redeclare block-scoped variable 'THREE'.
!!! related TS6203 global.d.ts:3:21: 'THREE' was also declared here.
}

==== test.ts (0 errors) ====
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/checkMergedGlobalUMDSymbol.symbols
Expand Up @@ -19,12 +19,12 @@ declare global {
>global : Symbol(global, Decl(global.d.ts, 2, 26))

export const THREE: typeof _three;
>THREE : Symbol(THREE, Decl(global.d.ts, 0, 0), Decl(global.d.ts, 5, 14))
>THREE : Symbol(THREE, Decl(global.d.ts, 5, 14))
>_three : Symbol(_three, Decl(global.d.ts, 0, 6))
}

=== test.ts ===
const m = THREE
>m : Symbol(m, Decl(test.ts, 0, 5))
>THREE : Symbol(THREE, Decl(global.d.ts, 0, 0), Decl(global.d.ts, 5, 14))
>THREE : Symbol(THREE, Decl(global.d.ts, 5, 14))

12 changes: 6 additions & 6 deletions tests/baselines/reference/checkMergedGlobalUMDSymbol.types
Expand Up @@ -24,16 +24,16 @@ declare global {
> : ^^^^^^^^^^^^^

export const THREE: typeof _three;
>THREE : typeof import("global")
> : ^^^^^^^^^^^^^^^^^^^^^^^
>THREE : typeof _three
> : ^^^^^^^^^^^^^
>_three : typeof _three
> : ^^^^^^^^^^^^^
}

=== test.ts ===
const m = THREE
>m : typeof import("global")
> : ^^^^^^^^^^^^^^^^^^^^^^^
>THREE : typeof import("global")
> : ^^^^^^^^^^^^^^^^^^^^^^^
>m : typeof import("three")
> : ^^^^^^^^^^^^^^^^^^^^^^
>THREE : typeof import("three")
> : ^^^^^^^^^^^^^^^^^^^^^^

47 changes: 47 additions & 0 deletions tests/baselines/reference/checkerInitializationCrash.errors.txt
@@ -0,0 +1,47 @@
/node_modules/@fullcalendar/core/index.d.ts(4,10): error TS2300: Duplicate identifier 'VNode'.
/node_modules/@fullcalendar/react/index.d.ts(4,19): error TS2300: Duplicate identifier 'VNode'.


==== /node_modules/@fullcalendar/react/index.d.ts (1 errors) ====
import * as react from 'react';
declare global {
namespace FullCalendarVDom {
export import VNode = react.ReactNode;
~~~~~
!!! error TS2300: Duplicate identifier 'VNode'.
!!! related TS6203 /node_modules/@fullcalendar/core/index.d.ts:4:10: 'VNode' was also declared here.
}
}

export default class FullCalendar {
}

==== /node_modules/@fullcalendar/core/index.d.ts (1 errors) ====
import * as preact from 'preact';
declare global {
namespace FullCalendarVDom {
type VNode = preact.VNode<any>;
~~~~~
!!! error TS2300: Duplicate identifier 'VNode'.
!!! related TS6203 /node_modules/@fullcalendar/react/index.d.ts:4:19: 'VNode' was also declared here.
}
}

export type EventInput = any;

==== /node_modules/@types/react/index.d.ts (0 errors) ====
export = React;
export as namespace React;
declare namespace React {
type ReactNode = any;
function useMemo<T>(factory: () => T, deps: undefined): T;
}

==== /node_modules/preact/index.d.ts (0 errors) ====
export as namespace preact;
export interface VNode<P = {}> {}

==== /index.tsx (0 errors) ====
import FullCalendar from "@fullcalendar/react";
import { EventInput } from "@fullcalendar/core";

6 changes: 3 additions & 3 deletions tests/baselines/reference/checkerInitializationCrash.symbols
Expand Up @@ -13,7 +13,7 @@ declare global {
export import VNode = react.ReactNode;
>VNode : Symbol(FullCalendarVDom.VNode, Decl(index.d.ts, 2, 30))
>react : Symbol(react, Decl(index.d.ts, 0, 6))
>ReactNode : Symbol(react.ReactNode, Decl(index.d.ts, 2, 25), Decl(index.d.ts, 2, 30))
>ReactNode : Symbol(react.ReactNode, Decl(index.d.ts, 2, 25))
}
}

Expand All @@ -32,7 +32,7 @@ declare global {
>FullCalendarVDom : Symbol(FullCalendarVDom, Decl(index.d.ts, 1, 16), Decl(index.d.ts, 1, 16))

type VNode = preact.VNode<any>;
>VNode : Symbol(React.ReactNode, Decl(index.d.ts, 2, 25), Decl(index.d.ts, 2, 30))
>VNode : Symbol(VNode, Decl(index.d.ts, 2, 30))
>preact : Symbol(preact, Decl(index.d.ts, 0, 6))
>VNode : Symbol(preact.VNode, Decl(index.d.ts, 0, 27))
}
Expand All @@ -52,7 +52,7 @@ declare namespace React {
>React : Symbol(React, Decl(index.d.ts, 1, 26))

type ReactNode = any;
>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 2, 25), Decl(index.d.ts, 2, 30))
>ReactNode : Symbol(ReactNode, Decl(index.d.ts, 2, 25))

function useMemo<T>(factory: () => T, deps: undefined): T;
>useMemo : Symbol(useMemo, Decl(index.d.ts, 3, 25))
Expand Down
5 changes: 4 additions & 1 deletion tests/baselines/reference/checkerInitializationCrash.types
Expand Up @@ -39,14 +39,16 @@ declare global {

namespace FullCalendarVDom {
type VNode = preact.VNode<any>;
>VNode : any
>VNode : VNode
> : ^^^^^
>preact : any
> : ^^^
}
}

export type EventInput = any;
>EventInput : any
> : ^^^

=== /node_modules/@types/react/index.d.ts ===
export = React;
Expand All @@ -63,6 +65,7 @@ declare namespace React {

type ReactNode = any;
>ReactNode : any
> : ^^^

function useMemo<T>(factory: () => T, deps: undefined): T;
>useMemo : <T>(factory: () => T, deps: undefined) => T
Expand Down
@@ -0,0 +1,33 @@
bar.d.ts(2,21): error TS2451: Cannot redeclare block-scoped variable 'foo'.
bar.d.ts(6,11): error TS2451: Cannot redeclare block-scoped variable 'foo'.
bar.d.ts(6,11): error TS2502: 'foo' is referenced directly or indirectly in its own type annotation.


==== bar.d.ts (3 errors) ====
import * as foo from './foo'
export as namespace foo
~~~
!!! error TS2451: Cannot redeclare block-scoped variable 'foo'.
!!! related TS6203 bar.d.ts:6:11: 'foo' was also declared here.
export = foo;

declare global {
const foo: typeof foo;
~~~
!!! error TS2451: Cannot redeclare block-scoped variable 'foo'.
!!! related TS6203 bar.d.ts:2:21: 'foo' was also declared here.
~~~
!!! error TS2502: 'foo' is referenced directly or indirectly in its own type annotation.
}

==== foo.d.ts (0 errors) ====
interface Root {
/**
* A .default property for ES6 default import compatibility
*/
default: Root;
}

declare const root: Root;
export = root;

Expand Up @@ -14,8 +14,8 @@ declare global {
>global : Symbol(global, Decl(bar.d.ts, 2, 13))

const foo: typeof foo;
>foo : Symbol(foo, Decl(foo.d.ts, 7, 13), Decl(bar.d.ts, 5, 9))
>foo : Symbol(foo, Decl(foo.d.ts, 7, 13), Decl(bar.d.ts, 5, 9))
>foo : Symbol(foo, Decl(bar.d.ts, 5, 9))
>foo : Symbol(foo, Decl(bar.d.ts, 5, 9))
}

=== foo.d.ts ===
Expand Down
Expand Up @@ -18,10 +18,10 @@ declare global {
> : ^^^^^^^^^^^^^

const foo: typeof foo;
>foo : Root
> : ^^^^
>foo : Root
> : ^^^^
>foo : any
> : ^^^
>foo : any
> : ^^^
}

=== foo.d.ts ===
Expand Down
@@ -1,8 +1,9 @@
input.ts(1,1): error TS2309: An export assignment cannot be used in a module with other exported elements.
input.ts(6,14): error TS2323: Cannot redeclare exported variable 'Sub'.
input.ts(6,14): error TS2300: Duplicate identifier 'Sub'.
input.ts(12,14): error TS2300: Duplicate identifier 'Sub'.


==== input.ts (2 errors) ====
==== input.ts (3 errors) ====
export = exports;
~~~~~~~~~~~~~~~~~
!!! error TS2309: An export assignment cannot be used in a module with other exported elements.
Expand All @@ -12,11 +13,15 @@ input.ts(6,14): error TS2323: Cannot redeclare exported variable 'Sub'.
}
export class Sub {
~~~
!!! error TS2323: Cannot redeclare exported variable 'Sub'.
!!! error TS2300: Duplicate identifier 'Sub'.
!!! related TS6203 input.ts:12:14: 'Sub' was also declared here.
instance!: {
t: number;
};
}
declare namespace exports {
export { Sub };
~~~
!!! error TS2300: Duplicate identifier 'Sub'.
!!! related TS6203 input.ts:6:14: 'Sub' was also declared here.
}
Expand Up @@ -14,7 +14,7 @@ declare class exports {
>t : Symbol(exports.t, Decl(input.ts, 2, 27))
}
export class Sub {
>Sub : Symbol(Sub, Decl(input.ts, 4, 1), Decl(input.ts, 4, 1))
>Sub : Symbol(Sub, Decl(input.ts, 4, 1))

instance!: {
>instance : Symbol(Sub.instance, Decl(input.ts, 5, 18))
Expand Down
Expand Up @@ -36,6 +36,6 @@ declare namespace exports {
> : ^^^^^^^^^^^^^^

export { Sub };
>Sub : typeof import("input").Sub
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^
>Sub : typeof Sub
> : ^^^^^^^^^^
}