package com.redhat.ceylon.eclipse.code.correct;
import static com.redhat.ceylon.eclipse.java2ceylon.Java2CeylonProxies.utilJ2C;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import com.redhat.ceylon.model.typechecker.model.Declaration;
import com.redhat.ceylon.model.typechecker.model.Unit;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
public class ConvertSwitchToIfProposal {
static void addConvertSwitchToIfProposal(
Collection<ICompletionProposal> proposals,
IDocument doc, IFile file, Tree.Statement statement) {
if (statement instanceof Tree.SwitchStatement) {
Tree.SwitchStatement ss =
(Tree.SwitchStatement) statement;
TextFileChange tfc =
new TextFileChange("Convert Switch To If",
file);
tfc.setEdit(new MultiTextEdit());
Tree.SwitchClause sc = ss.getSwitchClause();
if (sc==null) return;
Tree.SwitchCaseList scl = ss.getSwitchCaseList();
Tree.Switched switched = sc.getSwitched();
if (switched==null) return;
Tree.Expression e =
switched.getExpression();
Tree.Variable v =
switched.getVariable();
String name;
if (e!=null) {
Tree.Term t = e.getTerm();
if (t instanceof Tree.BaseMemberExpression) {
Tree.BaseMemberExpression bme =
(Tree.BaseMemberExpression) t;
name = bme.getDeclaration().getName();
tfc.addEdit(new DeleteEdit(sc.getStartIndex(),
scl.getStartIndex()-sc.getStartIndex()));
}
else {
return;
}
}
else if (v!=null) {
name = v.getDeclarationModel().getName();
tfc.addEdit(new ReplaceEdit(sc.getStartIndex(),
v.getStartIndex()-sc.getStartIndex(),
"value "));
tfc.addEdit(new ReplaceEdit(sc.getEndIndex()-1,
1, ";"));
}
else {
return;
}
String kw = "if";
int i=0;
for (Tree.CaseClause cc: scl.getCaseClauses()) {
Tree.CaseItem ci = cc.getCaseItem();
if (++i==scl.getCaseClauses().size() &&
scl.getElseClause()==null) {
tfc.addEdit(new ReplaceEdit(cc.getStartIndex(),
ci.getEndIndex()-cc.getStartIndex(),
"else"));
}
else {
tfc.addEdit(new ReplaceEdit(cc.getStartIndex(),
4, kw));
kw = "else if";
if (ci instanceof Tree.IsCase) {
tfc.addEdit(new InsertEdit(ci.getEndIndex()-1,
" " + name));
}
else if (ci instanceof Tree.MatchCase) {
Tree.MatchCase mc = (Tree.MatchCase) ci;
Tree.ExpressionList el =
mc.getExpressionList();
if (el.getExpressions().size()==1) {
Tree.Expression e0 =
el.getExpressions().get(0);
if (e0!=null) {
Tree.Term t0 = e0.getTerm();
if (t0 instanceof Tree.BaseMemberExpression) {
Tree.BaseMemberExpression bme =
(Tree.BaseMemberExpression) t0;
Declaration d = bme.getDeclaration();
Unit unit = statement.getUnit();
if (unit.getNullValueDeclaration()
.equals(d)) {
tfc.addEdit(new ReplaceEdit(ci.getStartIndex(),
ci.getDistance()-1,
"!exists " + name));
continue;
}
else if (unit.getLanguageModuleDeclaration("true")
.equals(d)) {
tfc.addEdit(new ReplaceEdit(ci.getStartIndex(),
ci.getDistance()-1,
name));
continue;
}
else if (unit.getLanguageModuleDeclaration("false")
.equals(d)) {
tfc.addEdit(new ReplaceEdit(ci.getStartIndex(),
ci.getDistance()-1,
"!" + name));
continue;
}
}
}
tfc.addEdit(new InsertEdit(ci.getStartIndex(),
name + " == "));
}
else {
tfc.addEdit(new InsertEdit(ci.getStartIndex(),
name + " in ["));
tfc.addEdit(new InsertEdit(ci.getEndIndex()-1,
"]"));
}
}
else {
return;
}
}
}
proposals.add(new CorrectionProposal(
"Convert 'switch' to 'if' chain", tfc,
new Region(sc.getStartIndex(), 0)));
}
}
static void addConvertIfToSwitchProposal(
Collection<ICompletionProposal> proposals,
IDocument doc, IFile file, Tree.Statement statement) {
if (statement instanceof Tree.IfStatement) {
Tree.IfStatement is =
(Tree.IfStatement) statement;
TextFileChange tfc =
new TextFileChange("Convert If To Switch",
file);
tfc.setEdit(new MultiTextEdit());
Tree.ConditionList cl =
is.getIfClause()
.getConditionList();
if (cl!=null) {
List<Tree.Condition> conditions =
cl.getConditions();
if (conditions.size()==1) {
Tree.Condition condition =
conditions.get(0);
String var;
String type;
if (condition instanceof Tree.IsCondition) {
Tree.IsCondition ic =
(Tree.IsCondition) condition;
if (ic.getNot()) return;
try {
Tree.Variable v = ic.getVariable();
int start = v.getStartIndex();
int len = v.getDistance();
var = doc.get(start, len);
}
catch (Exception e) {
e.printStackTrace();
return;
}
try {
Tree.Type t = ic.getType();
int start = t.getStartIndex();
int len = t.getDistance();
type = "is " + doc.get(start, len);
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
else if (condition instanceof Tree.ExistsCondition) {
Tree.ExistsCondition ec =
(Tree.ExistsCondition) condition;
type = ec.getNot() ? "null" : "is Object";
try {
Tree.Statement v = ec.getVariable();
int start = v.getStartIndex();
int len = v.getDistance();
var = doc.get(start, len);
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
else if (condition instanceof Tree.BooleanCondition) {
Tree.BooleanCondition ec =
(Tree.BooleanCondition) condition;
type = "true";
try {
Tree.Expression e = ec.getExpression();
int start = e.getStartIndex();
int len = e.getDistance();
var = doc.get(start, len);
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
else {
return;
}
String newline =
utilJ2C().indents().getDefaultLineDelimiter(doc) +
utilJ2C().indents().getIndent(is, doc);
tfc.addEdit(new ReplaceEdit(is.getStartIndex(),
cl.getEndIndex()-is.getStartIndex(),
"switch (" + var + ")" + newline +
"case (" + type +")"));
Tree.ElseClause ec = is.getElseClause();
if (ec==null) {
tfc.addEdit(new InsertEdit(is.getEndIndex(),
newline + "else {}"));
}
else {
Tree.Block b = ec.getBlock();
if (b.getMainToken()==null) {
int start = b.getStartIndex();
int end = b.getEndIndex();
tfc.addEdit(new InsertEdit(start,
"{" + newline +
utilJ2C().indents().getDefaultIndent()));
try {
for (int line=doc.getLineOfOffset(start)+1;
line<=doc.getLineOfOffset(end);
line++) {
tfc.addEdit(new InsertEdit(doc.getLineOffset(line),
utilJ2C().indents().getDefaultIndent()));
}
}
catch (Exception e) {
e.printStackTrace();
}
tfc.addEdit(new InsertEdit(end,
newline + "}"));
}
}
proposals.add(new CorrectionProposal(
"Convert 'if' to 'switch'", tfc,
new Region(is.getStartIndex(), 0)));
}
}
}
}
}