microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
101.02k stars 12.49k forks source link

Add capability of transforming and emitting JSDoc comments #17146

Open ghost opened 7 years ago

ghost commented 7 years ago

So I am trying to create a new documentation generator for TypeScript together with @BurtHarris. Currently it does not do much; I've been mainly tinkering a bit with the compiler API to see what it is capable of. You will be able to find it here when it's finished.

One of the things we thought about was the ability to 'target' JSDoc comments using the type information provided by TypeScript. I've been investigating how to tackle the issue. Ideally, it would use the transformers the compiler API has to offer but of all the functions provided in factory.ts, the ones that came closest were addSyntheticLeadingComment, setSyntheticLeadingComments, setSyntheticTrailingComments and addSyntheticTrailingComment; none of which provide the means to create complete synthetic JSDoc tags and comments.

So with this issue I'm actually asking the status-quo of this feature. Is it still possible to get this on the roadmap? If so, can I help? If not, is there a possibility of a patch that makes it possible to implement this as a third-party module?

Related issues

Previous attempts

ghost commented 7 years ago

I think we've found a way around it by using ts.createSynthesizedNode directly. Closing this issue for now.

ghost commented 7 years ago

I'm re-opening this as I would like to know if someone of the TypeScript team would accept pull requests for this feature. I've tried implementing it as a third-party module, but I need access to some private functions and currently it's not doable because JSDoc comments are not emitted (as far as I can see). I'm guessing this would require refactoring the comments.ts source file.

I also created a branch with a small example demonstrating how the explicit return type of a function could be added as a JSDoc comment.

rbuckton commented 7 years ago

We are discussing what changes we could make to comment emit to allow this. We already scan comments and often parse JSDoc comments for nodes. One option we are considering is reifying all comments in the compiler and storing them on Node, which we could then make accessible to transformers.

This would go a long way to simplifying comment emit in the emitter, but we need to balance this against the additional memory overhead associated with storing comment ranges for all nodes.

weswigham commented 6 years ago

@sandersn didn't you change our APIs recently to happen to fulfill this request?

liyikun commented 5 years ago

@rbuckton
Is there a new api to add the ast node of jsdoc?

liyikun commented 5 years ago

I think we've found a way around it by using ts.createSynthesizedNode directly. Closing this issue for now.

@samvv hi ,I am currently doing generate a ts code using JSON , I hope I can add jsdoc to ast node .but ts not support similar addSyntheticLeadingComment method, Do you have any good ideas here?

ghost commented 5 years ago

@liyikun Hmmm, been a while since I played with this. Unfortunately, I don't know how to create a synthetic node in the current version of TypeScript. I only know of https://github.com/microsoft/tsdoc, which covers my use-case.

Jack-Works commented 4 years ago

ts.createSynthesizedNode

Hmm sorry but it is no longer exists anymore. So how can I transform a JSDoc comment now?

alanhoff commented 4 years ago

it's possible to emit jsdoc nodes using ts.factory.createJSDocComment, example:

https://gist.github.com/alanhoff/b1a2ed871cf7046ca1f2f3c9e0bae1aa

nonara commented 4 years ago

it's possible to emit jsdoc nodes using ts.factory.createJSDocComment

Is this new as of TS 4? And are there any issues with transform?

bali182 commented 3 years ago

Any news on how to use JSDoc comments with the factory? Parsing seems to work very well,

https://astexplorer.net/#/gist/63752d280452826f4031882c9943cd1a/dd91c7dbc66f70466e50f72a13c9a322fbd2d220

But I have seen no way of attaching a JSDocComment node to another node. The only way that works for printing (that I found), is mixing the JSDocComments in with other nodes, but this gives type errors, and was told in #44151 that it's not the intended way to use them.

So is there any way to use JSDoc* nodes?

bali182 commented 3 years ago

Looking at the emitter source the JSDoc* stuff is emitted but the jsDoc field of the nodes not traversed (just what it seems at a first look).

Assigning the jsDoc property to a node doesn't seem to work either. This is what I tried:

function withJsDoc<T extends Node>(node: T, jsDoc: JSDoc): T {
  const anyNode = node as any
  anyNode.jsDoc = jsDoc
  return anyNode
}

const ast = factory.createTypeAliasDeclaration(
  undefined,
  undefined,
  factory.createIdentifier("Foo"),
  undefined,
  getRighthandSideTypeAst(...),
)

const astWithDoc = withJsDoc(ast, factory.createJSDocComment('foo'))

// print astWithDoc

rbuckton commented 3 years ago

JSDoc nodes aren't a formal part of the AST. Rather, they are an abstraction over leading and trailing trivia (including comments) purely to recognize JSDoc types. This allows us to avoid adding nodes to our tree for every comment, since they can be recovered by re-scanning the trivia of a node. As I mentioned in #44151, the best option I can think of would be to allow JSDoc nodes to be added via addSyntheticLeadingComment and related functions, so that they could be printed with the correct indentation during emit.

Danielku15 commented 4 months ago

I found this issue as a follow up on https://github.com/microsoft/TypeScript/issues/41486. I tried to create a custom transformer to rewrite my JSDocs. It might not be a nice JSDoc node style API, but it works to change the comments with with a afterDeclarations transformer using addSyntheticLeadingComment and setSyntheticLeadingComment.

But I face a significant problem: there is no beforeDeclarations transformer. A lot of the AST nodes have already been erased and I cannot obtain anymore the information I want to use for my JSDocs (PropertyDeclaration initializers).

I will try to open a PR adding a beforeDeclarations transformer feature. This would be at least a small step forward allowing some more meaningful JSDoc auto-generation use-cases.