astexplorer icon indicating copy to clipboard operation
astexplorer copied to clipboard

tslint rules unable to operate on JSX nodes

Open cucumbur opened this issue 5 years ago • 2 comments

Describe the bug I'm not sure this is a bug, it's also possible that it might be misunderstanding thing about how the tool / the TS/JS parsing and transforming works. I work on a project with custom tslint rules enabled for it, and - like with tslint-react - I can use the JSX parts of the typescript API, like ts.SyntaxKind.JsxElement. For non-JSX rules, I can use ASTexplorer to develop or play around with rules to understand them, but when the rule has JSX, I can't work with JSX nodes, despite it showing up in the parsing tree.

To Reproduce Steps to reproduce the behavior:

  1. Select JavaScript as the language, typescript as the parser, and tslint as the transform. Enable jsx under the typescript options.
  2. Enter JSX (React, in this case) code into the upper left code window, and enter a rule in the bottom code window. The rule has some type of walker that attempts to compare the node's kind with ts.SyntaxKind.JsxOpeningElement (or any other JSX type of element). (In this specific case, I am just trying to mark every single JSXOpeningElement as a failure).

Expected behavior The lint rule will output linting errors at several spots - one at every node that is a JsxOpeningElement

Browser (please complete the following information):

  • OS: macOS 10.14.16
  • Browser Chrome, Firefox
  • Version: Chrome 80.0.3987.106 , Firefox 73.0.1

astexplorer settings:

  • Selected parser: typescript
  • Selected transformer: tslint
  • Contents of the local storage key explorerSettingsV1 (code can be removed if you don't want it to be public

{“showTransformPanel”:true,”parserSettings”:{},”parserPerCategory”:{“javascript”:”typescript”},”workbench”:{“parser”:”typescript”,”code”:”import * as React from ‘react’;\nimport { Image, StyleSheet, Text, View } from ‘react-native’;\nimport { Constants } from ‘../utils/Constants’;\nimport { GreenCheckMark } from ‘./Svgs’;\n\ninterface IProps {\n\tproductName: string;\n\tproductImage: any;\n}\n\nexport class HeaderView extends React.PureComponent<IProps> {\n\tpublic render() {\n\t\tconst { width, height, url } = this.props.productImage;\n\t\tconst productName = this.props.productName;\n\t\treturn productName ? (\n\t\t\t<View style={styles.container} testID=\”rn-eao-header\”>\n\t\t\t\t<GreenCheckMark height={24} width={24} style={styles.checkMarkImage} />\n\t\t\t\t{this.renderItemImage(width, height, url)}\n\t\t\t\t<View style={{ flex: 1 }}>\n\t\t\t\t\t<Text style={styles.headerText}>{Constants.Strings.AddedToCart}</Text>\n\t\t\t\t\t<Text style={styles.productNameText}>\n\t\t\t\t\t\t{productName}\n\t\t\t\t\t</Text>\n\t\t\t\t</View>\n\t\t\t</View>\n\t\t) : null;\n\t}\n}”,”keyMap”:”default”,”transform”:{“code”:”export class Rule extends Lint.Rules.AbstractRule {\n public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {\n return this.applyWithFunction(sourceFile, walk)\n }\n}\n\nfunction walk(ctx: Lint.WalkContext<void>): void {\n return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {\n if (node.kind === ts.SyntaxKind.JsxOpeningElement) {\n ctx.addFailureAtNode(node, ‘Is JSX Opening Element’)\n }\n return ts.forEachChild(node, cb)\n })\n}”,”transformer”:”tslint”}}}

Additional context Here is a link to the astexplorer gist: https://astexplorer.net/#/gist/823ef688a15c814776ecbbc51853bb86/3860d4a67443e1a8a095b82dfe18c230bbd87ac3

cucumbur avatar Mar 03 '20 19:03 cucumbur

Update: I have discovered why this happens. It is due to the filename astexplorer.ts being hardcoded in the tslint transformer. When the typescript option for JSX is selected on the website, the JSX preserve compiler setting is enabled in the typescript parser, and when enabled it saves as astExplorer.tsx. However, the tslint transformer solely gets astExplorer.ts, no matter what the settings of the parser are. This means that the tslint rule is actually running on previous code before the JSX option was turned on, if any at all.

I will try and see if I can make a PR with a fix - I know the transformer and parser are more or less disconnected, but I imagine there is some way to switch based on the jsx options.

cucumbur avatar Mar 03 '20 22:03 cucumbur

Thank you for the analysis, that's an interesting find. A PR would be appreciated!

fkling avatar Mar 13 '20 08:03 fkling