Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
108 changes: 89 additions & 19 deletions internal/transformers/declarations/transform.go
Original file line number Diff line number Diff line change
Expand Up @@ -741,22 +741,28 @@ func (tx *DeclarationTransformer) transformPropertyDeclaration(input *ast.Proper
if ast.IsPrivateIdentifier(input.Name()) {
return nil
}
return tx.Factory().UpdatePropertyDeclaration(
result := tx.Factory().UpdatePropertyDeclaration(
input,
tx.ensureModifiers(input.AsNode()),
input.Name(),
input.PostfixToken,
tx.ensureType(input.AsNode(), false),
tx.ensureNoInitializer(input.AsNode()),
)
// Always remove all comments first, then preserve JSDoc if present
tx.removeAllComments(result)
if input.AsNode().Flags&ast.NodeFlagsHasJSDoc != 0 {
tx.preserveJsDoc(result, input.AsNode())
}
return result
}

func (tx *DeclarationTransformer) transformSetAccessorDeclaration(input *ast.SetAccessorDeclaration) *ast.Node {
if ast.IsPrivateIdentifier(input.Name()) {
return nil
}

return tx.Factory().UpdateSetAccessorDeclaration(
result := tx.Factory().UpdateSetAccessorDeclaration(
input,
tx.ensureModifiers(input.AsNode()),
input.Name(),
Expand All @@ -766,13 +772,19 @@ func (tx *DeclarationTransformer) transformSetAccessorDeclaration(input *ast.Set
nil,
nil,
)
// Always remove all comments first, then preserve JSDoc if present
tx.removeAllComments(result)
if input.AsNode().Flags&ast.NodeFlagsHasJSDoc != 0 {
tx.preserveJsDoc(result, input.AsNode())
}
return result
}

func (tx *DeclarationTransformer) transformGetAccesorDeclaration(input *ast.GetAccessorDeclaration) *ast.Node {
if ast.IsPrivateIdentifier(input.Name()) {
return nil
}
return tx.Factory().UpdateGetAccessorDeclaration(
result := tx.Factory().UpdateGetAccessorDeclaration(
input,
tx.ensureModifiers(input.AsNode()),
input.Name(),
Expand All @@ -782,6 +794,12 @@ func (tx *DeclarationTransformer) transformGetAccesorDeclaration(input *ast.GetA
nil,
nil,
)
// Always remove all comments first, then preserve JSDoc if present
tx.removeAllComments(result)
if input.AsNode().Flags&ast.NodeFlagsHasJSDoc != 0 {
tx.preserveJsDoc(result, input.AsNode())
}
return result
}

const defaultModifierFlagsMask = ast.ModifierFlagsAll ^ ast.ModifierFlagsPublic
Expand Down Expand Up @@ -825,7 +843,7 @@ func (tx *DeclarationTransformer) updateAccessorParamList(input *ast.Node, isPri

func (tx *DeclarationTransformer) transformConstructorDeclaration(input *ast.ConstructorDeclaration) *ast.Node {
// A constructor declaration may not have a type annotation
return tx.Factory().UpdateConstructorDeclaration(
result := tx.Factory().UpdateConstructorDeclaration(
input,
tx.ensureModifiers(input.AsNode()),
nil, // no type params
Expand All @@ -834,6 +852,12 @@ func (tx *DeclarationTransformer) transformConstructorDeclaration(input *ast.Con
nil,
nil,
)
// Always remove all comments first, then preserve JSDoc if present
tx.removeAllComments(result)
if input.AsNode().Flags&ast.NodeFlagsHasJSDoc != 0 {
tx.preserveJsDoc(result, input.AsNode())
}
return result
}

func (tx *DeclarationTransformer) transformConstructSignatureDeclaration(input *ast.ConstructSignatureDeclaration) *ast.Node {
Expand Down Expand Up @@ -883,7 +907,7 @@ func (tx *DeclarationTransformer) transformMethodDeclaration(input *ast.MethodDe
} else if ast.IsPrivateIdentifier(input.Name()) {
return nil
} else {
return tx.Factory().UpdateMethodDeclaration(
result := tx.Factory().UpdateMethodDeclaration(
input,
tx.ensureModifiers(input.AsNode()),
nil,
Expand All @@ -895,6 +919,12 @@ func (tx *DeclarationTransformer) transformMethodDeclaration(input *ast.MethodDe
nil,
nil,
)
// Always remove all comments first, then preserve JSDoc if present
tx.removeAllComments(result)
if input.AsNode().Flags&ast.NodeFlagsHasJSDoc != 0 {
tx.preserveJsDoc(result, input.AsNode())
}
return result
}
}

Expand Down Expand Up @@ -984,11 +1014,38 @@ func (tx *DeclarationTransformer) tryGetResolutionModeOverride(node *ast.Node) *
}

func (tx *DeclarationTransformer) preserveJsDoc(updated *ast.Node, original *ast.Node) {
// !!! TODO: JSDoc comment support
// if (hasJSDocNodes(updated) && hasJSDocNodes(original)) {
// updated.jsDoc = original.jsDoc;
// }
// return setCommentRange(updated, getCommentRange(original));
// Get the source file to access JSDoc cache
sourceFile := tx.state.currentSourceFile
if sourceFile == nil {
return
}

// Check if original node has JSDoc comments
if original.Flags&ast.NodeFlagsHasJSDoc == 0 {
return
}

// Get JSDoc from original node
jsdoc := original.JSDoc(sourceFile)
if len(jsdoc) == 0 {
return
}

// Copy JSDoc to the updated node
cache := sourceFile.JSDocCache()
if cache == nil {
cache = make(map[*ast.Node][]*ast.Node)
sourceFile.SetJSDocCache(cache)
}

// Set JSDoc on the updated node
cache[updated] = jsdoc
updated.Flags |= ast.NodeFlagsHasJSDoc

// If there was a deprecated tag, preserve that too
if original.Flags&ast.NodeFlagsDeprecated != 0 {
updated.Flags |= ast.NodeFlagsDeprecated
}
}

func (tx *DeclarationTransformer) removeAllComments(node *ast.Node) {
Expand Down Expand Up @@ -1383,27 +1440,40 @@ func (tx *DeclarationTransformer) transformClassDeclaration(input *ast.ClassDecl
}
heritageClauses := tx.Factory().NewNodeList(heritageList)

classDecl := tx.Factory().UpdateClassDeclaration(
input,
modifiers,
input.Name(),
typeParameters,
heritageClauses,
members,
)
// Always remove all comments first, then preserve JSDoc if present
tx.removeAllComments(classDecl)
if input.AsNode().Flags&ast.NodeFlagsHasJSDoc != 0 {
tx.preserveJsDoc(classDecl, input.AsNode())
}

return tx.Factory().NewSyntaxList([]*ast.Node{
statement,
tx.Factory().UpdateClassDeclaration(
input,
modifiers,
input.Name(),
typeParameters,
heritageClauses,
members,
),
classDecl,
})
}

return tx.Factory().UpdateClassDeclaration(
result := tx.Factory().UpdateClassDeclaration(
input,
modifiers,
input.Name(),
typeParameters,
tx.Visitor().VisitNodes(input.HeritageClauses),
members,
)
// Always remove all comments first, then preserve JSDoc if present
tx.removeAllComments(result)
if input.AsNode().Flags&ast.NodeFlagsHasJSDoc != 0 {
tx.preserveJsDoc(result, input.AsNode())
}
return result
}

func (tx *DeclarationTransformer) transformVariableStatement(input *ast.VariableStatement) *ast.Node {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//// [tests/cases/compiler/declarationEmitCommentsPreservation.ts] ////

//// [declarationEmitCommentsPreservation.ts]
// Comment
export class DbObject {
// Comment
id: string = ""; // Comment
// Comment
method() { }
}

//// [declarationEmitCommentsPreservation.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DbObject = void 0;
// Comment
class DbObject {
// Comment
id = ""; // Comment
// Comment
method() { }
}
exports.DbObject = DbObject;


//// [declarationEmitCommentsPreservation.d.ts]
export declare class DbObject {
id: string;
method(): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//// [tests/cases/compiler/declarationEmitCommentsPreservation.ts] ////

=== declarationEmitCommentsPreservation.ts ===
// Comment
export class DbObject {
>DbObject : Symbol(DbObject, Decl(declarationEmitCommentsPreservation.ts, 0, 0))

// Comment
id: string = ""; // Comment
>id : Symbol(DbObject.id, Decl(declarationEmitCommentsPreservation.ts, 1, 23))

// Comment
method() { }
>method : Symbol(DbObject.method, Decl(declarationEmitCommentsPreservation.ts, 3, 20))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//// [tests/cases/compiler/declarationEmitCommentsPreservation.ts] ////

=== declarationEmitCommentsPreservation.ts ===
// Comment
export class DbObject {
>DbObject : DbObject

// Comment
id: string = ""; // Comment
>id : string
>"" : ""

// Comment
method() { }
>method : () => void
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//// [tests/cases/compiler/declarationEmitCommentsWithJSDoc.ts] ////

//// [declarationEmitCommentsWithJSDoc.ts]
// Regular comment - should be removed
/**
* JSDoc comment - should be preserved
*/
export class DbObject {
// Regular comment - should be removed
/**
* JSDoc property comment
*/
id: string = ""; // Trailing comment - should be removed

// Regular comment - should be removed
/**
* JSDoc method comment
* @returns void
*/
method() { }
}

//// [declarationEmitCommentsWithJSDoc.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DbObject = void 0;
// Regular comment - should be removed
/**
* JSDoc comment - should be preserved
*/
class DbObject {
// Regular comment - should be removed
/**
* JSDoc property comment
*/
id = ""; // Trailing comment - should be removed
// Regular comment - should be removed
/**
* JSDoc method comment
* @returns void
*/
method() { }
}
exports.DbObject = DbObject;


//// [declarationEmitCommentsWithJSDoc.d.ts]
export declare class DbObject {
id: string;
method(): void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//// [tests/cases/compiler/declarationEmitCommentsWithJSDoc.ts] ////

=== declarationEmitCommentsWithJSDoc.ts ===
// Regular comment - should be removed
/**
* JSDoc comment - should be preserved
*/
export class DbObject {
>DbObject : Symbol(DbObject, Decl(declarationEmitCommentsWithJSDoc.ts, 0, 0))

// Regular comment - should be removed
/**
* JSDoc property comment
*/
id: string = ""; // Trailing comment - should be removed
>id : Symbol(DbObject.id, Decl(declarationEmitCommentsWithJSDoc.ts, 4, 23))

// Regular comment - should be removed
/**
* JSDoc method comment
* @returns void
*/
method() { }
>method : Symbol(DbObject.method, Decl(declarationEmitCommentsWithJSDoc.ts, 9, 20))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// [tests/cases/compiler/declarationEmitCommentsWithJSDoc.ts] ////

=== declarationEmitCommentsWithJSDoc.ts ===
// Regular comment - should be removed
/**
* JSDoc comment - should be preserved
*/
export class DbObject {
>DbObject : DbObject

// Regular comment - should be removed
/**
* JSDoc property comment
*/
id: string = ""; // Trailing comment - should be removed
>id : string
>"" : ""

// Regular comment - should be removed
/**
* JSDoc method comment
* @returns void
*/
method() { }
>method : () => void
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,27 +65,22 @@ export class PublicWithDefault {


//// [parameterPropertyWithDefaultValueExtended.d.ts]
// Test with default value - should not have undefined
export declare class WithDefault {
readonly timestamp: Date;
constructor(timestamp?: Date);
}
// Test without default value but optional - should have undefined
export declare class WithoutDefault {
readonly timestamp?: Date | undefined;
constructor(timestamp?: Date | undefined);
}
// Test with explicit undefined type - should keep it
export declare class ExplicitUndefined {
readonly timestamp: Date | undefined;
constructor(timestamp?: Date | undefined);
}
// Test private parameter property with default value
export declare class PrivateWithDefault {
private timestamp;
constructor(timestamp?: Date);
}
// Test public parameter property with default value
export declare class PublicWithDefault {
timestamp: Date;
constructor(timestamp?: Date);
Expand Down
Loading
Loading