c2nes / javalang

Pure Python Java parser and tools
MIT License
736 stars 161 forks source link

How do I get a method's parameter's type? #46

Closed foresightyj closed 7 years ago

foresightyj commented 7 years ago

This is my code:

fht_android_src = "E:/FHT Mobile/Android/fht/app/src/main/java/com/fht360/fht"

for (dirpath, dirname, filenames) in os.walk(fht_android_src):
    for filename in filenames:
        if filename.endswith(".java"):
            filepath = os.path.join(dirpath, filename)
            # see https://stackoverflow.com/questions/19591458/python-reading-from-a-file-and-saving-to-utf-8
            if filename == "MainActivity.java":
                with io.open(filepath, 'r', encoding="utf8") as f:
                    content = f.read()
                    tree = javalang.parse.parse(content)
                    for path, node in tree:
                        # if isinstance(node, javalang.tree.ClassDeclaration):
                        #     # print(path, node)
                        #     print(node.name)
                        if isinstance(node, javalang.tree.MethodDeclaration):
                            # print(path, node)
                            if node.name == "onEvent":
                                handlerNode = node
                                handlerPath = path
                                print(handlerNode.parameters[0].type, handlerNode.parameters[0].name)

I am analyzing a typical Android Activity class, which have a bunch of onEvent methods for EventBus, these methods look like:

public void onEvent(UnreadChatMessageEvent event) {
    mNavFragment.showHomeDot(event.count);

    SPUtil.saveInteger(this, Constant.UnReadChatMessage, event.count);
    doTotalCount();
}

public void onEvent(FriendRequestMsgDotClearEvent event) {
    mNavFragment.showFriendsDot(0);

    SPUtil.saveInteger(this, Constant.UntreatedFriendRequest, 0);
    doTotalCount();
}

I want to get the type of the notification as something like: UnreadChatMessageEvent, but the type given by javalang is always ReferenceType:

image

foresightyj commented 7 years ago

OK. I got around it the ugly way by adding one line to parser.py:

The value token is there but is not passed into FormalParameter. Is there any reason that it is left out?

image

image

c2nes commented 7 years ago

ReferenceType is actually a type of AST node declared in javalang/tree.py. I believe handlerNode.parameters[0].type.name would give you what you're looking for.

import javalang.parse
sig = javalang.parse.parse_member_signature(r'''String foo(List<String> bar, Integer baz)''')
print(sig.parameters[0].type.name) # "List"
print(sig.parameters[1].type.name) # "String"
foresightyj commented 7 years ago

Oh. I feel stupid after seeing your answer. I jumped to conclusion too quickly. Sorry.