Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use offsets from .bgv file to select appropriate text #10510

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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 @@ -246,6 +246,8 @@ public abstract static class Member implements LengthToString {
public final String name;

private Member(Klass holder, String name, int accessFlags) {
assert holder != null : "GraphElements.methodDeclaringClass must not return null!";
assert name != null;
this.holder = holder;
this.accessFlags = accessFlags;
this.name = name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public String toString() {
String sep = "";
for (LocationStackFrame t = this; t != null; t = t.parent) {
sb.append(sep);
sb.append(methodHolderName(t)).append(".").append(t.method.name);
sb.append(methodHolderName(t)).append(".").append(methodName(t));
for (LocationStratum s : t.strata) {
if (s.file != null) {
sb.append("(").append(s.file).append(":").append(s.line).append(")");
Expand All @@ -63,6 +63,9 @@ public String toString() {
return sb.toString();
}

private static String methodName(LocationStackFrame t) {
return t != null && t.method != null ? t.method.name : null;
}
private static String methodHolderName(LocationStackFrame t) {
if (t != null && t.method != null && t.method.holder != null) {
return t.method.holder.name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ private void addResolvedLocation(String filename, FileObject source) {
}

FileKey fk = ctx.file(filename, source);
Location newLoc = new Location(spec, fk, lineno, lastloc, depth, -1);
Location newLoc = new Location(spec, fk, lineno, -1, -1, lastloc, depth, -1);
ctx.attachInfo(newLoc, javaInfo);
javaInfo.withLocation(newLoc);
result.add(newLoc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public final class Location {
*/
private final int originLine;

private final int startOffset;
private final int endOffset;

/**
* Additional data/services, like OpenCookie, Node to present the data etc.
*/
Expand All @@ -62,10 +65,12 @@ public final class Location {

private short frameFrom = -1, frameTo = -1;

public Location(String originSpec, FileKey originFile, int originLine, Location nested, int frame, int frameTo) {
public Location(String originSpec, FileKey originFile, int originLine, int startOffset, int endOffset, Location nested, int frame, int frameTo) {
this.file = originFile;
this.originSpec = originSpec;
this.originLine = originLine;
this.startOffset = startOffset;
this.endOffset = endOffset;
this.frameFrom = (short) frame;
this.frameTo = (short) (frameTo == -1 ? frame : frameTo);
}
Expand Down Expand Up @@ -103,6 +108,20 @@ public int getLine() {
return originLine;
}

/** A pair of offsets.
*
* @return either {@code null} when there are no offsets or an {code @int} array
* of size two. 0th element representing the start and 1st the end offset
* in the document.
*/
public int[] getOffsetsOrNull() {
if (startOffset >= 0 && endOffset > startOffset) {
return new int[] { startOffset, endOffset };
} else {
return null;
}
}

Lookup getLookup() {
return lookup;
}
Expand All @@ -119,6 +138,8 @@ public int hashCode() {
hash = 89 * hash + this.originLine;
hash = 89 * hash + Objects.hashCode(this.file);
hash = 89 * hash + Objects.hashCode(this.parent);
hash = 37 * hash + startOffset;
hash = 37 * hash + endOffset;
cachedHash = hash == -1 ? 7 : hash;
return cachedHash;
}
Expand All @@ -138,6 +159,12 @@ public boolean equals(Object obj) {
if (this.originLine != other.originLine) {
return false;
}
if (this.startOffset != other.startOffset) {
return false;
}
if (this.endOffset != other.endOffset) {
return false;
}
if (this.parent != other.parent) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public final class SourceLocationUtils {
* @param line the line number
* @return location object
*/
public static Location createLocation(FileObject f, int line) {
private static Location createLocation(FileObject f, int line) {
String spec = f.getPath() + ":" + line;
return new Location(spec, FileKey.fromFile(f), line, null, -1, -1);
return new Location(spec, FileKey.fromFile(f), line, -1, -1, null, -1, -1);
}

public static Collection<Location> atLine(List<Location> searchIn, int line) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@

package org.graalvm.visualizer.source.impl.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.graalvm.visualizer.source.Location;
import org.graalvm.visualizer.source.ui.Trackable;
import org.netbeans.api.actions.Openable;
Expand All @@ -34,14 +37,20 @@
import org.openide.text.Line;
import org.openide.util.NbBundle;

import javax.swing.SwingUtilities;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
import org.openide.text.Annotatable;
import org.openide.text.Annotation;
import org.openide.text.NbDocument;
import org.openide.util.Mutex;
import org.openide.util.Task;
import org.openide.util.TaskListener;

/**
*
*/
public class LocationOpener implements Openable, Trackable {
public final class LocationOpener implements Openable, Trackable {
private final Location location;

public LocationOpener(Location location) {
Expand All @@ -57,31 +66,48 @@ public void open() {
}

private void openOrView(boolean focus) {
FileObject toOpen;
toOpen = location.getOriginFile();
FileObject toOpen = location.getOriginFile();
if (toOpen == null) {
return;
}
int line = location.getLine();
EditorCookie cake = toOpen.getLookup().lookup(EditorCookie.class);

Line l;
try {
l = cake.getLineSet().getOriginal(line - 1);
} catch (IndexOutOfBoundsException ex) {
// expected, the source has changed
if (cake == null) {
return;
}
if (l == null) {
cake.open();
StatusDisplayer.getDefault().setStatusText(Bundle.ERR_LineNotFound());
return;
}
if (SwingUtilities.isEventDispatchThread()) {
l.show(Line.ShowOpenType.REUSE, focus ? Line.ShowVisibilityType.FRONT : Line.ShowVisibilityType.FRONT);
} else {
SwingUtilities.invokeLater(() -> l.show(Line.ShowOpenType.REUSE, focus ? Line.ShowVisibilityType.FRONT : Line.ShowVisibilityType.FRONT));

Task task = cake.prepareDocument();
class WhenShowing implements TaskListener, Runnable {
@Override
public void taskFinished(Task task) {
task.removeTaskListener(this);
Mutex.EVENT.postReadRequest(this);
}

@Override
public void run() {
final StyledDocument doc = cake.getDocument();
if (doc == null) {
return;
}
List<Annotatable> select = findLinesOrParts(cake.getLineSet(), doc, location.getLine() - 1, location.getOffsetsOrNull());
if (select.size() == 1 && select.get(0) instanceof Line) {
Line line = (Line) select.get(0);
line.show(Line.ShowOpenType.REUSE, focus ? Line.ShowVisibilityType.FRONT : Line.ShowVisibilityType.FRONT);
CurrentNodeAnnotation.highlight(select);
} else if (select.size() >= 1 && select.get(0) instanceof Line.Part) {
Line.Part part = (Line.Part) select.get(0);
part.getLine().show(Line.ShowOpenType.REUSE, focus ? Line.ShowVisibilityType.FRONT : Line.ShowVisibilityType.FRONT, part.getColumn());
CurrentNodeAnnotation.highlight(select);
} else {
// neither line nor offsets
cake.open();
StatusDisplayer.getDefault().setStatusText(Bundle.ERR_LineNotFound());
}
}

}
WhenShowing select = new WhenShowing();
task.addTaskListener(select);
}

@Override
Expand All @@ -104,4 +130,103 @@ public void viewIfOpened() {
public void view() {
openOrView(false);
}

/**
* Find {@link Line} or {@link Line.Part} to select.
*
* @param lines lines of the document to search in
* @param doc document to search in
* @param lineNumber line number (counting from zero} or value less then zero when there is no line info
* @param offsetsOrNull {@code int[] { startOffset, endOffset }} or {@code null}
* @return found {@link Line} or {@link Line.Part} or {@code null}
*/
static List<Annotatable> findLinesOrParts(Line.Set lines, StyledDocument doc, int lineNumber, int[] offsetsOrNull) {
assert doc != null;

Line exactLine = findLine(lines, lineNumber);
Line startLine = null;
Line endLine = null;
if (offsetsOrNull != null) {
int startOffsetLineNumber = NbDocument.findLineNumber(doc, offsetsOrNull[0]);
startLine = findLine(lines, startOffsetLineNumber);
int endOffsetLineNumber = NbDocument.findLineNumber(doc, offsetsOrNull[1]);
endLine = findLine(lines, endOffsetLineNumber);
}

if (startLine == null || (exactLine != null && startLine != exactLine)) {
// prefer exact line
return Collections.singletonList(exactLine);
} else {
// use offset line
int startLineOffset = NbDocument.findLineOffset(doc, startLine.getLineNumber());
int startColumn = offsetsOrNull[0] - startLineOffset;
if (startLine == endLine || endLine == null) {
int len = offsetsOrNull[1] - offsetsOrNull[0];
Line.Part linePart = startLine.createPart(startColumn, len);
return Collections.singletonList(linePart);
} else {
var multiple = new ArrayList<Annotatable>();
Line.Part firstLinePart = startLine.createPart(startColumn, startLine.getText().length() - startColumn);
multiple.add(firstLinePart);
for (var between = startLine.getLineNumber() + 1; between < endLine.getLineNumber(); between++) {
var lineBetween = findLine(lines, between);
if (lineBetween != null) {
multiple.add(lineBetween);
}
}
int endLineOffset = NbDocument.findLineOffset(doc, endLine.getLineNumber());
int endColumn = offsetsOrNull[1] - endLineOffset;
Line.Part lastLinePart = endLine.createPart(0, endColumn);
multiple.add(lastLinePart);
return multiple;
}
}
}

private static Line findLine(Line.Set lines, int line) {
try {
return lines.getOriginal(line);
} catch (IndexOutOfBoundsException ex) {
// expected, the source has changed
// just open the file
return null;
}
}

@NbBundle.Messages({
"CTL_CurrentNode=Current node"
})
private static final class CurrentNodeAnnotation extends Annotation {
private static List<CurrentNodeAnnotation> previous = Collections.emptyList();

private CurrentNodeAnnotation() {
}

private static void highlight(List<Annotatable> select) {
List<CurrentNodeAnnotation> newOnes = new ArrayList<>();
for (var l : select) {
var a = new CurrentNodeAnnotation();
newOnes.add(a);
a.attach(l);
}
List<CurrentNodeAnnotation> toClear;
synchronized (CurrentNodeAnnotation.class) {
toClear = previous;
previous = newOnes;
}
for (var a : toClear) {
a.detach();
}
}

@Override
public String getAnnotationType() {
return "NodePositionOffset";
}

@Override
public String getShortDescription() {
return Bundle.CTL_CurrentNode();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private Location processFrame() throws IOException, URISyntaxException {
fk = new FileKey(langMime, langStratum.uri);
}
Location newLoc = new Location(langStratum.uri,
fk, langStratum.line, lastloc, lastDepth, depth);
fk, langStratum.line, langStratum.startOffset, langStratum.endOffset, lastloc, lastDepth, depth);
if (newLoc.equals(lastloc)) {
replaceTop(newLoc);
return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>


<!DOCTYPE type PUBLIC "-//NetBeans//DTD annotation type 1.0//EN" "http://www.netbeans.org/dtds/annotation-type-1_0.dtd">
<type
name='NodePositionOffset'
description_key='Hint_NodePositionCurrent'
localizing_bundle='org.graalvm.visualizer.source.resources.Bundle'
visible='true'
glyph='nbresloc:/org/graalvm/visualizer/source/resources/extractNodes.gif'
highlight='0xC8FF00'
type='linepart'
priority='1100'
custom_sidebar_color='0xFFCCCC'
/>
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
<file name="NodePositionCurrent.xml" url="NodePositionCurrent.xml"/>
<file name="CallSiteCurrent.xml" url="CallSiteCurrent.xml"/>
<file name="CalledSiteCurrent.xml" url="CalledSiteCurrent.xml"/>
<file name="NodePositionOffset.xml" url="NodePositionOffset.xml"/>
</folder>
<folder name="FontsColors">
<folder name="NetBeans">
Expand Down
Loading
Loading