1

I would like to get the type of a method argument on a class using the typescript compiler API to provide code completion.

My class has the method byId(id: sap.ui.core.ID). I would like to check if the byId() method has this id parameter. So I start typing this.byId(|) and when I trigger code completion I would like to get the type at the position and if it is right I would look for the completion items in an XML file.

If I use the LanguageService class it only puts out the types after the brackets. The compiler API and the typechecker did not help, as they do not tend to get the symbols at the location.

Is there a straight forward way to get the type of a method parameter during code completion?

EDIT: Better Example for what I would like to do:

namespace app.controller {
    import Controller = sap.ui.core.mvc.Controller;
    export class App extends Controller {
        onInit() {
            this.byId(|)
            console.log("Initializing App Controller");
        }
    }
}

The | marks the position for the code completion.

1 Answer 1

2

You need to travelse AST. See sample script. I loop over source files childs, process clases, in clases is loop for methods and when i found method with the right name and parameters count i log type name of first parameter.

import ts = require("typescript");

var sf = ts.createSourceFile("aaa.ts", "class MyClass { byId(param: sap.ui.core.ID) {} }", ts.ScriptTarget.ES5);

// search all nodes of source file
sf.forEachChild(function (node: ts.Node) {

    // process only classes
    if (node.kind == ts.SyntaxKind.ClassDeclaration) {

        // get feautures of ClassDeclarations
        var cls: ts.ClassDeclaration = <ts.ClassDeclaration>node;

        // process class childs
        cls.forEachChild(function (m: ts.Node) {

            // limit proecssing to methods
            if (m.kind == ts.SyntaxKind.MethodDeclaration) {
                var method = <ts.MethodDeclaration>m;

                // process the right method with the right count of parameters
                if (method.name.getText(sf) == "byId" && method.parameters.length == 1) {
                    // get parameter type
                    var type = method.parameters[0].type

                    // get raw string of parametr type name
                    var typeName = type.getText(sf);

                    // response result
                    console.log("You've got it!" + typeName);
                }
            }

        });
    }
});
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your help! I'll try that tomorrow. But one problem would be, that the method would neither necessarily be named "byId", nor would it have only one parameter. But I'll start with that and expand to more complex cases.
You have to define condition which identify this method. Is this only one method in class? Is it everytime at first? Have it "by" in name everytime? If you can identify method by similar question (if keyword in typescript) it is very simple. You can also check that parameter type name starts with "sap.ui" or something similar.
I think the problem is not that trivial. I updated my question with an example. the method is a method on the base class Controller. I derive from it (or use it from another function, etc.) and it should check if the parameter at the cursor position is of the type sap.ui.core.ID. If so go to an xml file and search for all elements with id="bla". So it would work with any method that uses the sap.ui.core.Id type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.