forked from Apple-2-Tools/jace
Added basic error and warning highlighting as well as compiler summary
This commit is contained in:
parent
3b4960c3de
commit
693d29952b
@ -24,7 +24,8 @@ public class AcmeCompiler implements CompileResult<File> {
|
|||||||
|
|
||||||
boolean successful = false;
|
boolean successful = false;
|
||||||
File compiledAsset = null;
|
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> otherWarnings = new ArrayList<>();
|
||||||
List<String> rawOutput = new ArrayList<>();
|
List<String> rawOutput = new ArrayList<>();
|
||||||
|
|
||||||
@ -39,8 +40,13 @@ public class AcmeCompiler implements CompileResult<File> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Integer, String> getErrorsAndWarnings() {
|
public Map<Integer, String> getErrors() {
|
||||||
return errorsAndWarnings;
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Integer, String> getWarnings() {
|
||||||
|
return warnings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -101,11 +107,33 @@ public class AcmeCompiler implements CompileResult<File> {
|
|||||||
restoreSystemOutput();
|
restoreSystemOutput();
|
||||||
System.setProperty("user.dir", oldPath);
|
System.setProperty("user.dir", oldPath);
|
||||||
}
|
}
|
||||||
String output = baosOut.toString();
|
rawOutput.add("Error output:");
|
||||||
String errors = baosErr.toString();
|
extractOutput(baosErr.toString());
|
||||||
System.out.println("output: "+output);
|
rawOutput.add("");
|
||||||
System.out.println("error: "+errors);
|
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() {
|
public void restoreSystemOutput() {
|
||||||
|
@ -13,7 +13,9 @@ public interface CompileResult<T> {
|
|||||||
|
|
||||||
public T getCompiledAsset();
|
public T getCompiledAsset();
|
||||||
|
|
||||||
public Map<Integer, String> getErrorsAndWarnings();
|
public Map<Integer, String> getErrors();
|
||||||
|
|
||||||
|
public Map<Integer, String> getWarnings();
|
||||||
|
|
||||||
public List<String> getOtherMessages();
|
public List<String> getOtherMessages();
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import javafx.collections.ListChangeListener;
|
|||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.Event;
|
import javafx.event.Event;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Menu;
|
import javafx.scene.control.Menu;
|
||||||
import javafx.scene.control.MenuItem;
|
import javafx.scene.control.MenuItem;
|
||||||
import javafx.scene.control.Tab;
|
import javafx.scene.control.Tab;
|
||||||
@ -200,12 +201,18 @@ public class IdeController {
|
|||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void executeClicked(ActionEvent event) {
|
void executeClicked(ActionEvent event) {
|
||||||
getCurrentProgram().ifPresent(proxy -> proxy.execute());
|
getCurrentProgram().ifPresent(program -> {
|
||||||
|
program.execute();
|
||||||
|
updateStatusMessages(program.lastResult);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void testCompileClicked(ActionEvent event) {
|
void testCompileClicked(ActionEvent event) {
|
||||||
getCurrentProgram().ifPresent(proxy -> proxy.test());
|
getCurrentProgram().ifPresent(program -> {
|
||||||
|
program.test();
|
||||||
|
updateStatusMessages(program.lastResult);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -242,4 +249,12 @@ public class IdeController {
|
|||||||
runMenu.setDisable(hasNoItems);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,36 +29,6 @@ public class Program {
|
|||||||
|
|
||||||
public static String CODEMIRROR_EDITOR = "/codemirror/editor.html";
|
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 {
|
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");
|
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() {
|
public void createEditor() {
|
||||||
String document = targetFile == null ? getHandler().getNewDocumentContent() : getFileContents(targetFile);
|
String document = targetFile == null ? getHandler().getNewDocumentContent() : getFileContents(targetFile);
|
||||||
String optionString = buildOptions();
|
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);
|
setValue(document);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +166,37 @@ public class Program {
|
|||||||
return "";
|
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() {
|
private String buildOptions() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("{");
|
builder.append("{");
|
||||||
@ -215,6 +217,7 @@ public class Program {
|
|||||||
|
|
||||||
public void execute() {
|
public void execute() {
|
||||||
lastResult = getHandler().compile(this);
|
lastResult = getHandler().compile(this);
|
||||||
|
manageCompileResult(lastResult);
|
||||||
if (lastResult.isSuccessful()) {
|
if (lastResult.isSuccessful()) {
|
||||||
getHandler().execute(lastResult);
|
getHandler().execute(lastResult);
|
||||||
}
|
}
|
||||||
@ -222,6 +225,21 @@ public class Program {
|
|||||||
|
|
||||||
public void test() {
|
public void test() {
|
||||||
lastResult = getHandler().compile(this);
|
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("\\\"", """);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void log(String message) {
|
public void log(String message) {
|
||||||
|
@ -32,7 +32,12 @@ class TextHandler implements LanguageHandler<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
return Collections.EMPTY_MAP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Jace IDE</title>
|
<title>Jace IDE</title>
|
||||||
|
<!--<script src="lib/jquery-2.1.4.min.js"></script>-->
|
||||||
<script src="lib/codemirror.js"></script>
|
<script src="lib/codemirror.js"></script>
|
||||||
<link rel="stylesheet" href="lib/codemirror.css"/>
|
<link rel="stylesheet" href="lib/codemirror.css"/>
|
||||||
</head>
|
</head>
|
||||||
@ -14,6 +15,38 @@
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
.line-error {
|
||||||
|
background: #FBC2C4 !important;
|
||||||
|
color: #8a1f11 !important;
|
||||||
|
}
|
||||||
|
.line-warning {
|
||||||
|
background: #F8FFAB !important;
|
||||||
|
color: #000080 !important;
|
||||||
|
}
|
||||||
</style>
|
</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>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user