package bluej.stride.framedjava.errors;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import bluej.compiler.Diagnostic.DiagnosticOrigin;
import bluej.stride.framedjava.ast.ASTUtility;
import bluej.stride.framedjava.ast.FilledExpressionSlotFragment;
import bluej.stride.framedjava.ast.NameDefSlotFragment;
import bluej.stride.framedjava.ast.StringSlotFragment;
import bluej.stride.framedjava.ast.TypeSlotFragment;
import bluej.stride.framedjava.errors.Correction.SimpleCorrectionInfo;
import bluej.stride.framedjava.frames.AssignFrame;
import bluej.stride.framedjava.frames.ClassFrame;
import bluej.stride.framedjava.frames.VarFrame;
import bluej.stride.generic.Frame;
import bluej.stride.generic.FrameCursor;
import threadchecker.OnThread;
import threadchecker.Tag;
public class UndeclaredVariableLvalueError
extends DirectSlotError{
private final AssignFrame assignFrame;
private final List<Correction> corrections = new ArrayList<>();
private final String varName;
| Creates an error about an undeclared variable being used on the left-hand side of an assignment.
| The variable will occupy the entire left-hand side of an assignment frame, and will thus be
| a candidate for a quick fix which turns the assignment into a declaration+initialisation of that variable.
|
| @param slotFragment The fragment with the error.
| @param assignFrame The assignment frame with the error.
| @param possibleCorrections The possible other variable names (unfiltered: all variable names which are in scope)
|
@OnThread(Tag.FXPlatform)
public UndeclaredVariableLvalueError(StringSlotFragment slotFragment, AssignFrame assignFrame, Set<String> possibleCorrections)
{
super(slotFragment, DiagnosticOrigin.STRIDE_LATE);
this.assignFrame = assignFrame;
this.corrections.addAll(Correction.winnowAndCreateCorrections(assignFrame.getLHS().getText(), possibleCorrections.stream().map(SimpleCorrectionInfo::new), s -> assignFrame.getLHS().setText(s)));
this.varName = assignFrame.getLHS().getText();
}
@Override
@OnThread(Tag.Any)
public String getMessage()
{
return "Undeclared variable: " + varName;
}
@Override
public List getFixSuggestions()
{
ArrayList<FixSuggestion> fixes = new ArrayList<>();
fixes.add(new ChangeAssignmentToDeclarationAndInitialisation());
fixes.add(new AddFieldDeclaration());
fixes.addAll(corrections);
return fixes;
}
private class ChangeAssignmentToDeclarationAndInitialisation
extends FixSuggestion
{
@Override
public String getDescription()
{
return "Declare variable here";
}
@Override
public void execute()
{
assignFrame.getParentCanvas().replaceBlock(assignFrame, new VarFrame(assignFrame.getEditor(), null, false, false, new TypeSlotFragment("", ""),
new NameDefSlotFragment(assignFrame.getLHS().getText()), new FilledExpressionSlotFragment(assignFrame.getRHS().getSlotElement()), true));
}
}
private class AddFieldDeclaration
extends FixSuggestion
{
@Override
public String getDescription()
{
return "Declare field in class";
}
@Override
public void execute()
{
ClassFrame classFrame = (ClassFrame)ASTUtility.getTopLevelElement(assignFrame.getCode()).getFrame();
List<Frame> members = classFrame.getfieldsCanvas().getBlockContents();
Optional<Frame> firstNonField = members.stream().filter(f -> !(f instanceof VarFrame)).findFirst();
FrameCursor cursorAfter = (firstNonField.isPresent()) ? cursorAfter = classFrame.getfieldsCanvas().getCursorBefore(firstNonField.get()) : classFrame.getfieldsCanvas().getLastCursor();
classFrame.getfieldsCanvas().insertBlockBefore(new VarFrame(assignFrame.getEditor(), null, false, false,
new TypeSlotFragment("", ""), new NameDefSlotFragment(assignFrame.getLHS().getText()), null, true), cursorAfter);
}
}
@Override
public boolean isJavaPos()
{
return false;
}
}
top,
use,
map,
class UndeclaredVariableLvalueError
. UndeclaredVariableLvalueError
. getMessage
. getFixSuggestions
top,
use,
map,
class UndeclaredVariableLvalueError . ChangeAssignmentToDeclarationAndInitialisation
. getDescription
. execute
top,
use,
map,
class UndeclaredVariableLvalueError . ChangeAssignmentToDeclarationAndInitialisation . AddFieldDeclaration
. getDescription
. execute
. isJavaPos
129 neLoCode
+ 6 LoComm