generate JsDoc api.json fails on MemberExpressions with Literals

Aperta
#561 5 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@RandomByte ci sta già lavorando.

Dal 1/10/2021.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

module/ui5-builder

Expected Behavior

Running the build process to generate the api.json without errors:

    await builder.build({
        tree: tree,
        destPath: params.destPath,
        cleanDest: false,
        jsdoc: true,
        buildDependencies: true
    });

Current Behavior

.../node_modules/@ui5/builder/lib/processors/jsdoc/lib/ui5/plugin.js:294
       path: getObjectName(valueNode).split('.').slice(1).join('.') // TODO chaining if local has path
                                     ^
TypeError: Cannot read property 'split' of null

(Exception is generated here: https://github.com/SAP/ui5-builder/blob/master/lib/processors/jsdoc/lib/ui5/plugin.js#L294)

Steps to Reproduce the Issue

When you use babel-plugin-transform-modules-ui5 for TypeScript coding, you will import library enums like this:

import { FlexRendertype, ButtonType } from "sap/m/library";

Babel will transform that into an sap.ui.define() call with "sap/m/library" which produces a variable sap_m_library. After that, it will generate the enums as follows:

  const FlexRendertype = sap_m_library["FlexRendertype"];
  const ButtonType = sap_m_library["ButtonType"];

To reproduce, you only need to use this syntax, no TypeScript or other transformations are necessary.

The problem is gone when you rewrite the code as follows:

  const FlexRendertype = sap_m_library.FlexRendertype;
  const ButtonType = sap_m_library.ButtonType;

The reason for this is that in the getObjectName() function, only specific AST nodes are parsed: https://github.com/SAP/ui5-builder/blob/master/lib/processors/jsdoc/lib/ui5/plugin.js#L523

function getObjectName(node) {
	if ( node.type === Syntax.MemberExpression && !node.computed && node.property.type === Syntax.Identifier ) {
		const prefix = getObjectName(node.object);
		return prefix ? prefix + "." + node.property.name : null;
	} else if ( node.type === Syntax.Identifier ) {
		return /* scope[node.name] ? scope[node.name] : */ node.name;
	} else {
		return null;
	}
}

The error occurs if the node.type is MemberExpression, but node.computed is true and node.property.type is Literal.

This is how the AST looks like in the error case:

image

My suggestion is to add another else if clause which covers this case:

function getObjectName (node) {
    if( node.type === Syntax.MemberExpression && !node.computed && node.property.type === Syntax.Identifier ) {
        const prefix = getObjectName(node.object);
        return prefix ? prefix + "." + node.property.name : null;
    } else if( node.type === Syntax.MemberExpression && node.computed && node.property.type === Syntax.Literal ) {
        const prefix = getObjectName(node.object);
        return prefix ? prefix + "." + node.property.value : null;
    } else if( node.type === Syntax.Identifier ) {
        return /* scope[node.name] ? scope[node.name] : */ node.name;
    } else {
        return null;
    }
}

Context

  • UI5 Module Version (output of ui5 --version when using the CLI): 2.12.1
  • Node.js Version: 10.22.1
  • OS/Platform: OpenSUSE 15.2

Solution

I could also create a pull request if you don't have any better idea?

Lingua principale
JavaScript
Stelle
511
Fork
83
Merge medio
1g 5h
PR unite (30g)
55

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di UI5/cli

Tutte le issue di UI5/cli

Issue simili

Altre issue su JavaScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.