Skip to content

Commit 21e055c

Browse files
committed
fix range building for tabs or mixed tabs/spaces files
1 parent fb98dd4 commit 21e055c

File tree

1 file changed

+38
-5
lines changed

1 file changed

+38
-5
lines changed

semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbVisitor.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ private String semanticdbSymbol(Symbol sym) {
255255

256256
private Optional<Semanticdb.Range> semanticdbRange(
257257
JCDiagnostic.DiagnosticPosition pos, CompilerRange kind, Symbol sym) {
258+
LineMap lineMap = event.getCompilationUnit().getLineMap();
258259
if (sym == null) return Optional.empty();
259260
int start, end;
260261
if (kind.isFromPoint() && sym.name != null) {
@@ -269,21 +270,53 @@ private Optional<Semanticdb.Range> semanticdbRange(
269270
}
270271

271272
if (kind.isFromTextSearch() && sym.name.length() > 0) {
272-
return RangeFinder.findRange(
273-
getCurrentPath(), trees, getCurrentPath().getCompilationUnit(), sym, start, this.source);
273+
Optional<Semanticdb.Range> range =
274+
RangeFinder.findRange(
275+
getCurrentPath(),
276+
trees,
277+
getCurrentPath().getCompilationUnit(),
278+
sym,
279+
start,
280+
this.source);
281+
if (range.isPresent()) return Optional.of(correctForTabs(range.get(), lineMap, start));
282+
else return range;
274283
} else if (start != Position.NOPOS && end != Position.NOPOS && end > start) {
275-
LineMap lineMap = event.getCompilationUnit().getLineMap();
276284
Semanticdb.Range range =
277285
Semanticdb.Range.newBuilder()
278286
.setStartLine((int) lineMap.getLineNumber(start) - 1)
279287
.setStartCharacter((int) lineMap.getColumnNumber(start) - 1)
280288
.setEndLine((int) lineMap.getLineNumber(end) - 1)
281289
.setEndCharacter((int) lineMap.getColumnNumber(end) - 1)
282290
.build();
291+
292+
range = correctForTabs(range, lineMap, start);
293+
283294
return Optional.of(range);
284-
} else {
285-
return Optional.empty();
286295
}
296+
297+
return Optional.empty();
298+
}
299+
300+
private Semanticdb.Range correctForTabs(Semanticdb.Range range, LineMap lineMap, int start) {
301+
int startLinePos = (int) lineMap.getPosition(lineMap.getLineNumber(start), 0);
302+
303+
// javac replaces every tab with 8 spaces in the linemap. As this is potentially inconsistent
304+
// with the source file itself, we adjust for that here if the line is actually indented with
305+
// tabs.
306+
// As for every tab there are 8 spaces, we remove 7 spaces for every tab to get the correct
307+
// char offset (note: different to _column_ offset your editor shows)
308+
if (this.source.charAt(startLinePos) == '\t') {
309+
int count = 1;
310+
while (this.source.charAt(++startLinePos) == '\t') count++;
311+
range =
312+
range
313+
.toBuilder()
314+
.setStartCharacter(range.getStartCharacter() - (count * 7))
315+
.setEndCharacter(range.getEndCharacter() - (count * 7))
316+
.build();
317+
}
318+
319+
return range;
287320
}
288321

289322
private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(

0 commit comments

Comments
 (0)