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

textDocument/implementation Fails when arguments are present #3297

Open
TomKrcmar opened this issue Oct 8, 2024 · 2 comments
Open

textDocument/implementation Fails when arguments are present #3297

TomKrcmar opened this issue Oct 8, 2024 · 2 comments

Comments

@TomKrcmar
Copy link

TomKrcmar commented Oct 8, 2024

I am running Milestone 1.39.0

Given

The following is my test directory:
Main.java

class Main {
	static void main(String[] args) {
		IPerson person = new Person("Test", "User", 25);
		System.out.println("Hello, "+person.toStr(true)+"!");
	}
}

IPerson.java

interface IPerson {
	public String getName();
	public String getAge(boolean testBool);
	public String toStr(boolean testBool);
}

Person.java

class Person implements IPerson {
	String firstName;
	String lastName;
	int age;

	public Person(String firstName, String lastName, int age) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.age = age;
	}
	public String getName() {
		return this.firstName + " " + this.lastName;
	}
	public String getAge(boolean testBool) {
		return this.age + " years";
	}
	public String toStr(boolean testBool) {
		return "Name: " + this.getName() + "\nAge: " + this.getAge(testBool);
	}
}

When

When running textDocument/implementation on every position contained in the entire IPosition.java file, I would expect to get 4 hits (One for the interface implemented by the Person class, and one for each method implemented by the Person class).

Then

Instead, I get 2 hits, one for the Person implementer, then another for the getName() implementer.

If I remove the boolean testBool argument from getAge(), then textDocument/implementation returns 3 hits across the file, including getAge(). The same happens if I then remove testBool from toStr. All 4 expected hits work, only when the methods have no arguments. If I add an argument to one, it breaks and is no longer returned by textDocument/implementation.

Maybe I am missing something or have a wrong assumption? Even if so, the behavior seems bizarre to me.

Test Details

To clarify, I am running the request on every position in the file, because I've had some inconsistent behavior with range vs selectionRange coming from other responses by JDTLS, so I'm just testing across entire files to make sure of the behavior first. Maybe this will help. The following was generated by outputting . if 0 textDocument/implementation hits were found, and outputting the character at this position if more than 0 hits were found. For each position in IPerson.java. So you can see IPerson was a hit, and getName() was a hit, but not the other methods:

..........IPerson .
...............getName(..
........................................
.......................................

If I remove the boolean argument from getAge(), the mask looks like this:

..........IPerson .
...............getName(..
...............getAge(..
.......................................
@rgrunber
Copy link
Contributor

rgrunber commented Oct 25, 2024

What client are you using with JDT-LS ? Or are you writing your own from scratch ? I tried what you described for getAge and it seems to be working for vscode-java.

(line 2 (0-based) in IPerson.java corresponds to getAge and line 13 in Person.java corresponds to its implementation)

[Trace - 14:02:27] Sending request 'textDocument/implementation - (435)'.
Params: {
    "textDocument": {
        "uri": "file:///tmp/foo/IPerson.java"
    },
    "position": {
        "line": 2,
        "character": 19
    }
}


[Trace - 14:02:27] Received notification 'window/logMessage'.
Params: {
    "type": 3,
    "message": "Oct 25, 2024, 2:02:27 p.m. >> document/implementation"
}


[Info  - 14:02:27] Oct 25, 2024, 2:02:27 p.m. >> document/implementation
[Trace - 14:02:27] Received request 'window/workDoneProgress/create - (108)'.
Params: {
    "token": "586819f2-6a2e-40e7-a20e-e2ac3951d6c7"
}


[Trace - 14:02:27] Sending response 'window/workDoneProgress/create - (108)'. Processing request took 0ms
No result returned.


[Trace - 14:02:27] Received notification '$/progress'.
Params: {
    "token": "586819f2-6a2e-40e7-a20e-e2ac3951d6c7",
    "value": {
        "kind": "begin",
        "title": "Background task",
        "message": "Background task"
    }
}


[Trace - 14:02:27] Received notification '$/progress'.
Params: {
    "token": "586819f2-6a2e-40e7-a20e-e2ac3951d6c7",
    "value": {
        "kind": "report",
        "message": "Background task - 0% ",
        "percentage": 0
    }
}


[Trace - 14:02:28] Received notification '$/progress'.
Params: {
    "token": "586819f2-6a2e-40e7-a20e-e2ac3951d6c7",
    "value": {
        "kind": "end",
        "message": "Searching for implementors of 'IPerson.getAge(...)'..."
    }
}


[Trace - 14:02:28] Received response 'textDocument/implementation - (435)' in 112ms.
Result: [
    {
        "uri": "file:///tmp/foo/Person.java",
        "range": {
            "start": {
                "line": 13,
                "character": 15
            },
            "end": {
                "line": 13,
                "character": 21
            }
        }
    }
]

I could try to perform this in an even more basic manner on JDT-LS and just send over the raw json requests to really be sure. Are you able to detect if any errors have been reported ?

Update: I tried this on CLI and it didn't quite work so definitely something needing more investigation.

@rgrunber rgrunber added android and removed android labels Oct 29, 2024
@rgrunber
Copy link
Contributor

What does your initialize call look like / contain ? If all you have as your project is those 3 files, Main.java, IPerson.java, Person.java, your initialization call needs to contain the triggerFiles setting. This is something that we required in JDT-LS to properly resolve these unmanaged projects. The following worked for me :

{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
        "initializationOptions": {
            "workspaceFolders": [
                "file:///tmp/foo"
            ],
            "triggerFiles": [
                "file:///tmp/foo/IPerson.java"
            ],
            "settings": {
                "java": {
                    "home": "/home/rgrunber/.sdkman/candidates/java/17.0.13-tem/",
                    "autobuild": {
                        "enabled": true
                    }
                }
            },
            "extendedClientCapabilities": {
                "classFileContentsSupport": true
            }
        }
    }
}

Once the language server is started, the implementation call seems to work :

Sending :

{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "textDocument/implementation",
    "params": {
        "textDocument": {
            "uri": "file:///tmp/foo/IPerson.java"
        },
        "position": {
            "line": 2,
            "character": 19
        }
    }
}

results in a response of :

{
    "jsonrpc": "2.0",
    "id": 2,
    "result": [
        {
            "uri": "file:///tmp/foo/Person.java",
            "range": {
                "start": {
                    "line": 13,
                    "character": 15
                },
                "end": {
                    "line": 13,
                    "character": 21
                }
            }
        }
    ]
}

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

No branches or pull requests

2 participants