Skip to content

Commit

Permalink
feat: make error lines now
Browse files Browse the repository at this point in the history
  • Loading branch information
jumanji144 committed Jul 16, 2024
1 parent 8f587be commit c5b610f
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*
* @author Matt Coley
*/
public record CompilerDiagnostic(int line, int column, @Nonnull String message, @Nonnull Level level) {
public record CompilerDiagnostic(int line, int column, int length, @Nonnull String message, @Nonnull Level level) {
/**
* @param line
* New line number.
Expand All @@ -25,7 +25,7 @@ public record CompilerDiagnostic(int line, int column, @Nonnull String message,
*/
@Nonnull
public CompilerDiagnostic withLine(int line) {
return new CompilerDiagnostic(line, column, message, level);
return new CompilerDiagnostic(line, column, length, message, level);

Check warning on line 28 in recaf-core/src/main/java/software/coley/recaf/services/compile/CompilerDiagnostic.java

View check run for this annotation

Codecov / codecov/patch

recaf-core/src/main/java/software/coley/recaf/services/compile/CompilerDiagnostic.java#L28

Added line #L28 was not covered by tests
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ public void report(@Nonnull Diagnostic<? extends JavaFileObject> diagnostic) {
diagnostics.add(new CompilerDiagnostic(
(int) diagnostic.getLineNumber(),
(int) diagnostic.getColumnNumber(),
(int) diagnostic.getEndPosition() - (int) diagnostic.getPosition(),
diagnostic.getMessage(Locale.getDefault()),
mapKind(diagnostic.getKind())
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ private GenerateResult generateStandardClass(@Nonnull String source) {
source = source.replace("\t" + originalName + "(", "\t" + modifiedName + "(");
} else {
return new GenerateResult(null, List.of(
new CompilerDiagnostic(-1, -1, "Could not determine name of class", CompilerDiagnostic.Level.ERROR)));
new CompilerDiagnostic(-1, -1, 0,
"Could not determine name of class", CompilerDiagnostic.Level.ERROR)));
}

// Compile the class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,21 +568,28 @@ public double computeWidthUntilCharacter(int paragraph, int character) {
double width = 0;
int index = 0;

double lastWidth = 0;
double lastX = 0;

for (Text textNode : textNodes) {
String text = textNode.getText();
double boundWidth = textNode.getBoundsInLocal().getWidth();

if (index + text.length() < character) {
width += boundWidth;
index += text.length();
} else {
int length = character - index;
double lastStart = lastX + lastWidth;
double charWidth = boundWidth / StringUtil.getTabAdjustedLength(text);
width += charWidth * length;
break;

// Compute the width of the text until the character.
return lastStart + charWidth * (character - index);
}

lastWidth = boundWidth;
lastX = textNode.getLayoutX();
}

return width;
return 0L;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ public record Problem(int line, int column, int length, ProblemLevel level, Prob
*/
@Nonnull
public static Problem fromDiagnostic(@Nonnull CompilerDiagnostic diagnostic) {
// TODO: refactor CompilerDiagnostic to also have a length field
ProblemLevel level = switch (diagnostic.level()) {
case WARNING -> ProblemLevel.WARN;
case INFO -> ProblemLevel.INFO;
default -> ProblemLevel.ERROR;
};
return new Problem(diagnostic.line(), diagnostic.column(), 1,
return new Problem(diagnostic.line(), diagnostic.column(), diagnostic.length(),
level, ProblemPhase.BUILD, diagnostic.message());

Check warning on line 26 in recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/problem/Problem.java

View check run for this annotation

Codecov / codecov/patch

recaf-ui/src/main/java/software/coley/recaf/ui/control/richtext/problem/Problem.java#L25-L26

Added lines #L25 - L26 were not covered by tests
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
package software.coley.recaf.ui.control.richtext.problem;

import jakarta.annotation.Nonnull;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.Tooltip;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import org.kordamp.ikonli.carbonicons.CarbonIcons;
import software.coley.recaf.ui.control.FontIconView;
import software.coley.recaf.ui.control.richtext.Editor;
import software.coley.recaf.ui.control.richtext.linegraphics.AbstractLineGraphicFactory;
import software.coley.recaf.ui.control.richtext.linegraphics.LineContainer;
import software.coley.recaf.ui.control.richtext.linegraphics.AbstractTextBoundLineGraphicFactory;
import software.coley.recaf.ui.control.richtext.linegraphics.LineGraphicFactory;


/**
* Graphic factory that adds overlays to line graphics indicating the problem status of the line.
*
* @author Matt Coley
* @see ProblemTracking
*/
public class ProblemGraphicFactory extends AbstractLineGraphicFactory {
private Editor editor;

public class ProblemGraphicFactory extends AbstractTextBoundLineGraphicFactory {
/**
* New graphic factory.
*/
Expand All @@ -30,67 +23,61 @@ public ProblemGraphicFactory() {
}

@Override
public void install(@Nonnull Editor editor) {
this.editor = editor;
}
protected void apply(StackPane pane, int paragraph) {
if (editor.getProblemTracking() == null)
return;

@Override
public void uninstall(@Nonnull Editor editor) {
this.editor = null;
}
Problem problem = editor.getProblemTracking().getProblem(paragraph + 1);

@Override
public void apply(@Nonnull LineContainer container, int paragraph) {
ProblemTracking problemTracking = editor.getProblemTracking();

// Always null if no bracket tracking is registered for the editor.
if (problemTracking == null) return;

// Add problem graphic overlay to lines with problems.
int line = paragraph + 1;
Problem problem = problemTracking.getProblem(line);
if (problem != null) {
ProblemLevel level = problem.getLevel();
Color levelColor = switch (level) {
case ERROR -> Color.RED;
case WARN -> Color.YELLOW;
default -> Color.TURQUOISE;
};
Node graphic = switch (level) {
case ERROR -> new FontIconView(CarbonIcons.ERROR, levelColor);
case WARN -> new FontIconView(CarbonIcons.WARNING_ALT, levelColor);
default -> new FontIconView(CarbonIcons.INFORMATION, levelColor);
};

Rectangle shape = new Rectangle();
shape.widthProperty().bind(container.widthProperty());
shape.heightProperty().bind(container.heightProperty());
shape.setCursor(Cursor.HAND);
shape.setFill(levelColor);
shape.setOpacity(0.33);

Tooltip tooltip = new Tooltip(formatTooltipMessage(problem));
tooltip.setGraphic(graphic);
switch (level) {
case ERROR -> tooltip.getStyleClass().add("error-text");
case WARN -> tooltip.getStyleClass().add("warn-text");
}
Tooltip.install(shape, tooltip);
container.addTopLayer(shape);
}
if (problem == null)
return;

// compute the width of the draw canvas and offset required
int index = problem.column() + 1;
double toStart = editor.computeWidthUntilCharacter(paragraph, index);
double toEnd = editor.computeWidthUntilCharacter(paragraph, index + problem.length());
toEnd = Math.max(toEnd, toStart + 6);
double errorWidth = toEnd - toStart;

// Create the overlay
Canvas canvas = new Canvas(toEnd, containerHeight);
canvas.setManaged(false);
canvas.setMouseTransparent(true);
canvas.setTranslateY(3);
canvas.setTranslateX(toStart + 1.7);

pane.getChildren().add(canvas);

drawWaves(canvas, errorWidth);
}

private static String formatTooltipMessage(Problem problem) {
StringBuilder sb = new StringBuilder();
int line = problem.getLine();
if (line > 0) {
int column = problem.getColumn();
if (column >= 0) {
sb.append("Column ").append(column);
}
} else {
sb.append("Unknown line");
private void drawWaves(Canvas canvas, double errorWidth) {
var gc = canvas.getGraphicsContext2D();

// make a solid red line
gc.setStroke(Color.RED);
gc.setLineWidth(1);

gc.beginPath();

final double scalingFactor = .7;
final double waveUp = 3 * scalingFactor;
final double waveDown = 6 * scalingFactor;
final double stop = errorWidth - scalingFactor;

// draw sawtooth pattern
for (double offset = 0; offset < stop; offset += waveDown) {
gc.moveTo(offset, containerHeight - waveUp);
if (offset + waveUp < stop)
gc.lineTo(offset + waveUp, containerHeight - waveDown);
if (offset + waveDown < stop)
gc.lineTo(offset + waveDown, containerHeight - waveUp);
}
return sb.append('\n').append(problem.getMessage()).toString();

// draw one last wave up
gc.lineTo(stop, containerHeight - waveUp);

gc.stroke();
gc.closePath();
}
}

0 comments on commit c5b610f

Please sign in to comment.