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