package bluej.stride.framedjava.ast;

import java.util.stream.Stream;

import bluej.stride.framedjava.errors.CodeError;
import bluej.stride.framedjava.errors.ErrorShower;
import bluej.stride.framedjava.errors.JavaCompileError;
import bluej.stride.framedjava.errors.SyntaxCodeError;
import bluej.stride.framedjava.slots.ExpressionSlot;
import threadchecker.OnThread;
import threadchecker.Tag;


| A JavaFragment is a small piece of content in a Java class. It never spans more than one line, | and thus never includes a newline character. | public abstract class JavaFragment { private int lineNumber; private int columnNumber; private int len; public static enum Destination {
| Source will be as-is, with no substitutions | JAVA_FILE_TO_COMPILE, | Source may have substitutions to make it valid | SOURCE_DOC_TO_ANALYSE, | Source will be as-is, and no positions recorded | TEMPORARY; public boolean substitute() { return true; } }; @OnThread(Tag.FXPlatform) protected abstract String getJavaCode(Destination dest, ExpressionSlot<?> completing, Parser.DummyNameGenerator dummyNameGenerator); @OnThread(Tag.FX) public abstract ErrorShower getErrorShower(); @OnThread(Tag.FX) public final void recordDiskPosition(int lineNumber, int columnNumber, int len) { this.lineNumber = lineNumber; this.columnNumber = columnNumber; this.len = len; }
| This is an enum returned from checkCompileError. When a Java error is produced by javac, we | have to map this back to a location in Stride code. The way we do this is that we go through | the Java fragments (produced from the Stride code) in order, and ask them "Is this error |* position within your bounds?" The fragment then returns one of these enum values, documented below. * * Note that two adjacent fragments can both say that they overlap the error location, because * we include the left and right edges of the fragment, so an error exactly on the boundary of | two fragments will cause them both to say overlap. | static enum ErrorRelation {
| The error location lies before this fragment. | BEFORE_FRAGMENT, | The error location overlaps this fragment, and we are a good place to show it (e.g. a user-entered slot). | OVERLAPS_FRAGMENT, | The error location does overlap this fragment, but is not the best place to show it (e.g. a piece | of Java syntax that the user did not enter). Display on this only if there is no other overlapping | fragment that is suitable. | OVERLAPS_FRAGMENT_FALLBACK, | The error location lies after this fragment. | AFTER_FRAGMENT, | CANNOT_SHOW means that the fragment can never show errors (e.g. boilerplate) | CANNOT_SHOW; } public ErrorRelation checkCompileError(int startLine, int startColumn, int endLine, int endColumn) { if (startLine > lineNumber) return ErrorRelation.AFTER_FRAGMENT; else if (endLine < lineNumber) return ErrorRelation.BEFORE_FRAGMENT; if (startLine == lineNumber) { if (startColumn > columnNumber + len) return ErrorRelation.AFTER_FRAGMENT; if (endLine > lineNumber) return ErrorRelation.OVERLAPS_FRAGMENT; else if (endColumn < columnNumber) return ErrorRelation.BEFORE_FRAGMENT; } else if (endLine == lineNumber) { if (endColumn < columnNumber + len) return ErrorRelation.BEFORE_FRAGMENT; } return ErrorRelation.OVERLAPS_FRAGMENT; }
| Shows a compile error for this Java fragment, either on the fragment | itself or on its redirect (see getCompileErrorRedirect()). | | @param startLine The .java file error position. Will be mapped back to position in Java editor. | @param startColumn Ditto | @param endLine Ditto | @param endColumn Ditto | @param message The error message | @param identifier The error identifier (for data recording purposes). | @OnThread(Tag.FX) public final void showCompileError(int startLine, int startColumn, int endLine, int endColumn, String message, int identifier) { JavaFragment redirect = getCompileErrorRedirect(); if (redirect != null) { new JavaCompileError(redirect, 0, redirect.len, message, identifier); } else { int startPos = getErrorStartPos(startLine, startColumn); int endPos = getErrorEndPos(endLine, endColumn); new JavaCompileError(this, startPos, endPos, message, identifier); } }
| Gets the compile error redirect target. Some Java fragments | (e.g. the class keyword of a class declaration) don't support | showing errors, usually because they can't get keyboard focus | in the Stride error (which would mean the error could only be | read with the mouse: bad for accessibility). So such fragments | implement this method to return a nearby JavaFragment which can | show an error. Returns null if there's no redirect. | @OnThread(Tag.FX) protected abstract JavaFragment getCompileErrorRedirect(); public int getErrorEndPos(int endLine, int endColumn) { int endPos; if (endLine > lineNumber) endPos = len; else if (endLine == lineNumber) endPos = Math.max(0, Math.min(len, endColumn - columnNumber)); else{ } highlight everything: endPos = len; return endPos; } public int getErrorStartPos(int startLine, int startColumn) { int startPos; if (startLine < lineNumber) startPos = 0; else if (startLine == lineNumber) startPos = Math.min(Math.max(0, startColumn - columnNumber), len); else{ } highlight everything: startPos = 0; return startPos; }
| Finds any pre-compilation errors in this element, i.e. syntax errors. | | If this element returns no errors, then the code can be generated into valid Java. | | (TODO in the future, this should strengthen to: returning no errors means code won't give syntax error) | @OnThread(Tag.FXPlatform) public abstract Stream findEarlyErrors(); @OnThread(Tag.FXPlatform) public abstract void addError(CodeError codeError); public class PosInSourceDoc { public final int offset; public PosInSourceDoc(int offset) { this.offset = offset; }
/*public PosInSourceDoc() | |{} this.offset = 0; | |} public JavaFragment getFragment() { return JavaFragment.this; } } public PosInSourceDoc getPosInSourceDoc(int offset) { return new PosInSourceDoc(offset); } public PosInSourceDoc getPosInSourceDoc() { return getPosInSourceDoc(0); } }
top, use, map, abstract class JavaFragment

.   substitute
.   getJavaCode
.   getErrorShower
.   recordDiskPosition
.   checkCompileError
.   showCompileError
.   getCompileErrorRedirect
.   getErrorEndPos
.   getErrorStartPos
.   findEarlyErrors
.   addError

top, use, map, class JavaFragment . PosInSourceDoc

.   PosInSourceDoc
.   getFragment
.   getPosInSourceDoc
.   getPosInSourceDoc




246 neLoCode + 37 LoComm