Commit 80ef9020 authored by Michael Schwarz's avatar Michael Schwarz

Refactoring to get ride of 900 line method

parent 88a1cea3
......@@ -48,18 +48,14 @@ class ConflictPanel extends Composite {
private static final int HEADING_FONT_SIZE = 14;
private Conflict conflict;
// srdetails may be null if conflict is not a shift-reduce conflict
private ShiftReduceDetails srdetails;
boolean partOfCurrentConnected = false;
private ShiftReduceDetails srdetails; // Null if conflict is not a shift-reduce conflict
private boolean partOfCurrentConnected = false;
private boolean forceEnableDropdown = false;
private Label conflictTypeLabel;
private Link stateLabel;
private Label symbolLabel;
Combo resolutionOptions;
private Combo resolutionOptions;
private Button resolutionButton;
private Composite detailWrapper;
......@@ -68,18 +64,15 @@ class ConflictPanel extends Composite {
private List<Range> links = new ArrayList<Range>();
private Color backgroundColorReduceReduce = new Color(Display.getCurrent(), Colors.conflictBgBlue);
private Color foregroundColorReduceReduce = new Color(Display.getCurrent(), Colors.conflictFgBlue);
private Color foregroundColorReduceReduce = new Color(Display.getCurrent(), Colors.conflictFgBlue);
private Color backgroundColorShiftReduce = new Color(Display.getCurrent(), Colors.conflictBgYellow);
private Color foregroundColorShiftReduce = new Color(Display.getCurrent(), Colors.conflictFgYellow);
private Color foregroundColorShiftReduce = new Color(Display.getCurrent(), Colors.conflictFgYellow);
private Color backgroundColorShiftReduceAffected = new Color(Display.getCurrent(), Colors.conflictBgRed);
private Color foregroundColorShiftReduceAffected = new Color(Display.getCurrent(), Colors.conflictFgRed);
private Color foregroundColorShiftReduceAffected = new Color(Display.getCurrent(), Colors.conflictFgRed);
private Color backgroundColorShiftReduceUnrelated = new Color(Display.getCurrent(), Colors.conflictBgGray);
private Color foregroundColorShiftReduceUnrelated = new Color(Display.getCurrent(), Colors.conflictFgGray);
GridData gridData;
private GridData gridData;
public ConflictPanel(CupConflictsView cupConflictsView, Composite parent, int style) {
super(parent, style);
......@@ -288,21 +281,16 @@ class ConflictPanel extends Composite {
resolutionOptions.removeAll();
} else if (conflict instanceof ShiftReduceConflict) {
srdetails = this.cupConflictsView.new ShiftReduceDetails();
ShiftReduceConflict src = (ShiftReduceConflict) conflict;
changeColors(backgroundColorShiftReduce, foregroundColorShiftReduce);
resolutionOptions.setVisible(true);
resolutionButton.setVisible(true);
srdetails = this.cupConflictsView.new ShiftReduceDetails(src,crm);
ProductionRight conflict1Ast = src.getConflictItem1().the_production().getAstNode();
conflictTypeLabel.setText("Shift-Reduce conflict");
changeColors(backgroundColorShiftReduce, foregroundColorShiftReduce);
conflictTypeLabel.setText("Shift-Reduce conflict");
symbolLabel.setText("Under symbol: " + src.getTerminal().name());
ProductionRight conflict1Ast = src.getConflictItem1()
.the_production().getAstNode();
// TODO: clean up the string builder mess ... ; OAOO!
StringBuilder builder = new StringBuilder();
......@@ -343,86 +331,63 @@ class ConflictPanel extends Composite {
detailText.setText(builder.toString());
resolutionOptions.setVisible(true);
resolutionButton.setVisible(true);
setShiftReduceResolutionOptions();
gridData.heightHint += detailText.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
} else {
throw new RuntimeException("unexpected conflict type.");
}
// Begin resolution hints
terminal sourceOfShiftPrec = src.getTerminal();
terminal sourceOfReducePrec = null;
}
private void setShiftReduceResolutionOptions(){
resolutionOptions.removeAll();
resolutionOptions.add("-- Choose an option --");
resolutionOptions.select(0);
if(srdetails.shiftAndReducePrecedenceFromSameTerminal()) {
// If the precedence of the terminal and the production come from the same terminal
// the thing we need to consider are assocs
// If the precedence is specifically set via %prec
if(conflict1Ast.hasSpecifiedPrecedence()){
sourceOfReducePrec = terminal.getShared(crm.getLaLrContext()).find(
conflict1Ast.getPrecedenceLike().getNameStringOrNull());
if(!srdetails.shiftAffectsOthers){
resolutionOptions.add("Shift (make " + srdetails.shift.name() +" right associative)");
resolutionOptions.add("Reduce (make " + srdetails.shift.name() +" left associative)");
}
// Terminal defining precedence is the last one in the current production
else {
for(IProductionRightPart part : conflict1Ast.getList()){
if(part instanceof ProductionSymbolRef){
ProductionSymbolRef ppsr = (ProductionSymbolRef)part;
terminal candidate = terminal.getShared(crm.getLaLrContext()).find(
ppsr.getNameStringOrNull());
if(candidate != null){
sourceOfReducePrec = candidate;
}
}
}
resolutionOptions.add("Affects others: Shift (make " + srdetails.shift.name() +" right associative)");
resolutionOptions.add("Affects others: Reduce (make " + srdetails.shift.name() +" left associative)");
}
srdetails.shift = sourceOfShiftPrec;
srdetails.shiftAffectsOthers = cupConflictsView.insertingPrecAffectsOtherConflicts(sourceOfShiftPrec);
srdetails.reduce = sourceOfReducePrec;
srdetails.reduceAffectsOthers = cupConflictsView.insertingPrecAffectsOtherConflicts(sourceOfReducePrec);
// RHS is only nonterminal and no %prec directive => sourceOfReducePrec == null
resolutionOptions.removeAll();
resolutionOptions.add("-- Choose an option --");
resolutionOptions.select(0);
}
else {
// If the precedence of the terminal and the production come from different terminals
// we need to choose the precedence
if(sourceOfShiftPrec.equals(sourceOfReducePrec)) {
// If the precedence of the terminal and the production come from the same terminal
// the thing we need to consider are assocs
if(!srdetails.shiftAffectsOthers){
resolutionOptions.add("Shift (make " + sourceOfShiftPrec.name() +" right associative)");
resolutionOptions.add("Reduce (make " + sourceOfShiftPrec.name() +" left associative)");
}
else {
resolutionOptions.add("Affects others: Shift (make " + sourceOfShiftPrec.name() +" right associative)");
resolutionOptions.add("Affects others: Reduce (make " + sourceOfShiftPrec.name() +" left associative)");
}
if(!srdetails.shiftAffectsOthers) {
resolutionOptions.add("Shift (insert precedence for " + srdetails.shift.name() +")");
}
else {
// If the precedence of the terminal and the production come from different terminals
// we need to choose the precedence
if(!srdetails.shiftAffectsOthers) {
resolutionOptions.add("Shift (insert precedence for " + sourceOfShiftPrec.name() +")");
}
else {
resolutionOptions.add("Affects others: Shift (insert precedence for " + sourceOfShiftPrec.name() +")");
resolutionOptions.add("Affects others: Shift (insert precedence for " + srdetails.shift.name() +")");
}
if(srdetails.reduce != null){
if(!srdetails.reduceAffectsOthers) {
resolutionOptions.add("Reduce (insert precedence for " + srdetails.reduce.name() +")");
}
if(sourceOfReducePrec != null){
if(!srdetails.reduceAffectsOthers) {
resolutionOptions.add("Reduce (insert precedence for " + sourceOfReducePrec.name() +")");
}
else{
resolutionOptions.add("Affects others: Reduce (insert precedence for " + sourceOfReducePrec.name() +")");
}
else{
resolutionOptions.add("Affects others: Reduce (insert precedence for " + srdetails.reduce.name() +")");
}
}
} else {
throw new RuntimeException("unexpected conflict type.");
}
}
/**
* Marks the conflict as affected if it is by the precedences to be inserted
* This entails setting the background color and hiding/showing/disbaeling the dropdown
* @param pti precedences to be inserted
*/
public void markIfAffected(PrecedenceToInsert pti){
if(conflict instanceof ShiftReduceConflict && pti.isAffected(srdetails)){
......@@ -468,6 +433,9 @@ class ConflictPanel extends Composite {
}
}
/**
* Abort a connected resolution. Enable dropdown and set to default values
*/
public void connectedEditAborted(){
if(conflict instanceof ShiftReduceConflict){
resolutionButton.setEnabled(true);
......@@ -479,7 +447,25 @@ class ConflictPanel extends Composite {
partOfCurrentConnected = false;
}
// replace (*) generated by CUP with BULLET U+2022 •
/**
* Check if conflict in this panel is part of current connected and needs precedence etc set
* @return True iff conflict in this panel is part of current connected and needs precedence etc set
*/
public boolean requiresResolutionButNotChosen(){
if(!partOfCurrentConnected){
return false;
}
else {
return resolutionOptions.getSelectionIndex() == 0;
}
}
/**
* replace (*) generated by CUP with BULLET U+2022 •
* @param item the item for which the pretty string is needed
* @return pretty string
* @throws internal_error
*/
private String prettyString(lalr_item item) throws internal_error {
return item.toString().replace("(*)", "\u2022");
}
......@@ -547,7 +533,6 @@ class ConflictPanel extends Composite {
}
};
private SelectionListener resolutionBoxSelected = new SelectionListener() {
@Override
......@@ -607,6 +592,11 @@ class ConflictPanel extends Composite {
};
/**
* Show the message that the precedences were cyclic. Reset the dropdown to the vlaue determined by the
* precedences
* @param e Exception that caused this. Contains cycle
*/
private void showCyclicMessageAndResetDropdown(PrecedenceCyclicException e){
Shell shell = new Shell(Display.getCurrent());
MessageBox box = new MessageBox(shell,SWT.ICON_WARNING | SWT.OK);
......
......@@ -73,6 +73,42 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
class ShiftReduceDetails {
terminal shift,reduce;
boolean shiftAffectsOthers,reduceAffectsOthers;
ShiftReduceDetails(ShiftReduceConflict src,ConflictResolutionManager crm){
shift = src.getTerminal();
reduce = null;
ProductionRight conflict1Ast = src.getConflictItem1().the_production().getAstNode();
// If the precedence is specifically set via %prec
if(conflict1Ast.hasSpecifiedPrecedence()){
reduce = terminal.getShared(crm.getLaLrContext()).find(
conflict1Ast.getPrecedenceLike().getNameStringOrNull());
}
// Terminal defining precedence is the last one in the current production
else {
for(IProductionRightPart part : conflict1Ast.getList()){
if(part instanceof ProductionSymbolRef){
ProductionSymbolRef ppsr = (ProductionSymbolRef)part;
terminal candidate = terminal.getShared(crm.getLaLrContext()).find(
ppsr.getNameStringOrNull());
if(candidate != null){
reduce = candidate;
}
}
}
}
// RHS is only nonterminal and no %prec directive => sourceOfReducePrec == null
shiftAffectsOthers = insertingPrecAffectsOtherConflicts(shift);
reduceAffectsOthers = insertingPrecAffectsOtherConflicts(reduce);
}
boolean shiftAndReducePrecedenceFromSameTerminal(){
return shift.equals(reduce);
}
}
public CupConflictsView(Composite realParent, Jumper jumper,CupTextEditor editor) {
......@@ -252,7 +288,6 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
scrolled.setMinSize(list.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
public void dispose() {
editor.getModel().unregisterModelObserver(this);
Controller.getInstance(editor).unregisterObserver(this);
......@@ -374,15 +409,13 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
// Conflicts are part of current connected conflicts that are not resolved yet.
for(ConflictPanel p: conflictPanels){
if(p.partOfCurrentConnected){
if(p.resolutionOptions.getSelectionIndex() == 0){
if(p.requiresResolutionButNotChosen()) {
Shell shell = new Shell(Display.getCurrent());
MessageBox box = new MessageBox(shell,SWT.ICON_WARNING | SWT.OK);
box.setText("Information");
box.setMessage("Please choose a way to resolve all conflicts that are affected. Then click this button again.");
box.open();
return;
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment