From 617af779928a5068af0abffbf2d938e0f2b5fe33 Mon Sep 17 00:00:00 2001 From: Mikhail Sennikovsky Date: Tue, 13 Nov 2007 10:25:41 +0000 Subject: [PATCH] Core fix for [bug 205840] Should file-level tool be updated when project toolchain changes? --- .../ObjectTypeBasedStorage.java | 8 ++ .../tcmodification/PerTypeSetStorage.java | 40 +++++++++- .../tcmodification/TcModificationUtil.java | 66 ++++++++++++++++- .../tcmodification/ToolListModification.java | 73 ++++++++++++++++++- .../IApplicableModification.java | 5 +- 5 files changed, 182 insertions(+), 10 deletions(-) diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ObjectTypeBasedStorage.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ObjectTypeBasedStorage.java index d215ddbc1b3..1a352228a23 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ObjectTypeBasedStorage.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ObjectTypeBasedStorage.java @@ -83,4 +83,12 @@ public final class ObjectTypeBasedStorage implements Cloneable { return null; } } + + public boolean isEmpty(){ + for(int i = 0; i < fStorage.length; i++){ + if(fStorage[i] != null) + return false; + } + return true; + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/PerTypeSetStorage.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/PerTypeSetStorage.java index 3aae275e1e0..8ffe9b74c40 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/PerTypeSetStorage.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/PerTypeSetStorage.java @@ -10,10 +10,10 @@ *******************************************************************************/ package org.eclipse.cdt.managedbuilder.internal.tcmodification; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; -public class PerTypeSetStorage { +public class PerTypeSetStorage implements Cloneable { private ObjectTypeBasedStorage fStorage = new ObjectTypeBasedStorage(); public Set getSet(int type, boolean create){ @@ -27,8 +27,40 @@ public class PerTypeSetStorage { protected Set createSet(Set set){ if(set == null) - return new HashSet(); - return (Set)((HashSet)set).clone(); + return new LinkedHashSet(); + return (Set)((LinkedHashSet)set).clone(); } + public Object clone(){ + try { + PerTypeSetStorage clone = (PerTypeSetStorage)super.clone(); + clone.fStorage = (ObjectTypeBasedStorage)fStorage.clone(); + int types[] = ObjectTypeBasedStorage.getSupportedObjectTypes(); + for(int i = 0; i < types.length; i++){ + Object o = clone.fStorage.get(i); + if(o != null){ + clone.fStorage.set(i, createSet((Set)o)); + } + } + return clone; + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + return null; + } + + public boolean isEmpty(boolean emptySetAsNull){ + if(fStorage.isEmpty()) + return true; + if(emptySetAsNull){ + int types[] = ObjectTypeBasedStorage.getSupportedObjectTypes(); + for(int i = 0; i < types.length; i++){ + Object o = fStorage.get(i); + if(o != null && !((Set)o).isEmpty()) + return false; + } + return true; + } + return false; + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/TcModificationUtil.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/TcModificationUtil.java index 158fecfc2aa..0caffed5c63 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/TcModificationUtil.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/TcModificationUtil.java @@ -165,6 +165,63 @@ public class TcModificationUtil { return storage; } + public static TreeMap createResultingChangesMap(TreeMap resultingMap, TreeMap initialMap){ + int[] types = ObjectTypeBasedStorage.getSupportedObjectTypes(); + int type; + TreeMap result = new TreeMap(PathComparator.INSTANCE); + initialMap = (TreeMap)initialMap.clone(); + + for(Iterator iter = resultingMap.entrySet().iterator(); iter.hasNext();){ + Map.Entry entry = (Map.Entry)iter.next(); + Object oPath = entry.getKey(); + + PerTypeSetStorage resStorage = (PerTypeSetStorage)entry.getValue(); + PerTypeSetStorage initStorage = (PerTypeSetStorage)initialMap.remove(oPath); + PerTypeSetStorage storage; + + if(initStorage == null && initStorage.isEmpty(true)){ + if(resStorage != null && !resStorage.isEmpty(true)){ + storage = (PerTypeSetStorage)resStorage.clone(); + } else { + storage = new PerTypeSetStorage(); + } + } else if(resStorage == null || resStorage.isEmpty(true)){ + storage = new PerTypeSetStorage(); + for(int i = 0; i < types.length; i++){ + Set set = initStorage.getSet(types[i], false); + if(set != null && set.size() != 0){ + storage.getSet(types[i], true); + } + } + } else { + Set initSet, resSet; + storage = new PerTypeSetStorage(); + for(int i = 0; i < types.length; i++){ + type = types[i]; + initSet = initStorage.getSet(type, false); + resSet = resStorage.getSet(type, false); + if(initSet == null || initSet.isEmpty()){ + if(resSet != null && !resSet.isEmpty()){ + storage.getSet(type, true).addAll(resSet); + } + } else if (resSet == null || resSet.isEmpty()){ + storage.getSet(type, true); + } else { + if(!initSet.equals(resSet)){ + storage.getSet(type, true).addAll(resSet); + } + } + } + } + + if(!storage.isEmpty(false)){ + result.put(oPath, storage); + } + } + + return result; + } + private static void processFolderInfo(PerTypeMapStorage storage, FolderInfo info, PerTypeMapStorage skipMapStorage, boolean addSkipPaths){ IPath p = info.getPath(); IToolChain rtc = ManagedBuildManager.getRealToolChain(info.getToolChain()); @@ -356,6 +413,12 @@ public class TcModificationUtil { set.add(realBuilder); } + public static TreeMap createPathMap(IConfiguration cfg){ + //TODO: optimize to calculate the map directly + PerTypeMapStorage storage = createRealToolToPathSet(cfg, null, false); + return createPathMap(storage); + } + public static TreeMap createPathMap(PerTypeMapStorage storage){ int[] types = ObjectTypeBasedStorage.getSupportedObjectTypes(); TreeMap result = new TreeMap(PathComparator.INSTANCE); @@ -367,7 +430,6 @@ public class TcModificationUtil { for(Iterator iter = map.entrySet().iterator(); iter.hasNext(); ){ Map.Entry entry = (Map.Entry)iter.next(); - IRealBuildObjectAssociation obj = (IRealBuildObjectAssociation)entry.getKey(); SortedSet pathSet = (SortedSet)entry.getValue(); for(Iterator pathIter = pathSet.iterator(); pathIter.hasNext(); ){ @@ -378,7 +440,7 @@ public class TcModificationUtil { result.put(path, oset); } - oset.getSet(obj.getType(), true).add(obj); + oset.getSet(type, true).add(entry.getKey()); } } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ToolListModification.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ToolListModification.java index 65e5ad389ed..e468c66a379 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ToolListModification.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/tcmodification/ToolListModification.java @@ -22,12 +22,19 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import org.eclipse.cdt.core.settings.model.util.CDataUtil; +import org.eclipse.cdt.managedbuilder.core.BuildException; +import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IResourceInfo; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; +import org.eclipse.cdt.managedbuilder.internal.core.Builder; +import org.eclipse.cdt.managedbuilder.internal.core.FolderInfo; import org.eclipse.cdt.managedbuilder.internal.core.IRealBuildObjectAssociation; import org.eclipse.cdt.managedbuilder.internal.core.ResourceInfo; import org.eclipse.cdt.managedbuilder.internal.core.Tool; +import org.eclipse.cdt.managedbuilder.internal.core.ToolChain; import org.eclipse.cdt.managedbuilder.internal.core.ToolChainModificationHelper; import org.eclipse.cdt.managedbuilder.internal.core.ToolListModificationInfo; import org.eclipse.cdt.managedbuilder.internal.tcmodification.ToolChainModificationManager.ConflictMatchSet; @@ -36,7 +43,9 @@ import org.eclipse.cdt.managedbuilder.tcmodification.IModificationOperation; import org.eclipse.cdt.managedbuilder.tcmodification.IToolListModification; import org.eclipse.cdt.managedbuilder.tcmodification.IToolModification; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; public abstract class ToolListModification implements IToolListModification { @@ -438,9 +447,69 @@ public abstract class ToolListModification implements return fAllSysTools; } - public void apply() throws CoreException { - ToolListModificationInfo info = getModificationInfo(); + public final void apply() throws CoreException { + TreeMap initialMap = TcModificationUtil.createPathMap(fRcInfo.getParent()); + TreeMap cur = getCompletePathMapStorage(); + TreeMap result = TcModificationUtil.createResultingChangesMap(cur, initialMap); + apply(result); + } + + private void apply(TreeMap resultingChangeMap) throws CoreException { + //the order matters here: we first should process tool-chain than a builder and then tools + int types[] = new int[]{ + IRealBuildObjectAssociation.OBJECT_TOOLCHAIN, + IRealBuildObjectAssociation.OBJECT_BUILDER, + IRealBuildObjectAssociation.OBJECT_TOOL, + }; + + int type; + IConfiguration cfg = fRcInfo.getParent(); + for(Iterator iter = resultingChangeMap.entrySet().iterator(); iter.hasNext(); ){ + Map.Entry entry = (Map.Entry)iter.next(); + IPath path = (IPath)entry.getKey(); + ResourceInfo rcInfo = (ResourceInfo)cfg.getResourceInfo(path, true); + if(rcInfo == null){ + rcInfo = (FolderInfo)cfg.createFolderInfo(path); + } + PerTypeSetStorage storage = (PerTypeSetStorage)entry.getValue(); + for(int i = 0; i < types.length; i++){ + type = types[i]; + Set set = storage.getSet(type, false); + if(set != null){ + apply(rcInfo, type, set); + } + } + } + } + + private void apply(ResourceInfo rcInfo, int type, Set set) throws CoreException { + switch(type){ + case IRealBuildObjectAssociation.OBJECT_TOOL: + ToolListModificationInfo info = rcInfo == fRcInfo ? getModificationInfo() : + ToolChainModificationHelper.getModificationInfo(rcInfo, rcInfo.getTools(), (Tool[])set.toArray(new Tool[set.size()])); info.apply(); + break; + case IRealBuildObjectAssociation.OBJECT_TOOLCHAIN: + if(rcInfo.isFolderInfo()){ + if(set.size() != 0){ + ToolChain tc = (ToolChain)set.iterator().next(); + try { + ((FolderInfo)rcInfo).changeToolChain(tc, CDataUtil.genId(tc.getId()), null); + } catch (BuildException e) { + throw new CoreException(new Status(IStatus.ERROR, ManagedBuilderCorePlugin.getUniqueIdentifier(), e.getLocalizedMessage(), e)); + } + } + } + break; + case IRealBuildObjectAssociation.OBJECT_BUILDER: + if(rcInfo.isRoot()){ + if(set.size() != 0){ + Builder b = (Builder)set.iterator().next(); + rcInfo.getParent().changeBuilder(b, CDataUtil.genId(b.getId()), null); + } + } + break; + } } private ToolListModificationInfo getModificationInfo(){ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/tcmodification/IApplicableModification.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/tcmodification/IApplicableModification.java index ef621ee2d01..4fe3e428d74 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/tcmodification/IApplicableModification.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/tcmodification/IApplicableModification.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.managedbuilder.tcmodification; +import org.eclipse.core.runtime.CoreException; + public interface IApplicableModification extends IModification { /** @@ -17,6 +19,5 @@ public interface IApplicableModification extends IModification { * resource info * @throws CoreException */ - //TODO: not implemented yet -// void apply() throws CoreException; + void apply() throws CoreException; }