Added basic error and warning highlighting as well as compiler summary

This commit is contained in:
Brendan Robert 2015-07-17 01:45:18 -05:00
parent 3b4960c3de
commit 693d29952b
6 changed files with 144 additions and 43 deletions

View File

@ -24,7 +24,8 @@ public class AcmeCompiler implements CompileResult<File> {
boolean successful = false;
File compiledAsset = null;
Map<Integer, String> errorsAndWarnings = new LinkedHashMap<>();
Map<Integer, String> errors = new LinkedHashMap<>();
Map<Integer, String> warnings = new LinkedHashMap<>();
List<String> otherWarnings = new ArrayList<>();
List<String> rawOutput = new ArrayList<>();
@ -39,8 +40,13 @@ public class AcmeCompiler implements CompileResult<File> {
}
@Override
public Map<Integer, String> getErrorsAndWarnings() {
return errorsAndWarnings;
public Map<Integer, String> getErrors() {
return errors;
}
@Override
public Map<Integer, String> getWarnings() {
return warnings;
}
@Override
@ -101,11 +107,33 @@ public class AcmeCompiler implements CompileResult<File> {
restoreSystemOutput();
System.setProperty("user.dir", oldPath);
}
String output = baosOut.toString();
String errors = baosErr.toString();
System.out.println("output: "+output);
System.out.println("error: "+errors);
rawOutput.add("Error output:");
extractOutput(baosErr.toString());
rawOutput.add("");
rawOutput.add("------------------------------");
rawOutput.add("Standard output:");
extractOutput(baosOut.toString());
}
public void extractOutput(String output) throws NumberFormatException {
for (String line : output.split("\\n")) {
rawOutput.add(line);
int lineNumberStart = line.indexOf(", line") + 6;
if (lineNumberStart > 6) {
int lineNumberEnd = line.indexOf(' ', lineNumberStart+1);
int actualLineNumber = Integer.parseUnsignedInt(line.substring(lineNumberStart, lineNumberEnd).trim());
String message = line.substring(lineNumberEnd).trim();
if (line.startsWith("Error")) {
errors.put(actualLineNumber, message);
} else {
warnings.put(actualLineNumber, message);
}
} else {
if (line.trim().length() > 1) {
otherWarnings.add(line);
}
}
}
}
public void restoreSystemOutput() {

View File

@ -13,7 +13,9 @@ public interface CompileResult<T> {
public T getCompiledAsset();
public Map<Integer, String> getErrorsAndWarnings();
public Map<Integer, String> getErrors();
public Map<Integer, String> getWarnings();
public List<String> getOtherMessages();

View File

@ -18,6 +18,7 @@ import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
@ -200,12 +201,18 @@ public class IdeController {
@FXML
void executeClicked(ActionEvent event) {
getCurrentProgram().ifPresent(proxy -> proxy.execute());
getCurrentProgram().ifPresent(program -> {
program.execute();
updateStatusMessages(program.lastResult);
});
}
@FXML
void testCompileClicked(ActionEvent event) {
getCurrentProgram().ifPresent(proxy -> proxy.test());
getCurrentProgram().ifPresent(program -> {
program.test();
updateStatusMessages(program.lastResult);
});
}
@FXML
@ -242,4 +249,12 @@ public class IdeController {
runMenu.setDisable(hasNoItems);
});
}
private void updateStatusMessages(CompileResult lastResult) {
String message = "Compiler was " + (lastResult.isSuccessful() ? " successful" : " NOT SUCCESSFUL");
message += " -- ";
message += lastResult.getErrors().size() + " error(s) and "+lastResult.getWarnings().size()+" warning(s) reported.";
statusBar.getItems().clear();
statusBar.getItems().add(new Label(message));
}
}

View File

@ -29,36 +29,6 @@ public class Program {
public static String CODEMIRROR_EDITOR = "/codemirror/editor.html";
public void save(File newTarget) {
FileWriter writer = null;
if (newTarget == null && targetFile == null) {
return;
}
if (newTarget != null) {
targetFile = newTarget;
}
filename = targetFile.getName();
try {
writer = new FileWriter(targetFile, false);
writer.append(getValue());
writer.close();
} catch (IOException ex) {
Logger.getLogger(Program.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException ex) {
Logger.getLogger(Program.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public boolean isChanged() {
return (Boolean) codeMirror.call("isClean");
}
public static enum DocumentType {
applesoft(new ApplesoftHandler(), "textfile", "*.bas"), assembly(new AssemblyHandler(), "textfile", "*.a", "*.s", "*.asm"), plain(new TextHandler(), "textfile", "*.txt"), hex(new TextHandler(), "textfile", "*.bin", "*.raw");
@ -165,7 +135,8 @@ public class Program {
public void createEditor() {
String document = targetFile == null ? getHandler().getNewDocumentContent() : getFileContents(targetFile);
String optionString = buildOptions();
codeMirror = (JSObject) editor.getEngine().executeScript("CodeMirror(document.body, " + optionString + ");");
editor.getEngine().executeScript("var codeMirror = CodeMirror(document.body, " + optionString + ");");
codeMirror = (JSObject) editor.getEngine().executeScript("codeMirror");
setValue(document);
}
@ -195,6 +166,37 @@ public class Program {
return "";
}
public void save(File newTarget) {
FileWriter writer = null;
if (newTarget == null && targetFile == null) {
return;
}
if (newTarget != null) {
targetFile = newTarget;
}
filename = targetFile.getName();
try {
writer = new FileWriter(targetFile, false);
writer.append(getValue());
writer.close();
} catch (IOException ex) {
Logger.getLogger(Program.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException ex) {
Logger.getLogger(Program.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public boolean isChanged() {
return (Boolean) codeMirror.call("isClean");
}
private String buildOptions() {
StringBuilder builder = new StringBuilder();
builder.append("{");
@ -215,6 +217,7 @@ public class Program {
public void execute() {
lastResult = getHandler().compile(this);
manageCompileResult(lastResult);
if (lastResult.isSuccessful()) {
getHandler().execute(lastResult);
}
@ -222,6 +225,21 @@ public class Program {
public void test() {
lastResult = getHandler().compile(this);
manageCompileResult(lastResult);
}
private void manageCompileResult(CompileResult lastResult) {
editor.getEngine().executeScript("clearHighlights()");
lastResult.getWarnings().forEach((line,message) ->
editor.getEngine().executeScript("highlightLine("+line+",false,\""+escapeString(message)+"\");")
);
lastResult.getErrors().forEach((line,message) ->
editor.getEngine().executeScript("highlightLine("+line+",true,\""+escapeString(message)+"\");")
);
}
private String escapeString(Object message) {
return String.valueOf(message).replaceAll("\\\"", "&quot;");
}
public void log(String message) {

View File

@ -32,7 +32,12 @@ class TextHandler implements LanguageHandler<String> {
}
@Override
public Map<Integer, String> getErrorsAndWarnings() {
public Map<Integer, String> getErrors() {
return Collections.EMPTY_MAP;
}
@Override
public Map<Integer, String> getWarnings() {
return Collections.EMPTY_MAP;
}

View File

@ -1,6 +1,7 @@
<html>
<head>
<title>Jace IDE</title>
<!--<script src="lib/jquery-2.1.4.min.js"></script>-->
<script src="lib/codemirror.js"></script>
<link rel="stylesheet" href="lib/codemirror.css"/>
</head>
@ -14,6 +15,38 @@
overflow-x: hidden;
overflow-y: hidden;
}
.line-error {
background: #FBC2C4 !important;
color: #8a1f11 !important;
}
.line-warning {
background: #F8FFAB !important;
color: #000080 !important;
}
</style>
<script>
var messages = [];
function clearHighlights() {
codeMirror.eachLine(function (line) {
codeMirror.removeLineClass(line, "background", "line-error");
codeMirror.removeLineClass(line, "background", "line-warning");
});
for (var i = 0; i < messages.length; ++i) {
codeMirror.removeLineWidget(messages[i]);
}
messages = [];
}
function highlightLine(lineNumber, isError, message) {
if (isError) {
codeMirror.removeLineClass(lineNumber-1, "background", "line-warning");
}
codeMirror.addLineClass(lineNumber - 1, 'background', isError ? 'line-error' : 'line-warning');
var msg = document.createElement("div");
var text = document.createTextNode(message);
msg.appendChild(text);
var widget = codeMirror.addLineWidget(lineNumber - 1, msg, {coverGutter: false, noHScroll: true});
messages.push(widget);
}
</script>
</body>
</html>