From d46e5977ea4fe25fe7099a989c5cec651688b6bd Mon Sep 17 00:00:00 2001 From: Alain Magloire Date: Wed, 24 Mar 2004 05:37:10 +0000 Subject: [PATCH] Implementation of IScannerInof on top of IPathEntry. --- core/org.eclipse.cdt.core/ChangeLog | 8 + .../cdt/core/resources/ScannerInfo.java | 64 ++++++ .../cdt/core/resources/ScannerProvider.java | 204 ++++++++++++++++++ 3 files changed, 276 insertions(+) create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java create mode 100644 core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index 33fdc5b44c4..470afedbb48 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,11 @@ +2004-03-23 Alain Magloire + + An implementation of IScannerInfoProvider on top + of the IPathEntry. + + * src/org/eclipse/cdt/core/resources/ScannerInfo.java + * src/org/eclipse/cdt/core/resources/ScannerInfoProvider.java + 2004-03-23 Alain Magloire Show the objects on the IOuputEntry path should diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java new file mode 100644 index 00000000000..f9ff3c4c8ce --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java @@ -0,0 +1,64 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.core.resources; + +import java.util.Collections; +import java.util.Map; + +import org.eclipse.cdt.core.parser.IScannerInfo; + +public class ScannerInfo implements IScannerInfo { + + private Map macroMap; + private String[] includePaths; + final static String[] EMPTY_ARRAY_STRING = new String[0]; + + protected ScannerInfo() { + } + + protected ScannerInfo(String[] includePaths, Map macroMap) { + this.includePaths = includePaths; + this.macroMap = macroMap; + } + + public synchronized void setIncludePaths(String[] paths) { + includePaths = paths; + } + + public synchronized void setDefinedSymbols(Map map) { + macroMap = map; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() + */ + public synchronized String[] getIncludePaths() { + if (includePaths == null) { + return EMPTY_ARRAY_STRING; + } + return includePaths; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() + */ + public synchronized Map getDefinedSymbols() { + if (macroMap == null) { + return Collections.EMPTY_MAP; + } + return macroMap; + } + +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java new file mode 100644 index 00000000000..df123c3741f --- /dev/null +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java @@ -0,0 +1,204 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.core.resources; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ElementChangedEvent; +import org.eclipse.cdt.core.model.ICElement; +import org.eclipse.cdt.core.model.ICElementDelta; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IElementChangedListener; +import org.eclipse.cdt.core.model.IIncludeEntry; +import org.eclipse.cdt.core.model.IMacroEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; +import org.eclipse.cdt.core.parser.IScannerInfoProvider; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; + +public class ScannerProvider implements IScannerInfoProvider, IElementChangedListener { + + // Listeners interested in build model changes + private static Map listeners; + + // Map of the cache scannerInfos + + /* + * @return + */ + private synchronized static Map getListeners() { + if (listeners == null) { + listeners = new HashMap(); + } + return listeners; + } + + /** + * @param project + * @param info + */ + private static void notifyInfoListeners(IProject project, IScannerInfo info) { + // Call in the cavalry + List listeners = (List)getListeners().get(project); + if (listeners == null) { + return; + } + ListIterator iter = listeners.listIterator(); + while (iter.hasNext()) { + ((IScannerInfoChangeListener)iter.next()).changeNotification(project, info); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource) + */ + public IScannerInfo getScannerInformation(IResource resource) { + IPath resPath = resource.getFullPath(); + ICProject cproject = CoreModel.getDefault().create(resource.getProject()); + ScannerInfo info = new ScannerInfo(); + try { + if (cproject != null) { + ArrayList includeList = new ArrayList(); + Map symbolMap = new HashMap(); + IPathEntry[] entries = cproject.getResolvedPathEntries(); + for (int i = 0; i < entries.length; i++) { + int kind = entries[i].getEntryKind(); + if (kind == IPathEntry.CDT_INCLUDE) { + IIncludeEntry include = (IIncludeEntry)entries[i]; + IPath entryPath = include.getPath(); + if (entryPath.equals(resPath) || + entryPath.isPrefixOf(resPath) && include.isExported()) { + includeList.add(include.getIncludePath().toOSString()); + } + } else if (kind == IPathEntry.CDT_MACRO) { + IMacroEntry macro = (IMacroEntry)entries[i]; + IPath entryPath = macro.getPath(); + if (entryPath.equals(resPath) || + entryPath.isPrefixOf(resPath) && macro.isExported()) { + String name = macro.getMacroName(); + if (name != null && name.length() > 0) { + String value = macro.getMacroValue(); + if (value == null) { + value = new String(); + } + symbolMap.put(name, value); + } + } + } + } + info.setDefinedSymbols(symbolMap); + info.setIncludePaths((String[])includeList.toArray()); + } + } catch (CModelException e) { + // + } + return info; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#subscribe(org.eclipse.core.resources.IResource, + * org.eclipse.cdt.core.parser.IScannerInfoChangeListener) + */ + public synchronized void subscribe(IResource resource, IScannerInfoChangeListener listener) { + if (resource == null || listener == null) { + return; + } + IProject project = resource.getProject(); + // Get listeners for this resource + Map map = getListeners(); + List list = (List)map.get(project); + if (list == null) { + // Create a new list + list = new ArrayList(); + map.put(project, list); + } + if (!list.contains(listener)) { + // Add the new listener for the resource + list.add(listener); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#unsubscribe(org.eclipse.core.resources.IResource, + * org.eclipse.cdt.core.parser.IScannerInfoChangeListener) + */ + public synchronized void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { + if (resource == null || listener == null) { + return; + } + IProject project = resource.getProject(); + // Remove the listener + Map map = getListeners(); + List list = (List)map.get(project); + if (list != null && !list.isEmpty()) { + // The list is not empty so try to remove listener + list.remove(listener); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.model.IElementChangedListener#elementChanged(org.eclipse.cdt.core.model.ElementChangedEvent) + */ + public void elementChanged(ElementChangedEvent event) { + try { + processDelta(event.getDelta()); + } catch(CModelException e) { + } + } + + protected boolean isPathEntryChange(ICElementDelta delta) { + int flags= delta.getFlags(); + return (delta.getKind() == ICElementDelta.CHANGED && + ((flags & ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE) != 0 || + (flags & ICElementDelta.F_CHANGED_PATHENTRY_MACRO) != 0 || + (flags & ICElementDelta.F_PATHENTRY_REORDER) !=0)); + } + + /** + * Processes a delta recursively. + */ + protected void processDelta(ICElementDelta delta) throws CModelException { + int kind= delta.getKind(); + int flags= delta.getFlags(); + ICElement element= delta.getElement(); + + if (isPathEntryChange(delta)) { + IResource res = element.getResource(); + IProject project = element.getCProject().getProject(); + if (res == null) { + res = project; + } + IScannerInfo info = getScannerInformation(res); + notifyInfoListeners(project, info); + } + + ICElementDelta[] affectedChildren= delta.getAffectedChildren(); + for (int i= 0; i < affectedChildren.length; i++) { + processDelta(affectedChildren[i]); + } + } + +}