/*******************************************************************************
* Copyright (c) 2011 Google, Inc 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.utils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.cdt.internal.ui.editor.ITranslationUnitEditorInput;
import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
/**
* Helper class for finding definitions.
*/
public class DefinitionFinder {
public static IASTName getDefinition(IASTSimpleDeclaration simpleDeclaration,
RefactoringASTCache astCache, IProgressMonitor pm) throws CoreException {
IIndex index = astCache.getIndex();
IASTDeclarator declarator = simpleDeclaration.getDeclarators()[0];
if (index == null) {
return null;
}
IIndexBinding binding = index.adaptBinding(declarator.getName().resolveBinding());
if (binding == null) {
return null;
}
return getDefinition(binding, astCache, index, pm);
}
private static IASTName getDefinition(IIndexBinding binding,
RefactoringASTCache astCache, IIndex index, IProgressMonitor pm) throws CoreException {
Set<String> searchedFiles = new HashSet<String>();
List<IASTName> definitions = new ArrayList<IASTName>();
IEditorPart[] dirtyEditors = EditorUtility.getDirtyEditors(true);
for (IEditorPart editor : dirtyEditors) {
if (pm != null && pm.isCanceled()) {
throw new OperationCanceledException();
}
IEditorInput editorInput = editor.getEditorInput();
if (editorInput instanceof ITranslationUnitEditorInput) {
ITranslationUnit tu =
CModelUtil.toWorkingCopy(((ITranslationUnitEditorInput) editorInput).getTranslationUnit());
findDefinitionsInTranslationUnit(binding, tu, astCache, definitions, null);
searchedFiles.add(tu.getLocation().toOSString());
}
}
IIndexName[] definitionsFromIndex = index.findDefinitions(binding);
for (IIndexName name : definitionsFromIndex) {
if (pm != null && pm.isCanceled()) {
throw new OperationCanceledException();
}
ITranslationUnit tu = CoreModelUtil.findTranslationUnitForLocation(
name.getFile().getLocation(), null);
if (searchedFiles.add(tu.getLocation().toOSString())) {
findDefinitionsInTranslationUnit(binding, tu, astCache, definitions, pm);
}
}
return definitions.size() == 1 ? definitions.get(0) : null;
}
private static void findDefinitionsInTranslationUnit(IIndexBinding binding, ITranslationUnit tu,
RefactoringASTCache astCache, List<IASTName> definitions, IProgressMonitor pm)
throws OperationCanceledException, CoreException {
IASTTranslationUnit ast = astCache.getAST(tu, pm);
findDefinitionsInAST(binding, ast, tu, definitions);
}
private static void findDefinitionsInAST(IIndexBinding binding, IASTTranslationUnit ast,
ITranslationUnit tu, List<IASTName> definitions) {
for (IName definition : ast.getDefinitions(binding)) {
if (definition instanceof IASTName) {
definitions.add((IASTName) definition);
}
}
}
}