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

feat: support for class properties #47

Merged
merged 5 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ Parameters:
- `params.inputFiles`: The list of files to scan and for which the documentation should be build.
- `params.options`: Optional compiler options to generate the docs

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/lib/docs.ts#L402)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/lib/docs.ts#L426)

### :gear: documentationToMarkdown

Expand All @@ -164,7 +164,7 @@ Parameters:
- `params.entries`: The entries of the documentation (functions, constants and classes).
- `params.options`: Optional configuration to render the Markdown content. See `types.ts` for details.

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/lib/markdown.ts#L280)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/lib/markdown.ts#L293)

### :gear: generateDocumentation

Expand Down
27 changes: 25 additions & 2 deletions src/lib/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
isInterfaceDeclaration,
isMethodDeclaration,
isModuleDeclaration,
isPropertyDeclaration,
isPropertySignature,
isTypeAliasDeclaration,
isVariableStatement
Expand Down Expand Up @@ -117,7 +118,10 @@ const isNodeExportedOrPublic = (node: Node): boolean => {
const flags = getCombinedModifierFlags(node as Declaration);

// Check for '#' methods or properties
if (isMethodDeclaration(node) && node.name.kind === SyntaxKind.PrivateIdentifier) {
if (
(isMethodDeclaration(node) || isPropertyDeclaration(node)) &&
node.name.kind === SyntaxKind.PrivateIdentifier
) {
return false;
}

Expand Down Expand Up @@ -255,9 +259,24 @@ const visit = ({

const visitChild = (node: Node) => {
const docEntries: DocEntry[] = visit({node, checker, types, ...rest});

// We do not need to repeat the file name for class members
// eslint-disable-next-line @typescript-eslint/no-unused-vars
classEntry.methods?.push(...docEntries.map(({fileName: _, ...rest}) => rest));
const omitFilename = ({fileName: _, ...rest}: DocEntry): Omit<DocEntry, 'fileName'> => rest;

classEntry.methods?.push(
...docEntries
.filter(({doc_type}) => doc_type === 'method' || doc_type === 'function')
.map(omitFilename)
);

const properties = docEntries
.filter(({doc_type}) => doc_type === 'property')
.map(omitFilename);

if (properties.length > 0) {
classEntry.properties = [...(classEntry?.properties ?? []), ...properties];
}
};

forEachChild(node, visitChild);
Expand Down Expand Up @@ -286,6 +305,10 @@ const visit = ({
((arrowFunc as ArrowFunction).parent as VariableDeclaration).name
);
addDocEntry({symbol, doc_type: 'function', node: arrowFunc});
} else if (isPropertyDeclaration(node)) {
// We test for the property after the arrow function because a public property of a class can be an arrow function.
const symbol = checker.getSymbolAtLocation(node.name);
addDocEntry({symbol, doc_type: 'property', node});
} else if (isVariableStatement(node)) {
const {
declarationList: {declarations, flags}
Expand Down
43 changes: 28 additions & 15 deletions src/lib/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const classesToMarkdown = ({
entry: DocEntry;
} & Required<Pick<MarkdownOptions, 'headingLevel'>> &
Omit<MarkdownOptions, 'headingLevel'>): string => {
const {name, url, documentation, methods, constructors} = entry;
const {name, url, documentation, methods, properties, constructors} = entry;

const markdown: string[] = [`${headingLevel}${emojiTitle({emoji, key: 'classes'})} ${name}\n`];

Expand Down Expand Up @@ -70,22 +70,35 @@ const classesToMarkdown = ({
markdown.push('\n');
}

if (!methods || methods.length === 0) {
return markdown.join('\n');
if ((methods?.length ?? 0) > 0) {
markdown.push(`${headingLevel}# Methods\n`);
markdown.push(`${tableOfContent({entries: methods ?? [], emoji})}\n`);

// Explicitly do not pass repo to generate the source code link afterwards for the all block
markdown.push(
`${toMarkdown({
entries: methods ?? [],
headingLevel: `${headingLevel}#`,
docType: 'Method',
emoji
})}`
);
}

markdown.push(`${headingLevel}# Methods\n`);
markdown.push(`${tableOfContent({entries: methods ?? [], emoji})}\n`);
if ((properties?.length ?? 0) > 0) {
markdown.push(`${headingLevel}# Properties\n`);
markdown.push(`${tableOfContent({entries: properties ?? [], emoji})}\n`);

// Explicitly do not pass repo to generate the source code link afterwards for the all block
markdown.push(
`${toMarkdown({
entries: methods ?? [],
headingLevel: `${headingLevel}#`,
docType: 'Method',
emoji
})}\n`
);
// Explicitly do not pass repo to generate the source code link afterwards for the all block
markdown.push(
`${toMarkdown({
entries: properties ?? [],
headingLevel: `${headingLevel}#`,
docType: 'Property',
emoji
})}`
);
}

return markdown.join('\n');
};
Expand Down Expand Up @@ -151,7 +164,7 @@ const toMarkdown = ({
}: {
entries: DocEntry[];
headingLevel: MarkdownHeadingLevel | '####';
docType: 'Constant' | 'Function' | 'Method' | 'Type' | 'Enum';
docType: 'Constant' | 'Function' | 'Method' | 'Property' | 'Type' | 'Enum';
} & Pick<MarkdownOptions, 'emoji'>): string => {
const jsDocsToParams = (jsDocs: JSDocTagInfo[]): Params[] => {
const params: JSDocTagInfo[] = jsDocs.filter(({name}: JSDocTagInfo) => name === 'param');
Expand Down
1 change: 1 addition & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {CompilerOptions, JSDocTagInfo} from 'typescript';

export type DocEntryType =
| 'property'
| 'function'
| 'method'
| 'class'
Expand Down
2 changes: 1 addition & 1 deletion src/test/markdown.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('markdown', () => {
expect(markdown).toEqual(expectedDoc);
});

it.each([35, 101, 129])('should generate a markdown link to line %s', (line) => {
it.each([35, 118, 146])('should generate a markdown link to line %s', (line) => {
const doc = buildDocumentation({
inputFiles: ['./src/test/mock.ts'],
options: {
Expand Down
9 changes: 9 additions & 0 deletions src/test/mock.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@
"doc_type": "method"
}
],
"properties": [
{
"name": "publicShouldBeDocumented",
"documentation": "The documentation of the public property.",
"type": "string",
"jsDocs": [],
"doc_type": "property"
}
],
"fileName": "src/test/mock.ts"
},
{
Expand Down
37 changes: 24 additions & 13 deletions src/test/mock.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function submit() {
```


[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L221)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L238)


## :wrench: Constants
Expand Down Expand Up @@ -155,12 +155,25 @@ Public method.
| ---------- | ---------- |
| `shouldBeDocumented` | `() => void` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L80)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L97)

### Properties

- [publicShouldBeDocumented](#gear-publicshouldbedocumented)

#### :gear: publicShouldBeDocumented

The documentation of the public property.

| Property | Type |
| ---------- | ---------- |
| `publicShouldBeDocumented` | `string` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L80)

## :factory: SnsLedgerCanister

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L101)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L118)

### Constructors

Expand All @@ -181,7 +194,7 @@ This create function is public as well.
| ---------- | ---------- |
| `create` | `(options: { canisterId?: string or undefined; }) => SnsLedgerCanister` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L116)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L133)

#### :gear: metadata

Expand All @@ -191,12 +204,11 @@ The token metadata (name, symbol, etc.).
| ---------- | ---------- |
| `metadata` | `(params: QueryParams) => Promise<SnsTokenMetadataResponse>` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L125)

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L142)

## :factory: default

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L129)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L146)

### Methods

Expand All @@ -210,8 +222,7 @@ Description
| ---------- | ---------- |
| `bar` | `() => void` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L133)

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L150)

## :nut_and_bolt: Enum

Expand Down Expand Up @@ -281,7 +292,7 @@ A type yolo
| ---------- | ---------- |
| `yolo` | `'string'` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L158)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L175)

### :gear: Abc

Expand All @@ -291,21 +302,21 @@ A type yolo
| ---------- | ---------- |
| `Abc` | `Foo and {hello: string}` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L163)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L180)

### :gear: StorageConfigSourceGlob

| Type | Type |
| ---------- | ---------- |
| `StorageConfigSourceGlob` | |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L234)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L251)

### :gear: SatelliteConfig

| Type | Type |
| ---------- | ---------- |
| `SatelliteConfig` | `Either<SatelliteId, SatelliteIds> and CliConfig and SatelliteConfigOptions` |

[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L260)
[:link: Source](https://github.com/peterpeterparker/tsdoc-markdown/tree/main/src/test/mock.ts#L277)

17 changes: 17 additions & 0 deletions src/test/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ export class LedgerCanister {
return {icp: 1n};
};

/**
* The documentation of the public property.
*/
publicShouldBeDocumented = 'hello';

/**
* Private property.
* @private
*/
private privateShouldNoBeDocumented = 'hello';

/**
* Private property with a # identifier.
* @private
*/
#privateShouldNoBeDocumentedNeither = 'hello';

/**
* Public method.
*/
Expand Down