/******************************************************************************* * 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); } } } }