package com.redhat.ceylon.eclipse.code.correct;
import static com.redhat.ceylon.eclipse.util.Nodes.findStatement;
import static com.redhat.ceylon.eclipse.util.Nodes.getIdentifyingNode;
import static com.redhat.ceylon.eclipse.util.Nodes.nameProposals;
import java.util.Collection;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.ltk.core.refactoring.TextChange;
import org.eclipse.ltk.core.refactoring.TextFileChange;
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.Tree.BaseMemberExpression;
import com.redhat.ceylon.eclipse.util.Nodes;
import com.redhat.ceylon.ide.common.util.FindReferencesVisitor;
import com.redhat.ceylon.model.typechecker.model.Declaration;
import com.redhat.ceylon.model.typechecker.model.Value;
class ShadowReferenceProposal extends CorrectionProposal {
ShadowReferenceProposal(int offset, int length, TextChange change) {
super("Shadow reference inside control structure", change,
new Region(offset, length));
}
static void addShadowSwitchReferenceProposal(IFile file,
Node node, Tree.CompilationUnit rootNode,
Collection<ICompletionProposal> proposals) {
if (node instanceof Tree.Term) {
Tree.Statement statement =
findStatement(rootNode, node);
if (statement instanceof Tree.SwitchStatement) {
String name = nameProposals(node)[0];
TextFileChange change =
new TextFileChange("Shadow Reference", file);
change.setEdit(new MultiTextEdit());
// Integer offset = statement.getStartIndex();
// change.addEdit(new ReplaceEdit(offset,
// node.getStartIndex()-offset,
// "value " + name + " = "));
// IDocument doc = getDocument(change);
// change.addEdit(new InsertEdit(node.getEndIndex(),
// ";" +
// getDefaultLineDelimiter(doc) +
// getIndent(statement, doc) +
// "switch (" + name));
Tree.SwitchStatement ss =
(Tree.SwitchStatement) statement;
int loc = node.getStartIndex();
change.addEdit(new InsertEdit(loc, name + " = "));
if (node instanceof BaseMemberExpression) {
Tree.BaseMemberExpression bme =
(BaseMemberExpression) node;
Declaration d = bme.getDeclaration();
if (d!=null) {
FindReferencesVisitor frv =
new FindReferencesVisitor(d);
frv.visit(ss.getSwitchCaseList());
for (Node n: frv.getNodeSet()) {
Node identifyingNode =
getIdentifyingNode(n);
Integer start =
identifyingNode.getStartIndex();
if (start!=loc) {
int len = identifyingNode.getText().length();
change.addEdit(new ReplaceEdit(start, len, name));
}
}
}
}
proposals.add(new ShadowReferenceProposal(
loc, name.length(), change));
}
}
}
static void addShadowReferenceProposal(IFile file,
Node node, Tree.CompilationUnit rootNode,
Collection<ICompletionProposal> proposals) {
if (node instanceof Tree.Variable) {
Tree.Variable var = (Tree.Variable) node;
int offset =
var.getIdentifier()
.getStartIndex();
Tree.Term term =
var.getSpecifierExpression()
.getExpression()
.getTerm();
String name = nameProposals(term)[0];
TextChange change =
new TextFileChange("Shadow Reference", file);
change.setEdit(new MultiTextEdit());
change.addEdit(new InsertEdit(offset, name + " = "));
Tree.Statement statement =
Nodes.findStatement(rootNode, node);
Value dec = var.getDeclarationModel();
FindReferencesVisitor frv =
new FindReferencesVisitor(dec);
frv.visit(statement);
for (Node n: frv.getNodeSet()) {
Node identifyingNode = getIdentifyingNode(n);
Integer start =
identifyingNode.getStartIndex();
if (start!=offset) {
int len = identifyingNode.getText().length();
change.addEdit(new ReplaceEdit(start, len, name));
}
}
proposals.add(new ShadowReferenceProposal(
offset, name.length(), change));
}
else if (node instanceof Tree.Term) {
String name = nameProposals(node)[0];
TextChange change =
new TextFileChange("Shadow Reference", file);
// change.setEdit(new MultiTextEdit());
Integer offset = node.getStartIndex();
change.setEdit(new InsertEdit(offset, name + " = "));
proposals.add(new ShadowReferenceProposal(
offset, name.length(), change));
}
}
}