1414
1515public class BytecodeSyntaxArea extends RSyntaxTextArea {
1616 public Map <Fold , List <Token >> tokenIndex ;
17+ public final Map <Token , Fold > parentFoldCache ;
1718 public boolean foldsBuilt ;
1819
1920 public BytecodeSyntaxArea () {
@@ -23,11 +24,15 @@ public BytecodeSyntaxArea() {
2324 setLinkGenerator (new BytecodeLinkGenerator ());
2425 addHyperlinkListener (this ::processClick );
2526
27+ parentFoldCache = new HashMap <>();
2628 foldsBuilt = false ;
2729 getFoldManager ().addPropertyChangeListener (evt -> {
28- if (evt .getPropertyName ().equals (FoldManager .PROPERTY_FOLDS_UPDATED )
29- && evt .getNewValue () != null )
30- parseLabels ();
30+ if (evt .getPropertyName ().equals (FoldManager .PROPERTY_FOLDS_UPDATED )) {
31+ parentFoldCache .clear ();
32+ if (evt .getNewValue () != null ) {
33+ parseLabels ();
34+ }
35+ }
3136 });
3237 }
3338
@@ -58,7 +63,7 @@ private void parseLabels(Fold parent, Fold f) {
5863 List <Token > methodTokens = tokenIndex .computeIfAbsent (parent , k -> new ArrayList <>());
5964 methodTokens .add (new TokenImpl (t ));
6065 if (methodTokens .size () != Integer .parseInt (t .getLexeme ().substring (1 )))
61- throw new IllegalArgumentException ("Invalid token numbering: " + methodTokens .size () + "vs " + Integer .parseInt (t .getLexeme ().substring (1 )));
66+ throw new IllegalArgumentException ("Invalid token numbering: " + methodTokens .size () + " vs " + Integer .parseInt (t .getLexeme ().substring (1 )));
6267 break ;
6368 }
6469 }
@@ -67,17 +72,19 @@ private void parseLabels(Fold parent, Fold f) {
6772 }
6873 }
6974
70- private Fold getMethodFold (Token t ) {
71- FoldManager foldManager = getFoldManager ();
72- Fold rootFold = foldManager .getFold (0 );
73- Fold curFold = foldManager .getDeepestFoldContaining (t .getOffset ());
74- while (curFold != null ) {
75- Fold parentFold = curFold .getParent ();
76- if (parentFold == rootFold )
77- return curFold ;
78- curFold = parentFold ;
79- }
80- throw new IllegalArgumentException ("Token is not parented in top-level (class def) fold" );
75+ private Fold getMethodFold (Token token ) {
76+ return parentFoldCache .computeIfAbsent (token , t -> {
77+ FoldManager foldManager = getFoldManager ();
78+ Fold rootFold = foldManager .getFold (0 );
79+ Fold curFold = foldManager .getDeepestFoldContaining (t .getOffset ());
80+ while (curFold != null ) {
81+ Fold parentFold = curFold .getParent ();
82+ if (parentFold == rootFold )
83+ return curFold ;
84+ curFold = parentFold ;
85+ }
86+ throw new IllegalArgumentException ("Token is not parented in top-level (class def) fold" );
87+ });
8188 }
8289
8390 private Token findLabelDefinition (Token label ) {
@@ -100,7 +107,7 @@ public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, int offs) {
100107 if (labelDef == null )
101108 return null ;
102109 int caretTarget = labelDef .getOffset ();
103- return new SetCaretLinkResult (caretTarget , textArea , offs );
110+ return new SetCaretLinkResult (textArea , offs , caretTarget );
104111 }
105112 return null ;
106113 }
@@ -111,7 +118,7 @@ private class SetCaretLinkResult implements LinkGeneratorResult {
111118 private final RSyntaxTextArea textArea ;
112119 private final int offs ;
113120
114- public SetCaretLinkResult (int caretTarget , RSyntaxTextArea textArea , int offs ) {
121+ public SetCaretLinkResult (RSyntaxTextArea textArea , int offs , int caretTarget ) {
115122 this .caretTarget = caretTarget ;
116123 this .textArea = textArea ;
117124 this .offs = offs ;
0 commit comments