diff options
author | Markus Schorn | 2008-10-02 11:36:51 +0000 |
---|---|---|
committer | Markus Schorn | 2008-10-02 11:36:51 +0000 |
commit | 3e28b31ae14ac9b0df055fbf4ec7ddbcc5e43ec6 (patch) | |
tree | b8796a652fc787963e734ce1cf4ad715ae53921f | |
parent | 4796a78346722d14c7523729e67b1f3be820d615 (diff) | |
download | org.eclipse.cdt-3e28b31ae14ac9b0df055fbf4ec7ddbcc5e43ec6.tar.gz org.eclipse.cdt-3e28b31ae14ac9b0df055fbf4ec7ddbcc5e43ec6.tar.xz org.eclipse.cdt-3e28b31ae14ac9b0df055fbf4ec7ddbcc5e43ec6.zip |
Implementation to select resource for a location, bug 248419.
22 files changed, 445 insertions, 338 deletions
diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java index 66d1bb2513c..e5d2d30974b 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java @@ -21,14 +21,13 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; @@ -41,7 +40,7 @@ public class GCCPerFileBOPConsoleParser extends AbstractGCCBOPConsoleParser { private final static String[] FILE_EXTENSIONS = { ".c", ".cc", ".cpp", ".cxx", ".C", ".CC", ".CPP", ".CXX" //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ }; - private final static List FILE_EXTENSIONS_LIST = Arrays.asList(FILE_EXTENSIONS); + private final static List<String> FILE_EXTENSIONS_LIST = Arrays.asList(FILE_EXTENSIONS); private GCCPerFileBOPConsoleParserUtility fUtil; @@ -57,14 +56,16 @@ public class GCCPerFileBOPConsoleParser extends AbstractGCCBOPConsoleParser { /* (non-Javadoc) * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#getUtility() */ - protected AbstractGCCBOPConsoleParserUtility getUtility() { + @Override + protected AbstractGCCBOPConsoleParserUtility getUtility() { return fUtil; } /* (non-Javadoc) * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#processSingleLine(java.lang.String) */ - protected boolean processCommand(String[] tokens) { + @Override + protected boolean processCommand(String[] tokens) { // GCC C/C++ compiler invocation int compilerInvocationIndex= findCompilerInvocation(tokens); if (compilerInvocationIndex < 0) { @@ -132,20 +133,13 @@ public class GCCPerFileBOPConsoleParser extends AbstractGCCBOPConsoleParser { } else { // search linked resources final IProject prj= fUtil.getProject(); - final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); - IFile[] foundOccurrences= root.findFilesForLocation(pFilePath); - for (int j=0; j<foundOccurrences.length; j++) { - if (prj.equals(foundOccurrences[j].getProject())) { - file= foundOccurrences[j]; - break; - } - } + file= ResourceLookup.selectFileForLocation(pFilePath, prj); } if (file != null) { CCommandDSC cmd = fUtil.getNewCCommandDSC(tokens, compilerInvocationIndex, extensionsIndex > 0); - List cmdList = new ArrayList(); + List<CCommandDSC> cmdList = new ArrayList<CCommandDSC>(); cmdList.add(cmd); - Map sc = new HashMap(1); + Map<ScannerInfoTypes, List<CCommandDSC>> sc = new HashMap<ScannerInfoTypes, List<CCommandDSC>>(1); sc.put(ScannerInfoTypes.COMPILER_COMMAND, cmdList); getCollector().contributeToScannerConfig(file, sc); } else diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java index d19258c552b..16fc36bab81 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java @@ -1,13 +1,13 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 IBM Corporation and others. + * Copyright (c) 2004, 2008 IBM Corporation 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: - * IBM - Initial API and implementation - * Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136) + * IBM - Initial API and implementation + * Tianchao Li (tianchao.li@gmail.com) - arbitrary build directory (bug #136136) *******************************************************************************/ package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.internal.core.MakeMessages; import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; @@ -42,16 +43,16 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser /* * For tracking the location of files being compiled */ - private Map fFilesInProject; - private List fCollectedFiles; - private List fNameConflicts; + private Map<String, IFile> fFilesInProject; + private List<IResource> fCollectedFiles; + private List<String> fNameConflicts; public ScannerInfoConsoleParserUtility(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator) { super(project, workingDirectory, markerGenerator); - fFilesInProject = new HashMap(); - fCollectedFiles = new ArrayList(); - fNameConflicts = new ArrayList(); + fFilesInProject = new HashMap<String, IFile>(); + fCollectedFiles = new ArrayList<IResource>(); + fNameConflicts = new ArrayList<String>(); collectFiles(getProject(), fCollectedFiles); @@ -135,7 +136,7 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser */ protected IFile findFileName(String fileName) { IPath path = new Path(fileName); - return (IFile) fFilesInProject.get(path.lastSegment()); + return fFilesInProject.get(path.lastSegment()); } protected IFile findFileInWorkspace(IPath path) { @@ -145,22 +146,15 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser file = root.getFileForLocation(path); // It may be a link resource so we must check it also. if (file == null) { - IFile[] files = root.findFilesForLocation(path); - for (int i = 0; i < files.length; i++) { - if (files[i].getProject().equals(getProject())) { - file = files[i]; - break; - } - } + file= ResourceLookup.selectFileForLocation(path, getProject()); } - } else { file = getProject().getFile(path); } return file; } - protected void collectFiles(IContainer parent, List result) { + protected void collectFiles(IContainer parent, List<IResource> result) { try { IResource[] resources = parent.members(); for (int i = 0; i < resources.length; i++) { @@ -181,10 +175,10 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser return fNameConflicts.contains(path.lastSegment()); } - public List translateRelativePaths(IFile file, String fileName, List includes) { - List translatedIncludes = new ArrayList(includes.size()); - for (Iterator i = includes.iterator(); i.hasNext(); ) { - String include = (String) i.next(); + public List<String> translateRelativePaths(IFile file, String fileName, List<String> includes) { + List<String> translatedIncludes = new ArrayList<String>(includes.size()); + for (Iterator<String> i = includes.iterator(); i.hasNext(); ) { + String include = i.next(); IPath includePath = new Path(include); if (!includePath.isAbsolute() && !includePath.isUNC()) { // do not translate UNC paths // First try the current working directory @@ -205,7 +199,7 @@ public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParser if (fileName.startsWith("..")) { //$NON-NLS-1$ // probably multiple choices for cwd, hopeless final String error = MakeMessages.getString("ConsoleParser.Working_Directory_Error_Message"); //$NON-NLS-1$ - TraceUtil.outputError(error, fileName); //$NON-NLS-1$ + TraceUtil.outputError(error, fileName); generateMarker(file, -1, error, IMarkerGenerator.SEVERITY_WARNING, fileName); break; } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java index c31536e7fe4..6f2779d8bb0 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java @@ -17,6 +17,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; @@ -44,14 +45,14 @@ public class CCommandDSC { private final static String KIND_ATTR = "kind"; //$NON-NLS-1$ private int commandId; - private List compilerCommand; // members are KVStringPair objects + private List<KVStringPair> compilerCommand; // members are KVStringPair objects private boolean discovered; private boolean cppFileType; // C or C++ file type private IProject project; - private List symbols; - private List includes; - private List quoteIncludes; + private List<String> symbols; + private List<String> includes; + private List<String> quoteIncludes; /** * @param cppFileType2 @@ -61,13 +62,13 @@ public class CCommandDSC { } public CCommandDSC(boolean cppFileType, IProject project) { - compilerCommand = new ArrayList(); + compilerCommand = new ArrayList<KVStringPair>(); discovered = false; this.cppFileType = cppFileType; - symbols = new ArrayList(); - includes = new ArrayList(); - quoteIncludes = new ArrayList(); + symbols = new ArrayList<String>(); + includes = new ArrayList<String>(); + quoteIncludes = new ArrayList<String>(); this.project = project; } @@ -84,7 +85,7 @@ public class CCommandDSC { option.getKey().equals(SCDOptionsEnum.IQUOTE.toString()))) { String value = option.getValue(); - value = (String)CygpathTranslator.translateIncludePaths(project, Collections.singletonList(value)).get(0); + value = CygpathTranslator.translateIncludePaths(project, Collections.singletonList(value)).get(0); value = makeRelative(project, new Path(value)).toOSString(); option = new KVStringPair(option.getKey(), value); } @@ -110,10 +111,11 @@ public class CCommandDSC { this.commandId = commandId; } + @Override public String toString() { String commandAsString = new String(); - for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { - KVStringPair optionPair = (KVStringPair)i.next(); + for (Iterator<KVStringPair> i = compilerCommand.iterator(); i.hasNext(); ) { + KVStringPair optionPair = i.next(); String value = optionPair.getValue(); commandAsString += optionPair.getKey() + SINGLE_SPACE + value + SINGLE_SPACE; @@ -132,8 +134,8 @@ public class CCommandDSC { */ public String getSCDRunnableCommand(boolean quoteIncludePaths, boolean quoteDefines) { String commandAsString = new String(); - for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { - KVStringPair optionPair = (KVStringPair)i.next(); + for (Iterator<KVStringPair> i = compilerCommand.iterator(); i.hasNext(); ) { + KVStringPair optionPair = i.next(); if (optionPair.getKey().equals(SCDOptionsEnum.COMMAND.toString())) { commandAsString += optionPair.getValue() + SINGLE_SPACE; } @@ -172,8 +174,8 @@ public class CCommandDSC { */ public String getCompilerName() { String compiler = new String(); - for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { - KVStringPair optionPair = (KVStringPair)i.next(); + for (Iterator<KVStringPair> i = compilerCommand.iterator(); i.hasNext(); ) { + KVStringPair optionPair = i.next(); if (optionPair.getKey().equals(SCDOptionsEnum.COMMAND.toString())) { compiler = optionPair.getValue(); break; @@ -185,10 +187,10 @@ public class CCommandDSC { /** * @return list of strings */ - public List getImacrosFile() { - List imacrosFiles = new ArrayList(); - for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { - KVStringPair optionPair = (KVStringPair)i.next(); + public List<String> getImacrosFile() { + List<String> imacrosFiles = new ArrayList<String>(); + for (Iterator<KVStringPair> i = compilerCommand.iterator(); i.hasNext(); ) { + KVStringPair optionPair = i.next(); if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE.toString())) { imacrosFiles.add(makeAbsolute(project,optionPair.getValue())); } @@ -199,10 +201,10 @@ public class CCommandDSC { /** * @return list of strings */ - public List getIncludeFile() { - List includeFiles = new ArrayList(); - for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { - KVStringPair optionPair = (KVStringPair)i.next(); + public List<String> getIncludeFile() { + List<String> includeFiles = new ArrayList<String>(); + for (Iterator<KVStringPair> i = compilerCommand.iterator(); i.hasNext(); ) { + KVStringPair optionPair = i.next(); if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE.toString())) { includeFiles.add(makeAbsolute(project,optionPair.getValue())); } @@ -217,6 +219,7 @@ public class CCommandDSC { /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ + @Override public boolean equals(Object arg0) { if (arg0 != null && arg0.getClass().equals(this.getClass())) { CCommandDSC other = (CCommandDSC)arg0; @@ -228,6 +231,7 @@ public class CCommandDSC { /* (non-Javadoc) * @see java.lang.Object#hashCode() */ + @Override public int hashCode() { return compilerCommand.hashCode(); } @@ -235,37 +239,37 @@ public class CCommandDSC { /** * @return Returns the includes as strings. */ - public List getIncludes() { + public List<String> getIncludes() { return makeAbsolute(project, includes); } /** * @param includes The includes to set. */ - public void setIncludes(List includes) { + public void setIncludes(List<String> includes) { this.includes = includes; } /** * @return Returns the quote include paths as strings (for #include "...") */ - public List getQuoteIncludes() { + public List<String> getQuoteIncludes() { return makeAbsolute(project, quoteIncludes); } /** * @param includes. Quote include paths (for #include "...") */ - public void setQuoteIncludes(List includes) { + public void setQuoteIncludes(List<String> includes) { quoteIncludes = includes; } /** * @return Returns the symbols. */ - public List getSymbols() { + public List<String> getSymbols() { return symbols; } /** * @param symbols The symbols to set. */ - public void setSymbols(List symbols) { + public void setSymbols(List<String> symbols) { this.symbols = symbols; } /** @@ -288,9 +292,9 @@ public class CCommandDSC { Document doc = cmdElem.getOwnerDocument(); // serialize the command Element cmdDescElem = doc.createElement(CMD_DESCRIPTION_ELEM); - for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { + for (Iterator<KVStringPair> i = compilerCommand.iterator(); i.hasNext(); ) { Element optionElem = doc.createElement(OPTION_ELEM); - KVStringPair option = (KVStringPair) i.next(); + KVStringPair option = i.next(); optionElem.setAttribute(KEY_ATTR, option.getKey()); optionElem.setAttribute(VALUE_ATTR, option.getValue()); cmdDescElem.appendChild(optionElem); @@ -298,23 +302,23 @@ public class CCommandDSC { cmdElem.appendChild(cmdDescElem); // serialize includes and symbols Element siElem = doc.createElement(CMD_SI_ELEM); - for (Iterator j = quoteIncludes.iterator(); j.hasNext(); ) { + for (Iterator<String> j = quoteIncludes.iterator(); j.hasNext(); ) { Element siItem = doc.createElement(SI_ITEM_ELEM); siItem.setAttribute(KIND_ATTR, "INCLUDE_PATH"); //$NON-NLS-1$ - siItem.setAttribute(VALUE_ATTR, (String) j.next()); + siItem.setAttribute(VALUE_ATTR, j.next()); siItem.setAttribute(QUOTE_INCLUDE_ATTR, "true"); //$NON-NLS-1$ siElem.appendChild(siItem); } - for (Iterator j = includes.iterator(); j.hasNext(); ) { + for (Iterator<String> j = includes.iterator(); j.hasNext(); ) { Element siItem = doc.createElement(SI_ITEM_ELEM); siItem.setAttribute(KIND_ATTR, "INCLUDE_PATH"); //$NON-NLS-1$ - siItem.setAttribute(VALUE_ATTR, (String) j.next()); + siItem.setAttribute(VALUE_ATTR, j.next()); siElem.appendChild(siItem); } - for (Iterator j = symbols.iterator(); j.hasNext(); ) { + for (Iterator<String> j = symbols.iterator(); j.hasNext(); ) { Element siItem = doc.createElement(SI_ITEM_ELEM); siItem.setAttribute(KIND_ATTR, "SYMBOL_DEFINITION"); //$NON-NLS-1$ - siItem.setAttribute(VALUE_ATTR, (String) j.next()); + siItem.setAttribute(VALUE_ATTR, j.next()); siElem.appendChild(siItem); } cmdElem.appendChild(siElem); @@ -366,11 +370,11 @@ public class CCommandDSC { public void resolveOptions(IProject project) { if (!isDiscovered()) { // that's wrong for sure, options cannot be resolved fron the optionPairs?? - ArrayList symbols = new ArrayList(); - ArrayList includes = new ArrayList(); - ArrayList quoteincludes = new ArrayList(); - for (Iterator options = compilerCommand.iterator(); options.hasNext(); ) { - KVStringPair optionPair = (KVStringPair)options.next(); + ArrayList<String> symbols = new ArrayList<String>(); + ArrayList<String> includes = new ArrayList<String>(); + ArrayList<String> quoteincludes = new ArrayList<String>(); + for (Iterator<KVStringPair> options = compilerCommand.iterator(); options.hasNext(); ) { + KVStringPair optionPair = options.next(); String key = optionPair.getKey(); String value = optionPair.getValue(); if (key.equals(SCDOptionsEnum.INCLUDE.toString()) || key.equals(SCDOptionsEnum.ISYSTEM.toString())) { @@ -409,30 +413,16 @@ public class CCommandDSC { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); resource = root.findMember(path, false); if (resource == null) { - IResource[] resources = root.findFilesForLocation(path); - if (project != null) { - for (int i = 0; i < resources.length; i++) { - final IProject myProject = resources[i].getProject(); - // resource could be root, then myProject is null. - if (myProject != null && myProject.equals(project)) { - resource = resources[i]; - break; - } - } - } - // make a relative path to another project (better than an absolute path) - if (resource == null && resources.length > 0) { - resource = resources[0]; - } + resource= ResourceLookup.selectFileForLocation(path, project); } } return resource; } - public static List makeRelative(IProject project, List paths) { - List list = new ArrayList(paths.size()); - for (Iterator iter=paths.iterator(); iter.hasNext(); ) { - String path = (String)iter.next(); + public static List<String> makeRelative(IProject project, List<String> paths) { + List<String> list = new ArrayList<String>(paths.size()); + for (Iterator<String> iter=paths.iterator(); iter.hasNext(); ) { + String path = iter.next(); path = makeRelative(project, new Path(path)).toOSString(); list.add(path); } @@ -455,10 +445,10 @@ public class CCommandDSC { return path; } - public static List makeAbsolute(IProject project, List paths) { - List list = new ArrayList(paths.size()); - for (Iterator iter=paths.iterator(); iter.hasNext(); ) { - String path = (String)iter.next(); + public static List<String> makeAbsolute(IProject project, List<String> paths) { + List<String> list = new ArrayList<String>(paths.size()); + for (Iterator<String> iter=paths.iterator(); iter.hasNext(); ) { + String path = iter.next(); path = makeAbsolute(project, path); list.add(path); } diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/ResourceLookupTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/ResourceLookupTests.java index 0adba55e2de..986bf53c9c4 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/ResourceLookupTests.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/ResourceLookupTests.java @@ -26,6 +26,7 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; @@ -182,8 +183,6 @@ public class ResourceLookupTests extends TestCase { } public void testFindFilesByLocation() throws Exception { - IProject[] prjs= new IProject[]{fProject}; - fProject.create(new NullProgressMonitor()); fProject.open(new NullProgressMonitor()); createFolder(fProject, "folder1"); @@ -193,12 +192,18 @@ public class ResourceLookupTests extends TestCase { createFile(fProject, "folder2/abC.h"); URI uri= file.getLocationURI(); - IFile[] files= ResourceLookup.findFilesForLocation(uri, prjs); + IPath path= file.getLocation(); + IFile[] files= ResourceLookup.findFilesForLocationURI(uri); + assertEquals(1, files.length); + files= ResourceLookup.findFilesForLocation(path); assertEquals(1, files.length); if (new File("a").equals(new File("A"))) { URI upperCase= new URI(uri.getScheme(), uri.getSchemeSpecificPart().toUpperCase(), uri.getFragment()); - files= ResourceLookup.findFilesForLocation(upperCase, prjs); + IPath upperCasePath= new Path(path.toString().toUpperCase()); + files= ResourceLookup.findFilesForLocationURI(upperCase); + assertEquals(1, files.length); + files= ResourceLookup.findFilesForLocation(upperCasePath); assertEquals(1, files.length); } } diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 56a5cc21242..5f9dfd7e435 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -71,7 +71,7 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.internal.core.pdom.dom.cpp;x-internal:=true, org.eclipse.cdt.internal.core.pdom.export;x-internal:=true, org.eclipse.cdt.internal.core.pdom.indexer;x-friends:="org.eclipse.cdt.ui", - org.eclipse.cdt.internal.core.resources;x-internal:=true, + org.eclipse.cdt.internal.core.resources;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.make.core", org.eclipse.cdt.internal.core.util;x-internal:=true, org.eclipse.cdt.internal.errorparsers;x-internal:=true, org.eclipse.cdt.internal.formatter;x-internal:=true, diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModelUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModelUtil.java index 9d539425038..046d63e44af 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModelUtil.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModelUtil.java @@ -6,9 +6,9 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX Software Systems - Initial API and implementation - * Markus Schorn (Wind River Systems) - * IBM Corporation - EFS support + * QNX Software Systems - Initial API and implementation + * Markus Schorn (Wind River Systems) + * IBM Corporation - EFS support *******************************************************************************/ package org.eclipse.cdt.core.model; @@ -24,6 +24,7 @@ import org.eclipse.cdt.core.index.IndexLocationFactory; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.settings.model.ICTargetPlatformSetting; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -544,7 +545,7 @@ public class CoreModelUtil { * @since 4.0 */ public static ITranslationUnit findTranslationUnitForLocation(IPath location, ICProject preferredProject) throws CModelException { - IFile[] files= ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(location); + IFile[] files= ResourceLookup.findFilesForLocation(location); if (files.length > 0) { for (IFile file : files) { ITranslationUnit tu= findTranslationUnit(file); @@ -580,7 +581,7 @@ public class CoreModelUtil { * @since 5.0 */ public static ITranslationUnit findTranslationUnitForLocation(URI locationURI, ICProject preferredProject) throws CModelException { - IFile[] files= ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(locationURI); + IFile[] files= ResourceLookup.findFilesForLocationURI(locationURI); if (files.length > 0) { for (IFile file : files) { ITranslationUnit tu= findTranslationUnit(file); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java index 3cb2511f1aa..e0ce0ab2fa0 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Binary.java @@ -35,10 +35,10 @@ import org.eclipse.cdt.core.model.IBinary; import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.cdt.internal.core.util.MementoTokenizer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -327,9 +327,7 @@ public class Binary extends Openable implements IBinary { // See if this source file is already in the project. // We check this to determine if we should create a TranslationUnit or ExternalTranslationUnit IFile wkspFile = null; - IFile[] filesInWP = ResourcesPlugin - .getWorkspace().getRoot() - .findFilesForLocation(new Path(filename)); + IFile[] filesInWP = ResourceLookup.findFilesForLocation(new Path(filename)); for (IFile element : filesInWP) { if (element.isAccessible()) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java index 1b22a405eb4..546c1f1440f 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java @@ -55,6 +55,7 @@ import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.LocalProjectScope; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileInfo; import org.eclipse.core.filesystem.IFileStore; @@ -218,10 +219,7 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe // In case this is an external resource see if we can find // a file for it. if (res == null) { - IFile[] files = root.findFilesForLocation(path); - if (files.length > 0) { - res = files[0]; - } + res= ResourceLookup.selectFileForLocation(path, null); } return create(res, null); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java index 70d2197279f..578dcb88be5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexLocationFactory.java @@ -12,19 +12,15 @@ package org.eclipse.cdt.core.index; import java.net.URI; -import java.util.Arrays; -import java.util.Comparator; -import org.eclipse.cdt.core.CProjectNature; import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.index.IndexFileLocation; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; @@ -42,25 +38,6 @@ import org.eclipse.core.runtime.Path; */ public class IndexLocationFactory { /** - * Comparator to sort files for location. - */ - private static final class FILE_COMPARATOR implements Comparator<IFile> { - public int compare(IFile o1, IFile o2) { - return compare(o1.getLocationURI(), o2.getLocationURI()); - } - - private int compare(URI uri1, URI uri2) { - if (uri1 == uri2) - return 0; - if (uri1 == null) - return -1; - if (uri2 == null) - return 1; - return uri1.toString().compareTo(uri2.toString()); - } - } - - /** * Returns * <ul> * <li> the full path if this IIndexFileLocation if within the workspace root @@ -113,37 +90,11 @@ public class IndexLocationFactory { * @return an IIndexFileLocation for the specified resource, containing a workspace relative path if possible. */ public static IIndexFileLocation getIFLExpensive(ICProject cproject, String absolutePath) { - IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(absolutePath)); - if (files.length==1) { - IFile file = files[0]; - if (file.exists()) - return getWorkspaceIFL(file); - } else { - Arrays.sort(files, new FILE_COMPARATOR()); - final IProject preferredProject= cproject == null ? null : cproject.getProject(); - IFile fileInCProject= null; - for (IFile file : files) { - if (file.exists()) { - // check for preferred project - final IProject project = file.getProject(); - if (preferredProject != null && preferredProject.equals(project)) - return getWorkspaceIFL(file); + final IProject preferredProject= cproject == null ? null : cproject.getProject(); + IFile file= ResourceLookup.selectFileForLocation(new Path(absolutePath), preferredProject); + if (file != null) + return getWorkspaceIFL(file); - if (fileInCProject == null) { - try { - if (project.hasNature(CProjectNature.C_NATURE_ID)) { - fileInCProject= file; - } - } catch (CoreException e) { - // treat as non-c project - } - } - } - } - if (fileInCProject != null) - return getWorkspaceIFL(fileInCProject); - } - return getExternalIFL(absolutePath); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMExportOperation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMExportOperation.java index 6da96532779..0b96362267f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMExportOperation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMExportOperation.java @@ -34,6 +34,7 @@ import org.eclipse.cdt.core.model.LanguageManager; import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.pdom.dom.PDOMProjectIndexLocationConverter; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; @@ -221,7 +222,7 @@ public class TeamPDOMExportOperation implements IWorkspaceRunnable { finally { close(out); } - IFile[] wsResource= ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(fTargetLocationFile.getAbsolutePath())); + IFile[] wsResource= ResourceLookup.findFilesForLocation(new Path(fTargetLocationFile.getAbsolutePath())); for (int i = 0; i < wsResource.length; i++) { IFile file = wsResource[i]; file.refreshLocal(0, new NullProgressMonitor()); diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java index 11da9ca89fd..e2afadb3156 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ErrorParserManager.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.Vector; import org.eclipse.cdt.core.resources.ACBuilder; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.cdt.utils.CygPath; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -278,13 +279,7 @@ public class ErrorParserManager extends OutputStream { file = root.getFileForLocation(path); // It may be a link resource so we must check it also. if (file == null) { - IFile[] files = root.findFilesForLocation(path); - for (IFile file2 : files) { - if (file2.getProject().equals(fProject)) { - file = file2; - break; - } - } + file= ResourceLookup.selectFileForLocation(path, fProject); } } else { diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java index 531c1e24f85..06dd882928f 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/parser/ParserUtil.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.internal.core.model.DebugLogConstants; import org.eclipse.cdt.internal.core.parser.InternalParserUtil; import org.eclipse.cdt.internal.core.parser.ParserLogService; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; @@ -117,22 +118,18 @@ public class ParserUtil try { - IFile resultingResource = root.getFile(path); - if( resultingResource != null && resultingResource.exists() ) - return resultingResource; - resultingResource = root.getFileForLocation( path ); - if( resultingResource != null && resultingResource.exists() ) - return resultingResource; + IFile file = root.getFile(path); + if( file != null && file.exists() ) + return file; + + file = root.getFileForLocation( path ); + if( file != null && file.exists() ) + return file; // check for linked resources - IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(initialPath); - - // note for findFilesForLocation(IPath): This method does not consider whether resources actually exist at the given locations. - // so only return the first IFile found that is accessible - for (IFile file : files) { - if (file.isAccessible()) - return file; - } + file= ResourceLookup.selectFileForLocation(initialPath, null); + if (file != null && file.exists()) + return file; return null; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/FileRelevance.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/FileRelevance.java new file mode 100644 index 00000000000..a38297e4aa4 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/FileRelevance.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2008 Broadcom 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: + * James Blackburn (Broadcom) - Initial API and implementation + * Markus Schorn (Wind River Systems) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.resources; + +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.internal.core.model.CModelManager; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; + +/** + * This class computes a relevance for files in case we have to select + * from multiple files for the same file-system location. + */ +public class FileRelevance { + private static final int PREFERRED_PROJECT = 0x40; + private static final int CDT_PROJECT = 0x20; + private static final int ON_SOURCE_ROOT = 0x10; + + /** + * Compute a relevance for the given file. The higher the score the more relevant the + * file. It is determined by the following criteria: <br> + * - file belongs to preferred project <br> + * - file belongs to a cdt-project <br> + * - file belongs to a source folder of a cdt-project <br> + * @param f the file to compute the relevance for + * @return -1 if f1 is preferable, 1 if f2 is preferable, 0 if there is no difference. + */ + public static int getRelevance(IFile f, IProject preferredProject) { + int result= 0; + IProject p= f.getProject(); + if (p.equals(preferredProject)) + result+= PREFERRED_PROJECT; + + if (CoreModel.hasCNature(p)) { + result+= CDT_PROJECT; + ICProject cproject= CModelManager.getDefault().create(p); + if (cproject.isOnSourceRoot(f)) + result+= ON_SOURCE_ROOT; + } + return result; + } +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/LocationAdapter.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/LocationAdapter.java new file mode 100644 index 00000000000..e7eddacffa0 --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/LocationAdapter.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2008 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: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.resources; + +import java.io.File; +import java.io.IOException; +import java.net.URI; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; + +/** + * Provides common functionality for URI and IPath + */ +abstract class LocationAdapter<T> { + + public abstract String extractName(T location); + public abstract IFile[] platformsFindFilesForLocation(T location); + public abstract String getCanonicalPath(T location); + public abstract T getLocation(IFile file); + + public static final LocationAdapter<IPath> PATH = new LocationAdapter<IPath>() { + @Override + public String extractName(IPath location) { + return location.lastSegment(); + } + + @Override + public IFile[] platformsFindFilesForLocation(IPath location) { + return ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(location); + } + + @Override + public String getCanonicalPath(IPath location) { + final File file= location.toFile(); + try { + return file.getCanonicalPath(); + } catch (IOException e) { + // use non-canonical version + return file.getAbsolutePath(); + } + } + + @Override + public IPath getLocation(IFile file) { + return file.getLocation(); + } + }; + + public static final LocationAdapter<URI> URI = new LocationAdapter<URI>() { + @Override + public String extractName(URI location) { + String path= location.getPath(); + int idx= path.lastIndexOf('/'); + return path.substring(idx+1); + } + + @Override + public IFile[] platformsFindFilesForLocation(URI location) { + return ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(location); + } + + @Override + public String getCanonicalPath(URI location) { + if (!"file".equals(location.getScheme())) //$NON-NLS-1$ + return null; + + String path= location.getPath(); + try { + return new File(path).getCanonicalPath(); + } catch (IOException e) { + // use non-canonical version + return path; + } + } + + @Override + public URI getLocation(IFile file) { + return file.getLocationURI(); + } + }; +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java index 5e37fede7e8..c1c17d2ac7e 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookup.java @@ -20,46 +20,116 @@ import org.eclipse.core.runtime.IPath; * Allows for looking up resources by location or name. */ public class ResourceLookup { - private static ResourceLookupImpl sInstance= new ResourceLookupImpl(); + private static ResourceLookupTree lookupTree= new ResourceLookupTree(); public static void startup() { - sInstance.startup(); + lookupTree.startup(); } public static void shutdown() { - sInstance.shutdown(); - } - - public static IFile[] findFilesForLocation(URI location, IProject[] projects) { - return sInstance.findFilesForLocation(location, projects); + lookupTree.shutdown(); } /** * Searches for files with the given location suffix. + * + * At this point the method works for sources and headers (no other content types), only. + * This is done to use less memory and can be changed if necessary. + * * @param locationSuffix the suffix to match, always used as relative path. * @param projects the projects to search * @param ignoreCase whether or not to ignore case when comparing the suffix. */ public static IFile[] findFilesByName(IPath locationSuffix, IProject[] projects, boolean ignoreCase) { - return sInstance.findFilesByName(locationSuffix, projects, ignoreCase); + return lookupTree.findFilesByName(locationSuffix, projects, ignoreCase); + } + + /** + * Uses a lookup-tree that finds resources for locations using the canonical representation + * of the path. The method does not work for files where the name (last segment) of the + * resources differs from the name of the location. + */ + public static IFile[] findFilesForLocationURI(URI location) { + return lookupTree.findFilesForLocationURI(location); + } + + /** + * Uses a lookup-tree that finds resources for locations using the canonical representation + * of the path. The method does not work for files where the name (last segment) of the + * resources differs from the name of the location. + */ + public static IFile[] findFilesForLocation(IPath location) { + return lookupTree.findFilesForLocation(location); + } + + /** + * Uses {@link #findFilesForLocationURI(URI)} and selects the most relevant file + * from the result. Files form the first project, from cdt-projects and those on source + * roots are preferred, see {@link FileRelevance}. + * @param location an URI for the location of the files to search for. + * @param preferredProject a project to be preferred over others, or <code>null</code>. + * @return a file for the location in one of the given projects, or <code>null</code>. + */ + public static IFile selectFileForLocationURI(URI location, IProject preferredProject) { + return selectFile(findFilesForLocationURI(location), preferredProject); + } + + /** + * Uses {@link #findFilesForLocation(IPath)} and selects the most relevant file + * from the result. Files form the first project, from cdt-projects and those on source + * roots are preferred, see {@link FileRelevance}. + * @param location a path for the location of the files to search for. + * @param preferredProject a project to be preferred over others, or <code>null</code>. + * @return a file for the location in one of the given projects, or <code>null</code>. + */ + public static IFile selectFileForLocation(IPath location, IProject preferredProject) { + return selectFile(findFilesForLocation(location), preferredProject); + } + + private static IFile selectFile(IFile[] files, IProject preferredProject) { + if (files.length == 0) + return null; + + if (files.length == 1) { + final IFile file= files[0]; + if (file.isAccessible()) + return file; + } + + IFile best= null; + int bestRelevance= -1; + + for (int i = 1; i < files.length; i++) { + IFile file = files[i]; + if (file.isAccessible()) { + int relevance= FileRelevance.getRelevance(file, preferredProject); + if (best == null || relevance > bestRelevance || + (relevance == bestRelevance && + best.getFullPath().toString().compareTo(file.getFullPath().toString()) > 0)) { + bestRelevance= relevance; + best= file; + } + } + } + return best; } /** * For testing, only. */ public static void dump() { - sInstance.dump(); + lookupTree.dump(); } /** * For testing, only. */ public static void unrefNodeMap() { - sInstance.unrefNodeMap(); + lookupTree.unrefNodeMap(); } /** * For testing, only. */ public static void simulateNodeMapCollection() { - sInstance.simulateNodeMapCollection(); + lookupTree.simulateNodeMapCollection(); } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookupImpl.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookupTree.java index 95eac4f55ac..29208fcadd5 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookupImpl.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/resources/ResourceLookupTree.java @@ -10,8 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.resources; -import java.io.File; -import java.io.IOException; import java.lang.ref.SoftReference; import java.net.URI; import java.util.ArrayList; @@ -65,7 +63,7 @@ import org.eclipse.core.runtime.jobs.Job; * A node contains the name of a file plus a link to the parent resource. From that we can compute * the resource path and obtain further information via the resource. */ -class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisitor, IResourceProxyVisitor { +class ResourceLookupTree implements IResourceChangeListener, IResourceDeltaVisitor, IResourceProxyVisitor { private static final int UNREF_DELAY = 10 * 60000; // 10 min private static final boolean VISIT_CHILDREN = true; @@ -88,7 +86,7 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit if (idx < 0) return true; - return fExtensions.contains(filename.substring(idx+1)) != fInvert; + return fExtensions.contains(filename.substring(idx+1).toUpperCase()) != fInvert; } } @@ -109,7 +107,7 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit parent.fHasChildren= true; } } - + private final Object fLock= new Object(); private final Job fUnrefJob; private SoftReference<Map<Integer, Object>> fNodeMapRef; @@ -122,7 +120,7 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit private boolean fNeedCleanup; private Node fLastFolderNode; - public ResourceLookupImpl() { + public ResourceLookupTree() { fRootNode= new Node(null, CharArrayUtils.EMPTY, true) {}; fFileExtensions= new HashMap<String, Extensions>(); fUnrefJob= new Job("Timer") { //$NON-NLS-1$ @@ -326,10 +324,11 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit * Initializes file-extensions and node map */ private void initFileExtensions() { + if (fDefaultExtensions == null) { - HashSet<String> select= new HashSet<String>(); + HashSet<String> cdtContentTypes= new HashSet<String>(); String[] registeredContentTypes= CoreModel.getRegistedContentTypeIds(); - select.addAll(Arrays.asList(registeredContentTypes)); + cdtContentTypes.addAll(Arrays.asList(registeredContentTypes)); final IContentTypeManager ctm= Platform.getContentTypeManager(); final IContentType[] ctts= ctm.getAllContentTypes(); @@ -337,40 +336,37 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit outer: for (IContentType ctt : ctts) { IContentType basedOn= ctt; while (basedOn != null) { - if (select.contains(basedOn.getId())) + if (cdtContentTypes.contains(basedOn.getId())) continue outer; basedOn= basedOn.getBaseType(); } // this is a non-cdt content type - String[] fspecs= ctt.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); - result.addAll(Arrays.asList(fspecs)); + addFileSpecs(ctt, result); } fCDTProjectExtensions= new Extensions(result, true); result= new HashSet<String>(); - select.clear(); - select.add(CCorePlugin.CONTENT_TYPE_CHEADER); - select.add(CCorePlugin.CONTENT_TYPE_CXXHEADER); for (IContentType ctt : ctts) { IContentType basedOn= ctt; - boolean selectme= false; while (basedOn != null) { - if (select.contains(basedOn.getId())) { - selectme= true; + if (cdtContentTypes.contains(basedOn.getId())) { + addFileSpecs(ctt, result); break; } basedOn= basedOn.getBaseType(); } - if (selectme) { - // this is content type for a header file - String[] fspecs= ctt.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); - result.addAll(Arrays.asList(fspecs)); - } } fDefaultExtensions= new Extensions(result, false); } } + private void addFileSpecs(IContentType ctt, Set<String> result) { + String[] fspecs= ctt.getFileSpecs(IContentType.FILE_EXTENSION_SPEC); + for (String fspec : fspecs) { + result.add(fspec.toUpperCase()); + } + } + /** * Inserts a node for the given path. */ @@ -594,21 +590,49 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit } /** - * Searches for all files with the given location. + * Searches for all files with the given location. In case the name of the location is + * a cdt-content type the lookup tree is consulted, otherwise as a fallback the platform's + * method is called. + */ + public IFile[] findFilesForLocationURI(URI location) { + return findFilesForLocation(location, LocationAdapter.URI); + } + + /** + * Searches for all files with the given location. In case the name of the location is + * a cdt-content type the lookup tree is consulted, otherwise as a fallback the platform's + * method is called. + */ + public IFile[] findFilesForLocation(IPath location) { + return findFilesForLocation(location, LocationAdapter.PATH); + } + + /** + * Searches for all files with the given location. In case the name of the location is + * a cdt-content type the lookup tree is consulted, otherwise as a fallback the platform's + * method is called. */ - public IFile[] findFilesForLocation(URI location, IProject[] projects) { + public <T> IFile[] findFilesForLocation(T location, LocationAdapter<T> adapter) { initFileExtensions(); - String name= extractName(location); - Node[] candidates; + String name= adapter.extractName(location); + Node[] candidates= null; synchronized (fLock) { - initializeProjects(projects); + initializeProjects(ResourcesPlugin.getWorkspace().getRoot().getProjects()); Object obj= fNodeMap.get(hashCode(name.toCharArray())); if (obj == null) { - return NO_FILES; + if (fDefaultExtensions.isRelevant(name)) + return NO_FILES; + } else { + candidates= convert(obj); } - candidates= convert(obj); } - return extractMatchesForLocation(candidates, location); + + // fall back to platform functionality + if (candidates == null) { + return adapter.platformsFindFilesForLocation(location); + } + + return extractMatchesForLocation(candidates, location, adapter); } private Node[] convert(Object obj) { @@ -649,12 +673,6 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit return extractMatchesForName(candidates, name, suffix, ignoreCase); } - private String extractName(URI location) { - String path= location.getPath(); - int idx= path.lastIndexOf('/'); - return path.substring(idx+1); - } - /** * Selects the actual matches for the list of candidate nodes. */ @@ -717,16 +735,16 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit /** * Selects the actual matches from the list of candidates */ - private IFile[] extractMatchesForLocation(Node[] candidates, URI location) { + private <T> IFile[] extractMatchesForLocation(Node[] candidates, T location, LocationAdapter<T> adapter) { final IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); - final String searchPath= getCanonicalPath(location); + final String searchPath= adapter.getCanonicalPath(location); IFile[] result= null; int resultIdx= 0; for (int i = 0; i < candidates.length; i++) { final Node node = candidates[i]; if (!node.fIsFolder) { final IFile file= root.getFile(createPath(node)); - final URI loc= file.getLocationURI(); + final T loc= adapter.getLocation(file); if (loc != null) { if (!loc.equals(location)) { if (searchPath == null) @@ -735,7 +753,7 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit if (node.fCanonicHash != 0 && node.fCanonicHash != searchPath.hashCode()) continue; - final String candPath= getCanonicalPath(loc); + final String candPath= adapter.getCanonicalPath(loc); if (candPath == null) continue; @@ -760,21 +778,6 @@ class ResourceLookupImpl implements IResourceChangeListener, IResourceDeltaVisit return result; } - private String getCanonicalPath(URI location) { - if (!"file".equals(location.getScheme())) //$NON-NLS-1$ - return null; - - String path= location.getPath(); - try { - path= new File(path).getCanonicalPath(); - } catch (IOException e) { - // use non-canonical version - } - return path; - } - - - @SuppressWarnings("nls") public void dump() { List<String> lines= new ArrayList<String>(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java index 7b35dcc1a2e..9854b8e5949 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java @@ -52,6 +52,8 @@ import org.eclipse.cdt.core.parser.IScannerInfoProvider; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.utils.PathUtil; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; + import org.eclipse.cdt.internal.ui.CPluginImages; import org.eclipse.cdt.internal.ui.dialogs.ElementListSelectionDialog; import org.eclipse.cdt.internal.ui.util.EditorUtility; @@ -181,7 +183,7 @@ public class OpenIncludeAction extends Action { */ private IPath[] resolveIncludeLink(IPath path) { if (!isInProject(path)) { - IFile[] files = getWorkspaceRoot().findFilesForLocation(path); + IFile[] files = ResourceLookup.findFilesForLocation(path); if (files.length > 0) { IPath[] paths = new IPath[files.length]; for (int i = 0; i < files.length; i++) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java index c20722db779..db4d9451349 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/includebrowser/IBDropTargetListener.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2008 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 @@ -15,8 +15,6 @@ import java.util.Iterator; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspaceRoot; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.ISelection; @@ -33,6 +31,8 @@ import org.eclipse.ui.part.ResourceTransfer; import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; + public class IBDropTargetListener implements DropTargetListener { private IBViewPart fIncludeBrowser; @@ -119,10 +119,9 @@ public class IBDropTargetListener implements DropTargetListener { private ITranslationUnit findFirstTranslationUnit(Object o) { if (o instanceof String[]) { String[] filePaths= (String[]) o; - IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); for (int i = 0; i < filePaths.length; i++) { String filePath = filePaths[i]; - ITranslationUnit tu= findTranslationUnit(root.findFilesForLocation(Path.fromOSString(filePath))); + ITranslationUnit tu= findTranslationUnit(ResourceLookup.findFilesForLocation(Path.fromOSString(filePath))); if (tu != null) { return tu; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeContentProvider.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeContentProvider.java index 9955ed70f48..d68c6a1a9c4 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeContentProvider.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/PDOMSearchTreeContentProvider.java @@ -38,6 +38,8 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; + /** * @author Doug Schaefer * @@ -122,7 +124,7 @@ public class PDOMSearchTreeContentProvider implements ITreeContentProvider, IPDO files= new IFile[] {ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(location.getFullPath()))}; } else { IPath path= IndexLocationFactory.getAbsolutePath(element.getLocation()); - files= ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path); + files= ResourceLookup.findFilesForLocation(path); } boolean handled= false; if (files.length > 0) { diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java index 33f780c5bc9..fa5d788be74 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/EditorUtility.java @@ -69,6 +69,8 @@ import org.eclipse.cdt.core.resources.EFSFileStorage; import org.eclipse.cdt.core.resources.FileStorage; import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; + import org.eclipse.cdt.internal.ui.editor.CEditor; import org.eclipse.cdt.internal.ui.editor.CEditorMessages; import org.eclipse.cdt.internal.ui.editor.ITranslationUnitEditorInput; @@ -435,45 +437,24 @@ public class EditorUtility { project= cProject.getProject(); } } - IFile bestMatch= null; - IFile secondBestMatch= null; + IFile file= ResourceLookup.selectFileForLocation(location, project); + if (file != null && file.isAccessible()) + return file; + IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); - IFile[] files= root.findFilesForLocation(location); - if (files.length == 0) { - // workaround http://bugs.eclipse.org/233939 - IFile file= root.getFileForLocation(location); - if (file != null) { - files= new IFile[] { file }; - } - } - for (IFile file : files) { - if (file.isAccessible()) { - if (project != null && file.getProject().equals(project)) { - bestMatch= file; - break; - } else if (CoreModel.hasCNature(file.getProject())) { - bestMatch= file; - if (project == null) { - break; - } - } else { - // match in non-CDT project - secondBestMatch= file; - } - } - } - bestMatch= bestMatch != null ? bestMatch : secondBestMatch; - if (bestMatch == null) { - // try workspace relative path - if (location.segmentCount() >= 2) { - // @see IContainer#getFile for the required number of segments - IFile file= root.getFile(location); - if (file != null && file.isAccessible()) { - bestMatch= file; - } - } + // workaround http://bugs.eclipse.org/233939 + file= root.getFileForLocation(location); + if (file != null && file.isAccessible()) + return file; + + // try workspace relative path + if (location.segmentCount() >= 2) { + // @see IContainer#getFile for the required number of segments + file= root.getFile(location); + if (file != null && file.isAccessible()) + return file; } - return bestMatch; + return null; } /** @@ -493,29 +474,12 @@ public class EditorUtility { project= cProject.getProject(); } } - IFile bestMatch= null; - IFile secondBestMatch= null; - IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot(); - IFile[] files= root.findFilesForLocationURI(locationURI); - for (IFile file : files) { - if (file.isAccessible()) { - if (project != null && file.getProject().equals(project)) { - bestMatch= file; - break; - } else if (CoreModel.hasCNature(file.getProject())) { - bestMatch= file; - if (project == null) { - break; - } - } else { - // match in non-CDT project - secondBestMatch= file; - } - } - } - bestMatch= bestMatch != null ? bestMatch : secondBestMatch; - - return bestMatch; + + IFile file= ResourceLookup.selectFileForLocationURI(locationURI, project); + if (file != null && file.isAccessible()) + return file; + + return null; } /** diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java index 66692c4fabf..13f3a6c4503 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/newui/AbstractCPropertyTab.java @@ -58,6 +58,8 @@ import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICResourceDescription; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; + import org.eclipse.cdt.internal.ui.dialogs.StatusInfo; /** @@ -477,9 +479,7 @@ public abstract class AbstractCPropertyTab implements ICPropertyTab { } else { IResource resource = null; if(path.isAbsolute()){ - IFile fs[] = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path); - if(fs != null && fs.length > 0) - resource = fs[0]; + resource= ResourceLookup.selectFileForLocation(path, prj); } dialog.setInitialSelection(resource); dialog.setValidator(new ISelectionStatusValidator() { diff --git a/core/org.eclipse.cdt.ui/utils.ui/org/eclipse/cdt/utils/ui/controls/FileListControl.java b/core/org.eclipse.cdt.ui/utils.ui/org/eclipse/cdt/utils/ui/controls/FileListControl.java index a090bb561ff..526524ddebe 100644 --- a/core/org.eclipse.cdt.ui/utils.ui/org/eclipse/cdt/utils/ui/controls/FileListControl.java +++ b/core/org.eclipse.cdt.ui/utils.ui/org/eclipse/cdt/utils/ui/controls/FileListControl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 BitMethods Inc and others. + * Copyright (c) 2004, 2008 BitMethods 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 @@ -63,6 +63,8 @@ import org.eclipse.cdt.ui.newui.TypedCDTViewerFilter; import org.eclipse.cdt.ui.newui.UIMessages; import org.eclipse.cdt.utils.cdtvariables.IVariableContextInfo; +import org.eclipse.cdt.internal.core.resources.ResourceLookup; + /** * Instances of this class allow the user to add,remove, delete, moveup and movedown * the items in the list control. @@ -190,9 +192,7 @@ public class FileListControl { } else { IResource resource = null; if(path.isAbsolute()){ - IFile fs[] = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(path); - if(fs != null && fs.length > 0) - resource = fs[0]; + resource= ResourceLookup.selectFileForLocation(path, null); } if(resource == null) resource = rc; |