Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@
import java.util.List;

public class Scope {

public static class LineRange {
final int start;
final int end;

public LineRange(int start, int end) {
this.start = start;
this.end = end;
}
}

@Json(name = "scope_type")
private final ScopeType scopeType;

Expand All @@ -16,6 +27,12 @@ public class Scope {
@Json(name = "end_line")
private final int endLine;

@Json(name = "has_injectible_lines")
private final boolean hasInjectibleLines;

@Json(name = "injectible_lines")
private final List<LineRange> injectibleLines;

private final String name;

@Json(name = "language_specifics")
Expand All @@ -30,6 +47,8 @@ public Scope(
int startLine,
int endLine,
String name,
boolean hasInjectibleLines,
List<LineRange> injectibleLines,
LanguageSpecifics languageSpecifics,
List<Symbol> symbols,
List<Scope> scopes) {
Expand All @@ -38,6 +57,8 @@ public Scope(
this.startLine = startLine;
this.endLine = endLine;
this.name = name;
this.hasInjectibleLines = hasInjectibleLines;
this.injectibleLines = injectibleLines;
this.languageSpecifics = languageSpecifics;
this.symbols = symbols;
this.scopes = scopes;
Expand All @@ -63,6 +84,14 @@ public String getName() {
return name;
}

public boolean hasInjectibleLines() {
return hasInjectibleLines;
}

public List<LineRange> getInjectibleLines() {
return injectibleLines;
}

public LanguageSpecifics getLanguageSpecifics() {
return languageSpecifics;
}
Expand Down Expand Up @@ -110,6 +139,8 @@ public static class Builder {
private final int startLine;
private final int endLine;
private String name;
private boolean hasInjectibleLines;
private List<LineRange> injectibleLines;
private LanguageSpecifics languageSpecifics;
private List<Symbol> symbols;
private List<Scope> scopes;
Expand All @@ -126,6 +157,16 @@ public Builder name(String name) {
return this;
}

public Builder hasInjectibleLines(boolean hasInjectibleLines) {
this.hasInjectibleLines = hasInjectibleLines;
return this;
}

public Builder injectibleLines(List<LineRange> injectibleLines) {
this.injectibleLines = injectibleLines;
return this;
}

public Builder languageSpecifics(LanguageSpecifics languageSpecifics) {
this.languageSpecifics = languageSpecifics;
return this;
Expand All @@ -143,7 +184,16 @@ public Builder scopes(List<Scope> scopes) {

public Scope build() {
return new Scope(
scopeType, sourceFile, startLine, endLine, name, languageSpecifics, symbols, scopes);
scopeType,
sourceFile,
startLine,
endLine,
name,
hasInjectibleLines,
injectibleLines,
languageSpecifics,
symbols,
scopes);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Label;
Expand Down Expand Up @@ -124,6 +126,8 @@ private static List<Scope> extractMethods(ClassNode classNode, String sourceFile
.name(method.name)
.scopes(varScopes)
.symbols(methodSymbols)
.hasInjectibleLines(!methodLineInfo.ranges.isEmpty())
.injectibleLines(methodLineInfo.ranges)
.languageSpecifics(methodSpecifics)
.build();
methodScopes.add(methodScope);
Expand Down Expand Up @@ -431,26 +435,47 @@ private static Scope maxScope(Scope scope1, Scope scope2) {
: scope1;
}

private static int getFirstLine(MethodNode methodNode) {
AbstractInsnNode node = methodNode.instructions.getFirst();
while (node != null) {
if (node.getType() == AbstractInsnNode.LINE) {
LineNumberNode lineNumberNode = (LineNumberNode) node;
return lineNumberNode.line;
static List<Scope.LineRange> buildRanges(List<Integer> sortedLineNo) {
if (sortedLineNo.isEmpty()) {
return Collections.emptyList();
}
List<Scope.LineRange> ranges = new ArrayList<>();
int start = sortedLineNo.get(0);
int previous = start;
int i = 1;
outer:
while (i < sortedLineNo.size()) {
int currentLineNo = sortedLineNo.get(i);
while (currentLineNo == previous + 1) {
i++;
previous++;
if (i < sortedLineNo.size()) {
currentLineNo = sortedLineNo.get(i);
} else {
break outer;
}
}
node = node.getNext();
ranges.add(new Scope.LineRange(start, previous));
start = currentLineNo;
previous = start;
i++;
}
return 0;
ranges.add(new Scope.LineRange(start, previous));
return ranges;
}

private static MethodLineInfo extractMethodLineInfo(MethodNode methodNode) {
Map<Label, Integer> map = new HashMap<>();
int startLine = getFirstLine(methodNode);
int maxLine = startLine;
List<Integer> lineNo = new ArrayList<>();
Set<Integer> dedupSet = new HashSet<>();
AbstractInsnNode node = methodNode.instructions.getFirst();
int maxLine = 0;
while (node != null) {
if (node.getType() == AbstractInsnNode.LINE) {
LineNumberNode lineNumberNode = (LineNumberNode) node;
if (dedupSet.add(lineNumberNode.line)) {
lineNo.add(lineNumberNode.line);
}
maxLine = Math.max(lineNumberNode.line, maxLine);
}
if (node.getType() == AbstractInsnNode.LABEL) {
Expand All @@ -461,7 +486,10 @@ private static MethodLineInfo extractMethodLineInfo(MethodNode methodNode) {
}
node = node.getNext();
}
return new MethodLineInfo(startLine, maxLine, map);
lineNo.sort(Integer::compareTo);
int startLine = lineNo.isEmpty() ? 0 : lineNo.get(0);
List<Scope.LineRange> ranges = buildRanges(lineNo);
return new MethodLineInfo(startLine, maxLine, map, ranges);
}

private static ClassNode parseClassFile(byte[] classfileBuffer) {
Expand All @@ -475,11 +503,15 @@ public static class MethodLineInfo {
final int start;
final int end;
final Map<Label, Integer> lineMap;
final List<Scope.LineRange> ranges;

public MethodLineInfo(int start, int end, Map<Label, Integer> lineMap) {
public MethodLineInfo(
int start, int end, Map<Label, Integer> lineMap, List<Scope.LineRange> ranges) {
this.start = start;
this.end = end;
this.lineMap = lineMap;

this.ranges = ranges;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void testSimpleFlush() {
assertEquals("file", symbolContent.getPartName());
assertEquals("file.json", symbolContent.getFileName());
assertEquals(
"{\"language\":\"JAVA\",\"scopes\":[{\"end_line\":0,\"scope_type\":\"JAR\",\"start_line\":0}],\"service\":\"service1\"}",
"{\"language\":\"JAVA\",\"scopes\":[{\"end_line\":0,\"has_injectible_lines\":false,\"scope_type\":\"JAR\",\"start_line\":0}],\"service\":\"service1\"}",
new String(symbolContent.getContent()));
}

Expand Down Expand Up @@ -109,12 +109,12 @@ public void splitByJarScopes() {
}

@Test
public void splitTootManyJarScopes() {
public void splitTooManyJarScopes() {
SymbolUploaderMock symbolUploaderMock = new SymbolUploaderMock();
Config config = mock(Config.class);
when(config.getServiceName()).thenReturn("service1");
when(config.isSymbolDatabaseCompressed()).thenReturn(false);
SymbolSink symbolSink = new SymbolSink(config, symbolUploaderMock, 2048);
SymbolSink symbolSink = new SymbolSink(config, symbolUploaderMock, 4096);
final int NUM_JAR_SCOPES = 21;
for (int i = 0; i < NUM_JAR_SCOPES; i++) {
symbolSink.addScope(
Expand Down
Loading