package com.redhat.ceylon.eclipse.code.refactor; import static com.redhat.ceylon.eclipse.code.correct.LinkedModeCompletionProposal.getSupertypeProposals; import static com.redhat.ceylon.eclipse.code.preferences.CeylonPreferenceInitializer.LINKED_MODE_EXTRACT; import java.util.Collections; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.link.LinkedPosition; import org.eclipse.jface.text.link.LinkedPositionGroup; import org.eclipse.jface.text.link.ProposalPosition; import com.redhat.ceylon.compiler.typechecker.tree.Tree; import com.redhat.ceylon.eclipse.code.correct.LinkedModeCompletionProposal; import com.redhat.ceylon.eclipse.code.correct.LinkedModeImporter; import com.redhat.ceylon.eclipse.code.editor.CeylonEditor; import com.redhat.ceylon.eclipse.core.builder.CeylonNature; import com.redhat.ceylon.eclipse.ui.CeylonPlugin; import com.redhat.ceylon.eclipse.util.LinkedMode; import com.redhat.ceylon.ide.common.util.escaping_; import com.redhat.ceylon.model.typechecker.model.Type; import com.redhat.ceylon.model.typechecker.model.Unit; public abstract class ExtractLinkedMode extends RefactorLinkedMode { protected LinkedPosition namePosition; protected LinkedPositionGroup linkedPositionGroup; public ExtractLinkedMode(CeylonEditor editor) { super(editor); } @Override public void done() { if (isEnabled()) { IProject project = editor.getParseController() .getProject(); if (CeylonNature.isEnabled(project)) { setName(getNewNameFromNamePosition()); if (isShowPreview() || forceWizardMode()) { try { revertChanges(); openPreview(); } catch (Exception e) { e.printStackTrace(); } } } super.done(); } else { super.cancel(); } } protected abstract boolean forceWizardMode(); public boolean isEnabled() { String newName = getNewNameFromNamePosition(); return newName.matches("^\\w(\\w|\\d)*$") && !escaping_.get_().isKeyword(newName); } protected abstract int getNameOffset(); protected abstract int getTypeOffset(); protected void addNamePosition(IDocument document, int offset2, int length) { addNamePosition(document, offset2, length, Collections.<IRegion>emptyList()); } protected void addNamePosition(IDocument document, int offset, int length, List<IRegion> regions) { linkedPositionGroup = new LinkedPositionGroup(); namePosition = new ProposalPosition(document, getNameOffset(), getInitialName().length(), 0, LinkedModeCompletionProposal .getNameProposals( getTypeOffset(), 1, getNameProposals())); try { linkedPositionGroup.addPosition(namePosition); linkedPositionGroup.addPosition( new LinkedPosition(document, offset, length, 2)); int i = 3; for (IRegion region: regions) { linkedPositionGroup.addPosition( new LinkedPosition(document, region.getOffset(), region.getLength(), i++)); } linkedModeModel.addGroup(linkedPositionGroup); } catch (BadLocationException e) { e.printStackTrace(); } } protected abstract String[] getNameProposals(); protected void addTypePosition(IDocument document, Type type, int offset, int length) { Tree.CompilationUnit rootNode = editor.getParseController() .getLastCompilationUnit(); Unit unit = rootNode.getUnit(); LinkedModeImporter importer = new LinkedModeImporter(document, editor) { @Override public void selected(Type type) { super.selected(type); setReturnType(type); } }; linkedModeModel.addLinkingListener(importer); ProposalPosition linkedPosition = new ProposalPosition(document, offset, length, 1, getSupertypeProposals(offset, unit, type, canBeInferred(), getKind(), importer)); try { LinkedMode.addLinkedPosition(linkedModeModel, linkedPosition); } catch (BadLocationException e) { e.printStackTrace(); } } protected abstract void setReturnType(Type type); protected abstract void addLinkedPositions( IDocument document, Tree.CompilationUnit rootNode, int adjust); @Override protected String getNewNameFromNamePosition() { try { return namePosition.getContent(); } catch (BadLocationException e) { return getInitialName(); } } @Override protected void setupLinkedPositions( IDocument document, int adjust) throws BadLocationException { Tree.CompilationUnit rootNode = editor.getParseController() .getLastCompilationUnit(); addLinkedPositions(document, rootNode, adjust); } public static boolean useLinkedMode() { return CeylonPlugin.getPreferences() .getBoolean(LINKED_MODE_EXTRACT); } @Override public final String getHintTemplate() { return "Enter name for extracted " + getKind() + " declaration {0}"; } @Override protected final void updatePopupLocation() { LinkedPosition currentLinkedPosition = getCurrentLinkedPosition(); if (currentLinkedPosition==null) { getInfoPopup() .setHintTemplate(getHintTemplate()); } else if (currentLinkedPosition.getSequenceNumber()==1) { getInfoPopup() .setHintTemplate("Enter type for extracted " + getKind() + " declaration {0}"); } else { getInfoPopup() .setHintTemplate("Enter name for extracted " + getKind() + " declaration {0}"); } } public boolean canBeInferred() { return false; } protected abstract String getKind(); }