Skip to content

Added bracket highlighting for generic angle brackets #8500

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

TylerDelRosario
Copy link

@TylerDelRosario TylerDelRosario commented May 11, 2025

#5024

  • Added bracket highlighting for generic angle brackets.

  • Includes a couple of new unit tests.

The biggest hurdle is that bit wise shift operators get tokenized by the lexer. The simplest solution would be to take the input TokenHierarchy and split GTGT tokens into separate GT tokens.

But after diving into the lexer module, it seems that almost all token related classes are either immutable or contain package-private constructors. If there's a way that TokenHierarchy can be modified, I would genuinely like to learn how.

Otherwise, I've opted to add an algorithm that specifically handles angle brackets while managing the counter and offsets accordingly.

Thank you to matthiasblaesing for showing where the appropriate files are and the lexer token stream.


^Add meaningful description above

Click to collapse/expand PR instructions

By opening a pull request you confirm that, unless explicitly stated otherwise, the changes -

  • are all your own work, and you have the right to contribute them.
  • are contributed solely under the terms and conditions of the Apache License 2.0 (see section 5 of the license for more information).

Please make sure (eg. git log) that all commits have a valid name and email address for you in the Author field.

If you're a first time contributor, see the Contributing guidelines for more information.

If you're a committer, please label the PR before pressing "Create pull request" so that the right test jobs can run.

PR approval and merge checklist:

  1. Was this PR correctly labeled, did the right tests run? When did they run?
  2. Is this PR squashed?
  3. Are author name / email address correct? Are co-authors correctly listed? Do the commit messages need updates?
  4. Does the PR title and description still fit after the Nth iteration? Is the description sufficient to appear in the release notes?

If this PR targets the delivery branch: don't merge. (full wiki article)

@@ -428,7 +520,7 @@ public static List<TokenSequence<?>> getEmbeddedTokenSequences(
for(int i = sequences.size() - 1; i >= 0; i--) {
TokenSequence<?> seq = sequences.get(i);
if (seq.language() == language) {
break;
break;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong indentation

Copy link
Contributor

@matthiasblaesing matthiasblaesing left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this. I left a few inline comments, but this needs at least another round. The current state works for simple cases, but fails at others.

I also noticed that comparisons are marked as error:

grafik

Bitshifts also look broken:

grafik

It might be necessary to create a brace matcher that does not report errors for type braces, but only the matches. Or you'd need to find a marker where to stop scanning.

@@ -428,7 +520,7 @@ public static List<TokenSequence<?>> getEmbeddedTokenSequences(
for(int i = sequences.size() - 1; i >= 0; i--) {
TokenSequence<?> seq = sequences.get(i);
if (seq.language() == language) {
break;
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is unnessary and wrong as already indicated by @essien. Please remove.

@@ -98,13 +99,13 @@ public int[] findOrigin() throws BadLocationException, InterruptedException {
context.getLimitOffset(),
PAIRS
);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove space at end of lines (see lines 102, 108, 150, 154, 160)

if (sq.token().id() == JavaTokenId.GTGTGT) {
if (originId == JavaTokenId.GT) {
if (originOffset != sq.offset()) {
int test = sq.offset();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stray test code?

assertMatches2("Map^<Class<? extends AbstractStudent>, Map<CourseTime, List<? extends AbstractCourse>>^>");
assertMatches2("Map<Class<? extends AbstractStudent>, Map^<CourseTime, List<? extends AbstractCourse>^>>");
assertMatches2("Map x = new HashMap<String, List^<String^>>()");
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs more test cases. I added some and hit a bug:

        assertMatches2("^<test^>");
        assertMatches2("Map^<Class<? extends AbstractStudent>,  Map<CourseTime, List<? extends AbstractCourse>>^>");
        assertMatches2("Map<Class<? extends AbstractStudent>,  Map^<CourseTime, List<? extends AbstractCourse>^>>");
        assertMatches2("Map<Class<? extends AbstractStudent>,  Map<CourseTime, List^<? extends AbstractCourse^>>>");
        assertMatches2("Map<Class^<? extends AbstractStudent^>,  Map<CourseTime, List<? extends AbstractCourse>>>");
        assertMatches2("Map^<Map<CourseTime, List<? extends AbstractCourse>>, Class<? extends AbstractStudent>^>");
        assertMatches2("Map<Map^<CourseTime, List<? extends AbstractCourse>^>, Class<? extends AbstractStudent>>");
        assertMatches2("Map<Map<CourseTime, List^<? extends AbstractCourse^>>, Class<? extends AbstractStudent>>");
        assertMatches2("Map<Map<CourseTime, List<? extends AbstractCourse>>, Class^<? extends AbstractStudent^>>");
        assertMatches2("Map x = new HashMap<String, List^<String^>>()");
        assertMatches2("Map x = new HashMap^<String, List<String>^>()");

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May I also add that <> should match in the below:

class LinkedList < T extends Object & Serializable > {
}

but <> should not match in the below:

int Object = 2;
int Serializable = 3;
boolean result = 1 < Object & Serializable > 4;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there needs to be some way to differentiate generic brackets from comparison/operator brackets.

Comment on lines +259 to +263
/* One idea was to modify the input TokenHierachy to split
** GTGT tokens into 2 separate GT and GT tokens. However,
** it seems like almost all token related classes are immutable
** or inaccessible due to private constructors. Leading me to
** write this. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TokenHierarchy/-sequence represents the lexing result and yes, for analysis they are read-only. This comment gives reasoning for the current implementation, but reads more like "note to self", then intentional for others.

}
}

//Shouldn't happen, but added it anyways.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume that this refers to the fact, that after each opening brace a type must be placed? I mean List<TYPE?

if (sq.token().id() == JavaTokenId.GTGT) {
if (originId == JavaTokenId.GT) {
if (originOffset != sq.offset()) {
counter += (originOffset - sq.offset());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the idea here. Why is the originOffset used here? Shouldn't count just count the number of unmatched braces?

@TylerDelRosario
Copy link
Author

Thank you for taking your time to build and review this. I genuinely appreciate the feedback.
I'm going add these unit tests and give this another round to specifically address the comparison and bitwise error markers while making my code more readable. I'll also fix the formatting errors that you and essien pointed out.

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

Successfully merging this pull request may close these issues.

3 participants