Fix JS declaration emit for acessors in a class/interface merge (#40456)

This commit is contained in:
Wesley Wigham
2020-09-10 10:39:41 -07:00
committed by GitHub
parent 156cb4c1f9
commit 683979246f
5 changed files with 270 additions and 2 deletions

View File

@@ -6354,7 +6354,8 @@ namespace ts {
if ((symbol.flags & (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) && (!isConstMergedWithNS || isTypeOnlyNamespace(symbol))) || isConstMergedWithNSPrintableAsSignatureMerge) {
serializeModule(symbol, symbolName, modifierFlags);
}
if (symbol.flags & SymbolFlags.Interface) {
// The class meaning serialization should handle serializing all interface members
if (symbol.flags & SymbolFlags.Interface && !(symbol.flags & SymbolFlags.Class)) {
serializeInterface(symbol, symbolName, modifierFlags);
}
if (symbol.flags & SymbolFlags.Alias) {
@@ -7040,7 +7041,7 @@ namespace ts {
}
// This is an else/if as accessors and properties can't merge in TS, but might in JS
// If this happens, we assume the accessor takes priority, as it imposes more constraints
else if (p.flags & (SymbolFlags.Property | SymbolFlags.Variable)) {
else if (p.flags & (SymbolFlags.Property | SymbolFlags.Variable | SymbolFlags.Accessor)) {
return setTextRange(createProperty(
/*decorators*/ undefined,
factory.createModifiersFromModifierFlags((isReadonlySymbol(p) ? ModifierFlags.Readonly : 0) | flag),

View File

@@ -0,0 +1,89 @@
//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsClassAccessor.ts] ////
//// [supplement.d.ts]
export { };
declare module "./argument.js" {
interface Argument {
idlType: any;
default: null;
}
}
//// [base.js]
export class Base {
constructor() { }
toJSON() {
const json = { type: undefined, name: undefined, inheritance: undefined };
return json;
}
}
//// [argument.js]
import { Base } from "./base.js";
export class Argument extends Base {
/**
* @param {*} tokeniser
*/
static parse(tokeniser) {
return;
}
get type() {
return "argument";
}
/**
* @param {*} defs
*/
*validate(defs) { }
}
//// [base.js]
export class Base {
constructor() { }
toJSON() {
const json = { type: undefined, name: undefined, inheritance: undefined };
return json;
}
}
//// [argument.js]
import { Base } from "./base.js";
export class Argument extends Base {
/**
* @param {*} tokeniser
*/
static parse(tokeniser) {
return;
}
get type() {
return "argument";
}
/**
* @param {*} defs
*/
*validate(defs) { }
}
//// [base.d.ts]
export class Base {
toJSON(): {
type: any;
name: any;
inheritance: any;
};
}
//// [argument.d.ts]
export class Argument extends Base {
/**
* @param {*} tokeniser
*/
static parse(tokeniser: any): void;
get type(): string;
/**
* @param {*} defs
*/
validate(defs: any): Generator<never, void, unknown>;
idlType: any;
default: null;
}
import { Base } from "./base.js";

View File

@@ -0,0 +1,68 @@
=== tests/cases/conformance/jsdoc/declarations/supplement.d.ts ===
export { };
declare module "./argument.js" {
>"./argument.js" : Symbol("tests/cases/conformance/jsdoc/declarations/argument", Decl(argument.js, 0, 0), Decl(supplement.d.ts, 0, 11))
interface Argument {
>Argument : Symbol(Argument, Decl(argument.js, 0, 33), Decl(supplement.d.ts, 1, 32))
idlType: any;
>idlType : Symbol(Argument.idlType, Decl(supplement.d.ts, 2, 24))
default: null;
>default : Symbol(Argument.default, Decl(supplement.d.ts, 3, 21))
}
}
=== tests/cases/conformance/jsdoc/declarations/base.js ===
export class Base {
>Base : Symbol(Base, Decl(base.js, 0, 0))
constructor() { }
toJSON() {
>toJSON : Symbol(Base.toJSON, Decl(base.js, 1, 21))
const json = { type: undefined, name: undefined, inheritance: undefined };
>json : Symbol(json, Decl(base.js, 4, 13))
>type : Symbol(type, Decl(base.js, 4, 22))
>undefined : Symbol(undefined)
>name : Symbol(name, Decl(base.js, 4, 39))
>undefined : Symbol(undefined)
>inheritance : Symbol(inheritance, Decl(base.js, 4, 56))
>undefined : Symbol(undefined)
return json;
>json : Symbol(json, Decl(base.js, 4, 13))
}
}
=== tests/cases/conformance/jsdoc/declarations/argument.js ===
import { Base } from "./base.js";
>Base : Symbol(Base, Decl(argument.js, 0, 8))
export class Argument extends Base {
>Argument : Symbol(Argument, Decl(argument.js, 0, 33), Decl(supplement.d.ts, 1, 32))
>Base : Symbol(Base, Decl(argument.js, 0, 8))
/**
* @param {*} tokeniser
*/
static parse(tokeniser) {
>parse : Symbol(Argument.parse, Decl(argument.js, 1, 36))
>tokeniser : Symbol(tokeniser, Decl(argument.js, 5, 17))
return;
}
get type() {
>type : Symbol(Argument.type, Decl(argument.js, 7, 5))
return "argument";
}
/**
* @param {*} defs
*/
*validate(defs) { }
>validate : Symbol(Argument.validate, Decl(argument.js, 11, 5))
>defs : Symbol(defs, Decl(argument.js, 16, 14))
}

View File

@@ -0,0 +1,69 @@
=== tests/cases/conformance/jsdoc/declarations/supplement.d.ts ===
export { };
declare module "./argument.js" {
>"./argument.js" : typeof import("tests/cases/conformance/jsdoc/declarations/argument")
interface Argument {
idlType: any;
>idlType : any
default: null;
>default : null
>null : null
}
}
=== tests/cases/conformance/jsdoc/declarations/base.js ===
export class Base {
>Base : Base
constructor() { }
toJSON() {
>toJSON : () => { type: any; name: any; inheritance: any; }
const json = { type: undefined, name: undefined, inheritance: undefined };
>json : { type: any; name: any; inheritance: any; }
>{ type: undefined, name: undefined, inheritance: undefined } : { type: undefined; name: undefined; inheritance: undefined; }
>type : undefined
>undefined : undefined
>name : undefined
>undefined : undefined
>inheritance : undefined
>undefined : undefined
return json;
>json : { type: any; name: any; inheritance: any; }
}
}
=== tests/cases/conformance/jsdoc/declarations/argument.js ===
import { Base } from "./base.js";
>Base : typeof Base
export class Argument extends Base {
>Argument : Argument
>Base : Base
/**
* @param {*} tokeniser
*/
static parse(tokeniser) {
>parse : (tokeniser: any) => void
>tokeniser : any
return;
}
get type() {
>type : string
return "argument";
>"argument" : "argument"
}
/**
* @param {*} defs
*/
*validate(defs) { }
>validate : (defs: any) => Generator<never, void, unknown>
>defs : any
}

View File

@@ -0,0 +1,41 @@
// @allowJs: true
// @checkJs: true
// @target: es2019
// @outDir: ./out
// @declaration: true
// @filename: supplement.d.ts
export { };
declare module "./argument.js" {
interface Argument {
idlType: any;
default: null;
}
}
// @filename: base.js
export class Base {
constructor() { }
toJSON() {
const json = { type: undefined, name: undefined, inheritance: undefined };
return json;
}
}
// @filename: argument.js
import { Base } from "./base.js";
export class Argument extends Base {
/**
* @param {*} tokeniser
*/
static parse(tokeniser) {
return;
}
get type() {
return "argument";
}
/**
* @param {*} defs
*/
*validate(defs) { }
}