Retrieving methods statements using a certain API

22 views
Skip to first unread message

May Sayed

unread,
Sep 11, 2019, 9:13:54 PM9/11/19
to Boa Language and Infrastructure User Forum
Hi,
I am new to Boa. I am trying to retrieve methods statements using a certain API from the code repositories. I am modifying this query to accomplish that but facing some problems, below is the updated query and the error I am facing, can you help me figure out the error? 


p: Project = input;
out: output set of array of Statement;

projects: set of string;
methods: set of array of Statement;
files: set of string;
imports_List: bool;
uses_List: bool;

visit(p, visitor {
    before repo: CodeRepository -> {
        # Visit only newest snapshot.
        snapshot := getsnapshot(repo, "SOURCE_JAVA_JLS");
        foreach (i: int; def(snapshot[i])) {
            visit(snapshot[i]);
        }
        stop;
    }
    before f: ChangedFile -> {
        if (contains(projects, p.name) || contains(files, f.name) || match("test", lowercase(f.name))) stop;
        add(files, f.name);
    }
    before astRoot: ASTRoot -> {
        imports: = astRoot.imports;
        imports_List = false;
        # Check imports to know whether simple type references match the type.
        # `java.lang.*` types are always implicitly imported.
        foreach (i: int; def(imports[i])) {
            if ((imports[i] == "java.util.List") || (imports[i] == "java.util.*")) {
                imports_List = true;
            }
        }
    }
    before method: Method -> {
        if (contains(projects, p.name)) stop;
        # Searching for methods that use _all_ requested type, hence, resetting uses.
        uses_List = false;
    }
    before t: Type -> {
        # Check type literals.
        if ((imports_List && t.name == "List") || (t.name == "java.util.List")) {
            uses_List = true;
        }
    }
    before variable: Variable -> {
        # Check variable/parameter types.
        if ((imports_List && variable.variable_type.name == "List") || (variable.variable_type.name == "java.util.List")) {
            uses_List = true;
        }
    }
    before e: Expression -> {
        # Check static method call receivers.
        if (e.kind == ExpressionKind.METHODCALL) {
            # BOA does not distinguish static calls from calls on variables. We assume a match, if the variable
            # name matches the simple type name and the type is imported. This causes false positives, if a
            # variable shadows the type.
            exists(i: int; e.expressions[i].kind == ExpressionKind.VARACCESS) {
                if ((imports_List && e.expressions[i].variable == "List") || (e.expressions[i].variable == "java.util.List")) {
                    uses_List = true;
                }
            }
        }
    }
    after method: Method -> {
        if (uses_List) {
            out << method.statements;
            add(methods, method.statements);
        }
    }
});


Error: Encountered typecheck error at line 2, column 5. boa.types.BoaArray cannot be cast to boa.types.BoaScalar
out: output set of array of Statement;


Robert Dyer

unread,
Sep 12, 2019, 1:04:31 AM9/12/19
to Boa Language and Infrastructure User Forum
Hi May,

I think the main problem is you are trying to output an array, and none of the aggregators support that.  You probably want to output strings instead.

Then in the Method visitor, the array 'method.statements' you can iterate over and output each one (convert them to string using the string() function).

I'm not exactly sure what the point of the 'methods' global is, as it doesnt seem to be used - only added to.

Hope that helps!

- Robert
Reply all
Reply to author
Forward
0 new messages