Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java')
-rw-r--r--xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java1665
1 files changed, 1665 insertions, 0 deletions
diff --git a/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java b/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java
new file mode 100644
index 00000000000..69f62b6409f
--- /dev/null
+++ b/xlc/org.eclipse.cdt.make.xlc.core/src/org/eclipse/cdt/make/xlc/core/scannerconfig/PerFileXLCScannerInfoCollector.java
@@ -0,0 +1,1665 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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 Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.make.xlc.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
+import org.eclipse.cdt.core.settings.model.CMacroEntry;
+import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
+import org.eclipse.cdt.core.settings.model.ICLanguageSetting;
+import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
+import org.eclipse.cdt.core.settings.model.ICProjectDescription;
+import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
+import org.eclipse.cdt.core.settings.model.ICSettingEntry;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredScannerInfoSerializable;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo2;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector3;
+import org.eclipse.cdt.make.core.scannerconfig.InfoContext;
+import org.eclipse.cdt.make.core.scannerconfig.PathInfo;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathManager;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore;
+import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
+import org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector;
+import org.eclipse.cdt.make.xlc.core.activator.Activator;
+import org.eclipse.cdt.make.xlc.core.messages.Messages;
+import org.eclipse.cdt.make.xlc.core.scannerconfig.util.XLCCommandDSC;
+import org.eclipse.cdt.managedbuilder.core.IConfiguration;
+import org.eclipse.cdt.managedbuilder.core.IInputType;
+import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo;
+import org.eclipse.cdt.managedbuilder.core.ITool;
+import org.eclipse.cdt.managedbuilder.core.IToolChain;
+import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
+import org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector;
+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.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.core.runtime.jobs.ISchedulingRule;
+import org.eclipse.core.runtime.jobs.Job;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * @author crecoskie
+ *
+ */
+public class PerFileXLCScannerInfoCollector implements IScannerInfoCollector3, IManagedScannerInfoCollector {
+
+ protected class ScannerConfigUpdateJob extends Job {
+
+ private InfoContext fContext;
+ private IDiscoveredPathInfo fPathInfo;
+ private boolean fIsDefaultContext;
+ private List<IResource> fChangedResources;
+
+ public ScannerConfigUpdateJob(InfoContext context, IDiscoveredPathInfo pathInfo, boolean isDefaultContext, List<IResource> changedResources) {
+ super(Messages.getString("PerFileXLCScannerInfoCollector.0")); //$NON-NLS-1$);
+ fContext = context;
+ fPathInfo = pathInfo;
+ fIsDefaultContext = isDefaultContext;
+ fChangedResources = changedResources;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+
+ // get the scanner info profile ID
+
+ IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(project);
+ IConfiguration config = info.getDefaultConfiguration();
+
+ String profileID = config.getToolChain().getScannerConfigDiscoveryProfileId();
+ IDiscoveredPathManager manager = MakeCorePlugin.getDefault().getDiscoveryManager();
+
+ if(manager instanceof DiscoveredPathManager) {
+ ((DiscoveredPathManager)manager).updateDiscoveredInfo(fContext, fPathInfo, fIsDefaultContext, fChangedResources, profileID);
+ }
+
+ // reload project description to hopefully get the data to take
+ ICProjectDescriptionManager descriptionManager = CoreModel.getDefault().getProjectDescriptionManager();
+ ICProjectDescription cProjectDescription = descriptionManager.getProjectDescription(project, true /* writable */);
+ ICConfigurationDescription configDes = cProjectDescription.getActiveConfiguration();
+
+ IToolChain toolchain = config.getToolChain();
+ for(ITool tool : toolchain.getTools()) {
+ for(IInputType inputType : tool.getInputTypes()) {
+ IContentType contentType = inputType.getSourceContentType();
+ if(contentType != null) {
+ for(IResource resource : fChangedResources) {
+ // get language settings for the resource
+ ICLanguageSetting langSetting = configDes.getLanguageSettingForFile(resource.getProjectRelativePath(), false);
+
+ if(langSetting == null) {
+ continue;
+ }
+
+ // get content type IDs for the setting
+ String[] contentTypeIDs = langSetting.getSourceContentTypeIds();
+
+ // if the setting doesn't handle our content type ID, then go to the next resource
+ boolean found = false;
+ for(String id : contentTypeIDs) {
+ if(id.equals(contentType.getId())) {
+ found = true;
+ break;
+ }
+ }
+
+ if(!found) {
+ continue;
+ }
+
+ // update all the scanner config entries on the setting
+ updateIncludeSettings(langSetting);
+ updateMacroSettings(langSetting);
+
+ }
+ }
+
+ }
+ }
+
+ descriptionManager.setProjectDescription(project, cProjectDescription, true /* force */, monitor);
+
+ } catch (CoreException e) {
+ Activator.log(e);
+ return Activator.createStatus(Messages.getString("PerFileXLCScannerInfoCollector.1")); //$NON-NLS-1$
+ }
+ return Status.OK_STATUS;
+ }
+
+ private boolean updateMacroSettings(ICLanguageSetting langSetting) {
+ ICLanguageSettingEntry[] entries = langSetting.getSettingEntries(ICSettingEntry.MACRO);
+ List<ICLanguageSettingEntry> newEntries = new LinkedList<ICLanguageSettingEntry>();
+ for(ICLanguageSettingEntry entry : entries) {
+ newEntries.add(entry);
+ }
+
+
+ boolean entriesChanged = false;
+
+ // look for settings corresponding to each path we discovered
+ Map<String, String> discSymbols = fPathInfo.getSymbols();
+ for (String symbol : discSymbols.keySet()) {
+ boolean symbolFound = false;
+
+ for (ICLanguageSettingEntry entry : entries) {
+ if (((CMacroEntry) entry).getName().equals(symbol)) {
+ int flags = entry.getFlags();
+ symbolFound = true; // it's already there, so don't set it
+ break;
+ }
+ }
+
+ // if we didn't find the path, add it
+ if(!symbolFound) {
+ entriesChanged = true;
+ CMacroEntry newEntry = new CMacroEntry(symbol, discSymbols.get(symbol), ICSettingEntry.BUILTIN | ICSettingEntry.READONLY | ICSettingEntry.RESOLVED);
+ newEntries.add(newEntry);
+ }
+ }
+
+ // if we changed the entries, then set the new ones
+ if(entriesChanged) {
+ langSetting.setSettingEntries(ICSettingEntry.MACRO, newEntries.toArray(new ICLanguageSettingEntry[0]));
+ }
+
+ return entriesChanged;
+ }
+
+ private boolean updateIncludeSettings(ICLanguageSetting langSetting) {
+ ICLanguageSettingEntry[] entries = langSetting.getSettingEntries(ICSettingEntry.INCLUDE_PATH);
+ List<ICLanguageSettingEntry> newEntries = new LinkedList<ICLanguageSettingEntry>();
+ for(ICLanguageSettingEntry entry : entries) {
+ newEntries.add(entry);
+ }
+
+
+ boolean entriesChanged = false;
+
+ // look for settings corresponding to each path we discovered
+ IPath[] discPaths = fPathInfo.getIncludePaths();
+ for (IPath path : discPaths) {
+ boolean pathFound = false;
+
+ for (ICLanguageSettingEntry entry : entries) {
+ if (((CIncludePathEntry) entry).getLocation().equals(path)) {
+ pathFound = true; // it's already there, so don't set it
+ break;
+ }
+ }
+
+ // if we didn't find the path, add it
+ if(!pathFound) {
+ entriesChanged = true;
+ CIncludePathEntry newEntry = new CIncludePathEntry(path, ICSettingEntry.BUILTIN | ICSettingEntry.READONLY | ICSettingEntry.RESOLVED);
+ newEntries.add(newEntry);
+ }
+ }
+
+ // if we changed the entries, then set the new ones
+ if(entriesChanged) {
+ langSetting.setSettingEntries(ICSettingEntry.INCLUDE_PATH, newEntries.toArray(new ICLanguageSettingEntry[0]));
+ }
+
+ return entriesChanged;
+ }
+ }
+
+ protected class MergedPerFileDiscoveredPathInfo implements IPerFileDiscoveredPathInfo2 {
+ private IDiscoveredPathInfo fInfo1;
+ private IPerFileDiscoveredPathInfo2 fInfo2;
+
+ public MergedPerFileDiscoveredPathInfo(IDiscoveredPathInfo info1, IPerFileDiscoveredPathInfo2 info2) {
+ fInfo1 = info1;
+ fInfo2 = info2;
+ }
+
+ private IPerFileDiscoveredPathInfo2 getPerFileInfo1() {
+ if(fInfo1 instanceof IPerFileDiscoveredPathInfo2) {
+ return (IPerFileDiscoveredPathInfo2) fInfo1;
+ }
+
+ else {
+ return null;
+ }
+ }
+
+ public Map getPathInfoMap() {
+ synchronized (fLock) {
+ IPerFileDiscoveredPathInfo2 info1 = getPerFileInfo1();
+ if (info1 != null) {
+ Map map = new HashMap();
+ map.putAll(info1.getPathInfoMap());
+ map.putAll(fInfo2.getPathInfoMap());
+ return map;
+ }
+
+ else {
+ return fInfo2.getPathInfoMap();
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getIncludeFiles(org.eclipse.core.runtime.IPath)
+ */
+ public IPath[] getIncludeFiles(IPath path) {
+ synchronized (fLock) {
+ IPerFileDiscoveredPathInfo2 info1 = getPerFileInfo1();
+ if (info1 != null) {
+ List<IPath> list = new LinkedList<IPath>();
+ for (IPath path1 : info1.getIncludeFiles(path)) {
+ list.add(path1);
+ }
+
+ for (IPath path1 : fInfo2.getIncludeFiles(path)) {
+ list.add(path1);
+ }
+ return list.toArray(new IPath[0]);
+ }
+
+ else {
+ return fInfo2.getIncludeFiles(path);
+ }
+ }
+ }
+
+ public IPath[] getIncludePaths(IPath path) {
+ synchronized (fLock) {
+
+ Set<IPath> pathSet = new HashSet<IPath>();
+
+ // add project level settings if other info is per project
+ if (fInfo1 instanceof DiscoveredPathInfo) {
+ for (IPath path1 : fInfo1.getIncludePaths()) {
+ pathSet.add(path1);
+ }
+ }
+
+ else {
+ IPerFileDiscoveredPathInfo2 info1 = getPerFileInfo1();
+ if (info1 != null) {
+ // add file level settings
+ for (IPath path1 : info1.getIncludePaths(path)) {
+ pathSet.add(path1);
+ }
+ }
+ }
+
+ // add file level settings
+ for (IPath path2 : fInfo2.getIncludePaths(path)) {
+ pathSet.add(path2);
+ }
+
+ return pathSet.toArray(new IPath[0]);
+ }
+ }
+
+ public IPath[] getMacroFiles(IPath path) {
+ synchronized (fLock) {
+ Set<IPath> pathSet = new HashSet<IPath>();
+
+ IPerFileDiscoveredPathInfo2 info1 = getPerFileInfo1();
+ if (info1 != null) {
+ // add file level settings
+ for (IPath path1 : info1.getMacroFiles(path)) {
+ pathSet.add(path1);
+ }
+ }
+
+ // add file level settings
+ for (IPath path2 : fInfo2.getMacroFiles(path)) {
+ pathSet.add(path2);
+ }
+
+ return pathSet.toArray(new IPath[0]);
+ }
+ }
+
+ public IPath[] getQuoteIncludePaths(IPath path) {
+ synchronized (fLock) {
+
+ Set<IPath> pathSet = new HashSet<IPath>();
+
+ IPerFileDiscoveredPathInfo2 info1 = getPerFileInfo1();
+ if (info1 != null) {
+ // add file level settings
+ for (IPath path1 : info1.getQuoteIncludePaths(path)) {
+ pathSet.add(path1);
+ }
+ }
+
+ // add file level settings
+ for (IPath path2 : fInfo2.getQuoteIncludePaths(path)) {
+ pathSet.add(path2);
+ }
+
+ return pathSet.toArray(new IPath[0]);
+ }
+ }
+
+ public Map getSymbols(IPath path) {
+ synchronized (fLock) {
+
+ Map<String, String> symbols = new HashMap<String, String>();
+
+ // add project level settings
+ Map<String, String> projectSymbols = (Map<String, String>) fInfo1.getSymbols();
+ for (String symbol : projectSymbols.keySet()) {
+ symbols.put(symbol, projectSymbols.get(symbol));
+ }
+
+ IPerFileDiscoveredPathInfo2 info1 = getPerFileInfo1();
+ if (info1 != null) {
+ // add file level settings
+ symbols.putAll(info1.getSymbols(path));
+ }
+
+ // add file level settings
+ symbols.putAll(fInfo2.getSymbols(path));
+
+ return symbols;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#isEmpty(org.eclipse.core.runtime.IPath)
+ */
+ public boolean isEmpty(IPath path) {
+ synchronized (fLock) {
+ boolean info1empty = false;
+
+ IPerFileDiscoveredPathInfo2 info1 = getPerFileInfo1();
+ if (info1 != null) {
+ info1empty = info1.isEmpty(path);
+ } else {
+ info1empty = fInfo1.getIncludePaths().length == 0 && fInfo1.getSymbols().size() == 0;
+ }
+
+ return fInfo2.isEmpty(path) && info1empty;
+ }
+ }
+
+ public IPath[] getIncludePaths() {
+ synchronized (fLock) {
+ return fInfo1.getIncludePaths();
+ }
+ }
+
+ public IProject getProject() {
+ return fInfo1.getProject();
+ }
+
+ public IDiscoveredScannerInfoSerializable getSerializable() {
+ return fInfo2.getSerializable();
+ }
+
+ public Map getSymbols() {
+ synchronized (fLock) {
+ return fInfo1.getSymbols();
+ }
+ }
+
+ }
+
+ /**
+ * Per file DPI object
+ *
+ * @author vhirsl
+ */
+ protected class PerFileDiscoveredPathInfo implements IPerFileDiscoveredPathInfo2 {
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludeFiles(org.eclipse.core.runtime.IPath)
+ */
+ public IPath[] getIncludeFiles(IPath path) {
+ synchronized (fLock) {
+
+ Set<IPath> pathSet = new LinkedHashSet<IPath>();
+ // get the command
+ CCommandDSC cmd = getCommand(path);
+ if (cmd != null) {
+ IPath[] paths = stringListToPathArray(cmd.getIncludeFile());
+ pathSet.addAll(Arrays.asList(paths));
+ }
+ // use project scope scanner info
+ if (psi == null) {
+ generateProjectScannerInfo();
+ }
+
+ for(IPath path2 : psi.includeFiles) {
+ pathSet.add(path2);
+ }
+
+ return pathSet.toArray(new IPath[0]);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths()
+ */
+ public IPath[] getIncludePaths() {
+ final IPath[] includepaths;
+ final IPath[] quotepaths;
+ synchronized (fLock) {
+// return new IPath[0];
+ includepaths = getAllIncludePaths(INCLUDE_PATH);
+ quotepaths = getAllIncludePaths(QUOTE_INCLUDE_PATH);
+ }
+ if (quotepaths == null || quotepaths.length == 0) {
+ return includepaths;
+ }
+ if (includepaths == null || includepaths.length == 0) {
+ return quotepaths;
+ }
+ ArrayList<IPath> result = new ArrayList<IPath>(includepaths.length + quotepaths.length);
+ result.addAll(Arrays.asList(includepaths));
+ result.addAll(Arrays.asList(quotepaths));
+ return result.toArray(new IPath[result.size()]);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths(org.eclipse.core.runtime.IPath)
+ */
+ public IPath[] getIncludePaths(IPath path) {
+ synchronized (fLock) {
+ Set<IPath> pathSet = new LinkedHashSet<IPath>();
+ // get the command
+ CCommandDSC cmd = getCommand(path);
+ if (cmd != null) {
+ IPath[] paths = stringListToPathArray(cmd.getIncludes());
+ pathSet.addAll(Arrays.asList(paths));
+ }
+ // use project scope scanner info
+ if (psi == null) {
+ generateProjectScannerInfo();
+ }
+
+ for(IPath path2 : psi.includePaths) {
+ pathSet.add(path2);
+ }
+
+ return pathSet.toArray(new IPath[0]);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getMacroFiles(org.eclipse.core.runtime.IPath)
+ */
+ public IPath[] getMacroFiles(IPath path) {
+ synchronized (fLock) {
+ Set<IPath> pathSet = new LinkedHashSet<IPath>();
+ // get the command
+ CCommandDSC cmd = getCommand(path);
+ if (cmd != null) {
+ IPath[] paths = stringListToPathArray(cmd.getImacrosFile());
+ pathSet.addAll(Arrays.asList(paths));
+ }
+ // use project scope scanner info
+ if (psi == null) {
+ generateProjectScannerInfo();
+ }
+
+ for(IPath path2 : psi.macrosFiles) {
+ pathSet.add(path2);
+ }
+
+ return pathSet.toArray(new IPath[0]);
+ }
+ }
+
+ public Map<IResource, PathInfo> getPathInfoMap() {
+ synchronized (fLock) {
+ //TODO: do we need to cache this?
+ return calculatePathInfoMap();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getProject()
+ */
+ public IProject getProject() {
+ return project;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getQuoteIncludePaths(org.eclipse.core.runtime.IPath)
+ */
+ public IPath[] getQuoteIncludePaths(IPath path) {
+ synchronized (fLock) {
+ Set<IPath> pathSet = new LinkedHashSet<IPath>();
+ // get the command
+ CCommandDSC cmd = getCommand(path);
+ if (cmd != null) {
+ IPath[] paths = stringListToPathArray(cmd.getQuoteIncludes());
+ pathSet.addAll(Arrays.asList(paths));
+ }
+ // use project scope scanner info
+ if (psi == null) {
+ generateProjectScannerInfo();
+ }
+
+ for(IPath path2 : psi.quoteIncludePaths) {
+ pathSet.add(path2);
+ }
+
+ return pathSet.toArray(new IPath[0]);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getSerializable()
+ */
+ public IDiscoveredScannerInfoSerializable getSerializable() {
+ synchronized (fLock) {
+ return sid;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSymbols()
+ */
+ public Map<String, String> getSymbols() {
+// return new HashMap();
+ synchronized (fLock) {
+ return getAllSymbols();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @seeorg.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.
+ * IDiscoveredPathInfo#getSymbols(org.eclipse.core.runtime.IPath)
+ */
+ public Map<String, String> getSymbols(IPath path) {
+ synchronized (fLock) {
+ Map<String, String> definedSymbols = new HashMap<String, String>();
+
+ // put project data in first so file level data can override it
+ // use project scope scanner info
+ if (psi == null) {
+ generateProjectScannerInfo();
+ }
+ definedSymbols.putAll(psi.definedSymbols);
+
+ // get the command
+ CCommandDSC cmd = getCommand(path);
+ if (cmd != null && cmd.isDiscovered()) {
+ List symbols = cmd.getSymbols();
+ for (Iterator i = symbols.iterator(); i.hasNext();) {
+ String symbol = (String) i.next();
+ String key = ScannerConfigUtil.getSymbolKey(symbol);
+ String value = ScannerConfigUtil.getSymbolValue(symbol);
+ definedSymbols.put(key, value);
+ }
+
+ }
+ // use project scope scanner info
+ if (psi == null) {
+ generateProjectScannerInfo();
+ }
+ definedSymbols.putAll(psi.definedSymbols);
+ return definedSymbols;
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#isEmpty(org.eclipse.core.runtime.IPath)
+ */
+ public boolean isEmpty(IPath path) {
+ synchronized (fLock) {
+ boolean rc = true;
+ IResource resource = project.getWorkspace().getRoot().findMember(path);
+ if (resource != null) {
+ if (resource instanceof IFile) {
+ rc = (getCommand((IFile) resource) == null);
+ } else if (resource instanceof IProject) {
+ synchronized (fLock) {
+ rc = (psi == null || psi.isEmpty());
+ }
+ }
+ }
+ return rc;
+ }
+ }
+
+ }
+
+ public static class ProjectScannerInfo {
+ public Map<String, String> definedSymbols;
+ public IPath[] includeFiles;
+ public IPath[] includePaths;
+ public IPath[] macrosFiles;
+ public IPath[] quoteIncludePaths;
+ public boolean isEmpty() {
+ return (includePaths.length == 0 &&
+ quoteIncludePaths.length == 0 &&
+ includeFiles.length == 0 &&
+ macrosFiles.length == 0 &&
+ definedSymbols.size() == 0);
+ }
+ }
+
+ public class ScannerInfoData implements IDiscoveredScannerInfoSerializable {
+ public static final String DEFINED_SYMBOL = "definedSymbol"; //$NON-NLS-1$
+ public static final String ID_ATTR = "id"; //$NON-NLS-1$
+ public static final String INCLUDE_PATH = "includePath"; //$NON-NLS-1$
+
+ private static final String NAME = "name"; //$NON-NLS-1$
+
+ public static final String PATH = "path"; //$NON-NLS-1$
+ private static final String PROJECT = "project"; //$NON-NLS-1$
+ public static final String REMOVED = "removed"; //$NON-NLS-1$
+ public static final String SYMBOL = "symbol"; //$NON-NLS-1$
+ public final Map<Integer, CCommandDSC> commandIdCommandMap; // map of all commands
+ public final Map<Integer, Set<IFile>> commandIdToFilesMap; // command id and set of files it applies to
+ public final Map<IFile, Integer> fileToCommandIdMap; // maps each file to the corresponding command id
+
+ public ScannerInfoData() {
+ commandIdCommandMap = new LinkedHashMap<Integer, CCommandDSC>(); // [commandId, command]
+ fileToCommandIdMap = new HashMap<IFile, Integer>(); // [file, commandId]
+ commandIdToFilesMap = new HashMap<Integer, Set<IFile>>(); // [commandId, set of files]
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#deserialize(org.w3c.dom.Element)
+ */
+ public void deserialize(Element collectorElem) {
+ synchronized (fLock) {
+
+ for (Node child = collectorElem.getFirstChild(); child != null; child = child.getNextSibling()) {
+ if(child.getNodeName().equals(PROJECT)) {
+ Element projectElement = (Element) child;
+ String projectName = projectElement.getAttribute(NAME);
+
+ IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+
+ Map<ScannerInfoTypes, List<String>> scannerInfo = new HashMap<ScannerInfoTypes, List<String>>();
+
+ List<String> includes = new LinkedList<String>();
+ List<String> symbols = new LinkedList<String>();
+
+ // iterate over children
+ for(Node projectChild = projectElement.getFirstChild(); projectChild != null; projectChild = projectChild.getNextSibling()) {
+ if(projectChild.getNodeName().equals(INCLUDE_PATH)) {
+ Element childElem = (Element) projectChild;
+ String path = childElem.getAttribute(PATH);
+ if(path != null) {
+ includes.add(path);
+ }
+ }
+ else if(projectChild.getNodeName().equals(DEFINED_SYMBOL)) {
+ Element childElem = (Element) projectChild;
+ String symbol = childElem.getAttribute(SYMBOL);
+
+ if(symbol != null) {
+ symbols.add(symbol);
+ }
+ }
+ }
+
+ // add loaded scanner info to project settings for this collector
+ scannerInfo.put(ScannerInfoTypes.INCLUDE_PATHS, includes);
+ scannerInfo.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, symbols);
+ fProjectSettingsMap.put(project, scannerInfo);
+ }
+
+
+ else if (child.getNodeName().equals(CC_ELEM)) {
+ Element cmdElem = (Element) child;
+ boolean cppFileType = cmdElem.getAttribute(FILE_TYPE_ATTR).equals("c++"); //$NON-NLS-1$
+ XLCCommandDSC command = new XLCCommandDSC(cppFileType, project);
+ command.setCommandId(Integer.parseInt(cmdElem.getAttribute(ID_ATTR)));
+ // deserialize command
+ command.deserialize(cmdElem);
+ // get set of files the command applies to
+ NodeList appliesList = cmdElem.getElementsByTagName(APPLIES_TO_ATTR);
+ if (appliesList.getLength() > 0) {
+ Element appliesElem = (Element) appliesList.item(0);
+ NodeList fileList = appliesElem.getElementsByTagName(FILE_ELEM);
+ for (int i = 0; i < fileList.getLength(); ++i) {
+ Element fileElem = (Element) fileList.item(i);
+ String fileName = fileElem.getAttribute(PATH_ATTR);
+ IFile file = project.getFile(fileName);
+ addCompilerCommand(file, command);
+ }
+ applyFileDeltas();
+ }
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#getCollectorId()
+ */
+ public String getCollectorId() {
+ return COLLECTOR_ID;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#serialize(org.w3c.dom.Element)
+ */
+ public void serialize(Element collectorElem) {
+ try {
+ synchronized (fLock) {
+ Document doc = collectorElem.getOwnerDocument();
+
+ // serialize project level info
+ for (IProject project : fProjectSettingsMap.keySet()) {
+ // create a project node
+ Element projectElement = doc.createElement(PROJECT);
+ projectElement.setAttribute(NAME, project.getName());
+
+ Map<ScannerInfoTypes, List<String>> scannerInfo = (Map<ScannerInfoTypes, List<String>>) fProjectSettingsMap.get(project);
+
+ List<String> includes = scannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS);
+ for(String include : includes) {
+ Element pathElement = doc.createElement(INCLUDE_PATH);
+ pathElement.setAttribute(PATH, include);
+ //Boolean removed = (Boolean) includes.contains(include);
+ //if (removed != null && removed.booleanValue() == true) {
+ // pathElement.setAttribute(REMOVED, "true"); //$NON-NLS-1$
+ //}
+ pathElement.setAttribute(REMOVED, "false"); //$NON-NLS-1$
+ projectElement.appendChild(pathElement);
+ }
+
+ // Now do the same for the symbols
+ List<String> symbols = scannerInfo.get(ScannerInfoTypes.SYMBOL_DEFINITIONS);
+
+ for(String symbol : symbols) {
+ Element symbolElement = doc.createElement(DEFINED_SYMBOL);
+ symbolElement.setAttribute(SYMBOL, symbol);
+ projectElement.appendChild(symbolElement);
+ }
+ collectorElem.appendChild(projectElement);
+ }
+
+ // serialize file level info
+ List<Integer> commandIds = new ArrayList<Integer>(commandIdCommandMap.keySet());
+ Collections.sort(commandIds);
+ for (Iterator<Integer> i = commandIds.iterator(); i.hasNext(); ) {
+ Integer commandId = i.next();
+ CCommandDSC command = commandIdCommandMap.get(commandId);
+
+ Element cmdElem = doc.createElement(CC_ELEM);
+ collectorElem.appendChild(cmdElem);
+ cmdElem.setAttribute(ID_ATTR, commandId.toString());
+ cmdElem.setAttribute(FILE_TYPE_ATTR, command.appliesToCPPFileType() ? "c++" : "c"); //$NON-NLS-1$ //$NON-NLS-2$
+ // write command and scanner info
+ command.serialize(cmdElem);
+ // write files command applies to
+ Element filesElem = doc.createElement(APPLIES_TO_ATTR);
+ cmdElem.appendChild(filesElem);
+ Set<IFile> files = commandIdToFilesMap.get(commandId);
+ if (files != null) {
+ for (Iterator<IFile> j = files.iterator(); j.hasNext(); ) {
+ Element fileElem = doc.createElement(FILE_ELEM);
+ IFile file = j.next();
+ IPath path = file.getProjectRelativePath();
+ fileElem.setAttribute(PATH_ATTR, path.toString());
+ filesElem.appendChild(fileElem);
+ }
+ }
+ }
+ }
+
+ }
+ catch(Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ protected static final String APPLIES_TO_ATTR = "appliesToFiles"; //$NON-NLS-1$
+
+ protected static final String CC_ELEM = "compilerCommand"; //$NON-NLS-1$
+
+ public static final String COLLECTOR_ID = Activator.PLUGIN_ID + ".PerFileXLCScannerInfoCollector"; //$NON-NLS-1$
+
+ protected static final String FILE_ELEM = "file"; //$NON-NLS-1$
+
+ protected static final String FILE_TYPE_ATTR = "fileType"; //$NON-NLS-1$
+
+ protected static final String ID_ATTR = "id"; //$NON-NLS-1$
+
+ protected static final int INCLUDE_FILE = 3;
+
+ protected static final int INCLUDE_PATH = 1;
+
+
+
+ protected static final int MACROS_FILE = 4;
+
+ protected static final String PATH_ATTR = "path"; //$NON-NLS-1$
+
+ protected static final int QUOTE_INCLUDE_PATH = 2;
+
+ protected static PathInfo createFilePathInfo(CCommandDSC cmd){
+ IPath[] includes = stringListToPathArray(cmd.getIncludes());
+ IPath[] quotedIncludes = stringListToPathArray(cmd.getQuoteIncludes());
+ IPath[] incFiles = stringListToPathArray(cmd.getIncludeFile());
+ IPath[] macroFiles = stringListToPathArray(cmd.getImacrosFile());
+ List symbols = cmd.getSymbols();
+ Map<String, String> definedSymbols = new HashMap<String, String>(symbols.size());
+ for (Iterator i = symbols.iterator(); i.hasNext(); ) {
+ String symbol = (String) i.next();
+ String key = ScannerConfigUtil.getSymbolKey(symbol);
+ String value = ScannerConfigUtil.getSymbolValue(symbol);
+ definedSymbols.put(key, value);
+ }
+
+ return new PathInfo(includes, quotedIncludes, definedSymbols, incFiles, macroFiles);
+ }
+ /**
+ * @param discovered
+ * @param allIncludes
+ * @return
+ */
+ protected static IPath[] stringListToPathArray(List<String> discovered) {
+ List<Path> allIncludes = new ArrayList<Path>(discovered.size());
+ for (Iterator<String> j = discovered.iterator(); j.hasNext(); ) {
+ String include = j.next();
+ if (!allIncludes.contains(include)) {
+ allIncludes.add(new Path(include));
+ }
+ }
+ return allIncludes.toArray(new IPath[allIncludes.size()]);
+ }
+ protected int commandIdCounter = 0;
+ protected InfoContext context;
+
+ /** monitor for data access */
+ protected final Object fLock = new Object();
+
+ private Map<IProject, Map<?, ?>> fProjectSettingsMap = new HashMap<IProject, Map<?, ?>>();
+
+ protected final SortedSet<Integer> freeCommandIdPool; // sorted set of free command ids
+ protected IProject project;
+ protected ProjectScannerInfo psi = null; // sum of all scanner info
+ protected final List<Integer> siChangedForCommandIdList; // list of command ids for which scanner info has changed
+ // protected List siChangedForFileList; // list of files for which scanner info has changed
+ protected final Map<IResource, Integer> siChangedForFileMap; // (file, comandId) map for deltas
+ protected ScannerInfoData sid; // scanner info data
+
+ /**
+ *
+ */
+ public PerFileXLCScannerInfoCollector() {
+ sid = new ScannerInfoData();
+
+// siChangedForFileList = new ArrayList();
+ siChangedForFileMap = new HashMap<IResource, Integer>();
+ siChangedForCommandIdList = new ArrayList<Integer>();
+
+ freeCommandIdPool = new TreeSet<Integer>();
+ }
+
+ /**
+ * @param file
+ * @param object
+ */
+ protected void addCompilerCommand(IFile file, CCommandDSC cmd) {
+ synchronized (fLock) {
+ List<CCommandDSC> existingCommands = new ArrayList<CCommandDSC>(sid.commandIdCommandMap.values());
+ int index = existingCommands.indexOf(cmd);
+ if (index != -1) {
+ cmd = existingCommands.get(index);
+ } else {
+ int commandId = -1;
+ if (!freeCommandIdPool.isEmpty()) {
+ Integer freeCommandId = freeCommandIdPool.first();
+ freeCommandIdPool.remove(freeCommandId);
+ commandId = freeCommandId.intValue();
+ } else {
+ commandId = ++commandIdCounter;
+ }
+ cmd.setCommandId(commandId);
+ sid.commandIdCommandMap.put(cmd.getCommandIdAsInteger(), cmd);
+ }
+
+ generateFileDelta(file, cmd);
+ }
+ }
+
+ /**
+ * @param commandId
+ * @param scannerInfo
+ */
+ protected void addScannerInfo(Integer commandId, Map scannerInfo) {
+ synchronized (fLock) {
+ CCommandDSC cmd = sid.commandIdCommandMap.get(commandId);
+ if (cmd != null) {
+ List<String> siItem = (List<String>) scannerInfo.get(ScannerInfoTypes.SYMBOL_DEFINITIONS);
+ cmd.setSymbols(siItem);
+ siItem = (List<String>) scannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS);
+ siItem = CygpathTranslator.translateIncludePaths(project, siItem);
+ siItem = CCommandDSC.makeRelative(project, siItem);
+ cmd.setIncludes(siItem);
+ siItem = (List<String>) scannerInfo.get(ScannerInfoTypes.QUOTE_INCLUDE_PATHS);
+ siItem = CygpathTranslator.translateIncludePaths(project, siItem);
+ siItem = CCommandDSC.makeRelative(project, siItem);
+ cmd.setQuoteIncludes(siItem);
+
+ cmd.setDiscovered(true);
+ }
+ }
+ }
+
+ /**
+ * @param type
+ * @param object
+ */
+ protected void addScannerInfo(ScannerInfoTypes type, List delta) {
+ // TODO Auto-generated method stub
+
+ }
+ /**
+ * @param file
+ * @param cmd
+ */
+ protected void applyFileDeltas() {
+ synchronized (fLock) {
+ for (Iterator<IResource> i = siChangedForFileMap.keySet().iterator(); i.hasNext();) {
+ IFile file = (IFile) i.next();
+ Integer commandId = siChangedForFileMap.get(file);
+ if (commandId != null) {
+
+ // update sid.commandIdToFilesMap
+ Set<IFile> fileSet = sid.commandIdToFilesMap.get(commandId);
+ if (fileSet == null) {
+ fileSet = new HashSet<IFile>();
+ sid.commandIdToFilesMap.put(commandId, fileSet);
+ CCommandDSC cmd = sid.commandIdCommandMap.get(commandId);
+ if (cmd != null) {
+ cmd.resolveOptions(project);
+ }
+ }
+ if (fileSet.add(file)) {
+ // update fileToCommandIdsMap
+ boolean change = true;
+ Integer oldCommandId = sid.fileToCommandIdMap.get(file);
+ if (oldCommandId != null) {
+ if (oldCommandId.equals(commandId)) {
+ change = false;
+ } else {
+ Set oldFileSet = sid.commandIdToFilesMap.get(oldCommandId);
+ if (oldFileSet != null) {
+ oldFileSet.remove(file);
+ }
+ }
+ }
+ if (change) {
+ sid.fileToCommandIdMap.put(file, commandId);
+ // TODO generate change event for this resource
+ // IPath path = file.getFullPath();
+ // if (!siChangedForFileList.contains(path)) {
+ // siChangedForFileList.add(path);
+ // }
+ }
+ }
+ }
+ }
+ generateProjectScannerInfo();
+ }
+ }
+
+
+ protected Map<IResource, PathInfo> calculatePathInfoMap() {
+ synchronized (fLock) {
+ Map<IResource, PathInfo> map = new HashMap<IResource, PathInfo>(sid.fileToCommandIdMap.size() + 1);
+ Map.Entry entry;
+ IFile file;
+ CCommandDSC cmd;
+ PathInfo fpi;
+ for (Iterator iter = sid.fileToCommandIdMap.entrySet().iterator(); iter.hasNext();) {
+ entry = (Map.Entry) iter.next();
+ file = (IFile) entry.getKey();
+ if (file != null) {
+ cmd = sid.commandIdCommandMap.get(entry.getValue());
+ if (cmd != null) {
+ fpi = createFilePathInfo(cmd);
+ map.put(file, fpi);
+ }
+ }
+ }
+
+ if (project != null) {
+ if (psi == null) {
+ generateProjectScannerInfo();
+ }
+
+ fpi = new PathInfo(psi.includePaths, psi.quoteIncludePaths, psi.definedSymbols, psi.includeFiles,
+ psi.macrosFiles);
+ map.put(project, fpi);
+ }
+
+ return map;
+ }
+ }
+
+ public void contributeToScannerConfig(Object resource, Map scannerInfo) {
+ // check the resource
+ String errorMessage = null;
+ if (resource == null) {
+ errorMessage = "resource is null";//$NON-NLS-1$
+ }
+ else if (resource instanceof Integer) {
+ synchronized (fLock) {
+ addScannerInfo(((Integer)resource), scannerInfo);
+ }
+ return;
+ }
+
+ if ((resource instanceof IFile)) {
+
+ if (((IFile) resource).getProject() == null) {
+ errorMessage = "project is null";//$NON-NLS-1$
+ } else if (!((IFile) resource).getProject().equals(project)) {
+ errorMessage = "wrong project";//$NON-NLS-1$
+ }
+ if (errorMessage != null) {
+ TraceUtil.outputError("PerFileSICollector.contributeToScannerConfig : ", errorMessage); //$NON-NLS-1$
+ return;
+ }
+
+ IFile file = (IFile) resource;
+
+ synchronized (fLock) {
+ for (Iterator i = scannerInfo.keySet().iterator(); i.hasNext();) {
+ ScannerInfoTypes type = (ScannerInfoTypes) i.next();
+ if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) {
+ List commands = (List) scannerInfo.get(type);
+ for (Iterator j = commands.iterator(); j.hasNext();) {
+ addCompilerCommand(file, (CCommandDSC) j.next());
+ }
+ } else {
+ addScannerInfo(type, (List) scannerInfo.get(type));
+ }
+ }
+ }
+ }
+
+ else if(resource instanceof IProject) {
+ // save to project level settings
+ synchronized (fLock) {
+ fProjectSettingsMap.put(((IProject) resource), scannerInfo);
+ }
+ }
+
+ else { // error
+ TraceUtil.outputError("PerFileSICollector.contributeToScannerConfig : ", "Not a project or file."); //$NON-NLS-1$ //$NON-NLS-2$
+ return;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#createPathInfoObject()
+ */
+ public IDiscoveredPathInfo createPathInfoObject() {
+ return new PerFileDiscoveredPathInfo();
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector#deleteAll(org.eclipse.core.resources.IResource)
+ */
+ public void deleteAll(IResource resource) {
+ synchronized (fLock) {
+ if (resource instanceof IProject) {
+ fProjectSettingsMap.remove(((IProject) resource));
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollectorCleaner#deleteAll(org.eclipse.core.resources.IResource)
+ */
+ public void deleteAll1(IResource resource) {
+ if (resource.equals(project)) {
+ synchronized (fLock) {
+// siChangedForFileList = new ArrayList();
+ siChangedForFileMap.clear();
+ Set<IFile> changedFiles = sid.fileToCommandIdMap.keySet();
+ for (Iterator<IFile> i = changedFiles.iterator(); i.hasNext(); ) {
+ IFile file = i.next();
+// IPath path = file.getFullPath();
+// siChangedForFileList.add(path);
+ siChangedForFileMap.put(file, null);
+ }
+
+ sid = new ScannerInfoData();
+ psi = null;
+
+ commandIdCounter = 0;
+ freeCommandIdPool.clear();
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector#
+ * deleteAllPaths(org.eclipse.core.resources.IResource)
+ */
+ public void deleteAllPaths(IResource resource) {
+ synchronized (fLock) {
+ if (resource instanceof IProject && fProjectSettingsMap != null) {
+ fProjectSettingsMap.remove(((IProject) resource));
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector#
+ * deleteAllSymbols(org.eclipse.core.resources.IResource)
+ */
+ public void deleteAllSymbols(IResource resource) {
+ synchronized (fLock) {
+ if (resource instanceof IProject && fProjectSettingsMap != null) {
+ fProjectSettingsMap.remove(((IProject) resource));
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector#
+ * deletePath(org.eclipse.core.resources.IResource, java.lang.String)
+ */
+ public void deletePath(IResource resource, String path) {
+ synchronized (fLock) {
+ if (resource instanceof IProject && fProjectSettingsMap != null) {
+ fProjectSettingsMap.remove(((IProject) resource));
+ }
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector#
+ * deleteSymbol(org.eclipse.core.resources.IResource, java.lang.String)
+ */
+ public void deleteSymbol(IResource resource, String symbol) {
+ synchronized (fLock) {
+ if (resource instanceof IProject && fProjectSettingsMap != null) {
+ fProjectSettingsMap.remove(((IProject) resource));
+ }
+ }
+ }
+
+ /**
+ * @param file
+ * @param cmd
+ */
+ protected void generateFileDelta(IFile file, CCommandDSC cmd) {
+ synchronized (fLock) {
+ Integer commandId = cmd.getCommandIdAsInteger();
+ Integer oldCommandId = sid.fileToCommandIdMap.get(file);
+
+ if (oldCommandId != null && oldCommandId.equals(commandId)) {
+ // already exists; remove form delta
+ siChangedForFileMap.remove(file);
+ } else {
+ // new (file, commandId) pair
+ siChangedForFileMap.put(file, commandId);
+ }
+ }
+ }
+
+ protected void generateProjectScannerInfo() {
+ synchronized (fLock) {
+ psi = new ProjectScannerInfo();
+ psi.includePaths = getAllIncludePaths(INCLUDE_PATH);
+ psi.quoteIncludePaths = getAllIncludePaths(QUOTE_INCLUDE_PATH);
+ psi.includeFiles = getAllIncludePaths(INCLUDE_FILE);
+ psi.macrosFiles = getAllIncludePaths(MACROS_FILE);
+ psi.definedSymbols = getAllSymbols();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector#getAllIncludePaths(int)
+ */
+ protected IPath[] getAllIncludePaths(int type) {
+ synchronized (fLock) {
+ IProject project = this.getInfoContext().getProject();
+
+ Map projectScannerInfo = fProjectSettingsMap.get(project);
+ List<String> includes = null;
+
+ if (projectScannerInfo != null) {
+ includes = (List<String>) projectScannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS);
+ }
+
+ List<IPath> pathList = new LinkedList<IPath>();
+
+ if (includes != null) {
+ for (String include : includes) {
+ pathList.add(new Path(include));
+ }
+ }
+
+ IPath[] fileIncludes = getAllIncludePaths1(type);
+
+ for (IPath include : fileIncludes) {
+ pathList.add(include);
+ }
+
+ return pathList.toArray(new IPath[0]);
+ }
+ }
+
+ /**
+ * @param type can be one of the following:
+ * <li><code>INCLUDE_PATH</code>
+ * <li><code>QUOTE_INCLUDE_PATH</code>
+ * <li><code>INCLUDE_FILE</code>
+ * <li><code>MACROS_FILE</code>
+ *
+ * @return list of IPath(s).
+ */
+ protected IPath[] getAllIncludePaths1(int type) {
+ synchronized (fLock) {
+ List<String> allIncludes = new ArrayList<String>();
+ for (Iterator<Integer> i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext();) {
+ Integer cmdId = i.next();
+ CCommandDSC cmd = sid.commandIdCommandMap.get(cmdId);
+ if (cmd.isDiscovered()) {
+ List<String> discovered = null;
+ switch (type) {
+ case INCLUDE_PATH:
+ discovered = cmd.getIncludes();
+ break;
+ case QUOTE_INCLUDE_PATH:
+ discovered = cmd.getQuoteIncludes();
+ break;
+ case INCLUDE_FILE:
+ discovered = cmd.getIncludeFile();
+ break;
+ case MACROS_FILE:
+ discovered = cmd.getImacrosFile();
+ break;
+ }
+ for (Iterator<String> j = discovered.iterator(); j.hasNext();) {
+ String include = j.next();
+ // the following line degrades perfomance
+ // see
+ // https://bugs.eclipse.org/bugs/show_bug.cgi?id=189127
+ // it is not necessary for renaming projects anyway
+ // include = CCommandDSC.makeRelative(project, new
+ // Path(include)).toPortableString();
+ if (!allIncludes.contains(include)) {
+ allIncludes.add(include);
+ }
+ }
+ }
+ }
+ return stringListToPathArray(allIncludes);
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.cdt.make.internal.core.scannerconfig2.PerFileSICollector#
+ * getAllSymbols()
+ */
+ protected Map<String, String> getAllSymbols() {
+ synchronized (fLock) {
+ IProject project = this.getInfoContext().getProject();
+
+ Map projectScannerInfo = fProjectSettingsMap.get(project);
+
+ Map<String, String> symbols = new HashMap<String, String>();
+
+ if (projectScannerInfo != null) {
+ List<String> projectSymbols = (List<String>) projectScannerInfo
+ .get(ScannerInfoTypes.SYMBOL_DEFINITIONS);
+
+ for (String symbol : projectSymbols) {
+ symbols.put(symbol, "1"); //$NON-NLS-1$
+ }
+ }
+
+ Map<String, String> fileSymbols = getAllSymbols1();
+
+ symbols.putAll(fileSymbols);
+
+ return symbols;
+ }
+ }
+
+ /**
+ * @return
+ */
+ protected Map<String, String> getAllSymbols1() {
+ synchronized (fLock) {
+ Map<String, String> symbols = new HashMap<String, String>();
+ for (Iterator<Integer> i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext();) {
+ Integer cmdId = i.next();
+ CCommandDSC cmd = sid.commandIdCommandMap.get(cmdId);
+ if (cmd.isDiscovered()) {
+ List discovered = cmd.getSymbols();
+ for (Iterator j = discovered.iterator(); j.hasNext();) {
+ String symbol = (String) j.next();
+ String key = ScannerConfigUtil.getSymbolKey(symbol);
+ String value = ScannerConfigUtil.getSymbolValue(symbol);
+ symbols.put(key, value);
+ }
+ }
+ }
+ return symbols;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#getCollectedScannerInfo(java.lang.Object, org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes)
+ */
+ public List<CCommandDSC> getCollectedScannerInfo(Object resource, ScannerInfoTypes type) {
+
+ List<CCommandDSC> rv = new ArrayList<CCommandDSC>();
+ // check the resource
+ String errorMessage = null;
+ if (resource == null) {
+ errorMessage = "resource is null";//$NON-NLS-1$
+ }
+ else if (!(resource instanceof IResource)) {
+ errorMessage = "resource is not an IResource";//$NON-NLS-1$
+ }
+ else if (((IResource) resource).getProject() == null) {
+ errorMessage = "project is null";//$NON-NLS-1$
+ }
+ else if (((IResource) resource).getProject() != project) {
+ errorMessage = "wrong project";//$NON-NLS-1$
+ }
+
+ if (errorMessage != null) {
+ TraceUtil.outputError("PerProjectSICollector.getCollectedScannerInfo : ", errorMessage); //$NON-NLS-1$
+ return rv;
+ }
+ if (project.equals(((IResource)resource).getProject())) {
+ if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) {
+ synchronized (fLock) {
+ for (Iterator<Integer> i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) {
+ Integer cmdId = i.next();
+ Set<IFile> fileSet = sid.commandIdToFilesMap.get(cmdId);
+ if (fileSet != null && !fileSet.isEmpty()) {
+ rv.add(sid.commandIdCommandMap.get(cmdId));
+ }
+ }
+ }
+ }
+ else if (type.equals(ScannerInfoTypes.UNDISCOVERED_COMPILER_COMMAND)) {
+// if (!siChangedForFileList.isEmpty()) {
+ synchronized (fLock) {
+ if (scannerInfoChanged()) {
+ if (siChangedForCommandIdList.isEmpty()) {
+// for (Iterator i = siChangedForFileList.iterator(); i.hasNext(); ) {
+ for (Iterator<IResource> i = siChangedForFileMap.keySet().iterator(); i.hasNext(); ) {
+// IPath path = (IPath) i.next();
+ IFile file = (IFile) i.next();
+ Integer cmdId = siChangedForFileMap.get(file);
+ if (cmdId != null) {
+ if (!siChangedForCommandIdList.contains(cmdId)) {
+ siChangedForCommandIdList.add(cmdId);
+ }
+ }
+ }
+ }
+ Collections.sort(siChangedForCommandIdList);
+ for (Iterator<Integer> i = siChangedForCommandIdList.iterator(); i.hasNext(); ) {
+ Integer cmdId = i.next();
+ CCommandDSC command = sid.commandIdCommandMap.get(cmdId);
+ rv.add(command);
+ }
+ }
+ }
+ }
+ }
+ return rv;
+ }
+
+ protected CCommandDSC getCommand(IFile file) {
+ synchronized (fLock) {
+ CCommandDSC cmd = null;
+ if (file != null) {
+ Integer cmdId = sid.fileToCommandIdMap.get(file);
+ if (cmdId != null) {
+ // get the command
+ cmd = sid.commandIdCommandMap.get(cmdId);
+ }
+ }
+ return cmd;
+ }
+ }
+
+ /**
+ * @param path
+ * @return
+ */
+ protected CCommandDSC getCommand(IPath path) {
+ synchronized (fLock) {
+ try {
+ IFile file = project.getWorkspace().getRoot().getFile(path);
+ return getCommand(file);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector#getDefinedSymbols()
+ */
+ public Map getDefinedSymbols() {
+ synchronized (fLock) {
+ return getAllSymbols();
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.managedbuilder.scannerconfig.IManagedScannerInfoCollector#getIncludePaths()
+ */
+ public List getIncludePaths() {
+ synchronized (fLock) {
+ List<String> pathStrings = new LinkedList<String>();
+
+ List<IPath> paths = Arrays.asList(getAllIncludePaths(INCLUDE_PATH));
+ paths.addAll(Arrays.asList(getAllIncludePaths(QUOTE_INCLUDE_PATH)));
+
+ for (IPath path : paths) {
+ pathStrings.add(path.toString());
+ }
+
+ return pathStrings;
+ }
+ }
+
+ protected InfoContext getInfoContext() {
+ return context;
+ }
+
+ protected void removeUnusedCommands() {
+ synchronized (fLock) {
+ for (Iterator i = sid.commandIdToFilesMap.entrySet().iterator(); i.hasNext();) {
+ Entry entry = (Entry) i.next();
+ Integer cmdId = (Integer) entry.getKey();
+ Set fileSet = (Set) entry.getValue();
+ if (fileSet.isEmpty()) {
+ // return cmdId to the free command id pool
+ freeCommandIdPool.add(cmdId);
+ }
+ }
+ for (Iterator<Integer> i = freeCommandIdPool.iterator(); i.hasNext();) {
+ Integer cmdId = i.next();
+ // the command does not have any files associated; remove
+ sid.commandIdCommandMap.remove(cmdId);
+ sid.commandIdToFilesMap.remove(cmdId);
+ }
+ while (!freeCommandIdPool.isEmpty()) {
+ Integer last = freeCommandIdPool.last();
+ if (last.intValue() == commandIdCounter) {
+ freeCommandIdPool.remove(last);
+ --commandIdCounter;
+ } else
+ break;
+ }
+ }
+ }
+
+ protected boolean scannerInfoChanged() {
+ synchronized (fLock) {
+ return (!fProjectSettingsMap.isEmpty()) || !siChangedForFileMap.isEmpty();
+ }
+ }
+
+ public void setInfoContext(InfoContext context) {
+ synchronized (fLock) {
+ this.project = context.getProject();
+ this.context = context;
+
+ try {
+ // deserialize from SI store
+ DiscoveredScannerInfoStore.getInstance().loadDiscoveredScannerInfoFromState(project, context, sid);
+ } catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#setProject(org.eclipse.core.resources.IProject)
+ */
+ public void setProject(IProject project) {
+ synchronized (fLock) {
+ setInfoContext(new InfoContext(project));
+ }
+ }
+
+ public void updateScannerConfiguration(IProgressMonitor monitor) throws CoreException {
+ if (monitor == null) {
+ monitor = new NullProgressMonitor();
+ }
+ monitor.beginTask(Messages.getString("ScannerInfoCollector.Processing"), 100); //$NON-NLS-1$
+ monitor.subTask(Messages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$
+ ArrayList<IResource> changedResources = new ArrayList<IResource>();
+ synchronized (fLock) {
+ if (scannerInfoChanged()) {
+ applyFileDeltas();
+ removeUnusedCommands();
+ changedResources.addAll(siChangedForFileMap.keySet());
+ siChangedForFileMap.clear();
+ }
+ siChangedForCommandIdList.clear();
+
+ // add in any projects that got project level info (from the specs provider)
+ changedResources.addAll(fProjectSettingsMap.keySet());
+
+ monitor.worked(50);
+ if (!changedResources.isEmpty()) {
+ // update outside monitor scope
+ try {
+ // update scanner configuration
+ monitor.subTask(Messages.getString("ScannerInfoCollector.Updating") + project.getName()); //$NON-NLS-1$
+ IDiscoveredPathInfo pathInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project, context);
+ //IDiscoveredPathInfo pathInfo = new PerFileDiscoveredPathInfo();
+ if (!(pathInfo instanceof IPerFileDiscoveredPathInfo)) {
+ pathInfo = createPathInfoObject();
+ }
+ else {
+ PerFileDiscoveredPathInfo perFilePathInfo = new PerFileDiscoveredPathInfo();
+
+ // merge them
+ if (!(pathInfo instanceof IPerFileDiscoveredPathInfo)) {
+ pathInfo = new MergedPerFileDiscoveredPathInfo(pathInfo, perFilePathInfo);
+ }
+ else {
+ pathInfo = perFilePathInfo;
+ }
+ }
+
+
+ Job job = new ScannerConfigUpdateJob(context, pathInfo, context.isDefaultContext(), changedResources);
+ ISchedulingRule rule = project;
+ job.setRule(rule);
+ job.schedule();
+
+
+
+// } finally {
+// manager.endRule(rule);
+// }
+
+ } catch (CoreException e) {
+ MakeCorePlugin.log(e);
+ }
+
+ catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+ monitor.worked(50);
+ monitor.done();
+ }
+
+} \ No newline at end of file

Back to the top