generate JsDoc api.json fails on MemberExpressions with Literals

Open
#561 5 comments 0 reactions 1 assignee View on GitHub

@RandomByte is already working on this.

Since Oct 1, 2021.

Assessment

This issue has not been assessed yet.

Description

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?

Dominant language
JavaScript
Stars
511
Forks
83
Avg merge
1d 5h
Merged PRs (30d)
55

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from UI5/cli

All issues in UI5/cli

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.