Skip to content

Commit 64deb6a

Browse files
authored
fixes range deriving for constructs incl classes/interfaces (#121)
Also fixes visitMethod generated constructor check for record classes
1 parent 48bce73 commit 64deb6a

File tree

106 files changed

+334
-226
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+334
-226
lines changed

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,35 @@ public enum CompilerRange {
2828
* Map the compiler (point + 1) position to SemanticDB start and use (point + symbol name length +
2929
* 1) for the SemanticDB end position.
3030
*/
31-
FROM_POINT_TO_SYMBOL_NAME_PLUS_ONE;
31+
FROM_POINT_TO_SYMBOL_NAME_PLUS_ONE,
32+
33+
/**
34+
* Use text search to find the start of the symbol name and use (found start + symbol name length)
35+
* for the SemanticDB end position;
36+
*/
37+
FROM_TEXT_SEARCH,
38+
39+
/**
40+
* Use text search to find the start of the symbol name, using the point position as the starting
41+
* search offset and using (found start + symbol name length) for the SemanticDB end position;
42+
*/
43+
FROM_POINT_WITH_TEXT_SEARCH;
3244

3345
public boolean isFromPoint() {
3446
switch (this) {
3547
case FROM_POINT_TO_SYMBOL_NAME:
3648
case FROM_POINT_TO_SYMBOL_NAME_PLUS_ONE:
49+
case FROM_POINT_WITH_TEXT_SEARCH:
50+
return true;
51+
default:
52+
return false;
53+
}
54+
}
55+
56+
public boolean isFromTextSearch() {
57+
switch (this) {
58+
case FROM_TEXT_SEARCH:
59+
case FROM_POINT_WITH_TEXT_SEARCH:
3760
return true;
3861
default:
3962
return false;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.sourcegraph.semanticdb_javac;
2+
3+
import com.sun.source.tree.CompilationUnitTree;
4+
import com.sun.source.tree.LineMap;
5+
import com.sun.source.util.TreePath;
6+
import com.sun.source.util.Trees;
7+
8+
import javax.lang.model.element.Element;
9+
import javax.lang.model.element.Name;
10+
import java.io.IOException;
11+
import java.util.HashMap;
12+
import java.util.Optional;
13+
import java.util.regex.Matcher;
14+
import java.util.regex.Pattern;
15+
16+
import static com.sourcegraph.semanticdb_javac.Debugging.pprint;
17+
18+
public class RangeFinder {
19+
public static Optional<Semanticdb.Range> findRange(
20+
TreePath path,
21+
Trees trees,
22+
CompilationUnitTree root,
23+
Element element,
24+
int startPos,
25+
String source) {
26+
LineMap lineMap = root.getLineMap();
27+
Name name = element.getSimpleName();
28+
if (name.contentEquals("<init>")) name = element.getEnclosingElement().getSimpleName();
29+
30+
int endPos = (int) trees.getSourcePositions().getEndPosition(root, path.getLeaf());
31+
// false for anonymous classes
32+
if (name.length() != 0) {
33+
startPos = findNameIn(name, startPos, source);
34+
endPos = startPos + name.length();
35+
}
36+
37+
if (endPos == -1 || startPos == -1) {
38+
return Optional.empty();
39+
}
40+
41+
Semanticdb.Range range =
42+
Semanticdb.Range.newBuilder()
43+
.setStartLine((int) lineMap.getLineNumber(startPos) - 1)
44+
.setStartCharacter((int) lineMap.getColumnNumber(startPos) - 1)
45+
.setEndLine((int) lineMap.getLineNumber(endPos) - 1)
46+
.setEndCharacter((int) lineMap.getColumnNumber(endPos) - 1)
47+
.build();
48+
return Optional.of(range);
49+
}
50+
51+
private static int findNameIn(CharSequence name, int start, String source) {
52+
if (source.equals("")) return -1;
53+
54+
int offset = source.indexOf(" " + name, start);
55+
if (offset > -1) {
56+
return offset + 1;
57+
}
58+
return -1;
59+
}
60+
}

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

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
package com.sourcegraph.semanticdb_javac;
22

33
import com.sun.source.tree.*;
4-
import com.sun.source.util.JavacTask;
5-
import com.sun.source.util.TaskEvent;
6-
import com.sun.source.util.TreePathScanner;
4+
import com.sun.source.util.*;
5+
import com.sun.tools.javac.code.Flags;
76
import com.sun.tools.javac.code.Symbol;
87
import com.sun.tools.javac.tree.EndPosTable;
98
import com.sun.tools.javac.tree.JCTree;
109
import com.sun.tools.javac.util.JCDiagnostic;
1110
import com.sun.tools.javac.util.Position;
1211
import com.sourcegraph.semanticdb_javac.Semanticdb.SymbolOccurrence.Role;
1312

13+
import javax.lang.model.element.Element;
1414
import javax.lang.model.util.Elements;
1515
import java.io.IOException;
1616
import java.nio.file.Path;
@@ -28,9 +28,11 @@ public class SemanticdbVisitor extends TreePathScanner<Void, Void> {
2828
private final JavacTask task;
2929
private final TaskEvent event;
3030
private final SemanticdbOptions options;
31+
private final Trees trees;
3132
private final EndPosTable endPosTable;
3233
private final ArrayList<Semanticdb.SymbolOccurrence> occurrences;
3334
private final ArrayList<Semanticdb.SymbolInformation> symbolInfos;
35+
private String source;
3436

3537
public SemanticdbVisitor(
3638
JavacTask task, GlobalSymbolsCache globals, TaskEvent event, SemanticdbOptions options) {
@@ -39,13 +41,15 @@ public SemanticdbVisitor(
3941
this.locals = new LocalSymbolsCache(); // Fresh cache per compilation unit.
4042
this.event = event;
4143
this.options = options;
44+
this.trees = Trees.instance(task);
4245
if (event.getCompilationUnit() instanceof JCTree.JCCompilationUnit) {
4346
this.endPosTable = ((JCTree.JCCompilationUnit) event.getCompilationUnit()).endPositions;
4447
} else {
4548
this.endPosTable = new EmptyEndPosTable();
4649
}
4750
this.occurrences = new ArrayList<>();
4851
this.symbolInfos = new ArrayList<>();
52+
this.source = semanticdbText();
4953
}
5054

5155
public Semanticdb.TextDocument buildTextDocument(CompilationUnitTree tree) {
@@ -56,7 +60,7 @@ public Semanticdb.TextDocument buildTextDocument(CompilationUnitTree tree) {
5660
.setSchema(Semanticdb.Schema.SEMANTICDB4)
5761
.setLanguage(Semanticdb.Language.JAVA)
5862
.setUri(semanticdbUri())
59-
.setText(semanticdbText())
63+
.setText(options.includeText ? this.source : "")
6064
.setMd5(semanticdbMd5())
6165
.addAllOccurrences(occurrences)
6266
.addAllSymbols(symbolInfos)
@@ -94,7 +98,8 @@ private void emitSymbolInformation(Symbol sym) {
9498
public Void visitClass(ClassTree node, Void unused) {
9599
if (node instanceof JCTree.JCClassDecl) {
96100
JCTree.JCClassDecl cls = (JCTree.JCClassDecl) node;
97-
emitSymbolOccurrence(cls.sym, cls, Role.DEFINITION, CompilerRange.FROM_POINT_TO_SYMBOL_NAME);
101+
emitSymbolOccurrence(
102+
cls.sym, cls, Role.DEFINITION, CompilerRange.FROM_POINT_WITH_TEXT_SEARCH);
98103
}
99104
return super.visitClass(node, unused);
100105
}
@@ -103,8 +108,11 @@ public Void visitClass(ClassTree node, Void unused) {
103108
public Void visitMethod(MethodTree node, Void unused) {
104109
if (node instanceof JCTree.JCMethodDecl) {
105110
JCTree.JCMethodDecl meth = (JCTree.JCMethodDecl) node;
106-
emitSymbolOccurrence(
107-
meth.sym, meth, Role.DEFINITION, CompilerRange.FROM_POINT_TO_SYMBOL_NAME);
111+
CompilerRange range = CompilerRange.FROM_POINT_TO_SYMBOL_NAME;
112+
if ((meth.sym.flags() & Flags.GENERATEDCONSTR) != 0L) {
113+
range = CompilerRange.FROM_TEXT_SEARCH;
114+
}
115+
emitSymbolOccurrence(meth.sym, meth, Role.DEFINITION, range);
108116
}
109117
return super.visitMethod(node, unused);
110118
}
@@ -177,7 +185,11 @@ private Optional<Semanticdb.Range> semanticdbRange(
177185
start = pos.getStartPosition();
178186
end = pos.getEndPosition(endPosTable);
179187
}
180-
if (start != Position.NOPOS && end != Position.NOPOS && end > start) {
188+
189+
if (kind.isFromTextSearch() && sym.name.length() > 0) {
190+
return RangeFinder.findRange(
191+
getCurrentPath(), trees, getCurrentPath().getCompilationUnit(), sym, start, this.source);
192+
} else if (start != Position.NOPOS && end != Position.NOPOS && end > start) {
181193
LineMap lineMap = event.getCompilationUnit().getLineMap();
182194
Semanticdb.Range range =
183195
Semanticdb.Range.newBuilder()
@@ -214,12 +226,13 @@ private Optional<Semanticdb.SymbolOccurrence> semanticdbOccurrence(
214226
}
215227

216228
private String semanticdbText() {
217-
if (!options.includeText) return "";
229+
if (source != null) return source;
218230
try {
219-
return event.getSourceFile().getCharContent(true).toString();
231+
source = event.getSourceFile().getCharContent(true).toString();
220232
} catch (IOException e) {
221-
return "";
233+
source = "";
222234
}
235+
return source;
223236
}
224237

225238
private String semanticdbMd5() {

tests/snapshots/src/main/generated/com/airbnb/epoxy/AfterPropsSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@
3939
// ^^^^^^^^^^^^^^^ reference java/lang/annotation/RetentionPolicy#
4040
// ^^^^^ reference java/lang/annotation/RetentionPolicy#CLASS.
4141
public @interface AfterPropsSet {
42-
// ^^^^^^^^^^^^^ definition com/airbnb/epoxy/AfterPropsSet#
42+
// ^^^^^^^^^^^^^ definition com/airbnb/epoxy/AfterPropsSet#
4343
}
4444

tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* See https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#asynchronous-support
2424
*/
2525
public abstract class AsyncEpoxyController extends EpoxyController {
26-
// ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyController#
26+
// ^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyController#
2727
// ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyController#
2828

2929
/**

tests/snapshots/src/main/generated/com/airbnb/epoxy/AsyncEpoxyDiffer.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@
5050
* Also adds support for canceling an in progress diff, and makes everything thread safe.
5151
*/
5252
class AsyncEpoxyDiffer {
53-
//^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#
53+
// ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#
5454

5555
interface ResultCallback {
56-
//^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#ResultCallback#
56+
// ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#ResultCallback#
5757
void onResult(@NonNull DiffResult result);
5858
// ^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#ResultCallback#onResult().
5959
// ^^^^^^^ reference androidx/annotation/NonNull#
@@ -322,7 +322,6 @@ public void submitList(@Nullable final List<? extends EpoxyModel<?>> newList) {
322322
// ^^^^^^^^^^^^^^^^ reference local13 6:5
323323
// ^^^^^^^^ reference java/lang/Runnable#
324324
// ^^^^^^^^ reference java/lang/Runnable#
325-
// ^ definition local13 1:4
326325
@Override
327326
// ^^^^^^^^ reference java/lang/Override#
328327
public void run() {
@@ -371,7 +370,6 @@ private void onRunCompleted(
371370
// ^^^^^^^^^^^^^^^^ reference local20 8:5
372371
// ^^^^^^^^ reference java/lang/Runnable#
373372
// ^^^^^^^^ reference java/lang/Runnable#
374-
// ^ definition local20 1:4
375373
@Override
376374
// ^^^^^^^^ reference java/lang/Override#
377375
public void run() {
@@ -449,8 +447,8 @@ private synchronized boolean tryLatchList(@Nullable List<? extends EpoxyModel<?>
449447
* generation number is synced with the list state at the time it was created.
450448
*/
451449
private static class GenerationTracker {
452-
// ^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#GenerationTracker#`<init>`().
453-
// ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#GenerationTracker#
450+
// ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#GenerationTracker#
451+
// ^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#GenerationTracker#`<init>`().
454452

455453
// Max generation of currently scheduled runnable
456454
private volatile int maxScheduledGeneration;
@@ -507,7 +505,7 @@ synchronized boolean finishGeneration(int runGeneration) {
507505
}
508506

509507
private static class DiffCallback extends DiffUtil.Callback {
510-
// ^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#DiffCallback#
508+
// ^^^^^^^^^^^^ definition com/airbnb/epoxy/AsyncEpoxyDiffer#DiffCallback#
511509
// ^^^^^^^^ reference DiffUtil/
512510
// ^^^^^^^^ reference DiffUtil/Callback#
513511

tests/snapshots/src/main/generated/com/airbnb/epoxy/AutoModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@
3636
// ^^^^^^^^^^^^^^^ reference java/lang/annotation/RetentionPolicy#
3737
// ^^^^^ reference java/lang/annotation/RetentionPolicy#CLASS.
3838
public @interface AutoModel {
39-
// ^^^^^^^^^ definition com/airbnb/epoxy/AutoModel#
39+
// ^^^^^^^^^ definition com/airbnb/epoxy/AutoModel#
4040

4141
}

tests/snapshots/src/main/generated/com/airbnb/epoxy/BaseEpoxyAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
// ^^^^^^^^^^^^ reference androidx/recyclerview/widget/RecyclerView#
6161

6262
public abstract class BaseEpoxyAdapter
63-
// ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BaseEpoxyAdapter#
63+
// ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BaseEpoxyAdapter#
6464
extends RecyclerView.Adapter<EpoxyViewHolder>
6565
// ^^^^^^^^^^^^ reference RecyclerView/
6666
// ^^^^^^^ reference RecyclerView/Adapter#

tests/snapshots/src/main/generated/com/airbnb/epoxy/BaseEpoxyTouchCallback.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// ^^^^ reference android/view/View#
77

88
interface BaseEpoxyTouchCallback<T extends EpoxyModel> {
9-
//^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BaseEpoxyTouchCallback#
9+
// ^^^^^^^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BaseEpoxyTouchCallback#
1010
// ^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyModel#
1111

1212
/**

tests/snapshots/src/main/generated/com/airbnb/epoxy/BoundViewHolders.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
@SuppressWarnings("WeakerAccess")
2424
//^^^^^^^^^^^^^^^ reference java/lang/SuppressWarnings#
2525
public class BoundViewHolders implements Iterable<EpoxyViewHolder> {
26-
// ^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#`<init>`().
27-
// ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#
26+
// ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#
27+
// ^^^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#`<init>`().
2828
// ^^^^^^^^ reference java/lang/Iterable#
2929
// ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyViewHolder#
3030
private final LongSparseArray<EpoxyViewHolder> holders = new LongSparseArray<>();
@@ -104,8 +104,8 @@ public EpoxyViewHolder getHolderForModel(EpoxyModel<?> model) {
104104
}
105105

106106
private class HolderIterator implements Iterator<EpoxyViewHolder> {
107-
// ^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#HolderIterator#`<init>`().
108-
// ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#HolderIterator#
107+
// ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#HolderIterator#
108+
// ^^^^^^^^^^^^^^ definition com/airbnb/epoxy/BoundViewHolders#HolderIterator#`<init>`().
109109
// ^^^^^^^^ reference java/util/Iterator#
110110
// ^^^^^^^^^^^^^^^ reference com/airbnb/epoxy/EpoxyViewHolder#
111111
private int position = 0;

0 commit comments

Comments
 (0)