cdt/cdt_6_0_x/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/OpenDeclarationsJob.java
author timkelly
Tue, 15 Dec 2009 14:30:07 -0600
branchRCL_2_4
changeset 128 d00b6e7a8c94
parent 37 c2bce6dd59e7
permissions -rw-r--r--
fix bug 10386 (mrege from CDT 6.0.1 HEAD)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     1
/*******************************************************************************
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     2
 * Copyright (c) 2009 Wind River Systems, Inc. and others.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     3
 * All rights reserved. This program and the accompanying materials
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     4
 * are made available under the terms of the Eclipse Public License v1.0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     5
 * which accompanies this distribution, and is available at
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     6
 * http://www.eclipse.org/legal/epl-v10.html
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     7
 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     8
 * Contributors:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     9
 *    Markus Schorn - initial API and implementation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    10
 *******************************************************************************/ 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    11
package org.eclipse.cdt.internal.ui.search.actions;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    12
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    13
import java.util.ArrayList;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    14
import java.util.Arrays;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    15
import java.util.Collection;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    16
import java.util.HashSet;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    17
import java.util.Iterator;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    18
import java.util.List;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    19
import java.util.Set;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    20
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    21
import org.eclipse.core.runtime.CoreException;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    22
import org.eclipse.core.runtime.IPath;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    23
import org.eclipse.core.runtime.IProgressMonitor;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    24
import org.eclipse.core.runtime.IStatus;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    25
import org.eclipse.core.runtime.Path;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    26
import org.eclipse.core.runtime.Status;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    27
import org.eclipse.core.runtime.jobs.Job;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    28
import org.eclipse.jface.text.IRegion;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    29
import org.eclipse.jface.text.ITextSelection;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    30
import org.eclipse.jface.text.Region;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    31
import org.eclipse.swt.widgets.Display;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    32
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    33
import org.eclipse.cdt.core.CCorePlugin;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    34
import org.eclipse.cdt.core.dom.IName;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    35
import org.eclipse.cdt.core.dom.ast.ASTNameCollector;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    36
import org.eclipse.cdt.core.dom.ast.DOMException;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    37
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    38
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    39
import org.eclipse.cdt.core.dom.ast.IASTFunctionStyleMacroParameter;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    40
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    41
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    42
import org.eclipse.cdt.core.dom.ast.IASTName;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    43
import org.eclipse.cdt.core.dom.ast.IASTNode;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    44
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    45
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorFunctionStyleMacroDefinition;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    46
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    47
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    48
import org.eclipse.cdt.core.dom.ast.IBinding;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    49
import org.eclipse.cdt.core.dom.ast.IParameter;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    50
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    51
import org.eclipse.cdt.core.dom.ast.IType;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    52
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    53
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    54
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    55
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    56
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    57
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    58
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    59
import org.eclipse.cdt.core.index.IIndex;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    60
import org.eclipse.cdt.core.index.IIndexBinding;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    61
import org.eclipse.cdt.core.index.IIndexMacro;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    62
import org.eclipse.cdt.core.index.IIndexManager;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    63
import org.eclipse.cdt.core.index.IIndexName;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    64
import org.eclipse.cdt.core.index.IndexFilter;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    65
import org.eclipse.cdt.core.model.ICElement;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    66
import org.eclipse.cdt.core.model.ICProject;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    67
import org.eclipse.cdt.core.model.ILanguage;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    68
import org.eclipse.cdt.core.model.ISourceRange;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    69
import org.eclipse.cdt.core.model.ISourceReference;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    70
import org.eclipse.cdt.core.model.ITranslationUnit;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    71
import org.eclipse.cdt.core.model.util.CElementBaseLabels;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    72
import org.eclipse.cdt.core.parser.util.ArrayUtil;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    73
import org.eclipse.cdt.ui.CUIPlugin;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    74
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    75
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    76
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    77
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    78
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    79
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    80
import org.eclipse.cdt.internal.core.index.IIndexFragmentName;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    81
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    82
import org.eclipse.cdt.internal.core.model.ext.CElementHandleFactory;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    83
import org.eclipse.cdt.internal.core.model.ext.ICElementHandle;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    84
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    85
import org.eclipse.cdt.internal.ui.actions.OpenActionUtil;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    86
import org.eclipse.cdt.internal.ui.editor.ASTProvider;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    87
import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    88
import org.eclipse.cdt.internal.ui.viewsupport.IndexUI;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    89
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    90
class OpenDeclarationsJob extends Job implements ASTRunnable {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    91
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    92
	private enum NameKind { REFERENCE, DECLARATION, USING_DECL, DEFINITION }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    93
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    94
	private final SelectionParseAction fAction;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    95
	private IProgressMonitor fMonitor;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    96
	private final ITranslationUnit fTranslationUnit;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    97
	private IIndex fIndex;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    98
	private final ITextSelection fTextSelection;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    99
	private final String fSelectedText;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   100
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   101
	OpenDeclarationsJob(SelectionParseAction action, ITranslationUnit editorInput, ITextSelection textSelection, String text) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   102
		super(CEditorMessages.OpenDeclarations_dialog_title);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   103
		fAction= action;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   104
		fTranslationUnit= editorInput;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   105
		fTextSelection= textSelection;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   106
		fSelectedText= text;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   107
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   108
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   109
	@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   110
	protected IStatus run(IProgressMonitor monitor) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   111
		try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   112
			return performNavigation(monitor);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   113
		} catch (CoreException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   114
			return e.getStatus();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   115
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   116
	}	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   117
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   118
	IStatus performNavigation(IProgressMonitor monitor) throws CoreException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   119
		fAction.clearStatusLine();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   120
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   121
		assert fIndex == null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   122
		if (fIndex != null)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   123
			return Status.CANCEL_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   124
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   125
		fMonitor= monitor;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   126
		fIndex= CCorePlugin.getIndexManager().getIndex(fTranslationUnit.getCProject(),
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   127
				IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_DEPENDENT);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   128
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   129
		try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   130
			fIndex.acquireReadLock();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   131
		} catch (InterruptedException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   132
			return Status.CANCEL_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   133
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   134
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   135
		try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   136
			return ASTProvider.getASTProvider().runOnAST(fTranslationUnit, ASTProvider.WAIT_ACTIVE_ONLY, monitor, this);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   137
		} finally {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   138
			fIndex.releaseReadLock();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   139
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   140
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   141
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   142
	public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   143
		if (ast == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   144
			return Status.OK_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   145
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   146
		int selectionStart = fTextSelection.getOffset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   147
		int selectionLength = fTextSelection.getLength();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   148
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   149
		final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   150
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   151
		IASTName sourceName= nodeSelector.findEnclosingName(selectionStart, selectionLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   152
		if (sourceName == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   153
			IASTName implicit = nodeSelector.findEnclosingImplicitName(selectionStart, selectionLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   154
			if (implicit != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   155
				IASTImplicitNameOwner owner = (IASTImplicitNameOwner) implicit.getParent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   156
				IASTImplicitName[] implicits = owner.getImplicitNames();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   157
				// There may be more than one name in the same spot
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   158
				if (implicits.length > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   159
					List<IName> allNames = new ArrayList<IName>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   160
					for (IASTImplicitName name : implicits) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   161
						if (((ASTNode) name).getOffset() == ((ASTNode) implicit).getOffset()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   162
							IBinding binding = name.resolveBinding(); // guaranteed to resolve
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   163
							IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   164
							allNames.addAll(Arrays.asList(declNames));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   165
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   166
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   167
					if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, allNames.toArray(new IName[0])))
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   168
						return Status.OK_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   169
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   170
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   171
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   172
			boolean found= false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   173
			final IASTNode parent = sourceName.getParent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   174
			if (parent instanceof IASTPreprocessorIncludeStatement) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   175
				openInclude(((IASTPreprocessorIncludeStatement) parent));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   176
				return Status.OK_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   177
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   178
			NameKind kind = getNameKind(sourceName);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   179
			IBinding b = sourceName.resolveBinding();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   180
			IBinding[] bindings = new IBinding[] { b };
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   181
			if (b instanceof IProblemBinding) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   182
				IBinding[] candidateBindings = ((IProblemBinding) b).getCandidateBindings();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   183
				if (candidateBindings.length != 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   184
					bindings = candidateBindings;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   185
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   186
			} else if (kind == NameKind.DEFINITION && b instanceof IType) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   187
				// Don't navigate away from a type definition.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   188
				// Select the name at the current location instead.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   189
				navigateToName(sourceName);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   190
				return Status.OK_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   191
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   192
			IName[] declNames = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   193
			String filename = ast.getFilePath();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   194
			for (IBinding binding : bindings) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   195
				if (binding != null && !(binding instanceof IProblemBinding)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   196
					IName[] names = findDeclNames(ast, kind, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   197
					for (int i = 0; i < names.length; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   198
						if (names[i] instanceof IIndexName &&
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   199
								filename.equals(((IIndexName) names[i]).getFileLocation().getFileName())) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   200
							// Exclude index names from the current file.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   201
							names[i] = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   202
						} else if (isSameName(names[i], sourceName)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   203
							// Exclude the current location.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   204
							names[i] = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   205
						} else if (binding instanceof IParameter) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   206
							if (!isInSameFunction(sourceName, names[i])) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   207
								names[i] = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   208
							}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   209
						} else if (binding instanceof ICPPTemplateParameter) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   210
							if (!isInSameTemplate(sourceName, names[i])) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   211
								names[i] = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   212
							}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   213
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   214
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   215
					compact(names);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   216
					if (declNames == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   217
						declNames = names;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   218
					} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   219
						declNames = (IName[]) ArrayUtil.addAll(IName.class, declNames, names);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   220
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   221
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   222
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   223
			declNames = (IName[]) ArrayUtil.removeNulls(IName.class, declNames);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   224
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   225
			if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, declNames)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   226
				found= true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   227
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   228
				// Leave old method as fallback for local variables, parameters and 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   229
				// everything else not covered by ICElementHandle.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   230
				found = navigateOneLocation(declNames);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   231
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   232
			if (!found && !navigationFallBack(ast, sourceName, kind)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   233
				fAction.reportSymbolLookupFailure(new String(sourceName.toCharArray()));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   234
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   235
			return Status.OK_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   236
		} 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   237
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   238
		// No enclosing name, check if we're in an include statement
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   239
		IASTNode node= nodeSelector.findEnclosingNode(selectionStart, selectionLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   240
		if (node instanceof IASTPreprocessorIncludeStatement) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   241
			openInclude((IASTPreprocessorIncludeStatement) node);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   242
			return Status.OK_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   243
		} else if (node instanceof IASTPreprocessorFunctionStyleMacroDefinition) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   244
			IASTPreprocessorFunctionStyleMacroDefinition mdef= (IASTPreprocessorFunctionStyleMacroDefinition) node;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   245
			for (IASTFunctionStyleMacroParameter par: mdef.getParameters()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   246
				String parName= par.getParameter();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   247
				if (parName.equals(fSelectedText)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   248
					if (navigateToLocation(par.getFileLocation())) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   249
						return Status.OK_STATUS;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   250
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   251
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   252
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   253
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   254
		if (!navigationFallBack(ast, null, NameKind.REFERENCE)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   255
			fAction.reportSelectionMatchFailure();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   256
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   257
		return Status.OK_STATUS; 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   258
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   259
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   260
	private IName[] findDeclNames(IASTTranslationUnit ast, NameKind kind, IBinding binding) throws CoreException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   261
		IName[] declNames = findNames(fIndex, ast, kind, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   262
		if (declNames.length == 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   263
			if (binding instanceof ICPPSpecialization) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   264
				// bug 207320, handle template instances
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   265
				IBinding specialized= ((ICPPSpecialization) binding).getSpecializedBinding();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   266
				if (specialized != null && !(specialized instanceof IProblemBinding)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   267
					declNames = findNames(fIndex, ast, NameKind.DEFINITION, specialized);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   268
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   269
			} else if (binding instanceof ICPPMethod) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   270
				// bug 86829, handle implicit methods.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   271
				ICPPMethod method= (ICPPMethod) binding;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   272
				if (method.isImplicit()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   273
					try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   274
						IBinding clsBinding= method.getClassOwner();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   275
						if (clsBinding != null && !(clsBinding instanceof IProblemBinding)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   276
							declNames= findNames(fIndex, ast, NameKind.REFERENCE, clsBinding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   277
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   278
					} catch (DOMException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   279
						// don't log problem bindings.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   280
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   281
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   282
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   283
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   284
		return declNames;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   285
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   286
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   287
	private IName[] findNames(IIndex index, IASTTranslationUnit ast, NameKind kind, IBinding binding) throws CoreException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   288
		IName[] declNames;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   289
		if (kind == NameKind.DEFINITION) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   290
			declNames= findDeclarations(index, ast, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   291
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   292
			declNames= findDefinitions(index, ast, kind, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   293
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   294
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   295
		if (declNames.length == 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   296
			if (kind == NameKind.DEFINITION) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   297
				declNames= findDefinitions(index, ast, kind, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   298
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   299
				declNames= findDeclarations(index, ast, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   300
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   301
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   302
		return declNames;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   303
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   304
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   305
	private IName[] findDefinitions(IIndex index, IASTTranslationUnit ast, NameKind kind, IBinding binding) throws CoreException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   306
		List<IASTName> declNames= new ArrayList<IASTName>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   307
		declNames.addAll(Arrays.asList(ast.getDefinitionsInAST(binding)));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   308
		for (Iterator<IASTName> i = declNames.iterator(); i.hasNext();) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   309
			IASTName name= i.next();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   310
			if (name.resolveBinding() instanceof ICPPUsingDeclaration) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   311
				i.remove();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   312
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   313
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   314
		if (!declNames.isEmpty()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   315
			return declNames.toArray(new IASTName[declNames.size()]);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   316
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   317
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   318
		// 2. Try definition in index
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   319
		return index.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   320
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   321
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   322
	private IName[] findDeclarations(IIndex index, IASTTranslationUnit ast,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   323
			IBinding binding) throws CoreException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   324
		IName[] declNames= ast.getDeclarationsInAST(binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   325
		for (int i = 0; i < declNames.length; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   326
			IName name = declNames[i];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   327
			if (name.isDefinition()) 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   328
				declNames[i]= null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   329
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   330
		declNames= (IName[]) ArrayUtil.removeNulls(IName.class, declNames);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   331
		if (declNames.length == 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   332
			declNames= index.findNames(binding, IIndex.FIND_DECLARATIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   333
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   334
		return declNames;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   335
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   336
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   337
	private static NameKind getNameKind(IName name) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   338
		if (name.isDefinition()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   339
			if (getBinding(name) instanceof ICPPUsingDeclaration) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   340
				return NameKind.USING_DECL;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   341
			} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   342
				return NameKind.DEFINITION;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   343
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   344
		} else if (name.isDeclaration()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   345
			return NameKind.DECLARATION;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   346
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   347
		return NameKind.REFERENCE;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   348
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   349
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   350
	private static IBinding getBinding(IName name) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   351
		if (name instanceof IASTName) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   352
			return ((IASTName) name).resolveBinding();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   353
		} else if (name instanceof IIndexFragmentName) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   354
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   355
				return ((IIndexFragmentName) name).getBinding();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   356
			} catch (CoreException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   357
				// Fall through to return null.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   358
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   359
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   360
		return null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   361
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   362
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   363
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   364
	 * Compacts an array by moving all <code>null</code> elements to the end.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   365
	 * @param array
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   366
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   367
	private void compact(Object[] array) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   368
		for (int i = 0, j = 0; i < array.length; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   369
			if (array[i] != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   370
				if (i != j) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   371
					array[j] = array[i];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   372
					array[i] = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   373
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   374
				j++;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   375
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   376
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   377
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   378
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   379
	private boolean isSameName(IName n1, IName n2) {
128
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   380
		if (n1 == n2)
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   381
			return true;
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   382
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   383
		IASTFileLocation loc1 = n1.getFileLocation();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   384
		IASTFileLocation loc2 = n2.getFileLocation();
128
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   385
		if (loc1 == null || loc2 == null) {
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   386
			return false;
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   387
		}
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   388
		return loc1.getFileName().equals(loc2.getFileName()) 
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   389
				&& loc1.getNodeOffset() == loc2.getNodeOffset()
d00b6e7a8c94 fix bug 10386 (mrege from CDT 6.0.1 HEAD)
timkelly
parents: 37
diff changeset
   390
				&& loc1.getNodeLength() == loc2.getNodeLength();}
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   391
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   392
	private static boolean isInSameFunction(IASTName name1, IName name2) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   393
		IASTDeclaration decl1 = getEnclosingDeclaration(name1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   394
		IASTDeclaration decl2 = name2 instanceof IASTName ? getEnclosingDeclaration((IASTName) name2) : null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   395
		return decl1 != null && decl1.equals(decl2) || decl1 == null && decl2 == null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   396
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   397
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   398
	private static IASTDeclaration getEnclosingDeclaration(IASTNode node) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   399
		while (node != null && !(node instanceof IASTDeclaration)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   400
			node= node.getParent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   401
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   402
		return (IASTDeclaration) node;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   403
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   404
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   405
	private static boolean isInSameTemplate(IASTName name1, IName name2) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   406
		IASTDeclaration decl1 = getEnclosingTemplateDeclaration(name1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   407
		IASTDeclaration decl2 = name2 instanceof IASTName ?
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   408
				getEnclosingTemplateDeclaration((IASTName) name2) : null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   409
		return decl1 != null && decl1.equals(decl2) || decl1 == null && decl2 == null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   410
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   411
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   412
	private static IASTDeclaration getEnclosingTemplateDeclaration(IASTNode node) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   413
		while (node != null && !(node instanceof ICPPASTTemplateDeclaration)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   414
			node= node.getParent();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   415
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   416
		return (IASTDeclaration) node;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   417
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   418
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   419
	private void convertToCElements(ICProject project, IIndex index, IName[] declNames, List<ICElement> elements) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   420
		for (IName declName : declNames) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   421
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   422
				ICElement elem = getCElementForName(project, index, declName);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   423
				if (elem instanceof ISourceReference) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   424
					elements.add(elem);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   425
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   426
			} catch (CoreException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   427
				CUIPlugin.log(e);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   428
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   429
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   430
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   431
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   432
	private ICElementHandle getCElementForName(ICProject project, IIndex index, IName declName) throws CoreException {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   433
		if (declName instanceof IIndexName) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   434
			return IndexUI.getCElementForName(project, index, (IIndexName) declName);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   435
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   436
		if (declName instanceof IASTName) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   437
			IASTName astName = (IASTName) declName;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   438
			IBinding binding= astName.resolveBinding();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   439
			if (binding != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   440
				ITranslationUnit tu= IndexUI.getTranslationUnit(project, astName);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   441
				if (tu != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   442
					IASTFileLocation loc= astName.getFileLocation();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   443
					IRegion region= new Region(loc.getNodeOffset(), loc.getNodeLength());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   444
					return CElementHandleFactory.create(tu, binding, astName.isDefinition(), region, 0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   445
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   446
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   447
			return null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   448
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   449
		return null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   450
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   451
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   452
	private boolean navigateViaCElements(ICProject project, IIndex index, IName[] declNames) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   453
		final ArrayList<ICElement> elements= new ArrayList<ICElement>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   454
		convertToCElements(project, index, declNames, elements);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   455
		return navigateCElements(elements);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   456
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   457
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   458
	private boolean navigateCElements(final List<ICElement> elements) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   459
		if (elements.isEmpty()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   460
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   461
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   462
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   463
		runInUIThread(new Runnable() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   464
			public void run() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   465
				ISourceReference target= null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   466
				if (elements.size() == 1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   467
					target= (ISourceReference) elements.get(0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   468
				} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   469
					if (OpenDeclarationsAction.sIsJUnitTest) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   470
						throw new RuntimeException("ambiguous input: " + elements.size()); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   471
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   472
					ICElement[] elemArray= elements.toArray(new ICElement[elements.size()]);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   473
					target = (ISourceReference) OpenActionUtil.selectCElement(elemArray, fAction.getSite().getShell(),
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   474
							CEditorMessages.OpenDeclarationsAction_dialog_title, CEditorMessages.OpenDeclarationsAction_selectMessage, 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   475
							CElementBaseLabels.ALL_DEFAULT | CElementBaseLabels.ALL_FULLY_QUALIFIED | CElementBaseLabels.MF_POST_FILE_QUALIFIED, 0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   476
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   477
				if (target != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   478
					ITranslationUnit tu= target.getTranslationUnit();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   479
					ISourceRange sourceRange;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   480
					try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   481
						sourceRange = target.getSourceRange();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   482
						if (tu != null && sourceRange != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   483
							fAction.open(tu.getLocation(), sourceRange.getIdStartPos(), sourceRange.getIdLength());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   484
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   485
					} catch (CoreException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   486
						CUIPlugin.log(e);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   487
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   488
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   489
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   490
		});
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   491
		return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   492
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   493
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   494
	private boolean navigateOneLocation(IName[] names) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   495
		for (IName name : names) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   496
			if (navigateToName(name)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   497
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   498
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   499
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   500
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   501
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   502
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   503
	private boolean navigateToName(IName name) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   504
		return navigateToLocation(name.getFileLocation());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   505
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   506
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   507
	private boolean navigateToLocation(IASTFileLocation fileloc) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   508
		if (fileloc == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   509
			return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   510
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   511
		final IPath path = new Path(fileloc.getFileName());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   512
		final int offset = fileloc.getNodeOffset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   513
		final int length = fileloc.getNodeLength();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   514
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   515
		runInUIThread(new Runnable() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   516
			public void run() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   517
				try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   518
					fAction.open(path, offset, length);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   519
				} catch (CoreException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   520
					CUIPlugin.log(e);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   521
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   522
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   523
		});
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   524
		return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   525
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   526
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   527
	private void runInUIThread(Runnable runnable) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   528
		if (Display.getCurrent() != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   529
			runnable.run();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   530
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   531
			Display.getDefault().asyncExec(runnable);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   532
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   533
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   534
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   535
	private void openInclude(IASTPreprocessorIncludeStatement incStmt) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   536
		String name = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   537
		if (incStmt.isResolved())
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   538
			name = incStmt.getPath();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   539
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   540
		if (name != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   541
			final IPath path = new Path(name);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   542
			runInUIThread(new Runnable() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   543
				public void run() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   544
					try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   545
						fAction.open(path, 0, 0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   546
					} catch (CoreException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   547
						CUIPlugin.log(e);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   548
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   549
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   550
			});
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   551
		} else {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   552
			fAction.reportIncludeLookupFailure(new String(incStmt.getName().toCharArray()));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   553
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   554
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   555
	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   556
	private boolean navigationFallBack(IASTTranslationUnit ast, IASTName sourceName, NameKind kind) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   557
		// bug 102643, as a fall-back we look up the selected word in the index
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   558
		if (fSelectedText != null && fSelectedText.length() > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   559
			try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   560
				final ICProject project = fTranslationUnit.getCProject();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   561
				final char[] name = fSelectedText.toCharArray();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   562
				List<ICElement> elems= new ArrayList<ICElement>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   563
								
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   564
				// bug 252549, search for names in the AST first
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   565
				Set<IBinding> primaryBindings= new HashSet<IBinding>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   566
				Set<IBinding> ignoreIndexBindings= new HashSet<IBinding>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   567
				ASTNameCollector nc= new ASTNameCollector(fSelectedText);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   568
				ast.accept(nc);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   569
				IASTName[] candidates= nc.getNames();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   570
				for (IASTName astName : candidates) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   571
					try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   572
						IBinding b= astName.resolveBinding();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   573
						if (b != null && !(b instanceof IProblemBinding)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   574
							if (primaryBindings.add(b)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   575
								ignoreIndexBindings.add(fIndex.adaptBinding(b));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   576
							}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   577
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   578
					} catch (RuntimeException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   579
						CUIPlugin.log(e);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   580
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   581
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   582
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   583
				// Search the index, also
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   584
				final IndexFilter filter = IndexFilter.getDeclaredBindingFilter(ast.getLinkage().getLinkageID(), false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   585
				final IIndexBinding[] idxBindings = fIndex.findBindings(name, false, filter, fMonitor);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   586
				for (IIndexBinding idxBinding : idxBindings) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   587
					if (!ignoreIndexBindings.contains(idxBinding)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   588
						primaryBindings.add(idxBinding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   589
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   590
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   591
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   592
				// Search for a macro in the index
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   593
				IIndexMacro[] macros= fIndex.findMacros(name, filter, fMonitor);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   594
				for (IIndexMacro macro : macros) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   595
					ICElement elem= IndexUI.getCElementForMacro(project, fIndex, macro);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   596
					if (elem != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   597
						elems.add(elem);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   598
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   599
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   600
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   601
				Collection<IBinding> secondaryBindings= removeSecondaryBindings(primaryBindings, sourceName);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   602
				// Convert bindings to CElements
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   603
				Collection<IBinding> bs= primaryBindings;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   604
				for (int k=0; k<2; k++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   605
					for (IBinding binding : bs) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   606
						IName[] names = findNames(fIndex, ast, kind, binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   607
						// Exclude names of the same kind.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   608
						for (int i = 0; i < names.length; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   609
							if (getNameKind(names[i]) == kind) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   610
								names[i] = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   611
							}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   612
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   613
						names = (IName[]) ArrayUtil.removeNulls(IName.class, names);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   614
						convertToCElements(project, fIndex, names, elems);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   615
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   616
					// in case we did not find anything, consider the secondary bindings
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   617
					if (!elems.isEmpty())
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   618
						break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   619
					bs= secondaryBindings;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   620
				} 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   621
				if (navigateCElements(elems)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   622
					return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   623
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   624
				if (sourceName != null && sourceName.isDeclaration()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   625
					// Select the name at the current location as the last resort. 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   626
					return navigateToName(sourceName);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   627
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   628
			} catch (CoreException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   629
				CUIPlugin.log(e);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   630
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   631
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   632
		return false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   633
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   634
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   635
	private Collection<IBinding> removeSecondaryBindings(Set<IBinding> primaryBindings, IASTName sourceName) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   636
		List<IBinding> result= new ArrayList<IBinding>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   637
		String[] sourceQualifiedName= null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   638
		int funcArgCount= -1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   639
		if (sourceName != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   640
			sourceQualifiedName= CPPVisitor.getQualifiedName(sourceName.resolveBinding());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   641
			if (sourceName.resolveBinding() instanceof ICPPUnknownBinding) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   642
				LookupData data= CPPSemantics.createLookupData(sourceName, false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   643
				if (data.functionCall()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   644
					funcArgCount= data.getFunctionArgumentCount();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   645
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   646
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   647
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   648
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   649
		for (Iterator<IBinding> iterator = primaryBindings.iterator(); iterator.hasNext();) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   650
			IBinding binding = iterator.next();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   651
			if (sourceQualifiedName != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   652
				String[] qualifiedName = CPPVisitor.getQualifiedName(binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   653
				if (!Arrays.equals(qualifiedName, sourceQualifiedName)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   654
					iterator.remove();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   655
					continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   656
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   657
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   658
			if (funcArgCount != -1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   659
				// for c++ we can check the number of parameters
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   660
				if (binding instanceof ICPPFunction) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   661
					ICPPFunction f= (ICPPFunction) binding;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   662
					try {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   663
						IParameter[] pars= f.getParameters();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   664
						if (pars.length < funcArgCount) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   665
							if (!f.takesVarArgs()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   666
								iterator.remove();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   667
								result.add(binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   668
								continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   669
							}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   670
						} else if (pars.length > funcArgCount) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   671
							IParameter p= pars[funcArgCount];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   672
							if (!(p instanceof ICPPParameter) || !((ICPPParameter) p).hasDefaultValue()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   673
								iterator.remove();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   674
								result.add(binding);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   675
								continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   676
							}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   677
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   678
					} catch (DOMException e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   679
						// ignore problem bindings
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   680
						continue;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   681
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   682
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   683
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   684
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   685
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   686
		return result;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   687
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   688
}