Skip to content

Commit

Permalink
Fixed declaration emit of object literals withs divergent accessors (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Oct 5, 2023
1 parent 5001433 commit 7377f5c
Show file tree
Hide file tree
Showing 14 changed files with 566 additions and 19 deletions.
40 changes: 36 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7292,6 +7292,30 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const propertyName = getPropertyNameNodeForSymbol(propertySymbol, context);
context.enclosingDeclaration = saveEnclosingDeclaration;
context.approximateLength += symbolName(propertySymbol).length + 1;

if (propertySymbol.flags & SymbolFlags.Accessor) {
const writeType = getWriteTypeOfSymbol(propertySymbol);
if (propertyType !== writeType) {
const getterDeclaration = getDeclarationOfKind<GetAccessorDeclaration>(propertySymbol, SyntaxKind.GetAccessor)!;
const getterSignature = getSignatureFromDeclaration(getterDeclaration);
typeElements.push(
setCommentRange(
signatureToSignatureDeclarationHelper(getterSignature, SyntaxKind.GetAccessor, context, { name: propertyName }) as GetAccessorDeclaration,
getterDeclaration,
),
);
const setterDeclaration = getDeclarationOfKind<SetAccessorDeclaration>(propertySymbol, SyntaxKind.SetAccessor)!;
const setterSignature = getSignatureFromDeclaration(setterDeclaration);
typeElements.push(
setCommentRange(
signatureToSignatureDeclarationHelper(setterSignature, SyntaxKind.SetAccessor, context, { name: propertyName }) as SetAccessorDeclaration,
setterDeclaration,
),
);
return;
}
}

const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined;
if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) {
const signatures = getSignaturesOfType(filterType(propertyType, t => !(t.flags & TypeFlags.Undefined)), SignatureKind.Call);
Expand Down Expand Up @@ -7332,9 +7356,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
typeElements.push(preserveCommentsOn(propertySignature));

function preserveCommentsOn<T extends Node>(node: T) {
if (some(propertySymbol.declarations, d => d.kind === SyntaxKind.JSDocPropertyTag)) {
const d = propertySymbol.declarations?.find(d => d.kind === SyntaxKind.JSDocPropertyTag)! as JSDocPropertyTag;
const commentText = getTextOfJSDocComment(d.comment);
const jsdocPropertyTag = propertySymbol.declarations?.find((d): d is JSDocPropertyTag => d.kind === SyntaxKind.JSDocPropertyTag);
if (jsdocPropertyTag) {
const commentText = getTextOfJSDocComment(jsdocPropertyTag.comment);
if (commentText) {
setSyntheticLeadingComments(node, [{ kind: SyntaxKind.MultiLineCommentTrivia, text: "*\n * " + commentText.replace(/\n/g, "\n * ") + "\n ", pos: -1, end: -1, hasTrailingNewLine: true }]);
}
Expand Down Expand Up @@ -9798,7 +9822,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
!(typeToSerialize.symbol && some(typeToSerialize.symbol.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) &&
!some(getPropertiesOfType(typeToSerialize), p => isLateBoundName(p.escapedName)) &&
!some(getPropertiesOfType(typeToSerialize), p => some(p.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) &&
every(getPropertiesOfType(typeToSerialize), p => isIdentifierText(symbolName(p), languageVersion));
every(getPropertiesOfType(typeToSerialize), p => {
if (!isIdentifierText(symbolName(p), languageVersion)) {
return false;
}
if (!(p.flags & SymbolFlags.Accessor)) {
return true;
}
return getNonMissingTypeOfSymbol(p) === getWriteTypeOfSymbol(p);
});
}

function makeSerializePropertySymbol<T extends Node>(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] ////

//// [declarationEmitObjectLiteralAccessors1.ts]
// same type accessors
export const obj1 = {
/** my awesome getter (first in source order) */
get x(): string {
return "";
},
/** my awesome setter (second in source order) */
set x(a: string) {},
};

// divergent accessors
export const obj2 = {
/** my awesome getter */
get x(): string {
return "";
},
/** my awesome setter */
set x(a: number) {},
};

export const obj3 = {
/** my awesome getter */
get x(): string {
return "";
},
};

export const obj4 = {
/** my awesome setter */
set x(a: number) {},
};




//// [declarationEmitObjectLiteralAccessors1.d.ts]
export declare const obj1: {
/** my awesome getter (first in source order) */
x: string;
};
export declare const obj2: {
/** my awesome getter */
get x(): string;
/** my awesome setter */
set x(a: number);
};
export declare const obj3: {
/** my awesome getter */
readonly x: string;
};
export declare const obj4: {
/** my awesome setter */
x: number;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] ////

=== declarationEmitObjectLiteralAccessors1.ts ===
// same type accessors
export const obj1 = {
>obj1 : Symbol(obj1, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 12))

/** my awesome getter (first in source order) */
get x(): string {
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 5, 4))

return "";
},
/** my awesome setter (second in source order) */
set x(a: string) {},
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 1, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 5, 4))
>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 7, 8))

};

// divergent accessors
export const obj2 = {
>obj2 : Symbol(obj2, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 12))

/** my awesome getter */
get x(): string {
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 15, 4))

return "";
},
/** my awesome setter */
set x(a: number) {},
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 11, 21), Decl(declarationEmitObjectLiteralAccessors1.ts, 15, 4))
>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 17, 8))

};

export const obj3 = {
>obj3 : Symbol(obj3, Decl(declarationEmitObjectLiteralAccessors1.ts, 20, 12))

/** my awesome getter */
get x(): string {
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 20, 21))

return "";
},
};

export const obj4 = {
>obj4 : Symbol(obj4, Decl(declarationEmitObjectLiteralAccessors1.ts, 27, 12))

/** my awesome setter */
set x(a: number) {},
>x : Symbol(x, Decl(declarationEmitObjectLiteralAccessors1.ts, 27, 21))
>a : Symbol(a, Decl(declarationEmitObjectLiteralAccessors1.ts, 29, 8))

};

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessors1.ts] ////

=== declarationEmitObjectLiteralAccessors1.ts ===
// same type accessors
export const obj1 = {
>obj1 : { x: string; }
>{ /** my awesome getter (first in source order) */ get x(): string { return ""; }, /** my awesome setter (second in source order) */ set x(a: string) {},} : { x: string; }

/** my awesome getter (first in source order) */
get x(): string {
>x : string

return "";
>"" : ""

},
/** my awesome setter (second in source order) */
set x(a: string) {},
>x : string
>a : string

};

// divergent accessors
export const obj2 = {
>obj2 : { get x(): string; set x(a: number); }
>{ /** my awesome getter */ get x(): string { return ""; }, /** my awesome setter */ set x(a: number) {},} : { get x(): string; set x(a: number); }

/** my awesome getter */
get x(): string {
>x : string

return "";
>"" : ""

},
/** my awesome setter */
set x(a: number) {},
>x : string
>a : number

};

export const obj3 = {
>obj3 : { readonly x: string; }
>{ /** my awesome getter */ get x(): string { return ""; },} : { readonly x: string; }

/** my awesome getter */
get x(): string {
>x : string

return "";
>"" : ""

},
};

export const obj4 = {
>obj4 : { x: number; }
>{ /** my awesome setter */ set x(a: number) {},} : { x: number; }

/** my awesome setter */
set x(a: number) {},
>x : number
>a : number

};

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//// [tests/cases/compiler/declarationEmitObjectLiteralAccessorsJs1.ts] ////

//// [index.js]
// same type accessors
export const obj1 = {
/**
* my awesome getter (first in source order)
* @returns {string}
*/
get x() {
return "";
},
/**
* my awesome setter (second in source order)
* @param {string} a
*/
set x(a) {},
};

// divergent accessors
export const obj2 = {
/**
* my awesome getter
* @returns {string}
*/
get x() {
return "";
},
/**
* my awesome setter
* @param {number} a
*/
set x(a) {},
};

export const obj3 = {
/**
* my awesome getter
* @returns {string}
*/
get x() {
return "";
},
};

export const obj4 = {
/**
* my awesome setter
* @param {number} a
*/
set x(a) {},
};




//// [index.d.ts]
export namespace obj1 {
let x: string;
}
export const obj2: {
/**
* my awesome getter
* @returns {string}
*/
get x(): string;
/**
* my awesome setter
* @param {number} a
*/
set x(a: number);
};
export namespace obj3 {
const x_1: string;
export { x_1 as x };
}
export namespace obj4 {
let x_2: number;
export { x_2 as x };
}

0 comments on commit 7377f5c

Please sign in to comment.