/******************************************************************************* * Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik * Rapperswil, University of applied sciences 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: * Institute for Software - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.ui.refactoring.utils; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.Region; import org.eclipse.jface.viewers.ISelection; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.internal.ui.refactoring.Container; /** * Helper class to support operations concerning a selection. * * @author Mirko Stocker, Lukas Felber */ public class SelectionHelper { public static Region getRegion(ISelection selection) { if (selection instanceof ITextSelection) { final ITextSelection txtSelection= (ITextSelection) selection; return new Region(txtSelection.getOffset(), txtSelection.getLength()); } return null; } public static IASTSimpleDeclaration findFirstSelectedDeclaration(final Region textSelection, IASTTranslationUnit translationUnit) { final Container<IASTSimpleDeclaration> container = new Container<IASTSimpleDeclaration>(); translationUnit.accept(new ASTVisitor() { { shouldVisitDeclarations = true; } @Override public int visit(IASTDeclaration declaration) { if (declaration instanceof IASTSimpleDeclaration && isSelectionOnExpression(textSelection, declaration)) { container.setObject((IASTSimpleDeclaration) declaration); } return super.visit(declaration); } }); return container.getObject(); } public static boolean isSelectionOnExpression(Region textSelection, IASTNode expression) { Region exprPos = createExpressionPosition(expression); int exprStart = exprPos.getOffset(); int selStart = textSelection.getOffset(); int selEnd = selStart + textSelection.getLength(); return exprStart + exprPos.getLength() >= selStart && exprStart <= selEnd; } public static boolean isExpressionWhollyInSelection(Region textSelection, IASTNode expression) { Region exprPos = createExpressionPosition(expression); int exprStart = exprPos.getOffset(); int selStart = textSelection.getOffset(); int selEnd = selStart + textSelection.getLength(); return exprStart >= selStart && exprStart + exprPos.getLength() <= selEnd; } public static boolean isInSameFile(IASTNode node, IFile file) { IPath path = new Path(node.getContainingFilename()); IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot(); IFile locFile = workspaceRoot.getFile(file.getLocation()); IFile tmpFile = workspaceRoot.getFile(path); return locFile.equals(tmpFile); } public static boolean isInSameFileSelection(Region textSelection, IASTNode node, IFile file) { if (isInSameFile(node, file)) { return SelectionHelper.isSelectionOnExpression(textSelection, node); } return false; } public static boolean isSelectedFile(Region textSelection, IASTNode node, IFile file) { if (isInSameFile(node, file)) { return isExpressionWhollyInSelection(textSelection, node); } return false; } protected static Region createExpressionPosition(IASTNode expression) { int start = Integer.MAX_VALUE; int nodeLength = 0; IASTNodeLocation[] nodeLocations = expression.getNodeLocations(); if (nodeLocations.length != 1) { for (IASTNodeLocation location : nodeLocations) { if (location instanceof IASTMacroExpansionLocation) { IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) location; int nodeOffset = macroLoc.asFileLocation().getNodeOffset(); if (nodeOffset < start) { start = nodeOffset; } nodeLength += macroLoc.asFileLocation().getNodeLength(); } else { IASTFileLocation loc = expression.getFileLocation(); int nodeOffset = loc.getNodeOffset(); if (nodeOffset < start) { start = nodeOffset; } nodeLength = loc.getNodeLength(); } } } else { if (nodeLocations[0] instanceof IASTMacroExpansionLocation) { IASTMacroExpansionLocation macroLoc = (IASTMacroExpansionLocation) nodeLocations[0]; start = macroLoc.asFileLocation().getNodeOffset(); nodeLength = macroLoc.asFileLocation().getNodeLength(); } else { IASTFileLocation loc = expression.getFileLocation(); start = loc.getNodeOffset(); nodeLength = loc.getNodeLength(); } } return new Region(start, nodeLength); } }