package com.redhat.ceylon.eclipse.code.correct;
import static com.redhat.ceylon.compiler.typechecker.parser.CeylonLexer.STRING_END;
import static com.redhat.ceylon.compiler.typechecker.parser.CeylonLexer.STRING_MID;
import static com.redhat.ceylon.compiler.typechecker.parser.CeylonLexer.STRING_START;
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.contentassist.ICompletionProposal;
import org.eclipse.ltk.core.refactoring.Change;
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.compiler.typechecker.tree.Node;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;
import com.redhat.ceylon.model.typechecker.model.Type;
class ConvertToConcatenationProposal extends CorrectionProposal {
private ConvertToConcatenationProposal(String name, Change change) {
super(name, change, null);
}
static void addConvertToConcatenationProposal(Collection<ICompletionProposal> proposals,
IFile file, Tree.CompilationUnit cu, final Node node, IDocument doc) {
class TemplateVisitor extends Visitor {
Tree.StringTemplate result;
@Override
public void visit(Tree.StringTemplate that) {
if (that.getStartIndex()<=node.getStartIndex() &&
that.getEndIndex()>=node.getEndIndex()) {
result = that;
}
super.visit(that);
}
}
TemplateVisitor tv = new TemplateVisitor();
tv.visit(cu);
Tree.StringTemplate template = tv.result;
if (template!=null) {
TextFileChange change = new TextFileChange("Convert to Concatenation", file);
change.setEdit(new MultiTextEdit());
Type st = node.getUnit().getStringType();
List<Tree.StringLiteral> literals = template.getStringLiterals();
List<Tree.Expression> expressions = template.getExpressions();
for (int i=0; i<literals.size(); i++) {
Tree.StringLiteral s = literals.get(i);
if (s.getText().isEmpty()) {
if (i>0 && i<literals.size()-1) {
change.addEdit(new ReplaceEdit(s.getStartIndex(), s.getDistance(), " + "));
}
else {
change.addEdit(new DeleteEdit(s.getStartIndex(), s.getDistance()));
}
}
else {
int stt = s.getToken().getType();
if (stt==STRING_END||stt==STRING_MID) {
change.addEdit(new ReplaceEdit(s.getStartIndex(), 2, " + \""));
}
if (stt==STRING_START||stt==STRING_MID) {
change.addEdit(new ReplaceEdit(s.getEndIndex()-2, 2, "\" + "));
}
}
if (i<expressions.size()) {
Tree.Expression e = expressions.get(i);
if (e.getTerm()
instanceof Tree.OperatorExpression) {
change.addEdit(new InsertEdit(e.getStartIndex(), "("));
change.addEdit(new InsertEdit(e.getEndIndex(), ")"));
}
if (!e.getTypeModel().isSubtypeOf(st)) {
change.addEdit(new InsertEdit(e.getEndIndex(), ".string"));
}
}
}
proposals.add(new ConvertToConcatenationProposal("Convert to string concatenation", change));
}
}
}