| /******************************************************************************* |
| * 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.Set; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| import java.util.Map.Entry; |
| |
| 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.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.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.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.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) { |
| pathSet.addAll(cmd.getIncludeFile()); |
| } |
| // 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) { |
| pathSet.addAll(cmd.getIncludes()); |
| } |
| // 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) { |
| pathSet.addAll(cmd.getImacrosFile()); |
| } |
| // 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) { |
| pathSet.addAll(cmd.getQuoteIncludes()); |
| } |
| // 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; |
| } |
| } |
| |
| ISchedulingRule rule = ResourcesPlugin.getWorkspace().getRoot(); |
| |
| Job job = new ScannerConfigUpdateJob(context, pathInfo, context.isDefaultContext(), changedResources); |
| job.setRule(ResourcesPlugin.getWorkspace().getRoot()); |
| job.schedule(); |
| |
| |
| |
| // } finally { |
| // manager.endRule(rule); |
| // } |
| |
| } catch (CoreException e) { |
| MakeCorePlugin.log(e); |
| } |
| |
| catch (Throwable e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| |
| monitor.worked(50); |
| monitor.done(); |
| } |
| |
| } |