package com.redhat.ceylon.eclipse.code.refactor;
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
import static com.redhat.ceylon.eclipse.code.correct.LinkedModeCompletionProposal.getNameProposals;
import static com.redhat.ceylon.eclipse.ui.CeylonPlugin.PLUGIN_ID;
import static com.redhat.ceylon.eclipse.util.DocLinks.hasPackage;
import static com.redhat.ceylon.eclipse.util.DocLinks.nameRegion;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
import org.eclipse.jface.text.link.ProposalPosition;
import org.eclipse.ltk.core.refactoring.DocumentChange;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
import org.eclipse.ui.IWorkbenchPartSite;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;
import com.redhat.ceylon.eclipse.code.editor.CeylonEditor;
import com.redhat.ceylon.eclipse.util.EditorUtil;
import com.redhat.ceylon.ide.common.util.escaping_;
import com.redhat.ceylon.model.typechecker.model.Declaration;
public class EnterAliasLinkedMode extends RefactorLinkedMode {
protected LinkedPosition namePosition;
protected LinkedPositionGroup linkedPositionGroup;
private EnterAliasRefactoring refactoring;
private final class LinkedPositionsVisitor
extends Visitor {
private final int adjust;
private final IDocument document;
private final LinkedPositionGroup linkedPositionGroup;
int i=2;
private LinkedPositionsVisitor(int adjust,
IDocument document,
LinkedPositionGroup linkedPositionGroup) {
this.adjust = adjust;
this.document = document;
this.linkedPositionGroup = linkedPositionGroup;
}
@Override
public void visit(
Tree.StaticMemberOrTypeExpression that) {
super.visit(that);
addLinkedPosition(that.getDeclaration(),
that.getIdentifier());
}
@Override
public void visit(Tree.SimpleType that) {
super.visit(that);
addLinkedPosition(that.getDeclarationModel(),
that.getIdentifier());
}
@Override
public void visit(Tree.MemberLiteral that) {
super.visit(that);
addLinkedPosition(that.getDeclaration(),
that.getIdentifier());
}
@Override
public void visit(Tree.DocLink that) {
super.visit(that);
Declaration base = that.getBase();
if (base!=null && !hasPackage(that)) {
Region region = nameRegion(that, 0);
addLinkedPosition(
base,
region.getOffset(),
region.getLength());
}
}
private void addLinkedPosition(Declaration dec,
Tree.Identifier id) {
if (id!=null) {
addLinkedPosition(
dec,
id.getStartIndex(),
id.getDistance());
}
}
private void addLinkedPosition(Declaration dec,
int pos, int len) {
if (dec!=null && refactoring.isReference(dec)) {
try {
int offset = getOriginalSelection().x;
int seq;
if (offset<pos || offset>pos+len) {
seq = i++;
}
else {
seq = 1; //the selected node
}
linkedPositionGroup.addPosition(
new LinkedPosition(document,
pos+adjust, len, seq));
}
catch (BadLocationException e) {
e.printStackTrace();
}
}
}
}
public EnterAliasLinkedMode(CeylonEditor editor) {
super(editor);
refactoring = new EnterAliasRefactoring(editor);
}
@Override
protected String getName() {
return refactoring.getNewName();
}
@Override
public String getHintTemplate() {
String name =
refactoring.getElement()
.getDeclarationModel()
.getName();
int count =
linkedPositionGroup.getPositions()
.length;
return "Enter alias for " + count +
" occurrences of '" + name +
"' {0}";
}
@Override
protected int performInitialChange(IDocument document) {
DocumentChange change =
new DocumentChange("Enter Alias", document);
int result = refactoring.refactorInFile(change);
EditorUtil.performChange(change);
return result;
}
@Override
protected String getNewNameFromNamePosition() {
try {
return namePosition.getContent();
}
catch (BadLocationException e) {
return getInitialName();
}
}
@Override
protected void setupLinkedPositions(
IDocument document, int adjust)
throws BadLocationException {
linkedPositionGroup = new LinkedPositionGroup();
Tree.ImportMemberOrType element =
refactoring.getElement();
int offset;
int length;
Tree.Alias alias = element.getAlias();
if (alias == null) {
Tree.Identifier id = element.getIdentifier();
offset = id.getStartIndex();
length = id.getDistance();
}
else {
Tree.Identifier id = alias.getIdentifier();
offset = id.getStartIndex();
length = id.getDistance();
}
String originalName = getInitialName();
String name =
element.getDeclarationModel()
.getName();
ICompletionProposal[] proposals =
getNameProposals(
offset, 0,
new String[] { name },
originalName);
namePosition =
new ProposalPosition(document,
offset, length, 0, proposals);
linkedPositionGroup.addPosition(namePosition);
editor.getParseController()
.getLastCompilationUnit()
.visit(new LinkedPositionsVisitor(
adjust, document,
linkedPositionGroup));
linkedModeModel.addGroup(linkedPositionGroup);
}
private boolean isEnabled() {
String newName = getNewNameFromNamePosition();
return !getInitialName().equals(newName) &&
newName.matches("^\\w(\\w|\\d)*$") &&
!escaping_.get_().isKeyword(newName);
}
@Override
public void done() {
if (isEnabled()) {
try {
// hideEditorActivity();
setName(getNewNameFromNamePosition());
revertChanges();
if (isShowPreview()) {
openPreview();
}
else {
IWorkbenchPartSite site =
editor.getSite();
new RefactoringExecutionHelper(
refactoring,
RefactoringStatus.WARNING,
getSaveMode(),
site.getShell(),
site.getWorkbenchWindow())
.perform(false, true);
}
}
catch (Exception e) {
e.printStackTrace();
}
// finally {
// unhideEditorActivity();
// }
super.done();
}
else {
super.cancel();
}
}
@Override
protected String getActionName() {
return PLUGIN_ID + ".action.enterAlias";
}
@Override
protected void setName(String name) {
refactoring.setNewName(name);
}
@Override
protected boolean canStart() {
return refactoring.getEnabled();
}
@Override
protected void openPreview() {
new EnterAliasRefactoringAction(editor) {
@Override
public Refactoring createRefactoring() {
return EnterAliasLinkedMode.this.refactoring;
}
@Override
public RefactoringWizard createWizard(
Refactoring refactoring) {
return new EnterAliasWizard(
(EnterAliasRefactoring)
refactoring) {
@Override
protected void addUserInputPages() {}
};
}
}.run();
}
@Override
protected void openDialog() {
new EnterAliasRefactoringAction(editor) {
@Override
public AbstractRefactoring createRefactoring() {
return EnterAliasLinkedMode.this.refactoring;
}
}.run();
}
}