-
Notifications
You must be signed in to change notification settings - Fork 401
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
Semantic highlighting improvements #1501
Semantic highlighting improvements #1501
Conversation
Can one of the admins verify this patch? |
add to whitelist |
Some of the tests for semantic tokens are failing now because they are expecting the token type A related issue to this is that color themes using the old |
@0dinD thanks for your contribution! Please make sure your commits are signed (git commit -s) and sign the Eclipse Contributor Agreement, before we can accept this PR. For the tests, we're aware of some unstable tests that might case some build failures now and again. Now, given the scope of your changes, you can safely simply amend and run the SemanticTokensCommandTest ( I'll let @Eskibear do the review for this one. |
Thank you for the suggestion about the tests! I have now fixed the existing tests to make them run, but I think some new tests should be added because of the additions I made. I will look into signing the Eclipse Contributor Agreement and signing my commits. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also played for a while and it was working as expected. Overall it's a great improvement, and I have below concerns:
- It does bring Semantic highlighting doesn't like java.* packages redhat-developer/vscode-java#1434 back, and we should fix that or at least work it around.
- It works well now for cases in Incorrect semantic highlighting for complex constructor invocations redhat-developer/vscode-java#1514 , better to add some test cases to guard.
|
||
@Override | ||
public boolean visit(SimpleName node) { | ||
TokenType tokenType = TokenType.getApplicableToken(node.resolveBinding()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redhat-developer/vscode-java#1434 is introduced again. And by the way it's not only for java
.
As far as redhat-developer/vscode-java#1434 goes, I think it would be better to fix whatever causes the binding of the package to be null, rather than working around the fact that it is null. Can you provide me with the environment and some instructions to reproduce this issue? I am currently unable to debug it since I cannot reproduce it. I will get to work adding new test cases for my changes. |
After some testing, I think I can conclude that this issue has something to do with the version of Java used to launch the server. Using JDK8 it works like expected:Using JDK11 or JDK14 I get the same issue as you do:
Are you sure that Java 8 is used to start the server? As in, Can you confirm my results on your machine? Any ideas as to why this might be happening? |
After thinking about it, I have a strong suspicion that this issue has something to do with the module system introduced in Java 9. That would explain why it does not appear on JDK8, and why it seems to only happen with the Java standard library. I will try to find out if this is the case, and what can be done about it. |
I have now found an easier way to reproduce this issue. It is not necessarily dependent upon the JDK version used to launch the server, as I previously thought. Rather, the issue is introduced whenever the property This pretty much confirms my suspicion of Java 9 modules being the cause of this issue. Now it's just a matter of figuring out why Also, can you verify that this issue is reproduced by setting |
I have now finally found the root cause of this issue! The actual issue
Why can the package binding not be resolved?Because it is a Why is it a
|
After making the root cause of the issue more clear, I realised that there is a better way to work around the null package bindings (See 7b53dce). I think the logic behind it should be pretty clear by looking at the small code addition and my javadoc comment. This is how the semantic highlighting looks now:Can you review this change? @Eskibear |
@0dinD in order for us to be able to merge this PR, make sure you squash all your commits into one, and sign it off using |
@fbricon I will make sure to squash all my commits and sign once the code seems ready to merge. As for your second comment, I do agree, but this behavior is not something that I changed with 7b53dce (correct me if I am wrong). Even with the current version of eclipse.jdt.ls, semantic tokens are missing for imports where the package bindings are null as a result of package accessibility for Java 9 modules. Merging of the qualified name (the current workaround) still only works if the import statement's target package does not resolve to a This screenshot is taken with the marketplace version of vscode-java:
The image you sent is another strange issue, but is seemingly unrelated to the package bindings. I can reproduce the same issue on the marketplace version of vscode-java. The semantic tokens on |
|
||
@Override | ||
public boolean visit(QualifiedName node) { | ||
if (node.resolveBinding() instanceof IPackageBinding) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can add || node.resolveBinding() instanceof ITypeBinding
to cover more cases. E.g.
import org.jcp.*;
import org.ietf.Eskibear;
I just verified your latest commit 7b53dce :
Room to improveFor a) For b)
But it doesn't fix Alternative implementationSo here comes an alternative approach. As the issues are all about import statements, can we just do it in override |
Yes, overriding |
After thinking about this some more, I realised that we do still need to visit qualified names, since package names not only occur in import statements, but also in cases where Types have their package explicitly specified: // Stupid example, but you get the point
java.lang.String string = new java.lang.String(); The main problem here is that we are doing guesswork as far as applying the package tokens, since they are discarded by Despite this, I made yet another workaround that should fix the comments you have made about the package highlighting. Can you review my latest commit @Eskibear ? |
Great. I tried you PR, it manages to cover all the cases we mentioned above.
So overall it looks good to me.
Not true, the problems only occur in import statements. So my original proposal was to only override @Override
public boolean visit(ImportDeclaration node) {
if node.isOnDemand()
visitPackage(node.getName()) // to highlight "java" in "import java.util.*"
else
visitPackageWithType(node.getName()) // to highlight "java" in "import java.util.List"
}
// in "visitPackageWithType", you can assign correct tokens for Qualifier and Name . An advantage of this proposal would be better performance. It only affects import statements, thus you don't have to perform the check |
I'm planning to perform a release on Wednesday, so if we can get that in, that'd be great. @0dinD make sure you get your signed commits + ECA tomorrow at the latest. |
Okay @fbricon , I can probably commit some final touches (addressing Eskibear's comment + adding new test cases) later today. I will make sure to squash and sign everything so you can merge it tomorrow if it looks ready to you. By the way, these changes might break styling for projects not using the new, more specific token types (Class, Interface, Enum, Parameter etc). For users of vscode-java this should not be a problem if we declare token types and their supertypes in the package.json contribution point. I plan to make a pull request for that also later today, which you should probably take a look at before you use the new version of eclipse.jdt.ls in vscode-java. For other projects using eclipse.jdt.ls, they probably have to figure out token supertypes in their own implementation, since what I am talking about is only available to VS Code extensions. This is the token type hierarchy I was thinking of declaring:
Do you agree? I am unsure of whether or not to give |
483c0ad
to
97fe211
Compare
I have now addressed Eskibear's comment in 3473f16. The new implementation only performs a check for null package bindings in import statements, when absolutely necessary. Also, I added some new test cases (483c0ad) to cover the new token types and modifiers I added in this PR. @Eskibear can you do a review of these changes? Finally, I have signed the ECA and squashed my old commits into a new signed commit. So feel free to merge this if you feel that it is ready, @fbricon . Also don't forget to merge my PR redhat-developer/vscode-java#1537 for declaring token supertypes in the vscode-java extension if you merge this PR, since it ensures backwards compatibility for VS Code themes using the "old" token types. |
return new SemanticTokens(data); | ||
} | ||
|
||
private List<Integer> encodeTokens() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
encodedTokens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed and amended to previous commit
LGTM |
Signed-off-by: 0dinD <[email protected]>
97fe211
to
785a6f1
Compare
@0dinD awesome work, thanks! |
@0dinD @fbricon Is it me or, after the merge, the formatting is no longer consistent with the rest of the Eclipse code format? For example, in |
@tommai78101 Are you sure that it is a space and not a tab character that you have configured to be 1-space wide? I re-indented everything under |
Implements redhat-developer/vscode-java#1488
Fixes redhat-developer/vscode-java#1514
Changes
.editorconfig
Token types and modifiers
Both token types and modifiers can now be found in their respective enum.
Made the naming scheme more consistent
TokenType.METHOD
instead ofTokenType.FUNCTION
toString()
method on the enum members return the more generic name used in the legend.Removed unused token types
Added new token types:
value
in@SuppressWarnings(value = "all")
)Added new token modifiers:
Semantic tokens visitor
TokenType
andTokenModifier
enums.java
andlang
injava.lang.Math
is part of anamespace
tokenlang
andMath
is not part of anamespace
tokennamespace
tokenTesting
I did not manage to run the tests, since they failed halfway through even before I made any changes to the code (I will try to debug this soon). At least one test will fail because of the change I made to the merging of package names, so that test will have to be rewritten. Also, I haven't written any tests for the above changes, since I could not set up testing to work on my machine. It would be very kind of someone to help me write these tests, maybe @Eskibear since you wrote the other semantic highlighting tests? I will try to get testing to work for me in the meantime.