@@ -110,17 +110,24 @@ private Optional<Semanticdb.Range> emitSymbolOccurrence(
110110 Element sym , Tree tree , Name name , Role role , CompilerRange kind ) {
111111 if (sym == null || name == null ) return Optional .empty ();
112112 Optional <Semanticdb .Range > range = semanticdbRange (tree , kind , sym , name .toString ());
113- emitSymbolOccurrence (sym , range , role );
114113 if (role == Role .DEFINITION ) {
114+ emitSymbolOccurrence (sym , range , role , computeEnclosingRange (tree ));
115115 // Only emit SymbolInformation for symbols that are defined in this compilation unit.
116116 emitSymbolInformation (sym , tree );
117+ return range ;
117118 }
119+ emitSymbolOccurrence (sym , range , role , Optional .empty ());
118120 return range ;
119121 }
120122
121- private void emitSymbolOccurrence (Element sym , Optional <Semanticdb .Range > range , Role role ) {
123+ private void emitSymbolOccurrence (
124+ Element sym ,
125+ Optional <Semanticdb .Range > range ,
126+ Role role ,
127+ Optional <Semanticdb .Range > enclosingRange ) {
122128 if (sym == null ) return ;
123- Optional <Semanticdb .SymbolOccurrence > occ = semanticdbOccurrence (sym , range , role );
129+ Optional <Semanticdb .SymbolOccurrence > occ =
130+ semanticdbOccurrence (sym , range , role , enclosingRange );
124131 occ .ifPresent (occurrences ::add );
125132 }
126133
@@ -298,7 +305,7 @@ private void resolveVariableTree(VariableTree node, TreePath treePath) {
298305 if (sym .getKind () == ElementKind .ENUM_CONSTANT ) {
299306 TreePath typeTreePath = nodes .get (node .getInitializer ());
300307 Element typeSym = trees .getElement (typeTreePath );
301- if (typeSym != null ) emitSymbolOccurrence (typeSym , range , Role .REFERENCE );
308+ if (typeSym != null ) emitSymbolOccurrence (typeSym , range , Role .REFERENCE , Optional . empty () );
302309 }
303310 }
304311 }
@@ -462,11 +469,14 @@ private Semanticdb.Range correctForTabs(Semanticdb.Range range, LineMap lineMap,
462469 }
463470
464471 private Optional <Semanticdb .SymbolOccurrence > semanticdbOccurrence (
465- Element sym , Optional <Semanticdb .Range > range , Role role ) {
472+ Element sym ,
473+ Optional <Semanticdb .Range > range ,
474+ Role role ,
475+ Optional <Semanticdb .Range > enclosingRange ) {
466476 if (range .isPresent ()) {
467477 String ssym = semanticdbSymbol (sym );
468478 if (!ssym .equals (SemanticdbSymbols .NONE )) {
469- Semanticdb .SymbolOccurrence occ = symbolOccurrence (ssym , range .get (), role );
479+ Semanticdb .SymbolOccurrence occ = symbolOccurrence (ssym , range .get (), role , enclosingRange );
470480 return Optional .of (occ );
471481 } else {
472482 return Optional .empty ();
@@ -476,6 +486,52 @@ private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(
476486 }
477487 }
478488
489+ /**
490+ * Computes the enclosing range for the given tree node. Returns the range of the nearest
491+ * non-trivial enclosing AST node. For definition occurrences, this includes the entire definition
492+ * including documentation. For reference occurrences, this includes the parent expression bounds.
493+ */
494+ private Optional <Semanticdb .Range > computeEnclosingRange (Tree tree ) {
495+ if (tree == null ) return Optional .empty ();
496+
497+ TreePath path = nodes .get (tree );
498+ if (path == null ) return Optional .empty ();
499+
500+ // For method, class, and variable definitions, use the tree itself as the enclosing range
501+ // since we're processing the definition node
502+ Tree enclosingTree = tree ;
503+ if (!(tree instanceof MethodTree
504+ || tree instanceof ClassTree
505+ || tree instanceof VariableTree )) {
506+ // For non-definition nodes (like references), use the parent
507+ TreePath parentPath = path .getParentPath ();
508+ if (parentPath == null ) return Optional .empty ();
509+ enclosingTree = parentPath .getLeaf ();
510+ if (enclosingTree == null || enclosingTree == compUnitTree ) return Optional .empty ();
511+ }
512+
513+ SourcePositions sourcePositions = trees .getSourcePositions ();
514+ int start = (int ) sourcePositions .getStartPosition (compUnitTree , enclosingTree );
515+ int end = (int ) sourcePositions .getEndPosition (compUnitTree , enclosingTree );
516+
517+ if (start != Diagnostic .NOPOS && end != Diagnostic .NOPOS && end > start ) {
518+ LineMap lineMap = compUnitTree .getLineMap ();
519+ Semanticdb .Range range =
520+ Semanticdb .Range .newBuilder ()
521+ .setStartLine ((int ) lineMap .getLineNumber (start ) - 1 )
522+ .setStartCharacter ((int ) lineMap .getColumnNumber (start ) - 1 )
523+ .setEndLine ((int ) lineMap .getLineNumber (end ) - 1 )
524+ .setEndCharacter ((int ) lineMap .getColumnNumber (end ) - 1 )
525+ .build ();
526+
527+ range = correctForTabs (range , lineMap , start );
528+
529+ return Optional .of (range );
530+ }
531+
532+ return Optional .empty ();
533+ }
534+
479535 private String semanticdbText () {
480536 if (source != null ) return source ;
481537 try {
0 commit comments