mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 337040 - MethodDefinitionInsertLocationFinder2 does not find implementation file when no definition already present. Patch by Marc-Andre Laperle.
This commit is contained in:
parent
29552b6bcf
commit
3715cdbbe8
8 changed files with 544 additions and 309 deletions
|
@ -26,11 +26,13 @@ import org.eclipse.cdt.core.model.ICProject;
|
||||||
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
import org.eclipse.cdt.core.testplugin.CProjectHelper;
|
||||||
import org.eclipse.cdt.core.testplugin.FileManager;
|
import org.eclipse.cdt.core.testplugin.FileManager;
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IFolder;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.resources.IWorkspace;
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,9 +65,6 @@ abstract public class BaseTestFramework extends TestCase {
|
||||||
//Set the id of the source indexer extension point as a session property to allow
|
//Set the id of the source indexer extension point as a session property to allow
|
||||||
//index manager to instantiate it
|
//index manager to instantiate it
|
||||||
project.setSessionProperty(IndexManager.indexerIDKey, sourceIndexerID);*/
|
project.setSessionProperty(IndexManager.indexerIDKey, sourceIndexerID);*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
/*boo*/
|
/*boo*/
|
||||||
}
|
}
|
||||||
|
@ -77,15 +76,14 @@ abstract public class BaseTestFramework extends TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseTestFramework()
|
public BaseTestFramework() {
|
||||||
{
|
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param name
|
* @param name
|
||||||
*/
|
*/
|
||||||
public BaseTestFramework(String name)
|
public BaseTestFramework(String name) {
|
||||||
{
|
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,20 +120,34 @@ abstract public class BaseTestFramework extends TestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IFile importFile(String fileName, String contents) throws Exception {
|
protected IFile importFile(String fileName, String contents) throws Exception {
|
||||||
// Obtain file handle
|
// Obtain file handle
|
||||||
IFile file = project.getProject().getFile(fileName);
|
IFile file = project.getProject().getFile(fileName);
|
||||||
|
|
||||||
InputStream stream = new ByteArrayInputStream(contents.getBytes());
|
InputStream stream = new ByteArrayInputStream(contents.getBytes());
|
||||||
// Create file input stream
|
// Create file input stream
|
||||||
if( file.exists() )
|
if (file.exists()) {
|
||||||
file.setContents(stream, false, false, monitor);
|
file.setContents(stream, false, false, monitor);
|
||||||
else
|
} else {
|
||||||
|
IPath path = file.getLocation();
|
||||||
|
path = path.makeRelativeTo(project.getLocation());
|
||||||
|
if (path.segmentCount() > 1) {
|
||||||
|
path = path.removeLastSegments(1);
|
||||||
|
|
||||||
|
for (int i = path.segmentCount() - 1; i >= 0; i--) {
|
||||||
|
IPath currentPath = path.removeLastSegments(i);
|
||||||
|
IFolder folder = project.getFolder(currentPath);
|
||||||
|
if (!folder.exists()) {
|
||||||
|
folder.create(false, true, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
file.create(stream, false, monitor);
|
file.create(stream, false, monitor);
|
||||||
|
}
|
||||||
|
|
||||||
fileManager.addFile(file);
|
fileManager.addFile(file);
|
||||||
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1458,6 +1458,7 @@ namespace foo
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=
|
//=
|
||||||
#include "Test.h"
|
#include "Test.h"
|
||||||
|
|
||||||
|
@ -1478,3 +1479,103 @@ namespace foo
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//!Bug 337040 - Insert definition in empty implementation file (.cxx)
|
||||||
|
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
|
||||||
|
//@.config
|
||||||
|
filename=Test.h
|
||||||
|
getters=testField
|
||||||
|
setters=testField
|
||||||
|
|
||||||
|
//@Test.h
|
||||||
|
#ifndef TEST_H_
|
||||||
|
#define TEST_H_
|
||||||
|
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
int /*$*/testField/*$$*/;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//=
|
||||||
|
#ifndef TEST_H_
|
||||||
|
#define TEST_H_
|
||||||
|
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
int testField;
|
||||||
|
public:
|
||||||
|
int getTestField() const;
|
||||||
|
void setTestField(int testField);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//@Test.cxx
|
||||||
|
|
||||||
|
//=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Test::getTestField() const
|
||||||
|
{
|
||||||
|
return testField;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test::setTestField(int testField)
|
||||||
|
{
|
||||||
|
this->testField = testField;
|
||||||
|
}
|
||||||
|
|
||||||
|
//!Bug 337040 - Insert definition in empty implementation file in complex directory structure
|
||||||
|
//#org.eclipse.cdt.ui.tests.refactoring.gettersandsetters.GenerateGettersAndSettersTest
|
||||||
|
//@.config
|
||||||
|
filename=component_b/public_headers/Test.h
|
||||||
|
getters=testField
|
||||||
|
setters=testField
|
||||||
|
|
||||||
|
//@component_b/public_headers/Test.h
|
||||||
|
#ifndef TEST_H_
|
||||||
|
#define TEST_H_
|
||||||
|
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
int /*$*/testField/*$$*/;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//=
|
||||||
|
#ifndef TEST_H_
|
||||||
|
#define TEST_H_
|
||||||
|
|
||||||
|
class Test
|
||||||
|
{
|
||||||
|
int testField;
|
||||||
|
public:
|
||||||
|
int getTestField() const;
|
||||||
|
void setTestField(int testField);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//@component_b/implementation/Test.cpp
|
||||||
|
|
||||||
|
//=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Test::getTestField() const
|
||||||
|
{
|
||||||
|
return testField;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test::setTestField(int testField)
|
||||||
|
{
|
||||||
|
this->testField = testField;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@component_a/public_headers/Test.h
|
||||||
|
|
||||||
|
//=
|
||||||
|
|
||||||
|
//@component_a/implementation/Test.cpp
|
||||||
|
|
||||||
|
//=
|
||||||
|
|
|
@ -811,3 +811,25 @@ void n1::n2::A::B::testmethod2()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//!Bug 337040 - Insert definition in empty implementation file (.cxx)
|
||||||
|
//#org.eclipse.cdt.ui.tests.refactoring.implementmethod.ImplementMethodRefactoringTest
|
||||||
|
//@.config
|
||||||
|
filename=A.h
|
||||||
|
//@A.h
|
||||||
|
|
||||||
|
class TestClass {
|
||||||
|
public:
|
||||||
|
/*$*/void foo();/*$$*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//@A.cxx
|
||||||
|
|
||||||
|
//=
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void TestClass::foo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,355 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2011 Wind River Systems, 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:
|
||||||
|
* Anton Leherbauer (Wind River Systems) - initial API and implementation
|
||||||
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Marc-Andre Laperle - Extracted Util class from ToggleSourceHeaderAction
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.internal.ui.editor;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IContainer;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IResourceProxy;
|
||||||
|
import org.eclipse.core.resources.IResourceProxyVisitor;
|
||||||
|
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.core.runtime.content.IContentType;
|
||||||
|
import org.eclipse.core.runtime.content.IContentTypeManager;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
|
import org.eclipse.cdt.core.index.IIndex;
|
||||||
|
import org.eclipse.cdt.core.index.IIndexName;
|
||||||
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
|
import org.eclipse.cdt.core.model.ICProject;
|
||||||
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A collection of static methods for finding the source file corresponding to a header
|
||||||
|
* and vice versa.
|
||||||
|
*/
|
||||||
|
public final class SourceHeaderPartnerFinder {
|
||||||
|
|
||||||
|
private static class Counter {
|
||||||
|
public int fCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SourceHeaderPartnerFinder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the partner file for a translation unit.
|
||||||
|
* The partner file is the corresponding source or header file
|
||||||
|
* based on heuristics.
|
||||||
|
*
|
||||||
|
* @since 4.0
|
||||||
|
*/
|
||||||
|
private static class PartnerFileComputer implements ASTRunnable {
|
||||||
|
PartnerFileVisitor fVisitor = null;
|
||||||
|
|
||||||
|
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
||||||
|
if (ast != null && ast.getIndex() != null) {
|
||||||
|
fVisitor = new PartnerFileVisitor();
|
||||||
|
ast.accept(fVisitor);
|
||||||
|
}
|
||||||
|
return Status.OK_STATUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPath getPartnerFileLocation() {
|
||||||
|
if(fVisitor != null) {
|
||||||
|
return fVisitor.getPartnerFileLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PartnerFileVisitor extends ASTVisitor {
|
||||||
|
/**
|
||||||
|
* When this many times the same partner file is hit,
|
||||||
|
* we are confident enough to take it.
|
||||||
|
*/
|
||||||
|
private static final int CONFIDENCE_LIMIT = 15;
|
||||||
|
/**
|
||||||
|
* When this many times no match was found in the index,
|
||||||
|
* we suspect that we won't get a good partner.
|
||||||
|
*/
|
||||||
|
private static final int SUSPECT_LIMIT = 15;
|
||||||
|
|
||||||
|
private IIndex fIndex;
|
||||||
|
private IPath fFilePath;
|
||||||
|
private Map<IPath, Counter> fMap;
|
||||||
|
/** The confidence level == number of hits */
|
||||||
|
private int fConfidence;
|
||||||
|
/** Suspect level == number of no index matches */
|
||||||
|
private int fSuspect;
|
||||||
|
/** The current favorite partner file */
|
||||||
|
private IPath fFavoriteLocation;
|
||||||
|
|
||||||
|
{
|
||||||
|
shouldVisitDeclarators= true;
|
||||||
|
shouldVisitTranslationUnit = true;
|
||||||
|
}
|
||||||
|
public PartnerFileVisitor() {
|
||||||
|
fMap= new HashMap<IPath, Counter>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTTranslationUnit tu) {
|
||||||
|
fIndex= tu.getIndex();
|
||||||
|
if(fIndex == null) {
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
fFilePath= Path.fromOSString(tu.getFilePath());
|
||||||
|
return super.visit(tu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPath getPartnerFileLocation() {
|
||||||
|
return fFavoriteLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int visit(IASTDeclarator declarator) {
|
||||||
|
if (declarator instanceof IASTFunctionDeclarator) {
|
||||||
|
IASTName name= declarator.getName();
|
||||||
|
if (name != null && declarator.getNestedDeclarator() == null) {
|
||||||
|
IBinding binding= name.resolveBinding();
|
||||||
|
if (binding != null && !(binding instanceof IProblemBinding)) {
|
||||||
|
boolean isDefinition= name.isDefinition();
|
||||||
|
final IIndexName[] partnerNames;
|
||||||
|
try {
|
||||||
|
if (isDefinition) {
|
||||||
|
partnerNames= fIndex.findNames(binding,
|
||||||
|
IIndex.FIND_DECLARATIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
|
||||||
|
} else {
|
||||||
|
partnerNames= fIndex.findNames(binding,
|
||||||
|
IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
|
||||||
|
}
|
||||||
|
if (partnerNames.length == 0) {
|
||||||
|
++fSuspect;
|
||||||
|
if (fSuspect == SUSPECT_LIMIT) {
|
||||||
|
fFavoriteLocation= null;
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i= 0; i < partnerNames.length; i++) {
|
||||||
|
IIndexName partnerName= partnerNames[i];
|
||||||
|
IASTFileLocation partnerLocation= partnerName.getFileLocation();
|
||||||
|
if (partnerLocation != null) {
|
||||||
|
IPath partnerFileLocation= Path.fromOSString(partnerLocation.getFileName());
|
||||||
|
if (!fFilePath.equals(partnerFileLocation)) {
|
||||||
|
addPotentialPartnerFileLocation(partnerFileLocation);
|
||||||
|
if (fConfidence == CONFIDENCE_LIMIT) {
|
||||||
|
return PROCESS_ABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (CoreException exc) {
|
||||||
|
CUIPlugin.log(exc.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return PROCESS_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPotentialPartnerFileLocation(IPath partnerFileLocation) {
|
||||||
|
Counter counter= fMap.get(partnerFileLocation);
|
||||||
|
if (counter == null) {
|
||||||
|
counter= new Counter();
|
||||||
|
fMap.put(partnerFileLocation, counter);
|
||||||
|
}
|
||||||
|
++counter.fCount;
|
||||||
|
if (counter.fCount > fConfidence) {
|
||||||
|
fConfidence= counter.fCount;
|
||||||
|
fFavoriteLocation= partnerFileLocation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a file in the given resource container for the given basename.
|
||||||
|
*
|
||||||
|
* @param container
|
||||||
|
* @param basename
|
||||||
|
* @return a matching {@link IFile} or <code>null</code>, if no matching file was found
|
||||||
|
*/
|
||||||
|
private static IFile findInContainer(IContainer container, final String basename) {
|
||||||
|
final IFile[] result= { null };
|
||||||
|
IResourceProxyVisitor visitor= new IResourceProxyVisitor() {
|
||||||
|
public boolean visit(IResourceProxy proxy) throws CoreException {
|
||||||
|
if (result[0] != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!proxy.isAccessible()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (proxy.getType() == IResource.FILE && proxy.getName().equals(basename)) {
|
||||||
|
result[0]= (IFile)proxy.requestResource();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}};
|
||||||
|
try {
|
||||||
|
container.accept(visitor, 0);
|
||||||
|
} catch (CoreException exc) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IContentType[] getPartnerContentTypes(String contentTypeId) {
|
||||||
|
IContentTypeManager mgr= Platform.getContentTypeManager();
|
||||||
|
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CHEADER)) {
|
||||||
|
return new IContentType[] {
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CSOURCE),
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXSOURCE)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CSOURCE)) {
|
||||||
|
return new IContentType[] {
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CHEADER),
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXHEADER)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CXXHEADER)) {
|
||||||
|
return new IContentType[] {
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXSOURCE),
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CSOURCE)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CXXSOURCE)) {
|
||||||
|
return new IContentType[] {
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXHEADER),
|
||||||
|
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CHEADER)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return new IContentType[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds a partner translation unit based on filename/extension matching.
|
||||||
|
*
|
||||||
|
* @param a partner translation unit or <code>null</code>
|
||||||
|
*/
|
||||||
|
private static ITranslationUnit getPartnerFileFromFilename(ITranslationUnit tu) {
|
||||||
|
IPath sourceFileLocation= tu.getLocation();
|
||||||
|
if (sourceFileLocation == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
IPath partnerBasePath= sourceFileLocation.removeFileExtension();
|
||||||
|
IContentType[] contentTypes= getPartnerContentTypes(tu.getContentTypeId());
|
||||||
|
HashSet<String> extensionsTried= new HashSet<String>();
|
||||||
|
for (int j = 0; j < contentTypes.length; j++) {
|
||||||
|
IContentType contentType= contentTypes[j];
|
||||||
|
String[] partnerExtensions;
|
||||||
|
partnerExtensions= contentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
|
||||||
|
for (int i= 0; i < partnerExtensions.length; i++) {
|
||||||
|
String ext= partnerExtensions[i];
|
||||||
|
if (extensionsTried.add(ext)) {
|
||||||
|
String partnerFileBasename= partnerBasePath.addFileExtension(ext).lastSegment();
|
||||||
|
|
||||||
|
IFile partnerFile= null;
|
||||||
|
IContainer container = tu.getResource().getParent();
|
||||||
|
while (container != null && partnerFile == null && !(container instanceof IWorkspaceRoot)) {
|
||||||
|
partnerFile= findInContainer(container, partnerFileBasename);
|
||||||
|
container = container.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partnerFile != null) {
|
||||||
|
ITranslationUnit partnerUnit= (ITranslationUnit) CoreModel.getDefault().create(partnerFile);
|
||||||
|
if (partnerUnit != null) {
|
||||||
|
return partnerUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// External translation unit - try in same directory
|
||||||
|
if (tu.getResource() == null) {
|
||||||
|
IPath partnerFileLoation= partnerBasePath.removeLastSegments(1).append(partnerFileBasename);
|
||||||
|
ITranslationUnit partnerUnit= CoreModel.getDefault().createTranslationUnitFrom(
|
||||||
|
tu.getCProject(), partnerFileLoation);
|
||||||
|
if (partnerUnit != null) {
|
||||||
|
return partnerUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ITranslationUnit getPartnerTranslationUnit(ITranslationUnit tu) {
|
||||||
|
ITranslationUnit partnerUnit= getPartnerFileFromFilename(tu);
|
||||||
|
|
||||||
|
if (partnerUnit == null) {
|
||||||
|
// Search partner file based on definition/declaration association
|
||||||
|
IProgressMonitor monitor= new NullProgressMonitor();
|
||||||
|
PartnerFileComputer computer= new PartnerFileComputer();
|
||||||
|
ASTProvider.getASTProvider().runOnAST(tu, ASTProvider.WAIT_ACTIVE_ONLY, monitor, computer);
|
||||||
|
partnerUnit = createTranslationUnit(computer.getPartnerFileLocation(), tu.getCProject());
|
||||||
|
}
|
||||||
|
return partnerUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ITranslationUnit getPartnerTranslationUnit(ITranslationUnit tu,
|
||||||
|
RefactoringASTCache astCache) throws CoreException {
|
||||||
|
ITranslationUnit partnerUnit= getPartnerFileFromFilename(tu);
|
||||||
|
|
||||||
|
if (partnerUnit == null) {
|
||||||
|
// Search partner file based on definition/declaration association
|
||||||
|
IProgressMonitor monitor= new NullProgressMonitor();
|
||||||
|
IASTTranslationUnit ast = astCache.getAST(tu, monitor);
|
||||||
|
PartnerFileVisitor visitor = new PartnerFileVisitor();
|
||||||
|
ast.accept(visitor);
|
||||||
|
partnerUnit = createTranslationUnit(visitor.getPartnerFileLocation(), tu.getCProject());
|
||||||
|
}
|
||||||
|
return partnerUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ITranslationUnit createTranslationUnit(IPath partnerFileLoation, ICProject cProject) {
|
||||||
|
ITranslationUnit partnerUnit = null;
|
||||||
|
if (partnerFileLoation != null) {
|
||||||
|
partnerUnit= (ITranslationUnit) CoreModel.getDefault().create(partnerFileLoation);
|
||||||
|
if (partnerUnit == null) {
|
||||||
|
partnerUnit= CoreModel.getDefault().createTranslationUnitFrom(cProject.getCProject(),
|
||||||
|
partnerFileLoation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return partnerUnit;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,53 +12,20 @@
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.ui.editor;
|
package org.eclipse.cdt.internal.ui.editor;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IContainer;
|
|
||||||
import org.eclipse.core.resources.IFile;
|
|
||||||
import org.eclipse.core.resources.IResource;
|
|
||||||
import org.eclipse.core.resources.IResourceProxy;
|
|
||||||
import org.eclipse.core.resources.IResourceProxyVisitor;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
|
||||||
import org.eclipse.core.runtime.IPath;
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.IStatus;
|
|
||||||
import org.eclipse.core.runtime.NullProgressMonitor;
|
|
||||||
import org.eclipse.core.runtime.Path;
|
|
||||||
import org.eclipse.core.runtime.Platform;
|
|
||||||
import org.eclipse.core.runtime.Status;
|
|
||||||
import org.eclipse.core.runtime.content.IContentType;
|
|
||||||
import org.eclipse.core.runtime.content.IContentTypeManager;
|
|
||||||
import org.eclipse.ui.IEditorInput;
|
import org.eclipse.ui.IEditorInput;
|
||||||
import org.eclipse.ui.IEditorPart;
|
import org.eclipse.ui.IEditorPart;
|
||||||
import org.eclipse.ui.PartInitException;
|
import org.eclipse.ui.PartInitException;
|
||||||
import org.eclipse.ui.texteditor.ITextEditor;
|
import org.eclipse.ui.texteditor.ITextEditor;
|
||||||
import org.eclipse.ui.texteditor.TextEditorAction;
|
import org.eclipse.ui.texteditor.TextEditorAction;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
|
||||||
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.core.model.CModelException;
|
||||||
import org.eclipse.cdt.core.model.CoreModel;
|
|
||||||
import org.eclipse.cdt.core.model.ILanguage;
|
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
import org.eclipse.cdt.ui.IWorkingCopyManager;
|
import org.eclipse.cdt.ui.IWorkingCopyManager;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,119 +35,6 @@ import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||||
*/
|
*/
|
||||||
public class ToggleSourceAndHeaderAction extends TextEditorAction {
|
public class ToggleSourceAndHeaderAction extends TextEditorAction {
|
||||||
|
|
||||||
private static class Counter {
|
|
||||||
public int fCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute the partner file for a translation unit.
|
|
||||||
* The partner file is the corresponding source or header file
|
|
||||||
* based on heuristics.
|
|
||||||
*
|
|
||||||
* @since 4.0
|
|
||||||
*/
|
|
||||||
private static class PartnerFileComputer extends ASTVisitor implements ASTRunnable {
|
|
||||||
/**
|
|
||||||
* When this many times the same partner file is hit,
|
|
||||||
* we are confident enough to take it.
|
|
||||||
*/
|
|
||||||
private static final int CONFIDENCE_LIMIT = 15;
|
|
||||||
/**
|
|
||||||
* When this many times no match was found in the index,
|
|
||||||
* we suspect that we won't get a good partner.
|
|
||||||
*/
|
|
||||||
private static final int SUSPECT_LIMIT = 15;
|
|
||||||
|
|
||||||
private IIndex fIndex;
|
|
||||||
private IPath fFilePath;
|
|
||||||
private Map<IPath, Counter> fMap;
|
|
||||||
/** The confidence level == number of hits */
|
|
||||||
private int fConfidence;
|
|
||||||
/** Suspect level == number of no index matches */
|
|
||||||
private int fSuspect;
|
|
||||||
/** The current favorite partner file */
|
|
||||||
private IPath fFavoriteLocation;
|
|
||||||
|
|
||||||
{
|
|
||||||
shouldVisitDeclarators= true;
|
|
||||||
}
|
|
||||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
|
||||||
if (ast != null) {
|
|
||||||
fIndex= ast.getIndex();
|
|
||||||
fFilePath= Path.fromOSString(ast.getFilePath());
|
|
||||||
fMap= new HashMap<IPath, Counter>();
|
|
||||||
if (fIndex != null) {
|
|
||||||
ast.accept(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Status.OK_STATUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IPath getPartnerFileLocation() {
|
|
||||||
return fFavoriteLocation;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.ASTVisitor#visit(org.eclipse.cdt.core.dom.ast.IASTDeclarator)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int visit(IASTDeclarator declarator) {
|
|
||||||
if (declarator instanceof IASTFunctionDeclarator) {
|
|
||||||
IASTName name= declarator.getName();
|
|
||||||
if (name != null && declarator.getNestedDeclarator() == null) {
|
|
||||||
IBinding binding= name.resolveBinding();
|
|
||||||
if (binding != null && !(binding instanceof IProblemBinding)) {
|
|
||||||
boolean isDefinition= name.isDefinition();
|
|
||||||
final IIndexName[] partnerNames;
|
|
||||||
try {
|
|
||||||
if (isDefinition) {
|
|
||||||
partnerNames= fIndex.findNames(binding, IIndex.FIND_DECLARATIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
|
|
||||||
} else {
|
|
||||||
partnerNames= fIndex.findNames(binding, IIndex.FIND_DEFINITIONS | IIndex.SEARCH_ACROSS_LANGUAGE_BOUNDARIES);
|
|
||||||
}
|
|
||||||
if (partnerNames.length == 0) {
|
|
||||||
++fSuspect;
|
|
||||||
if (fSuspect == SUSPECT_LIMIT) {
|
|
||||||
fFavoriteLocation= null;
|
|
||||||
return PROCESS_ABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i= 0; i < partnerNames.length; i++) {
|
|
||||||
IIndexName partnerName= partnerNames[i];
|
|
||||||
IASTFileLocation partnerLocation= partnerName.getFileLocation();
|
|
||||||
if (partnerLocation != null) {
|
|
||||||
IPath partnerFileLocation= Path.fromOSString(partnerLocation.getFileName());
|
|
||||||
if (!fFilePath.equals(partnerFileLocation)) {
|
|
||||||
addPotentialPartnerFileLocation(partnerFileLocation);
|
|
||||||
if (fConfidence == CONFIDENCE_LIMIT) {
|
|
||||||
return PROCESS_ABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (CoreException exc) {
|
|
||||||
CUIPlugin.log(exc.getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return PROCESS_SKIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addPotentialPartnerFileLocation(IPath partnerFileLocation) {
|
|
||||||
Counter counter= fMap.get(partnerFileLocation);
|
|
||||||
if (counter == null) {
|
|
||||||
counter= new Counter();
|
|
||||||
fMap.put(partnerFileLocation, counter);
|
|
||||||
}
|
|
||||||
++counter.fCount;
|
|
||||||
if (counter.fCount > fConfidence) {
|
|
||||||
fConfidence= counter.fCount;
|
|
||||||
fFavoriteLocation= partnerFileLocation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ITranslationUnit fgLastPartnerUnit;
|
private static ITranslationUnit fgLastPartnerUnit;
|
||||||
private static ITranslationUnit fgLastSourceUnit;
|
private static ITranslationUnit fgLastSourceUnit;
|
||||||
|
|
||||||
|
@ -261,130 +115,6 @@ public class ToggleSourceAndHeaderAction extends TextEditorAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// search partner file based on filename/extension
|
// search partner file based on filename/extension
|
||||||
ITranslationUnit partnerUnit= getPartnerFileFromFilename(tUnit);
|
return SourceHeaderPartnerFinder.getPartnerTranslationUnit(tUnit);
|
||||||
|
|
||||||
if (partnerUnit == null) {
|
|
||||||
// search partner file based on definition/declaration association
|
|
||||||
IProgressMonitor monitor= new NullProgressMonitor();
|
|
||||||
PartnerFileComputer computer= new PartnerFileComputer();
|
|
||||||
ASTProvider.getASTProvider().runOnAST(tUnit, ASTProvider.WAIT_ACTIVE_ONLY, monitor, computer);
|
|
||||||
IPath partnerFileLoation= computer.getPartnerFileLocation();
|
|
||||||
if (partnerFileLoation != null) {
|
|
||||||
partnerUnit= (ITranslationUnit) CoreModel.getDefault().create(partnerFileLoation);
|
|
||||||
if (partnerUnit == null) {
|
|
||||||
partnerUnit= CoreModel.getDefault().createTranslationUnitFrom(tUnit.getCProject(), partnerFileLoation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return partnerUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a partner translation unit based on filename/extension matching.
|
|
||||||
*
|
|
||||||
* @param a partner translation unit or <code>null</code>
|
|
||||||
*/
|
|
||||||
private ITranslationUnit getPartnerFileFromFilename(ITranslationUnit tUnit) {
|
|
||||||
IPath sourceFileLocation= tUnit.getLocation();
|
|
||||||
if (sourceFileLocation == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
IPath partnerBasePath= sourceFileLocation.removeFileExtension();
|
|
||||||
IContentType[] contentTypes= getPartnerContentTypes(tUnit.getContentTypeId());
|
|
||||||
HashSet<String> extensionsTried= new HashSet<String>();
|
|
||||||
for (int j = 0; j < contentTypes.length; j++) {
|
|
||||||
IContentType contentType= contentTypes[j];
|
|
||||||
String[] partnerExtensions;
|
|
||||||
partnerExtensions= contentType.getFileSpecs(IContentType.FILE_EXTENSION_SPEC);
|
|
||||||
for (int i= 0; i < partnerExtensions.length; i++) {
|
|
||||||
String ext= partnerExtensions[i];
|
|
||||||
if (extensionsTried.add(ext)) {
|
|
||||||
String partnerFileBasename= partnerBasePath.addFileExtension(ext).lastSegment();
|
|
||||||
|
|
||||||
IFile partnerFile= null;
|
|
||||||
if (tUnit.getResource() != null) {
|
|
||||||
partnerFile= findInContainer(tUnit.getResource().getParent(), partnerFileBasename);
|
|
||||||
}
|
|
||||||
if (partnerFile == null) {
|
|
||||||
partnerFile= findInContainer(tUnit.getCProject().getProject(), partnerFileBasename);
|
|
||||||
}
|
|
||||||
if (partnerFile != null) {
|
|
||||||
ITranslationUnit partnerUnit= (ITranslationUnit) CoreModel.getDefault().create(partnerFile);
|
|
||||||
if (partnerUnit != null) {
|
|
||||||
return partnerUnit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// external tanslation unit - try in same directory
|
|
||||||
if (tUnit.getResource() == null) {
|
|
||||||
IPath partnerFileLoation= partnerBasePath.removeLastSegments(1).append(partnerFileBasename);
|
|
||||||
ITranslationUnit partnerUnit= CoreModel.getDefault().createTranslationUnitFrom(tUnit.getCProject(), partnerFileLoation);
|
|
||||||
if (partnerUnit != null) {
|
|
||||||
return partnerUnit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a file in the given resource container for the given basename.
|
|
||||||
*
|
|
||||||
* @param container
|
|
||||||
* @param basename
|
|
||||||
* @return a matching {@link IFile} or <code>null</code>, if no matching file was found
|
|
||||||
*/
|
|
||||||
private IFile findInContainer(IContainer container, final String basename) {
|
|
||||||
final IFile[] result= { null };
|
|
||||||
IResourceProxyVisitor visitor= new IResourceProxyVisitor() {
|
|
||||||
public boolean visit(IResourceProxy proxy) throws CoreException {
|
|
||||||
if (result[0] != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!proxy.isAccessible()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (proxy.getType() == IResource.FILE && proxy.getName().equals(basename)) {
|
|
||||||
result[0]= (IFile)proxy.requestResource();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}};
|
|
||||||
try {
|
|
||||||
container.accept(visitor, 0);
|
|
||||||
} catch (CoreException exc) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
return result[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
private IContentType[] getPartnerContentTypes(String contentTypeId) {
|
|
||||||
IContentTypeManager mgr= Platform.getContentTypeManager();
|
|
||||||
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CHEADER)) {
|
|
||||||
return new IContentType[] {
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CSOURCE),
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXSOURCE)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CSOURCE)) {
|
|
||||||
return new IContentType[] {
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CHEADER),
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXHEADER)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CXXHEADER)) {
|
|
||||||
return new IContentType[] {
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXSOURCE),
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CSOURCE)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (contentTypeId.equals(CCorePlugin.CONTENT_TYPE_CXXSOURCE)) {
|
|
||||||
return new IContentType[] {
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CXXHEADER),
|
|
||||||
mgr.getContentType(CCorePlugin.CONTENT_TYPE_CHEADER)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return new IContentType[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,7 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring2 {
|
||||||
|
|
||||||
IASTSimpleDeclaration decl = context.existingFields.get(0);
|
IASTSimpleDeclaration decl = context.existingFields.get(0);
|
||||||
InsertLocation2 location = MethodDefinitionInsertLocationFinder2.find(
|
InsertLocation2 location = MethodDefinitionInsertLocationFinder2.find(
|
||||||
decl.getFileLocation(), decl.getParent(), astCache);
|
tu, decl.getFileLocation(), decl.getParent(), astCache);
|
||||||
|
|
||||||
if (location.getFile() == null || NodeHelper.isContainedInTemplateDeclaration(decl)) {
|
if (location.getFile() == null || NodeHelper.isContainedInTemplateDeclaration(decl)) {
|
||||||
location.setNodeToInsertAfter(NodeHelper.findTopLevelParent(decl), tu);
|
location.setNodeToInsertAfter(NodeHelper.findTopLevelParent(decl), tu);
|
||||||
|
|
|
@ -15,10 +15,9 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.eclipse.core.resources.IFile;
|
import org.eclipse.core.resources.IFile;
|
||||||
import org.eclipse.core.resources.ResourcesPlugin;
|
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IPath;
|
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
|
@ -27,7 +26,11 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.resources.ResourceLookup;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.SourceHeaderPartnerFinder;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.FileHelper;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.FileHelper;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
|
||||||
|
@ -85,12 +88,15 @@ public class MethodDefinitionInsertLocationFinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPath path = file.getLocation().removeFileExtension().addFileExtension("cpp"); //$NON-NLS-1$
|
ITranslationUnit tu = (ITranslationUnit) CCorePlugin.getDefault().getCoreModel().create(file);
|
||||||
IFile fileForLocation = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
|
ITranslationUnit partner = SourceHeaderPartnerFinder.getPartnerTranslationUnit(tu);
|
||||||
|
if (partner != null) {
|
||||||
|
IFile fileForLocation = ResourceLookup.selectFileForLocation(partner.getLocation(), file.getProject());
|
||||||
if (fileForLocation != null && fileForLocation.exists()) {
|
if (fileForLocation != null && fileForLocation.exists()) {
|
||||||
result.setInsertFile(fileForLocation);
|
result.setInsertFile(fileForLocation);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,9 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.SourceHeaderPartnerFinder;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache;
|
import org.eclipse.cdt.internal.ui.refactoring.RefactoringASTCache;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTNameInContext;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTNameInContext;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder2;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder2;
|
||||||
|
@ -60,7 +62,7 @@ public class MethodDefinitionInsertLocationFinder2 {
|
||||||
return functionDefinitionInParents;
|
return functionDefinitionInParents;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InsertLocation2 find(IASTFileLocation methodDeclarationLocation, IASTNode parent,
|
public static InsertLocation2 find(ITranslationUnit declarationTu, IASTFileLocation methodDeclarationLocation, IASTNode parent,
|
||||||
RefactoringASTCache astCache) throws CoreException {
|
RefactoringASTCache astCache) throws CoreException {
|
||||||
IASTDeclaration[] declarations = NodeHelper.getDeclarations(parent);
|
IASTDeclaration[] declarations = NodeHelper.getDeclarations(parent);
|
||||||
InsertLocation2 insertLocation = new InsertLocation2();
|
InsertLocation2 insertLocation = new InsertLocation2();
|
||||||
|
@ -83,6 +85,13 @@ public class MethodDefinitionInsertLocationFinder2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (insertLocation.getTranslationUnit() == null) {
|
||||||
|
ITranslationUnit partner = SourceHeaderPartnerFinder.getPartnerTranslationUnit(declarationTu, astCache);
|
||||||
|
if (partner != null) {
|
||||||
|
insertLocation.setParentNode(astCache.getAST(partner, null), partner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return insertLocation;
|
return insertLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue