@@ -110,17 +110,18 @@ 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 );
113+ Optional <Semanticdb .Range > enclosingRange = computeEnclosingRange (tree );
114+ emitSymbolOccurrence (sym , range , role , enclosingRange );
114115 if (role == Role .DEFINITION ) {
115116 // Only emit SymbolInformation for symbols that are defined in this compilation unit.
116117 emitSymbolInformation (sym , tree );
117118 }
118119 return range ;
119120 }
120121
121- private void emitSymbolOccurrence (Element sym , Optional <Semanticdb .Range > range , Role role ) {
122+ private void emitSymbolOccurrence (Element sym , Optional <Semanticdb .Range > range , Role role , Optional < Semanticdb . Range > enclosingRange ) {
122123 if (sym == null ) return ;
123- Optional <Semanticdb .SymbolOccurrence > occ = semanticdbOccurrence (sym , range , role );
124+ Optional <Semanticdb .SymbolOccurrence > occ = semanticdbOccurrence (sym , range , role , enclosingRange );
124125 occ .ifPresent (occurrences ::add );
125126 }
126127
@@ -298,7 +299,7 @@ private void resolveVariableTree(VariableTree node, TreePath treePath) {
298299 if (sym .getKind () == ElementKind .ENUM_CONSTANT ) {
299300 TreePath typeTreePath = nodes .get (node .getInitializer ());
300301 Element typeSym = trees .getElement (typeTreePath );
301- if (typeSym != null ) emitSymbolOccurrence (typeSym , range , Role .REFERENCE );
302+ if (typeSym != null ) emitSymbolOccurrence (typeSym , range , Role .REFERENCE , Optional . empty () );
302303 }
303304 }
304305 }
@@ -462,11 +463,11 @@ private Semanticdb.Range correctForTabs(Semanticdb.Range range, LineMap lineMap,
462463 }
463464
464465 private Optional <Semanticdb .SymbolOccurrence > semanticdbOccurrence (
465- Element sym , Optional <Semanticdb .Range > range , Role role ) {
466+ Element sym , Optional <Semanticdb .Range > range , Role role , Optional < Semanticdb . Range > enclosingRange ) {
466467 if (range .isPresent ()) {
467468 String ssym = semanticdbSymbol (sym );
468469 if (!ssym .equals (SemanticdbSymbols .NONE )) {
469- Semanticdb .SymbolOccurrence occ = symbolOccurrence (ssym , range .get (), role );
470+ Semanticdb .SymbolOccurrence occ = symbolOccurrence (ssym , range .get (), role , enclosingRange );
470471 return Optional .of (occ );
471472 } else {
472473 return Optional .empty ();
@@ -476,6 +477,51 @@ private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(
476477 }
477478 }
478479
480+ /**
481+ * Computes the enclosing range for the given tree node.
482+ * Returns the range of the nearest non-trivial enclosing AST node.
483+ * For definition occurrences, this includes the entire definition including documentation.
484+ * For reference occurrences, this includes the parent expression bounds.
485+ */
486+ private Optional <Semanticdb .Range > computeEnclosingRange (Tree tree ) {
487+ if (tree == null ) return Optional .empty ();
488+
489+ TreePath path = nodes .get (tree );
490+ if (path == null ) return Optional .empty ();
491+
492+ // For method, class, and variable definitions, use the tree itself as the enclosing range
493+ // since we're processing the definition node
494+ Tree enclosingTree = tree ;
495+ if (!(tree instanceof MethodTree || tree instanceof ClassTree || tree instanceof VariableTree )) {
496+ // For non-definition nodes (like references), use the parent
497+ TreePath parentPath = path .getParentPath ();
498+ if (parentPath == null ) return Optional .empty ();
499+ enclosingTree = parentPath .getLeaf ();
500+ if (enclosingTree == null || enclosingTree == compUnitTree ) return Optional .empty ();
501+ }
502+
503+ SourcePositions sourcePositions = trees .getSourcePositions ();
504+ int start = (int ) sourcePositions .getStartPosition (compUnitTree , enclosingTree );
505+ int end = (int ) sourcePositions .getEndPosition (compUnitTree , enclosingTree );
506+
507+ if (start != Diagnostic .NOPOS && end != Diagnostic .NOPOS && end > start ) {
508+ LineMap lineMap = compUnitTree .getLineMap ();
509+ Semanticdb .Range range =
510+ Semanticdb .Range .newBuilder ()
511+ .setStartLine ((int ) lineMap .getLineNumber (start ) - 1 )
512+ .setStartCharacter ((int ) lineMap .getColumnNumber (start ) - 1 )
513+ .setEndLine ((int ) lineMap .getLineNumber (end ) - 1 )
514+ .setEndCharacter ((int ) lineMap .getColumnNumber (end ) - 1 )
515+ .build ();
516+
517+ range = correctForTabs (range , lineMap , start );
518+
519+ return Optional .of (range );
520+ }
521+
522+ return Optional .empty ();
523+ }
524+
479525 private String semanticdbText () {
480526 if (source != null ) return source ;
481527 try {
0 commit comments