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

TypeError: Cannot read properties of undefined (reading 'getName') #21

Open
alichry opened this issue Mar 10, 2023 · 3 comments
Open

TypeError: Cannot read properties of undefined (reading 'getName') #21

alichry opened this issue Mar 10, 2023 · 3 comments

Comments

@alichry
Copy link
Contributor

alichry commented Mar 10, 2023

Hi there,

While trying to run tsuml2 --glob test.ts, the following exception was thrown TypeError: Cannot read properties of undefined (reading 'getName'). Here is a reproducible example:

# test.ts
export interface ITest {
  run(): void;
  hide(): void;
}

export type ITransformedTest = {
  [m in string &  keyof ITest as `shouldI${Capitalize<m>}`]: boolean;
} & { // remove this and no exception would be thrown
  shouldIFight(): boolean; 
}

export class Should implements ITransformedTest {
  shouldIRun: boolean = true;
  shouldIHide: boolean = false;

  shouldIFight() {
    return ! this.shouldIRun && ! this.shouldIHide;
  }
}
@alichry
Copy link
Contributor Author

alichry commented Mar 10, 2023

While the exception is caught and printed, this is output SVG:
out
After applying the below patch to parser.jsgetClassOrInterfaceName,

...
        if (classOrIf instanceof SimpleAST.Type) {
-             name = classOrIf.getSymbol().getName();
+             name = classOrIf.getSymbol() ? classOrIf.getSymbol().getName() : undefined;

-             if (name === "__type") {
+             if (name === "__type" || name === undefined) {
                  name = classOrIf.getAliasSymbol().getName();
              }
...

no exceptions were thrown, resulting in:
out
Notice ITransformedTest is now shown in the UML diagram, however, the diagram lacks its properties. This is not ideal but at least it would include the type in the result.

Based on my analysis, when parseTypes is called for ITransformedTest it halts here.

Seems like we have two issues, retrieving a type name and parsing its properties. I am unfamiliar with the codebase but I am happy to create a PR. Do you think the above fix is proper? if so, I am happy to open a PR for the first issue, and if you would give me any pointers, I can start working on the second issue.

@demike
Copy link
Owner

demike commented Mar 10, 2023

Would be nice if you could provide a PR for the first issue.
I will then take a look at the second problem ( where I placed the 'todo' comment 😁)

@alichry
Copy link
Contributor Author

alichry commented Mar 10, 2023

Thank you for your response @demike. I have submitted a PR to fix the first issue. I have this snippet in my workshop:

// parser.ts
/* introduce new function getMethodsAndProperties */
function getMethodsAndProperties(typeNode: SimpleAST.TypeNode) {
    console.log(`Node kind name ${typeNode.getKindName()}`);

    let propertyDeclarations: SimpleAST.PropertySignature[] = [];
    let methodDeclarations: SimpleAST.MethodSignature[] = [];
    if (typeNode instanceof SimpleAST.TypeLiteralNode) {
        propertyDeclarations = typeNode.getProperties();
        methodDeclarations = typeNode.getMethods();
    } else if (typeNode instanceof SimpleAST.IntersectionTypeNode) {
        const childNodes = typeNode.getTypeNodes();

        childNodes.forEach((tn, i) => {
            const pm = getMethodsAndProperties(tn);
            if (! pm) {
                return;
            }
            propertyDeclarations = propertyDeclarations.concat(pm.propertyDeclarations);
            methodDeclarations = methodDeclarations.concat(pm.methodDeclarations);
        });
    } else if (typeNode instanceof SimpleAST.MappedTypeNode) {
        const typeParameter = typeNode.getTypeParameter();
        const constraint = typeParameter?.getConstraint();

        console.log("MappedType constraint kind name:",  constraint?.getKindName());

        // typeNode.getChildren().forEach((child, i) => {
        //     console.log(`Child #${i} kind ${child.getKindName()} text ${child.getText()}`);
        //     // Type Parameter
        //     // AsKeyword
        //     if (child instanceof SimpleAST.TemplateLiteralTypeNode) {
        //         console.log("Child TemplateLiteralNode");
        //         console.log(child);
        //         child.forEachChild((ll) => {
        //             console.log(`LL ${ll.getText()}`);
        //         });
        //         child.forEachDescendant((dd) => {
        //             console.log(`DD ${dd}`);
        //         });
        //     }

        //     // Syntax List
        // });

        return;
    } else {
        return;
    }

    return {
        propertyDeclarations,
        methodDeclarations
    }
}

export function parseTypes(typeDeclaration: SimpleAST.TypeAliasDeclaration) {

    const name = getClassOrInterfaceName(typeDeclaration) || 'undefined';
    const t = typeDeclaration.getType();
    const typeNode = typeDeclaration.getTypeNode();

    let propertyDeclarations: SimpleAST.PropertySignature[] = [];
    let methodDeclarations: SimpleAST.MethodSignature[] = [];

    if(typeNode instanceof SimpleAST.TypeLiteralNode) {
        propertyDeclarations = typeNode.getProperties();
        methodDeclarations = typeNode.getMethods();
    } else if (typeNode instanceof SimpleAST.IntersectionTypeNode) {
        const res = getMethodsAndProperties(typeNode);
        if (! res) {
            return;
        }
        propertyDeclarations = res.propertyDeclarations;
        methodDeclarations = res.methodDeclarations;
    } else {
        // no structured type --> lets skip that (for now)
        return;
    }
    ...
}

With this change, shouldIFight is added to the UML. However, shouldIRun and shouldIHide are not present.
I am currently trying to derive the property declarations from MappedTypeNode.
out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants