Bug 540325: [RJ-Dbg] Improve support for breakpoints in nested functions
Change-Id: Ie6639e59020d157dbef3f2698d54c94af93c5b84
diff --git a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Srcref.java b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Srcref.java
index 407003f..a0ba0c4 100644
--- a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Srcref.java
+++ b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Srcref.java
@@ -33,133 +33,174 @@
public static final int NA= Integer.MIN_VALUE;
- public static final int @Nullable [] diff(final int[] base, final int[] rel) {
- final int[] diff= new int[6];
-
- if (base[BEGIN_LINE] > 0 && rel[BEGIN_LINE] > 0) {
- diff[BEGIN_LINE]= 1 + rel[BEGIN_LINE] - base[BEGIN_LINE];
- if (diff[BEGIN_LINE] <= 0) {
- return null;
- }
- }
- else {
- diff[BEGIN_LINE]= NA;
- }
- if (diff[BEGIN_LINE] == 1) {
- if (base[BEGIN_COLUMN] > 0 && rel[BEGIN_COLUMN] > 0) {
- diff[BEGIN_COLUMN]= 1 + rel[BEGIN_COLUMN] - base[BEGIN_COLUMN];
- if (diff[BEGIN_COLUMN] <= 0) {
- return null;
- }
- }
- else {
- diff[BEGIN_COLUMN]= NA;
- }
- if (base[BEGIN_BYTE] > 0 && rel[BEGIN_BYTE] > 0) {
- diff[BEGIN_BYTE]= 1 + rel[BEGIN_BYTE] - base[BEGIN_BYTE];
- if (diff[BEGIN_BYTE] <= 0) {
- diff[BEGIN_BYTE]= NA;
- }
- }
- else {
- diff[BEGIN_BYTE]= NA;
- }
- }
-
- if (base[BEGIN_LINE] > 0 && rel[END_LINE] > 0) {
- diff[END_LINE]= 1 + rel[END_LINE] - base[BEGIN_LINE];
- if (diff[END_LINE] <= 0) {
- return null;
- }
- }
- else {
- diff[END_LINE]= NA;
- }
- if (diff[END_LINE] == 1) {
- if (base[BEGIN_COLUMN] > 0 && rel[END_COLUMN] > 0) {
- diff[END_COLUMN]= 1 + rel[END_COLUMN] - base[BEGIN_COLUMN];
- if (diff[END_COLUMN] <= 0) {
- return null;
- }
- }
- else {
- diff[END_COLUMN]= NA;
- }
- if (base[BEGIN_BYTE] > 0 && rel[END_BYTE] > 0) {
- diff[END_BYTE]= 1 + rel[END_BYTE] - base[BEGIN_BYTE];
- if (diff[END_BYTE] <= 0) {
- diff[END_BYTE]= NA;
- }
- }
- else {
- diff[END_BYTE]= NA;
- }
- }
-
- return diff;
+ public static final int[] copy(final int[] srcref) {
+ final int[] clone= new int[6];
+ System.arraycopy(srcref, 0, clone, 0, 6);
+ return clone;
}
- public static final int addLine(final int base, final int diff) {
- if (base > 0 && diff > 0) {
- return base + diff - 1;
+ public static final int addLine(final int main, final int ref) {
+ if (main > 0 && ref > 0) {
+ return main + ref - 1;
}
else {
return NA;
}
}
- public static final int[] add(final int[] base, final int[] diff) {
- final int[] sum= new int[6];
+ public static final int @Nullable [] substract(final int[] main, final int[] ref) {
+ final int[] result= new int[6];
- sum[BEGIN_LINE]= addLine(base[BEGIN_LINE], diff[BEGIN_LINE]);
- if (diff[BEGIN_LINE] == 1) {
- if (base[BEGIN_COLUMN] > 0 && diff[BEGIN_COLUMN] > 0) {
- sum[BEGIN_COLUMN]= base[BEGIN_COLUMN] + diff[BEGIN_COLUMN] - 1;
- }
- else {
- sum[BEGIN_COLUMN]= NA;
- }
- if (base[BEGIN_BYTE] > 0 && diff[BEGIN_BYTE] > 0) {
- sum[BEGIN_BYTE]= base[BEGIN_BYTE] + diff[BEGIN_BYTE] - 1;
- }
- else {
- sum[BEGIN_BYTE]= NA;
+ if (main[BEGIN_LINE] > 0 && ref[BEGIN_LINE] > 0) {
+ result[BEGIN_LINE]= 1 + main[BEGIN_LINE] - ref[BEGIN_LINE];
+ if (result[BEGIN_LINE] <= 0) {
+ return null;
}
}
else {
- sum[BEGIN_COLUMN]= base[BEGIN_COLUMN];
- sum[BEGIN_BYTE]= base[BEGIN_BYTE];
+ result[BEGIN_LINE]= NA;
}
-
- sum[END_LINE]= addLine(base[BEGIN_LINE], diff[END_LINE]);
- if (diff[END_LINE] == 1) {
- if (base[BEGIN_COLUMN] > 0 && diff[END_COLUMN] > 0) {
- sum[END_COLUMN]= base[BEGIN_COLUMN] + diff[END_COLUMN] - 1;
+ if (result[BEGIN_LINE] == 1) {
+ if (main[BEGIN_COLUMN] > 0 && ref[BEGIN_COLUMN] > 0) {
+ result[BEGIN_COLUMN]= 1 + main[BEGIN_COLUMN] - ref[BEGIN_COLUMN];
+ if (result[BEGIN_COLUMN] <= 0) {
+ return null;
+ }
}
else {
- sum[END_COLUMN]= NA;
+ result[BEGIN_COLUMN]= NA;
}
- if (base[BEGIN_BYTE] > 0 && diff[END_BYTE] > 0) {
- sum[END_BYTE]= base[BEGIN_BYTE] + diff[END_BYTE] - 1;
+ if (main[BEGIN_BYTE] > 0 && ref[BEGIN_BYTE] > 0) {
+ result[BEGIN_BYTE]= 1 + main[BEGIN_BYTE] - ref[BEGIN_BYTE];
+ if (result[BEGIN_BYTE] <= 0) {
+ result[BEGIN_BYTE]= NA;
+ }
}
else {
- sum[END_BYTE]= NA;
+ result[BEGIN_BYTE]= NA;
}
}
else {
- sum[END_COLUMN]= base[END_COLUMN];
- sum[END_BYTE]= base[END_BYTE];
+ result[BEGIN_COLUMN]= main[BEGIN_COLUMN];
+ result[BEGIN_BYTE]= NA;
}
- return sum;
+ if (main[END_LINE] > 0 && ref[BEGIN_LINE] > 0) {
+ result[END_LINE]= 1 + main[END_LINE] - ref[BEGIN_LINE];
+ if (result[END_LINE] <= 0) {
+ return null;
+ }
+ }
+ else {
+ result[END_LINE]= NA;
+ }
+ if (result[END_LINE] == 1) {
+ if (main[END_COLUMN] > 0 && ref[BEGIN_COLUMN] > 0) {
+ result[END_COLUMN]= 1 + main[END_COLUMN] - ref[BEGIN_COLUMN];
+ if (result[END_COLUMN] <= 0) {
+ return null;
+ }
+ }
+ else {
+ result[END_COLUMN]= NA;
+ }
+ if (main[END_BYTE] > 0 && ref[BEGIN_BYTE] > 0) {
+ result[END_BYTE]= 1 + main[END_BYTE] - ref[BEGIN_BYTE];
+ if (result[END_BYTE] <= 0) {
+ result[END_BYTE]= NA;
+ }
+ }
+ else {
+ result[END_BYTE]= NA;
+ }
+ }
+ else {
+ result[END_COLUMN]= main[END_COLUMN];
+ result[END_BYTE]= NA;
+ }
+
+ return result;
}
+ public static final int[] add(final int[] main, final int[] ref) {
+ final int[] result= new int[6];
+
+ result[BEGIN_LINE]= addLine(main[BEGIN_LINE], ref[BEGIN_LINE]);
+ if (main[BEGIN_LINE] == 1) {
+ if (main[BEGIN_COLUMN] > 0 && ref[BEGIN_COLUMN] > 0) {
+ result[BEGIN_COLUMN]= main[BEGIN_COLUMN] + ref[BEGIN_COLUMN] - 1;
+ }
+ else {
+ result[BEGIN_COLUMN]= NA;
+ }
+ if (main[BEGIN_BYTE] > 0 && ref[BEGIN_BYTE] > 0) {
+ result[BEGIN_BYTE]= main[BEGIN_BYTE] + ref[BEGIN_BYTE] - 1;
+ }
+ else {
+ result[BEGIN_BYTE]= NA;
+ }
+ }
+ else {
+ result[BEGIN_COLUMN]= main[BEGIN_COLUMN];
+ result[BEGIN_BYTE]= main[BEGIN_BYTE];
+ }
+
+ result[END_LINE]= addLine(main[END_LINE], ref[BEGIN_LINE]);
+ if (main[END_LINE] == 1) {
+ if (main[BEGIN_COLUMN] > 0 && ref[END_COLUMN] > 0) {
+ result[END_COLUMN]= main[BEGIN_COLUMN] + ref[END_COLUMN] - 1;
+ }
+ else {
+ result[END_COLUMN]= NA;
+ }
+ if (main[BEGIN_BYTE] > 0 && ref[END_BYTE] > 0) {
+ result[END_BYTE]= main[BEGIN_BYTE] + ref[END_BYTE] - 1;
+ }
+ else {
+ result[END_BYTE]= NA;
+ }
+ }
+ else {
+ result[END_COLUMN]= main[END_COLUMN];
+ result[END_BYTE]= main[END_BYTE];
+ }
+
+ return result;
+ }
+
+
+ public static final int[] merge(final int[] main, final int[] last) {
+ final int[] result= copy(main);
+ if (last != main && last[END_LINE] > 0) {
+ if (last[END_LINE] == result[END_LINE]) {
+ if (last[END_COLUMN] > 0 && last[END_COLUMN] > result[END_COLUMN]) {
+ result[END_COLUMN]= last[END_COLUMN];
+ result[END_BYTE]= last[END_BYTE];
+ }
+ }
+ else if (last[END_LINE] > result[END_LINE]) {
+ result[END_LINE]= last[END_LINE];
+ result[END_COLUMN]= last[END_COLUMN];
+ result[END_BYTE]= last[END_BYTE];
+ }
+ }
+ return result;
+ }
public static final boolean equalsStart(final int[] srcref1, final int[] srcref2) {
return (srcref1[BEGIN_LINE] == srcref2[BEGIN_LINE]
&& srcref1[BEGIN_COLUMN] == srcref2[BEGIN_COLUMN]);
}
+ public static final boolean contains(final int[] srcref1, final int[] srcref2) {
+ return (((srcref1[BEGIN_LINE] == srcref2[BEGIN_LINE]) ?
+ (srcref1[BEGIN_COLUMN] <= srcref2[BEGIN_COLUMN]) :
+ (srcref1[BEGIN_LINE] < srcref2[BEGIN_LINE]) )
+ && ((srcref1[END_LINE] == srcref2[END_LINE]) ?
+ (srcref1[END_COLUMN] >= srcref2[END_COLUMN]) :
+ (srcref1[END_LINE] > srcref2[END_LINE]) ) );
+ }
+
public static final boolean equalsDim(final int[] srcref1, final int[] srcref2) {
return (srcref1[END_LINE] - srcref1[BEGIN_LINE] == srcref2[Srcref.END_LINE] - srcref2[BEGIN_LINE]
&& srcref1[END_COLUMN] - srcref1[BEGIN_COLUMN] == srcref2[Srcref.END_COLUMN] - srcref2[BEGIN_COLUMN]);
diff --git a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/TracepointPosition.java b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/TracepointPosition.java
index 773d685..d2f9a55 100644
--- a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/TracepointPosition.java
+++ b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/TracepointPosition.java
@@ -35,23 +35,35 @@
private final long id;
- protected int[] exprIndex;
- protected int @Nullable [] exprSrcref;
+ private final int[] exprIndex;
+ private final int[] @Nullable [] exprSrcrefs;
public TracepointPosition(final int type, final long id,
+ final int[] index) {
+ this.type= type;
+ this.id= id;
+ this.exprIndex= nonNullAssert(index);
+ this.exprSrcrefs= new int[this.exprIndex.length] @Nullable [];
+ }
+
+ public TracepointPosition(final int type, final long id,
final int[] index, final int @Nullable [] srcref) {
this.type= type;
this.id= id;
this.exprIndex= nonNullAssert(index);
- this.exprSrcref= srcref;
+ this.exprSrcrefs= new int[this.exprIndex.length] @Nullable [];
+ this.exprSrcrefs[this.exprSrcrefs.length - 1]= srcref;
}
TracepointPosition(final RJIO io) throws IOException {
this.type= io.readInt();
this.id= io.readLong();
- this.exprIndex= io.readIntArray();
- this.exprSrcref= io.readIntArray();
+ this.exprIndex= nonNullAssert(io.readIntArray());
+ this.exprSrcrefs= new int[this.exprIndex.length] @Nullable [];
+ for (int i= 0; i < this.exprSrcrefs.length; i++) {
+ this.exprSrcrefs[i]= io.readIntArray();
+ }
}
@Override
@@ -59,7 +71,10 @@
io.writeInt(this.type);
io.writeLong(this.id);
io.writeIntArray(this.exprIndex, this.exprIndex.length);
- io.writeIntArray(this.exprSrcref, (this.exprSrcref != null) ? 6 : -1);
+ for (int i= 0; i < this.exprSrcrefs.length; i++) {
+ final int[] srcref= this.exprSrcrefs[i];
+ io.writeIntArray(srcref, (srcref != null) ? 6 : -1);
+ }
}
@@ -77,8 +92,16 @@
return this.exprIndex;
}
+ public int [] @Nullable [] getSrcrefs() {
+ return this.exprSrcrefs;
+ }
+
+ public int @Nullable [] getSrcref(final int level) {
+ return this.exprSrcrefs[level];
+ }
+
public int @Nullable [] getSrcref() {
- return this.exprSrcref;
+ return this.exprSrcrefs[this.exprSrcrefs.length - 1];
}
@@ -129,7 +152,7 @@
final StringBuilder sb= new StringBuilder("TracepointPosition"); //$NON-NLS-1$
sb.append(" (type= ").append(this.type).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
sb.append("\n\t" + "exprIndex= ").append(Arrays.toString(this.exprIndex)); //$NON-NLS-1$ //$NON-NLS-2$
- sb.append("\n\t" + "exprSrcref= ").append(Arrays.toString(this.exprSrcref)); //$NON-NLS-1$ //$NON-NLS-2$
+ sb.append("\n\t" + "exprSrcref= ").append(Arrays.toString(getSrcref())); //$NON-NLS-1$ //$NON-NLS-2$
return sb.toString();
}
diff --git a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Tracepoints.java b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Tracepoints.java
index 15cf5e5..ae98da9 100644
--- a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Tracepoints.java
+++ b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/dbg/Tracepoints.java
@@ -14,7 +14,10 @@
package org.eclipse.statet.rj.server.dbg;
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -23,6 +26,7 @@
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNull;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
@NonNullByDefault
@@ -45,6 +49,16 @@
return -1;
}
+ public static final @Nullable TracepointPosition getPositionById(final List<? extends TracepointPosition> list,
+ final long id) {
+ for (int j= 0; j < list.size(); j++) {
+ final TracepointPosition p= list.get(j);
+ if (p.getId() == id) {
+ return p;
+ }
+ }
+ return null;
+ }
public static final boolean containsPositionsById(final List<? extends TracepointPosition> list,
final List<? extends TracepointPosition> requiredIds) {
@@ -99,7 +113,7 @@
return true;
}
- public static final List<TracepointPosition> filterPositionsById(final List<? extends TracepointPosition> list,
+ public static final List<TracepointPosition> filterPositionsByIdRequired(final List<? extends TracepointPosition> list,
final List<? extends TracepointPosition> requiredIds) {
final int l= requiredIds.size();
if (list.size() == l) {
@@ -120,7 +134,7 @@
return ImCollections.newList(array);
}
- public static final List<TracepointPosition> intersectPositionsById(final List<? extends TracepointPosition> list,
+ public static final List<TracepointPosition> filterPositionsById(final List<? extends TracepointPosition> list,
final List<? extends TracepointPosition> includedIds) {
final int l= includedIds.size();
final List<TracepointPosition> intersection= new ArrayList<>(l);
@@ -139,7 +153,7 @@
return intersection;
}
- public static final List<TracepointPosition> intersectPositionsById(final List<? extends TracepointPosition> list,
+ public static final List<TracepointPosition> filterPositionsById(final List<? extends TracepointPosition> list,
final long[] includedIds) {
final int l= includedIds.length;
final List<TracepointPosition> intersection= new ArrayList<>(l);
@@ -158,6 +172,95 @@
return intersection;
}
+ public static final List<TracepointPosition> filterPositionsBySrcref(final List<? extends TracepointPosition> list,
+ final int[] baseSrcref, final int[] includedSrcref) {
+ final List<TracepointPosition> intersection= new ArrayList<>(list.size());
+ for (int j= 0; j < list.size(); j++) {
+ final TracepointPosition p= list.get(j);
+ final int [] @Nullable [] srcrefs= p.getSrcrefs();
+ for (int i= 0; i < srcrefs.length; i++) {
+ if (srcrefs[i] != null
+ && Srcref.equalsStart(Srcref.add(srcrefs[i], baseSrcref), includedSrcref) ) {
+ intersection.add(p);
+ break;
+ }
+ }
+ }
+ return intersection;
+ }
+
+ public static final int @Nullable [] findIndexBySrcref(final List<? extends TracepointPosition> list,
+ final int[] baseSrcref, final int[] includedSrcref) {
+ for (int j= 0; j < list.size(); j++) {
+ final TracepointPosition p= list.get(j);
+ final int [] @Nullable [] srcrefs= p.getSrcrefs();
+ for (int depth= 0; depth < srcrefs.length; depth++) {
+ if (srcrefs[depth] != null
+ && Srcref.equalsStart(Srcref.add(srcrefs[depth], baseSrcref), includedSrcref) ) {
+ return Arrays.copyOf(p.getIndex(), depth + 1);
+ }
+ }
+ }
+ return null;
+ }
+
+ public static final int @Nullable [] findIndexByReference(final List<? extends TracepointPosition> list,
+ final List<? extends TracepointPosition> reference) {
+ if (!list.isEmpty()) {
+ final TracepointPosition p= list.get(0);
+ final TracepointPosition refP= nonNullAssert(getPositionById(reference, p.getId()));
+ final int[] index= p.getIndex();
+ final int depth= index.length - 1 - refP.getIndex().length;
+ if (depth > 0 && depth < index.length) {
+ return Arrays.copyOf(index, depth + 1);
+ }
+ }
+ return null;
+ }
+
+ private static final boolean equalsIndex(final int[] index, final int[] included) {
+ if (index.length < included.length) {
+ return false;
+ }
+ for (int i= 0; i < included.length; i++) {
+ if (index[i] != included[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static final int @Nullable [] getSrcrefForIndex(final List<? extends TracepointPosition> list,
+ final int[] includedIndex) {
+ final int depth= includedIndex.length - 1;
+ for (int j= 0; j < list.size(); j++) {
+ final TracepointPosition p= list.get(j);
+ final int[] srcref;
+ if (equalsIndex(p.getIndex(), includedIndex)
+ && (srcref= p.getSrcref(depth)) != null ) {
+ return srcref;
+ }
+ }
+ return null;
+ }
+
+ public static final List<TracepointPosition> rebasePositionsByIndex(final List<? extends TracepointPosition> list,
+ final int[] newBaseIndex) {
+ final int depth= newBaseIndex.length - 1;
+ final List<TracepointPosition> intersection= new ArrayList<>(list.size());
+ for (int j= 0; j < list.size(); j++) {
+ final TracepointPosition p= list.get(j);
+ final int[] index= p.getIndex();
+ if (equalsIndex(index, newBaseIndex)
+ && p.getSrcref() != null && p.getSrcref(depth) != null ) {
+ intersection.add(new TracepointPosition(p.getType(), p.getId(),
+ Arrays.copyOfRange(index, depth + 1, index.length),
+ Srcref.substract(p.getSrcref(), p.getSrcref(depth)) ));
+ }
+ }
+ return intersection;
+ }
+
private static final char[] DIGITS= new char[] {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
diff --git a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/rh/AbstractTracepointManager.java b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/rh/AbstractTracepointManager.java
index 0f573de..4bf7d39 100644
--- a/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/rh/AbstractTracepointManager.java
+++ b/core/org.eclipse.statet.rj.server/src/org/eclipse/statet/rj/server/rh/AbstractTracepointManager.java
@@ -14,13 +14,18 @@
package org.eclipse.statet.rj.server.rh;
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import static org.eclipse.statet.rj.server.dbg.Srcfiles.equalsTimestamp;
import static org.eclipse.statet.rj.server.dbg.Tracepoints.LOGGER;
import static org.eclipse.statet.rj.server.dbg.Tracepoints.containsPositionsById;
import static org.eclipse.statet.rj.server.dbg.Tracepoints.equalsPositions;
import static org.eclipse.statet.rj.server.dbg.Tracepoints.filterPositionsById;
+import static org.eclipse.statet.rj.server.dbg.Tracepoints.filterPositionsByIdRequired;
+import static org.eclipse.statet.rj.server.dbg.Tracepoints.findIndexByReference;
+import static org.eclipse.statet.rj.server.dbg.Tracepoints.findIndexBySrcref;
+import static org.eclipse.statet.rj.server.dbg.Tracepoints.getSrcrefForIndex;
import static org.eclipse.statet.rj.server.dbg.Tracepoints.indexOfTracepointById;
-import static org.eclipse.statet.rj.server.dbg.Tracepoints.intersectPositionsById;
+import static org.eclipse.statet.rj.server.dbg.Tracepoints.rebasePositionsByIndex;
import static org.eclipse.statet.rj.server.rh.ObjectManager.WEAK_REF;
import java.util.ArrayList;
@@ -67,6 +72,7 @@
private static final String ENV_INSTALLED_TAG= "#" + WEAK_REF + ":dbg.tracepoints";
+ private static final int MAX_HISTORY= 12;
private static final int MAX_FUZZY= 8;
@@ -171,6 +177,8 @@
protected static final ImList<TracepointPosition> NO_POSITIONS= ImCollections.emptyList();
protected static final ElementTracepoints NO_POSITION_ELEMENT_TRACEPOINTS= new ElementTracepoints(
new SrcfileData(null, null, 0), "", null, NO_POSITIONS ); //$NON-NLS-1$
+ protected static final ElementTracepoints NO_CHANGE_ELEMENT_TRACEPOINTS= new ElementTracepoints(
+ new SrcfileData(null, null, 0), "", null, NO_POSITIONS ); //$NON-NLS-1$
/**
@@ -224,7 +232,7 @@
}
public List<? extends TracepointPosition> getActualPositions(final List<? extends TracepointPosition> positions) {
- return filterPositionsById(positions, this.current.getPositions());
+ return filterPositionsByIdRequired(positions, this.current.getPositions());
}
public long getRequestedTimestamp() {
@@ -337,6 +345,7 @@
}
ElementEntry elementEntry= null;
+ boolean isNestedMatch= false;
if (id != null) { // by id
elementEntry= getElementEntry(id);
}
@@ -348,9 +357,16 @@
}
final ElementTracepoints cand= entry.getTracepoints(timestamp);
if (cand != null && cand.getElementSrcref() != null
- && Srcref.equalsStart(cand.getElementSrcref(), srcref)) {
- elementEntry= entry;
- break;
+ && Srcref.contains(cand.getElementSrcref(), srcref) ) {
+ if (Srcref.equalsStart(cand.getElementSrcref(), srcref)) {
+ elementEntry= entry;
+ isNestedMatch= false;
+ break;
+ }
+ else {
+ elementEntry= entry;
+ isNestedMatch= true;
+ }
}
}
}
@@ -391,7 +407,9 @@
}
}
return (elementEntry != null) ?
- elementEntry.findCurrentTracepoints(timestamp, srcref, this.states) :
+ (isNestedMatch) ?
+ elementEntry.findCurrentNestedTracepoints(timestamp, srcref, this.states) :
+ elementEntry.findCurrentTracepoints(timestamp, srcref, this.states) :
null;
}
@@ -496,7 +514,7 @@
this.history.set(0, tracepoints);
}
else {
- if (this.history.size() >= 10) {
+ if (this.history.size() >= MAX_HISTORY) {
this.history.remove(this.history.size() - 1);
}
this.history.add(0, tracepoints);
@@ -553,7 +571,7 @@
return cand;
}
best= cand;
- timestampPositions= intersectPositionsById(cand.getPositions(), current.getPositions());
+ timestampPositions= filterPositionsById(cand.getPositions(), current.getPositions());
end= i;
break;
}
@@ -593,7 +611,7 @@
}
if (end > 1 && !current.getPositions().isEmpty()) {
if (timestamp != 0) {
- List<TracepointPosition> timestampPositions= null;
+ List<TracepointPosition> timestampActualPositions= null;
for (int i= 0; i < end; i++) {
final ElementTracepoints cand= this.history.get(i);
if (equalsTimestamp(cand.getSrcfile().getTimestamp(), timestamp)) {
@@ -601,17 +619,17 @@
return new ElementTracepointsCollection(this.updateStamp,
current, cand, timestamp );
}
- timestampPositions= intersectPositionsById(cand.getPositions(), current.getPositions());
+ timestampActualPositions= filterPositionsById(cand.getPositions(), current.getPositions());
end= i;
break;
}
}
- if (timestampPositions != null && !timestampPositions.isEmpty() ) {
+ if (timestampActualPositions != null && !timestampActualPositions.isEmpty()) {
for (int i= 0; i < end; i++) {
final ElementTracepoints cand= this.history.get(i);
if (containsPositionsById(cand.getPositions(), current.getPositions())
- && equalsPositions(cand.getPositions(), timestampPositions,
- timestampPositions )) {
+ && equalsPositions(cand.getPositions(), timestampActualPositions,
+ timestampActualPositions )) {
return new ElementTracepointsCollection(this.updateStamp,
current, cand, timestamp );
}
@@ -643,6 +661,110 @@
}
}
+ public @Nullable ElementTracepointsCollection findCurrentNestedTracepoints(
+ final long timestamp, final int[] srcref,
+ final @Nullable StateSet states) {
+ synchronized (this.history) {
+ if (!this.history.isEmpty()) {
+ final ElementTracepoints current= this.history.get(0);
+ int end= this.history.size();
+ if (current.getPositions().isEmpty()
+ || (states != null && isAllDeleted(current.getPositions(), states)) ) {
+ return createNoPositionCollection();
+ }
+ if (timestamp != 0) {
+ int[] timestampSrcref= null;
+ List<TracepointPosition> timestampPositions= null;
+ for (int i= 0; i < end; i++) {
+ final ElementTracepoints cand= this.history.get(i);
+ if (equalsTimestamp(cand.getSrcfile().getTimestamp(), timestamp)) {
+ if (cand.getElementSrcref() == null) {
+ break;
+ }
+ final int[] index= findIndexBySrcref(cand.getPositions(),
+ nonNullAssert(cand.getElementSrcref()), srcref );
+ if (index != null) {
+ timestampSrcref= nonNullAssert(getSrcrefForIndex(
+ cand.getPositions(), index ));
+ timestampPositions= rebasePositionsByIndex(
+ cand.getPositions(), index );
+ if (containsPositionsById(cand.getPositions(), current.getPositions())) {
+ return createNestedCollection(current,
+ createNested(cand, timestampSrcref, filterPositionsById(
+ timestampPositions, current.getPositions() )),
+ timestamp, states );
+ }
+ }
+ end= i;
+ break;
+ }
+ }
+ if (timestampPositions != null && !timestampPositions.isEmpty()) {
+ for (int i= 0; i < end; i++) {
+ final ElementTracepoints cand= this.history.get(i);
+ if (containsPositionsById(cand.getPositions(), current.getPositions())) {
+ final List<TracepointPosition> compareList= filterPositionsById(
+ cand.getPositions(), timestampPositions );
+ final int[] index= findIndexByReference(compareList, timestampPositions);
+ if (index != null) {
+ final int[] candSrcref= nonNullAssert(getSrcrefForIndex(
+ compareList, index ));
+ final List<TracepointPosition> candPositions= rebasePositionsByIndex(
+ cand.getPositions(), index );
+ if (equalsPositions(candPositions, timestampPositions,
+ timestampPositions )) {
+ return createNestedCollection(current,
+ createNested(cand, candSrcref, filterPositionsById(
+ candPositions, current.getPositions() )),
+ timestamp, states );
+ }
+ }
+ }
+ }
+ { final List<TracepointPosition> positions= filterPositionsById(
+ timestampPositions, current.getPositions() );
+ if (positions.isEmpty()
+ || (states != null && isAllDeleted(positions, states)) ) {
+ return createNoPositionCollection();
+ }
+ }
+ }
+ return createNoChangeCollection();
+ }
+ }
+ return null;
+ }
+ }
+
+ private ElementTracepointsCollection createNoPositionCollection() {
+ return new ElementTracepointsCollection(this.updateStamp,
+ NO_POSITION_ELEMENT_TRACEPOINTS, NO_POSITION_ELEMENT_TRACEPOINTS, 0 );
+ }
+
+ private ElementTracepointsCollection createNoChangeCollection() {
+ return new ElementTracepointsCollection(this.updateStamp,
+ NO_CHANGE_ELEMENT_TRACEPOINTS, NO_CHANGE_ELEMENT_TRACEPOINTS, 0 );
+ }
+
+ private ElementTracepoints createNested(final ElementTracepoints cand,
+ final int[] srcref, final List<TracepointPosition> nestedPositions) {
+ return new ElementTracepoints(cand.getSrcfile(), this.id, srcref, nestedPositions);
+ }
+
+ private ElementTracepointsCollection createNestedCollection(final ElementTracepoints current,
+ final ElementTracepoints nested, final long requestedTimestamp,
+ final @Nullable StateSet states) {
+ final List<TracepointPosition> currentPositions= filterPositionsById(
+ current.getPositions(), nested.getPositions());
+ if (currentPositions.isEmpty()
+ || (states != null && isAllDeleted(currentPositions, states)) ) {
+ return createNoPositionCollection();
+ }
+ return new ElementTracepointsCollection(this.updateStamp,
+ new ElementTracepoints(current.getSrcfile(), this.id, null, currentPositions),
+ nested, requestedTimestamp );
+ }
+
}
protected class StateEntry implements Comparable<StateEntry> {