1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

2005-02-10 Alain Magloire

Part of the fix for 79596
	* model/org/eclipse/cdt/core/model/CoreModel.java
	* model/org/eclipse/cdt/core/model/IPathEntry.java
	* model/org/eclipse/cdt/core/model/IPathEntryContainerExtension.java
	* model/org/eclipse/cdt/internal/core/model/PathEntryManager.java
	* src/org/eclipse/cdt/core/resources/ScannerProvider.java
This commit is contained in:
Alain Magloire 2005-02-10 22:42:51 +00:00
parent 131e9d4d75
commit 6b3069ebc5
6 changed files with 276 additions and 107 deletions

View file

@ -1,3 +1,11 @@
2005-02-10 Alain Magloire
Part of the fix for 79596
* model/org/eclipse/cdt/core/model/CoreModel.java
* model/org/eclipse/cdt/core/model/IPathEntry.java
* model/org/eclipse/cdt/core/model/IPathEntryContainerExtension.java
* model/org/eclipse/cdt/internal/core/model/PathEntryManager.java
* src/org/eclipse/cdt/core/resources/ScannerProvider.java
2005-01-29 Alain Magloire 2005-01-29 Alain Magloire
Copy the spaces and Newlines. Copy the spaces and Newlines.
* model/org/eclipse/cdt/internal/core/model/CopylementsOperation.java * model/org/eclipse/cdt/internal/core/model/CopylementsOperation.java

View file

@ -706,7 +706,7 @@ public class CoreModel {
} }
/** /**
* This method returs the resolved pathentries for the project All * This method returns the resolved pathentries for the project All
* pathEntry.CDT_CONTAINER entries in the project's will be replaced by the * pathEntry.CDT_CONTAINER entries in the project's will be replaced by the
* entries they resolve to. * entries they resolve to.
* <p> * <p>
@ -724,6 +724,42 @@ public class CoreModel {
return pathEntryManager.getResolvedPathEntries(cproject); return pathEntryManager.getResolvedPathEntries(cproject);
} }
/**
* This method returns the include entries associated with a translation unit
* if the path does not refer to a valid translation unit an empty is return.
* <p>
* The resulting resolved entries are accurate for the given point in time.
* If the project's raw entries are later modified they can become out of
* date. Because of this, hanging on resolved pathentries is not
* recommended.
* </p>
*
* @return the resolved entries for the project
* @exception CModelException
* @see IPathEntry
*/
public static IIncludeEntry[] getIncludeEntries(IPath path) throws CModelException {
return pathEntryManager.getIncludeEntries(path);
}
/**
* This method returns the macro entries associated with a translation unit
* if the path does not refer to a valid translation unit an empty array is return.
* <p>
* The resulting resolved entries are accurate for the given point in time.
* If the project's raw entries are later modified they can become out of
* date. Because of this, hanging on resolved pathentries is not
* recommended.
* </p>
*
* @return the resolved entries for the project
* @exception CModelException
* @see IPathEntry
*/
public static IMacroEntry[] getMacroEntries(IPath path) throws CModelException {
return pathEntryManager.getMacroEntries(path);
}
/** /**
* Helper method finding the pathentry container initializer registered for * Helper method finding the pathentry container initializer registered for
* a given container ID or <code>null</code> if none was found while * a given container ID or <code>null</code> if none was found while

View file

@ -76,13 +76,13 @@ public interface IPathEntry {
int getEntryKind(); int getEntryKind();
/** /**
* Returns the affected IPath
* *
* @return IPath * @return true if exported.
*/ */
boolean isExported(); boolean isExported();
/** /**
* Returns the affected IPath
* *
* @return IPath * @return IPath
*/ */

View file

@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.model;
import org.eclipse.core.runtime.IPath;
/**
*
*/
public interface IPathEntryContainerExtension extends IPathEntryContainer {
/**
* Returns the set of include entries associated with the resource
* and empty array if none.
*
* @param path Workspace relative path.
* @return IIncludeEntry[] - the entries or empty set if none
* @see IPathEntry
*/
IIncludeEntry[] getIncludeEntries(IPath path);
/**
* Returns the set of macro entries associated with the resource
* and empty array if none.
*
* @param path Workspace relative path.
* @return IMacroEntry[] - the entries or empty set if none
* @see IPathEntry
*/
IMacroEntry[] getMacroEntries(IPath path);
}

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.model;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.List; import java.util.List;
@ -39,8 +40,10 @@ import org.eclipse.cdt.core.model.IMacroEntry;
import org.eclipse.cdt.core.model.IOutputEntry; import org.eclipse.cdt.core.model.IOutputEntry;
import org.eclipse.cdt.core.model.IPathEntry; import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.IPathEntryContainer; import org.eclipse.cdt.core.model.IPathEntryContainer;
import org.eclipse.cdt.core.model.IPathEntryContainerExtension;
import org.eclipse.cdt.core.model.IProjectEntry; import org.eclipse.cdt.core.model.IProjectEntry;
import org.eclipse.cdt.core.model.ISourceEntry; import org.eclipse.cdt.core.model.ISourceEntry;
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.core.model.PathEntryContainerInitializer; import org.eclipse.cdt.core.model.PathEntryContainerInitializer;
import org.eclipse.cdt.core.resources.IPathEntryStore; import org.eclipse.cdt.core.resources.IPathEntryStore;
@ -91,6 +94,10 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
static final IPathEntry[] NO_PATHENTRIES = new IPathEntry[0]; static final IPathEntry[] NO_PATHENTRIES = new IPathEntry[0];
static final IIncludeEntry[] NO_INCLUDENTRIES = new IIncludeEntry[0];
static final IMacroEntry[] NO_MACROENTRIES = new IMacroEntry[0];
// Synchronized the access of the cache entries. // Synchronized the access of the cache entries.
protected Map resolvedMap = new Hashtable(); protected Map resolvedMap = new Hashtable();
@ -152,6 +159,165 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return pathEntryManager; return pathEntryManager;
} }
public IIncludeEntry[] getIncludeEntries(IPath resPath) throws CModelException {
ICElement celement = CoreModel.getDefault().create(resPath);
if (celement instanceof ITranslationUnit) {
return getIncludeEntries((ITranslationUnit)celement);
}
return NO_INCLUDENTRIES;
}
public IIncludeEntry[] getIncludeEntries(ITranslationUnit cunit) throws CModelException {
ArrayList includeList = new ArrayList();
ICProject cproject = cunit.getCProject();
IPath resPath = cunit.getPath();
// Do this first so the containers get inialized.
IPathEntry[] entries = getResolvedPathEntries(cproject);
for (int i = 0; i < entries.length; ++i) {
if (entries[i].getEntryKind() == IPathEntry.CDT_INCLUDE) {
includeList.add(entries[i]);
}
}
IPathEntryContainer[] containers = getPathEntryContainers(cproject);
if (containers != null) {
for (int i = 0; i < containers.length; ++i) {
if (containers[i] instanceof IPathEntryContainerExtension) {
IIncludeEntry[] incs = ((IPathEntryContainerExtension)containers[i]).getIncludeEntries(resPath);
includeList.addAll(Arrays.asList(incs));
}
}
}
IIncludeEntry[] includes = (IIncludeEntry[]) includeList.toArray(new IIncludeEntry[includeList.size()]);
// Clear the list since we are reusing it.
includeList.clear();
// We need to reorder the include/macros:
// includes with the closest match to the resource will come first
// /project/src/file.c --> /usr/local/include
// /project --> /usr/include
//
// /usr/local/include must come first.
//
int count = resPath.segmentCount();
for (int i = 0; i < count; i++) {
IPath newPath = resPath.removeLastSegments(i);
for (int j = 0; j < includes.length; j++) {
IPath otherPath = includes[j].getPath();
if (newPath.equals(otherPath)) {
includeList.add(includes[j]);
}
}
}
// Since the include that comes from a project contribution are not
// tied to a resource they are added last.
for (int i = 0; i < entries.length; i++) {
IPathEntry entry = entries[i];
if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) {
IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath());
if (res != null && res.getType() == IResource.PROJECT) {
ICProject refCProject = CoreModel.getDefault().create((IProject)res);
if (refCProject != null) {
IPathEntry[] projEntries = refCProject.getResolvedPathEntries();
for (int j = 0; j < projEntries.length; j++) {
IPathEntry projEntry = projEntries[j];
if (projEntry.isExported()) {
if (projEntry.getEntryKind() == IPathEntry.CDT_INCLUDE) {
IIncludeEntry include = (IIncludeEntry)projEntry;
includeList.add(include);
}
}
}
}
}
}
}
return (IIncludeEntry[])includeList.toArray(new IIncludeEntry[includeList.size()]);
}
public IMacroEntry[] getMacroEntries(IPath resPath) throws CModelException {
ICElement celement = CoreModel.getDefault().create(resPath);
if (celement instanceof ITranslationUnit) {
return getMacroEntries((ITranslationUnit)celement);
}
return NO_MACROENTRIES;
}
public IMacroEntry[] getMacroEntries(ITranslationUnit cunit) throws CModelException {
ArrayList macroList = new ArrayList();
ICProject cproject = cunit.getCProject();
IPath resPath = cunit.getPath();
// Do this first so the containers get inialized.
IPathEntry[] entries = getResolvedPathEntries(cproject);
for (int i = 0; i < entries.length; ++i) {
if (entries[i].getEntryKind() == IPathEntry.CDT_MACRO) {
macroList.add(entries[i]);
}
}
IPathEntryContainer[] containers = getPathEntryContainers(cproject);
if (containers != null) {
for (int i = 0; i < containers.length; ++i) {
if (containers[i] instanceof IPathEntryContainerExtension) {
IMacroEntry[] incs = ((IPathEntryContainerExtension)containers[i]).getMacroEntries(resPath);
macroList.addAll(Arrays.asList(incs));
}
}
}
IMacroEntry[] macros = (IMacroEntry[]) macroList.toArray(new IMacroEntry[macroList.size()]);
macroList.clear();
// For the macros the closest symbol will override
// /projec/src/file.c --> NDEBUG=1
// /project/src --> NDEBUG=0
//
// We will use NDEBUG=1 only
int count = resPath.segmentCount();
Map symbolMap = new HashMap();
for (int i = 0; i < count; i++) {
IPath newPath = resPath.removeLastSegments(i);
for (int j = 0; j < macros.length; j++) {
IPath otherPath = macros[j].getPath();
if (newPath.equals(otherPath)) {
String key = macros[j].getMacroName();
if (!symbolMap.containsKey(key)) {
symbolMap.put(key, macros[j]);
}
}
}
}
// Add the Project contributions last.
for (int i = 0; i < entries.length; i++) {
IPathEntry entry = entries[i];
if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) {
IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath());
if (res != null && res.getType() == IResource.PROJECT) {
ICProject refCProject = CoreModel.getDefault().create((IProject)res);
if (refCProject != null) {
IPathEntry[] projEntries = refCProject.getResolvedPathEntries();
for (int j = 0; j < projEntries.length; j++) {
IPathEntry projEntry = projEntries[j];
if (projEntry.isExported()) {
if (projEntry.getEntryKind() == IPathEntry.CDT_MACRO) {
IMacroEntry macro = (IMacroEntry)entry;
String key = macro.getMacroName();
if (!symbolMap.containsKey(key)) {
symbolMap.put(key, macro);
}
}
}
}
}
}
}
}
return (IMacroEntry[])symbolMap.values().toArray(NO_MACROENTRIES);
}
public IPathEntry[] getResolvedPathEntries(ICProject cproject) throws CModelException { public IPathEntry[] getResolvedPathEntries(ICProject cproject) throws CModelException {
boolean markers = cproject.getProject().getWorkspace().isTreeLocked(); boolean markers = cproject.getProject().getWorkspace().isTreeLocked();
return getResolvedPathEntries(cproject, !markers); return getResolvedPathEntries(cproject, !markers);
@ -549,6 +715,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} }
} }
public synchronized IPathEntryContainer[] getPathEntryContainers(ICProject cproject) {
IPathEntryContainer[] pcs = null;
Map projectContainers = (Map)Containers.get(cproject);
if (projectContainers != null) {
Collection collection = projectContainers.values();
pcs = (IPathEntryContainer[]) collection.toArray(new IPathEntryContainer[collection.size()]);
}
return pcs;
}
public IPathEntryContainer getPathEntryContainer(IContainerEntry entry, ICProject cproject) throws CModelException { public IPathEntryContainer getPathEntryContainer(IContainerEntry entry, ICProject cproject) throws CModelException {
return getPathEntryContainer(entry.getPath(), cproject); return getPathEntryContainer(entry.getPath(), cproject);
} }

View file

@ -18,15 +18,12 @@ import java.util.Map;
import org.eclipse.cdt.core.AbstractCExtension; import org.eclipse.cdt.core.AbstractCExtension;
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.CoreModel;
import org.eclipse.cdt.core.model.CoreModelUtil;
import org.eclipse.cdt.core.model.ElementChangedEvent; import org.eclipse.cdt.core.model.ElementChangedEvent;
import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.model.IElementChangedListener;
import org.eclipse.cdt.core.model.IIncludeEntry; import org.eclipse.cdt.core.model.IIncludeEntry;
import org.eclipse.cdt.core.model.IMacroEntry; import org.eclipse.cdt.core.model.IMacroEntry;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
import org.eclipse.cdt.core.parser.IScannerInfoProvider; import org.eclipse.cdt.core.parser.IScannerInfoProvider;
@ -85,107 +82,19 @@ public class ScannerProvider extends AbstractCExtension implements IScannerInfoP
*/ */
public IScannerInfo getScannerInformation(IResource resource) { public IScannerInfo getScannerInformation(IResource resource) {
IPath resPath = resource.getFullPath(); IPath resPath = resource.getFullPath();
ICProject cproject = CoreModel.getDefault().create(resource.getProject());
try { try {
if (cproject != null) { IIncludeEntry[] includeEntries = CoreModel.getIncludeEntries(resPath);
IPathEntry[] entries = cproject.getResolvedPathEntries(); String[] includes = new String[includeEntries.length];
for (int i = 0; i < includes.length; ++i) {
// First deal with the exclusion any entry that includes[i] = includeEntries[i].getFullIncludePath().toOSString();
// excludes the file should not be part of the list.
for (int k = 0; k < entries.length; k++) {
switch (entries[k].getEntryKind()) {
case IPathEntry.CDT_INCLUDE:
IIncludeEntry incEntry = (IIncludeEntry)entries[k];
if (CoreModelUtil.isExcluded(resPath, incEntry.fullExclusionPatternChars())) {
entries[k] = null;
} }
break; IMacroEntry[] macros = CoreModel.getMacroEntries(resPath);
case IPathEntry.CDT_MACRO:
IMacroEntry macEntry = (IMacroEntry)entries[k];
if (CoreModelUtil.isExcluded(resPath, macEntry.fullExclusionPatternChars())) {
entries[k] = null;
}
break;
case IPathEntry.CDT_PROJECT:
// do nothing.
break;
default:
// not interrested in the other types.
entries[k] = null;
}
}
// We need to reorder the include/macros:
// includes the closest match to the resource will come first
// /project/src/file.c --> /usr/local/include
// /project/src --> /usr/include
//
// /usr/local/include must come first.
//
// For the macros the closest symbol will override
// /projec/src/file.c --> NDEBUG=1
// /project/src --> NDEBUG=0
//
// We will use NDEBUG=1 only
int count = resPath.segmentCount();
ArrayList includeList = new ArrayList();
Map symbolMap = new HashMap(); Map symbolMap = new HashMap();
for (int i = 0; i < count; i++) { for (int i = 0; i < macros.length; ++i) {
IPath newPath = resPath.removeLastSegments(i); symbolMap.put(macros[i].getMacroName(), macros[i].getMacroValue());
for (int j = 0; j < entries.length; j++) {
if (entries[j] != null) {
IPathEntry entry = entries[j];
IPath otherPath = entry.getPath();
if (newPath.equals(otherPath)) {
if (entry.getEntryKind() == IPathEntry.CDT_INCLUDE) {
IIncludeEntry include = (IIncludeEntry)entry;
includeList.add(include.getFullIncludePath().toOSString());
} else if (entry.getEntryKind() == IPathEntry.CDT_MACRO) {
IMacroEntry macro = (IMacroEntry)entry;
String key = macro.getMacroName();
if (!symbolMap.containsKey(key)) {
symbolMap.put(key, macro.getMacroValue());
} }
}
}
}
}
}
// Add the Project contributions last.
for (int i = 0; i < entries.length; i++) {
IPathEntry entry = entries[i];
if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) {
IResource res = resource.getWorkspace().getRoot().findMember(entry.getPath());
if (res != null && res.getType() == IResource.PROJECT) {
ICProject refCProject = CoreModel.getDefault().create((IProject)res);
if (refCProject != null) {
IPathEntry[] projEntries = refCProject.getResolvedPathEntries();
for (int j = 0; j < projEntries.length; j++) {
IPathEntry projEntry = projEntries[j];
if (projEntry.isExported()) {
if (projEntry.getEntryKind() == IPathEntry.CDT_INCLUDE) {
IIncludeEntry include = (IIncludeEntry)projEntry;
includeList.add(include.getFullIncludePath().toOSString());
} else if (projEntry.getEntryKind() == IPathEntry.CDT_MACRO) {
IMacroEntry macro = (IMacroEntry)entry;
String key = macro.getMacroName();
if (!symbolMap.containsKey(key)) {
symbolMap.put(key, macro.getMacroValue());
}
}
}
}
}
}
}
}
String[] includes = new String[includeList.size()];
includeList.toArray(includes);
return new ScannerInfo(includes, symbolMap); return new ScannerInfo(includes, symbolMap);
}
} catch (CModelException e) { } catch (CModelException e) {
// //
} }