package no.uio.ifi.refaktor.utils; import static no.uio.ifi.refaktor.RefaktorAssert.assertThat; import static org.hamcrest.CoreMatchers.instanceOf; import org.eclipse.core.resources.IProject; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.NodeFinder; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.TextSelection; /** * A custom TextSelection that enforces the presence of * a compilation unit to back the selection. */ public class CompilationUnitTextSelection extends TextSelection implements ITextSelection { private ICompilationUnit compilationUnit; private NodeFinder nodeFinder; public CompilationUnitTextSelection(ICompilationUnit compilationUnit, int offset, int length) { super(offset, length); if (compilationUnit == null) throw new NullPointerException(this.getClass().getCanonicalName() + ": given compilation unit cannot be null"); this.compilationUnit = compilationUnit; } public CompilationUnitTextSelection(ICompilationUnit compilationUnit, ITextSelection selection) { this(compilationUnit, selection.getOffset(), selection.getLength()); } @Override public IDocument getDocument() { return DocumentUtils.getDocumentFromCompilationUnit(compilationUnit); } public int getEnd() { return getOffset() + getLength(); } public IProject getProject() { return compilationUnit.getJavaProject().getProject(); } public ICompilationUnit getCompilationUnit() { return compilationUnit; } public ASTNode getCoveringNode() { return getNodeFinder().getCoveringNode(); } public ASTNode getCoveredNode() { return getNodeFinder().getCoveredNode(); } private NodeFinder getNodeFinder() { if (nodeFinder == null) nodeFinder = ParseUtils.createNodeFinder(ParseUtils.parse(compilationUnit), this); return nodeFinder; } public boolean surroundsNode(ASTNode node) { return getOffset() <= node.getStartPosition() && endOfNode(node) <= getEnd(); } private int endOfNode(ASTNode node) { return node.getStartPosition() + node.getLength(); } public String getPackageName() { return getConcreteCompilationUnit().getPackage().getName().getFullyQualifiedName(); } public String getNameOfSurroundingType() { for (Object type: getConcreteCompilationUnit().types()) { assertThat(type, instanceOf(AbstractTypeDeclaration.class)); AbstractTypeDeclaration absTypeDecl = (AbstractTypeDeclaration) type; if (isSurroundedBy(absTypeDecl)) return absTypeDecl.getName().getFullyQualifiedName(); } return null; } private boolean isSurroundedBy(AbstractTypeDeclaration absTypeDecl) { return absTypeDecl.getStartPosition() <= getOffset() && getLength() <= absTypeDecl.getLength(); } private CompilationUnit getConcreteCompilationUnit() { ASTNode root = getCoveringNode().getRoot(); assertThat(root, instanceOf(CompilationUnit.class)); return (CompilationUnit) root; } @Override public boolean equals(Object obj) { if (obj instanceof CompilationUnitTextSelection) return super.equals(obj) && compilationUnit.equals(((CompilationUnitTextSelection)obj).compilationUnit); return false; } @Override public int hashCode() { return (getOffset() << 24) | (getLength() << 16) | compilationUnit.hashCode(); } @Override public String toString() { return "Offset: " + getOffset() + "; Length: " + getLength() + "; End: " + getEnd() + "; CU handle identifier: " + compilationUnit.getHandleIdentifier(); } @Override public int getStartLine() { return createTextSelectionWithDocument().getStartLine(); } @Override public int getEndLine() { return createTextSelectionWithDocument().getEndLine(); } @Override public String getText() { return createTextSelectionWithDocument().getText(); } private TextSelection createTextSelectionWithDocument() { return new TextSelection(getDocument(), getOffset(), getLength()); } }