Skip to content

Commit

Permalink
chore: fix links due to ts upgrade (#5825)
Browse files Browse the repository at this point in the history
# Pull Request

## 📖 Description

The Typescript version upgrade changes how it handles the @link JSDOC tag in comments causing them to be removed when the CEM Analyzer process the code. This results in the link URLs and text being rendered to markdown in such a way that they cannot be corrected into markdown links. This PR adds a CEM Analyzer plugin that checks for the existence of @link tags in the descriptions generated by "comment-parser" and retains the original text.

<!---
Provide some background and a description of your work.
What problem does this change solve?
Is this a breaking change, chore, fix, feature, etc?
-->

### 🎫 Issues

<!---
* List and link relevant issues here.
-->

## 👩‍💻 Reviewer Notes

<!---
Provide some notes for reviewers to help them provide targeted feedback and testing.

Do you recommend a smoke test for this PR? What steps should be followed?
Are there particular areas of the code the reviewer should focus on?
-->

## 📑 Test Plan

<!---
Please provide a summary of the tests affected by this work and any unique strategies employed in testing the features/fixes.
-->

## ✅ Checklist

### General

<!--- Review the list and put an x in the boxes that apply. -->

- [ ] I have included a change request file using `$ yarn change`
- [ ] I have added tests for my changes.
- [x] I have tested my changes.
- [ ] I have updated the project documentation to reflect my changes.
- [ ] I have read the [CONTRIBUTING](https://github.com/Microsoft/fast/blob/master/CONTRIBUTING.md) documentation and followed the [standards](https://www.fast.design/docs/community/code-of-conduct/#our-standards) for this project.

### Component-specific

<!--- Review the list and put an x in the boxes that apply. -->
<!--- Remove this section if not applicable. -->

- [ ] I have added a new component
- [ ] I have modified an existing component
- [ ] I have updated the [definition file](https://github.com/Microsoft/fast/blob/master/packages/web-components/fast-components/CONTRIBUTING.md#definition)
- [ ] I have updated the [configuration file](https://github.com/Microsoft/fast/blob/master/packages/web-components/fast-components/CONTRIBUTING.md#configuration)

## ⏭ Next Steps

<!---
If there is relevant follow-up work to this PR, please list any existing issues or provide brief descriptions of what you would like to do next.
-->
  • Loading branch information
williamw2 authored Apr 11, 2022
1 parent b836568 commit 74102a3
Show file tree
Hide file tree
Showing 17 changed files with 298 additions and 153 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { getClassMemberDoc } from "@custom-elements-manifest/analyzer/src/utils/manifest-helpers.js";
import { parse } from "comment-parser";

/**
* Code for this plugin was mostly copied from: https://github.com/bennypowers/cem-plugins/tree/main/plugins/cem-plugin-jsdoc-example
*/

/**
* Does the AST node have JSDoc tags?
* @template {import('typescript').Node} N
* @param {N} node
* @return {node is N & { jsDoc: import('typescript').JSDoc[] }}
*/
function hasJsDocComments(node) {
return "jsDoc" in node;
}

/**
* Given a manifest and a declaration name, get the declaration doc
* @param {Partial<import("custom-elements-manifest/schema").Module>} moduleDoc
* @param {string} name
* @return {import("custom-elements-manifest/schema").Declaration}
*/
function getDeclarationDoc(moduleDoc, name) {
return moduleDoc.declarations.find(x => x.name === name);
}

/**
* Fix a Node's JSDoc link comments
* @param {import('typescript').Node & { jsDoc: import('typescript').JSDoc[] }} node
* @param {import("custom-elements-manifest/schema").Declaration} doc
* @param {*} context
* @param {number} [offset=0]
*/
function fixLinks(node, doc, context, offset = 0) {
node?.jsDoc?.forEach(jsDoc => {
const parsed = parse(jsDoc?.getFullText());
parsed?.forEach(parsedJsDoc => {
if (
parsedJsDoc.description &&
parsedJsDoc.description.indexOf("{@link") >= 0
) {
doc.description = parsedJsDoc.description.trim();
}
});
});
}

/**
* @return {import('@custom-elements-manifest/analyzer').Plugin}
*/
export function jsdocLinkFix() {
return {
name: "jsdoc-example",
analyzePhase({ ts, node, moduleDoc, context }) {
if (!hasJsDocComments(node)) return;
if (ts.isClassDeclaration(node)) {
const className = node.name.getText();
const classDoc = getDeclarationDoc(moduleDoc, className);
if (!classDoc)
return (
context.dev &&
console.warn(
`[jsdoc-example]: Could not find class ${className} in module doc for path ${moduleDoc.path}`
)
);
fixLinks(node, classDoc, context);
} else if (ts.isPropertyDeclaration(node)) {
const propertyName = node.name.getText();
const className = node.parent?.name?.getText?.();
const classDoc = getDeclarationDoc(moduleDoc, className);
if (!classDoc) return;
const isStatic = node.modifiers?.some?.(
x => x.kind === ts.SyntaxKind.StaticKeyword
);
const propertyDoc = getClassMemberDoc(
moduleDoc,
className,
propertyName,
isStatic
);
if (!propertyDoc)
return (
context.dev &&
console.warn(
`[jsdoc-example]: Could not find property ${propertyName} of ${className} in module doc for path ${moduleDoc.path}`
)
);
fixLinks(node, propertyDoc, context, 1);
} else if (ts.isMethodDeclaration(node)) {
if (!ts.isClassDeclaration(node.parent)) return;
const methodName = node.name.getText();
const className = node.parent.name.getText();
const classDoc = getDeclarationDoc(moduleDoc, className);
if (!classDoc) return;
const isStatic = node.modifiers?.some?.(
x => x.kind === ts.SyntaxKind.StaticKeyword
);
const methodDoc = getClassMemberDoc(
moduleDoc,
className,
methodName,
isStatic
);
if (!methodDoc)
return (
context.dev &&
console.warn(
`[jsdoc-example]: Could not find method ${methodName} of ${className} in module doc for path ${moduleDoc.path}`
)
);
fixLinks(node, methodDoc, context, 1);
} else if (ts.isFunctionDeclaration(node)) {
const functionName = node.name.getText();
const functionDoc = getDeclarationDoc(moduleDoc, functionName);
if (!functionDoc)
return (
context.dev &&
console.warn(
`[jsdoc-example]: Could not find function ${functionName} in module doc for path ${moduleDoc.path}`
)
);
fixLinks(node, functionDoc, context);
} else if (ts.isVariableStatement(node)) {
node.declarationList?.declarations.forEach(dec => {
const name = dec.name.getText();
const doc = getDeclarationDoc(moduleDoc, name);
if (!doc)
return (
context.dev &&
console.warn(
`[jsdoc-example]: Could not find variable ${name} in module doc for path ${moduleDoc.path}`
)
);
fixLinks(node, doc, context);
});
}
},
};
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {jsdocLinkFix} from "./custom-elements-manifest-plugins.mjs";

export default {
/** Globs to analyze */
globs: ['src/**/*.ts'],
Expand All @@ -9,4 +11,7 @@ export default {
dev: false,
/** Enable special handling for fast */
fast: true,
plugins: [
jsdocLinkFix(),
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ export const myAccordionItem = AccordionItem.compose<AccordionItemOptions>({

| Name | Privacy | Type | Default | Description | Inherited From |
| --------------- | ------- | ------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `headinglevel` | public | `1 or 2 or 3 or 4 or 5 or 6` | `2` | Configures the https://www.w3.org/TR/wai-aria-1.1/#aria-level or level of the heading element. | |
| `headinglevel` | public | `1 or 2 or 3 or 4 or 5 or 6` | `2` | Configures the [level](https://www.w3.org/TR/wai-aria-1.1/#aria-level) of the heading element. | |
| `expanded` | public | `boolean` | `false` | Expands or collapses the item. | |
| `id` | public | `string` | | The item ID | |
| `$presentation` | public | `ComponentPresentation or null` | | A property which resolves the ComponentPresentation instance for the current component. | FoundationElement |
Expand Down
16 changes: 8 additions & 8 deletions packages/web-components/fast-foundation/src/anchor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ This component is built with the expectation that focus is delegated to the anch

| Name | Privacy | Type | Default | Description | Inherited From |
| ---------------- | ------- | -------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `download` | public | `string` | | Prompts the user to save the linked URL. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `href` | public | `string` | | The URL the hyperlink references. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `ping` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `referrerpolicy` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `rel` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `target` | public | `"_self" or "_blank" or "_parent" or "_top"` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `type` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | |
| `download` | public | `string` | | Prompts the user to save the linked URL. See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `href` | public | `string` | | The URL the hyperlink references. See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `ping` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `referrerpolicy` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `rel` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `target` | public | `"_self" or "_blank" or "_parent" or "_top"` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `type` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | |
| `control` | public | `HTMLAnchorElement` | | References the root element | |
| `$presentation` | public | `ComponentPresentation or null` | | A property which resolves the ComponentPresentation instance for the current component. | FoundationElement |
| `template` | public | `ElementViewTemplate or void or null` | | Sets the template of the element instance. When undefined, the element will attempt to resolve the template from the associated presentation or custom element definition. | FoundationElement |
Expand Down
16 changes: 8 additions & 8 deletions packages/web-components/fast-foundation/src/breadcrumb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,14 @@ This component is built with the expectation that focus is delegated to the anch

| Name | Privacy | Type | Default | Description | Inherited From |
| ---------------- | ------- | -------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `download` | public | `string` | | Prompts the user to save the linked URL. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `href` | public | `string` | | The URL the hyperlink references. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `ping` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `referrerpolicy` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `rel` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `target` | public | `"_self" or "_blank" or "_parent" or "_top"` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `type` | public | `string` | | See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a or `<a>` element for more information. | Anchor |
| `download` | public | `string` | | Prompts the user to save the linked URL. See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `href` | public | `string` | | The URL the hyperlink references. See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `hreflang` | public | `string` | | Hints at the language of the referenced resource. See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `ping` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `referrerpolicy` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `rel` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `target` | public | `"_self" or "_blank" or "_parent" or "_top"` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `type` | public | `string` | | See [`<a>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) for more information. | Anchor |
| `control` | public | `HTMLAnchorElement` | | References the root element | Anchor |
| `$presentation` | public | `ComponentPresentation or null` | | A property which resolves the ComponentPresentation instance for the current component. | FoundationElement |
| `template` | public | `ElementViewTemplate or void or null` | | Sets the template of the element instance. When undefined, the element will attempt to resolve the template from the associated presentation or custom element definition. | FoundationElement |
Expand Down
Loading

0 comments on commit 74102a3

Please sign in to comment.