/*******************************************************************************
* Copyright (c) 2011 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:
* Martin Schwab & Thomas Kallenberg - initial API and implementation
******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.togglefunction;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.internal.ui.refactoring.IndexToASTNameHelper;
import org.eclipse.cdt.internal.ui.refactoring.utils.TranslationUnitHelper;
public class ToggleRefactoringContext {
private IASTFunctionDefinition targetDefinition;
private IASTFunctionDeclarator targetDeclaration;
private IASTTranslationUnit targetDefinitionUnit;
private IASTTranslationUnit targetDeclarationUnit;
private IIndex index;
private IASTTranslationUnit selectionUnit;
private IFile selectionFile;
private IBinding binding;
private IASTName selectionName;
private boolean defaultAnswer;
private boolean settedDefaultAnswer;
public ToggleRefactoringContext(IIndex index, IFile file, ITextSelection selection) {
this.index = index;
this.selectionFile = file;
findSelectionUnit();
findSelectedFunctionDeclarator(selection);
findBinding();
findDeclaration();
findDefinition();
}
public void findSelectedFunctionDeclarator(ITextSelection selection) {
selectionName = new DeclaratorFinder(selection, selectionUnit).getName();
}
public void findBinding() {
try {
binding = index.findBinding(selectionName);
if(binding == null) {
binding = selectionName.resolveBinding();
}
} catch (CoreException e) {
CUIPlugin.log(e);
}
}
// Declaration may still be null afterwards, but thats ok.
public void findDeclaration() {
try {
IIndexName[] decnames = index.findNames(binding, IIndex.FIND_DECLARATIONS);
if (decnames.length > 1)
throw new NotSupportedException(
Messages.ToggleRefactoringContext_MultipleDeclarations);
for (IIndexName iname : decnames) {
selectionUnit = getTUForNameinFile(iname);
IASTName astname = IndexToASTNameHelper.findMatchingASTName(
selectionUnit, iname, index);
if (astname != null) {
targetDeclaration = findFunctionDeclarator(astname);
targetDeclarationUnit = selectionUnit;
break;
}
}
} catch (CoreException e) {
CUIPlugin.log(e);
}
}
public void findDefinition() {
try {
IIndexName[] defnames = index.findNames(binding, IIndex.FIND_DEFINITIONS);
if (defnames.length > 1) {
throw new NotSupportedException(Messages.ToggleRefactoringContext_MultipleDefinitions);
}
for (IIndexName iname : defnames) {
IASTTranslationUnit unit = getTUForNameinFile(iname);
IASTName astname = IndexToASTNameHelper.findMatchingASTName(
unit, iname, index);
if (astname != null) {
targetDefinition = findFunctionDefinition(astname);
targetDefinitionUnit = unit;
break;
}
}
} catch (CoreException e) {
CUIPlugin.log(e);
}
if (targetDefinition == null)
throw new NotSupportedException(Messages.ToggleRefactoringContext_NoDefinitionFound);
}
public IASTFunctionDeclarator getDeclaration() {
return targetDeclaration;
}
public IASTFunctionDefinition getDefinition() {
return targetDefinition;
}
public IASTTranslationUnit getDeclarationUnit() {
return targetDeclarationUnit;
}
public IASTTranslationUnit getDefinitionUnit() {
return targetDefinitionUnit;
}
public IFile getSelectionFile() {
return selectionFile;
}
public IASTTranslationUnit getTUForSiblingFile() {
IASTTranslationUnit unit = getDeclarationUnit();
if (unit == null)
unit = getDefinitionUnit();
try {
return ToggleNodeHelper.getSiblingFile(getSelectionFile(), unit);
} catch (CoreException e) {
CUIPlugin.log(e);
return null;
}
}
private void findSelectionUnit() {
try {
selectionUnit = TranslationUnitHelper.loadTranslationUnit(
selectionFile, true);
} catch (Exception e) {
}
if (selectionUnit == null)
throw new NotSupportedException(Messages.ToggleRefactoringContext_NoTuFound);
}
private IASTTranslationUnit getTUForNameinFile(IIndexName iname)
throws CModelException, CoreException {
if (isSameFileAsInTU(iname)) {
return selectionUnit;
}
IPath path = new Path(iname.getFileLocation().getFileName());
return TranslationUnitHelper.loadTranslationUnit(path.toString(), true);
}
private boolean isSameFileAsInTU(IIndexName iname) {
return iname.getFileLocation().getFileName().equals(
selectionUnit.getFileLocation().getFileName());
}
private IASTFunctionDeclarator findFunctionDeclarator(IASTNode node) {
if (node instanceof IASTSimpleDeclaration) {
return (IASTFunctionDeclarator) ((IASTSimpleDeclaration) node).getDeclarators()[0];
}
return ToggleNodeHelper.getAncestorOfType(node, IASTFunctionDeclarator.class);
}
private IASTFunctionDefinition findFunctionDefinition(IASTNode node) {
return ToggleNodeHelper.getAncestorOfType(node, IASTFunctionDefinition.class);
}
public void setDefaultAnswer(boolean defaultAnswer) {
this.defaultAnswer = defaultAnswer;
}
public boolean getDefaultAnswer() {
return defaultAnswer;
}
public void setSettedDefaultAnswer(boolean settedDefaultAnswer) {
this.settedDefaultAnswer = settedDefaultAnswer;
}
public boolean isSettedDefaultAnswer() {
return settedDefaultAnswer;
}
}