From d43781d5fdc926938baeae3148c79e718c25b9c8 Mon Sep 17 00:00:00 2001 From: Mikhail Sennikovsky Date: Tue, 22 May 2007 12:42:30 +0000 Subject: [PATCH] Initial fix for [Bug 187822] Problem with setRawPathEntries --- .../model/BackwardCompatibilityTests.java | 129 ++++++++++++++++++ .../settings/model/TestCfgDataProvider.java | 2 + ...erAndDiscoveredEntriesCfgDataProvider.java | 43 ++++++ core/org.eclipse.cdt.core.tests/plugin.xml | 9 ++ .../cdt/core/testplugin/CProjectHelper.java | 10 +- ...coveredEntryConfigurationDataProvider.java | 84 ++++++++++++ .../model/util/PathEntryTranslator.java | 89 ++++++++++-- .../model/ConfigBasedPathEntryStore.java | 50 +++---- 8 files changed, 379 insertions(+), 37 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java create mode 100644 core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestUserAndDiscoveredEntriesCfgDataProvider.java create mode 100644 core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/extension/impl/UserAndDiscoveredEntryConfigurationDataProvider.java diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java new file mode 100644 index 00000000000..b1ee8bece1d --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/BackwardCompatibilityTests.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2007 Intel 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: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.settings.model; + +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.dom.IPDOMManager; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.testplugin.CProjectHelper; +import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.Path; + +public class BackwardCompatibilityTests extends BaseTestCase { + private static final String PROJ_NAME_PREFIX = "BackwardCompatibilityTests_"; + ICProject p1; + + public static TestSuite suite() { + return suite(BackwardCompatibilityTests.class, "_"); + } + + protected void setUp() throws Exception { + } + + protected void tearDown() throws Exception { + try { + if(p1 != null){ + p1.getProject().delete(true, null); + p1 = null; + } + } catch (CoreException e){ + } + } + + public void testPathEntriesForNewStyle() throws Exception { + p1 = CProjectHelper.createNewStileCProject(PROJ_NAME_PREFIX + "a", TestUserAndDiscoveredEntriesCfgDataProvider.PROVIDER_ID, IPDOMManager.ID_NO_INDEXER); + IProject project = p1.getProject(); + + IPathEntry[] entries = CoreModel.getRawPathEntries(p1); + IPathEntry[] resolvedentries = CoreModel.getResolvedPathEntries(p1); + IPathEntry[] expectedRawEntries = new IPathEntry[]{ + CoreModel.newContainerEntry(new Path("org.eclipse.cdt.core.CFG_BASED_CONTAINER")), + CoreModel.newSourceEntry(project.getFullPath()), + CoreModel.newOutputEntry(project.getFullPath()), + }; + assertEquals(expectedRawEntries.length, entries.length); + checkEntriesMatch(expectedRawEntries, entries); + + IPathEntry[] expectedResolvedEntries = new IPathEntry[]{ + CoreModel.newSourceEntry(project.getFullPath()), + CoreModel.newOutputEntry(project.getFullPath()), + CoreModel.newMacroEntry(project.getFullPath(), "a", "b"), + CoreModel.newMacroEntry(project.getFullPath(), "c", ""), + CoreModel.newIncludeEntry(project.getFullPath(), null, project.getLocation().append("a/b/c")), + CoreModel.newIncludeEntry(project.getFullPath(), null, new Path("/d/e/f")), + CoreModel.newIncludeEntry(project.getFullPath(), project.getFullPath().makeRelative(), new Path("g/h/i")), + CoreModel.newIncludeEntry(project.getFullPath(), new Path("j"), new Path("k/l")), + }; + assertEquals(expectedResolvedEntries.length, resolvedentries.length); + checkEntriesMatch(expectedResolvedEntries, resolvedentries); + + IPathEntry[] newEntries = new IPathEntry[entries.length + 1]; + System.arraycopy(entries, 0, newEntries, 0, entries.length); + newEntries[entries.length] = CoreModel.newIncludeEntry(new Path("d"), null, new Path("/C/d/e"), true, new Path[]{new Path("a"), new Path("b")}, false); + + IPathEntry[] newExpectedRawEntries = new IPathEntry[entries.length + 1]; + System.arraycopy(entries, 0, newExpectedRawEntries, 0, entries.length); + newExpectedRawEntries[entries.length] = CoreModel.newIncludeEntry(project.getFullPath().append("d"), null, new Path("/C/d/e"), true, new Path[]{new Path("a"), new Path("b")}, false); + + CoreModel.setRawPathEntries(p1, newEntries, null); + + entries = CoreModel.getRawPathEntries(p1); + assertEquals(newExpectedRawEntries.length, entries.length); + checkEntriesMatch(entries, newExpectedRawEntries); + + IPathEntry[] newExpectedResolved = new IPathEntry[resolvedentries.length + 1]; + System.arraycopy(resolvedentries, 0, newExpectedResolved, 0, resolvedentries.length); + newExpectedResolved[resolvedentries.length] = CoreModel.newIncludeEntry(project.getFullPath().append("d"), null, new Path("/C/d/e"), true, new Path[]{new Path("a"), new Path("b")}, false); + resolvedentries = CoreModel.getResolvedPathEntries(p1); + checkEntriesMatch(resolvedentries, newExpectedResolved); + } + + private void checkEntriesMatch(IPathEntry[] e1, IPathEntry[] e2){ + if(e1.length != e2.length) + fail("entries arrays have different length \ne1: " + dumpArray(e1) +"\ne2:" + dumpArray(e2) + "\n"); + + for(int i = 0; i < e1.length; i++){ + IPathEntry entry = e1[i]; + boolean found = false; + for(int k = 0; k < e2.length; k++){ + IPathEntry entry2 = e2[k]; + if(entry.equals(entry2)){ + found = true; + break; + } + } + if(!found) + fail("unable to find entry " + entry.toString() + "\nin array \n" + dumpArray(e2) + "\n"); + } + } + + private String dumpArray(Object array[]){ + if(array == null) + return "null"; + + StringBuffer buf = new StringBuffer(); + buf.append('['); + for(int i = 0; i < array.length; i++){ + if(i != 0){ + buf.append(",\n"); + } + buf.append(array[i].toString()); + } + buf.append(']'); + return buf.toString(); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestCfgDataProvider.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestCfgDataProvider.java index 6e7aa6c2d51..a155275d165 100644 --- a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestCfgDataProvider.java +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestCfgDataProvider.java @@ -11,7 +11,9 @@ package org.eclipse.cdt.core.settings.model; import org.eclipse.cdt.core.settings.model.extension.impl.CDefaultConfigurationDataProvider; +import org.eclipse.cdt.core.testplugin.CTestPlugin; public class TestCfgDataProvider extends CDefaultConfigurationDataProvider { + public static final String PROVIDER_ID = CTestPlugin.PLUGIN_ID + ".testCfgDataProvider"; } diff --git a/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestUserAndDiscoveredEntriesCfgDataProvider.java b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestUserAndDiscoveredEntriesCfgDataProvider.java new file mode 100644 index 00000000000..9a8c34381d8 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/model/org/eclipse/cdt/core/settings/model/TestUserAndDiscoveredEntriesCfgDataProvider.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007 Intel 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: + * Intel Corporation - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.settings.model; + +import org.eclipse.cdt.core.settings.model.extension.impl.UserAndDiscoveredEntryConfigurationDataProvider; +import org.eclipse.cdt.core.settings.model.util.KindBasedStore; +import org.eclipse.cdt.core.testplugin.CTestPlugin; + +public class TestUserAndDiscoveredEntriesCfgDataProvider extends UserAndDiscoveredEntryConfigurationDataProvider{ + public static final String PROVIDER_ID = CTestPlugin.PLUGIN_ID + ".testUserAndDiscoveredCfgDataProvider"; + + private static final KindBasedStore[] ENTRIES_STORES = new KindBasedStore[]{new KindBasedStore(false)}; + + static { + ICLanguageSettingEntry[] entries = new ICLanguageSettingEntry[4]; + entries[0] = new CIncludePathEntry("a/b/c", 0); + entries[1] = new CIncludePathEntry("/d/e/f", 0); + entries[2] = new CIncludePathEntry("g/h/i", ICSettingEntry.VALUE_WORKSPACE_PATH); + entries[3] = new CIncludePathEntry("/j/k/l", ICSettingEntry.VALUE_WORKSPACE_PATH); + + ENTRIES_STORES[0].put(ICSettingEntry.INCLUDE_PATH, entries); + + entries = new ICLanguageSettingEntry[2]; + entries[0] = new CMacroEntry("a", "b", 0); + entries[1] = new CMacroEntry("c", null, 0); + ENTRIES_STORES[0].put(ICSettingEntry.MACRO, entries); + } + + protected ICLanguageSettingEntry[] getAllDiscoveredEntries( + LanguageData data, int kind) { + ICLanguageSettingEntry entries[] = (ICLanguageSettingEntry[])ENTRIES_STORES[0].get(kind); + return entries != null ? (ICLanguageSettingEntry[])entries.clone() : new ICLanguageSettingEntry[0]; + } + +} diff --git a/core/org.eclipse.cdt.core.tests/plugin.xml b/core/org.eclipse.cdt.core.tests/plugin.xml index ece93e44bc2..615ec386dd0 100644 --- a/core/org.eclipse.cdt.core.tests/plugin.xml +++ b/core/org.eclipse.cdt.core.tests/plugin.xml @@ -53,6 +53,15 @@ class="org.eclipse.cdt.core.settings.model.TestCfgDataProvider"> + + + + + + path.segmentCount()) + segsToRemove = path.segmentCount() - 1; + if(segsToRemove < 0) + segsToRemove = 0; + + IPath filterPath = path.removeFirstSegments(segsToRemove); + if(parent != null){ - parent.addFilter(kind, path, removedParentSet); + parent.addFilter(kind, filterPath, removedParentSet); } Map map = getEntriesMap(kind, true); @@ -1479,6 +1490,18 @@ public class PathEntryTranslator { // return (IPath[])pathSet.toArray(new IPath[pathSet.size()]); // } + private RcDesInfo getRcDesInfo(PathSettingsContainer cr, ResourceInfo rcInfo){ + IResource rc = rcInfo.fRc; + IPath projPath = rc.getProjectRelativePath(); + PathSettingsContainer child = cr.getChildContainer(projPath, true, true); + RcDesInfo rcDes = (RcDesInfo)child.getValue(); + if(rcDes == null){ + rcDes = new RcDesInfo(rcInfo); + child.setValue(rcDes); + } + return rcDes; + } + private ReferenceSettingsInfo addPathEntries(ResolvedEntry[] rEntries, int op){ PathSettingsContainer cr = PathSettingsContainer.createRootContainer(); cr.setValue(new RcDesInfo(new ResourceInfo(fProject, true))); @@ -1487,13 +1510,15 @@ public class PathEntryTranslator { List projList = new ArrayList(); List exportSettingsList = new ArrayList(); ICSourceEntry srcEntries[] = null; - PathSettingsContainer child; +// PathSettingsContainer child; ResolvedEntry rEntry; IPath projPath; IResource rc; ResourceInfo rcInfo; for(int i = 0; i < rEntries.length; i++){ rEntry = rEntries[i]; + if(rEntry.isReadOnly()) + continue; if(toLanguageEntryKind(rEntry.fEntry.getEntryKind()) == 0){ switch(rEntry.fEntry.getEntryKind()){ case IPathEntry.CDT_SOURCE: @@ -1513,16 +1538,14 @@ public class PathEntryTranslator { exportSettingsList.add(rEntry); } rcInfo = rEntry.getResourceInfo(); - rc = rcInfo.fRc; - projPath = rc.getProjectRelativePath(); - child = cr.getChildContainer(projPath, true, true); - RcDesInfo rcDes = (RcDesInfo)child.getValue(); - if(rcDes == null){ - rcDes = new RcDesInfo(rcInfo); - child.setValue(rcDes); - } + RcDesInfo rcDes = getRcDesInfo(cr, rcInfo); rcDes.fResolvedEntries.add(rEntry); + + ResourceInfo[] fInfos = rEntry.getFilterInfos(); + for(int k = 0; k < fInfos.length; k++){ + getRcDesInfo(cr, fInfos[k]); + } } if(srcList.size() != 0){ @@ -1597,8 +1620,43 @@ public class PathEntryTranslator { ICSettingEntry.VALUE_WORKSPACE_PATH | ICSourceEntry.RESOLVED); } + + private static ICSettingEntry[] replaceUserEntries(ICSettingEntry[] oldEntries, ICSettingEntry[] newUsrEntries){ + Set set = new LinkedHashSet(); + Class componentType = null; + + if(newUsrEntries != null){ + for(int i = 0; i < newUsrEntries.length; i++ ){ + ICSettingEntry entry = newUsrEntries[i]; + if(entry.isBuiltIn() || entry.isReadOnly()) + continue; + set.add(entry); + } + componentType = newUsrEntries.getClass().getComponentType(); + } + + if(oldEntries != null){ + for(int i = 0; i < oldEntries.length; i++ ){ + ICSettingEntry entry = oldEntries[i]; + if(entry.isBuiltIn() || entry.isReadOnly()) + set.add(entry);; + } + if(componentType == null) + componentType = oldEntries.getClass().getComponentType(); + } + + if(componentType != null){ + ICSettingEntry[] result = (ICSettingEntry[])Array.newInstance(componentType, set.size()); + set.toArray(result); + return result; + } + return null; + } private void applySourceEntries(ICSourceEntry entries[], int op){ + ICSourceEntry[] oldEntries = fCfgData.getSourceEntries(); + entries = (ICSourceEntry[])replaceUserEntries(oldEntries, entries); + switch (op) { case OP_ADD: if(entries != null && entries.length != 0){ @@ -1722,7 +1780,12 @@ public class PathEntryTranslator { continue; ICLanguageSettingEntry opEntries[] = info.getEntries(kind); - ICLanguageSettingEntry oldEntries[] = op != OP_REPLACE ? lData.getEntries(kind) : null; + ICLanguageSettingEntry oldEntries[] = lData.getEntries(kind); + opEntries = (ICLanguageSettingEntry[])replaceUserEntries(oldEntries, opEntries); + + if(op == OP_REPLACE) + oldEntries = null; +// ICLanguageSettingEntry oldEntries[] = op != OP_REPLACE ? lData.getEntries(kind) : null; ICLanguageSettingEntry result[] = composeNewEntries(oldEntries, opEntries, op); lData.setEntries(kind, result); } @@ -1845,7 +1908,7 @@ public class PathEntryTranslator { for(int i = 0; i < filters.length; i++){ IResource rc = filters[i].fRc; IPath projPath = rc.getProjectRelativePath(); - if(projPath.isPrefixOf(path)){ + if(projPath.isPrefixOf(path.makeRelative())){ iter.remove(); break; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ConfigBasedPathEntryStore.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ConfigBasedPathEntryStore.java index a21ee00eb01..454b895c63f 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ConfigBasedPathEntryStore.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/ConfigBasedPathEntryStore.java @@ -118,31 +118,35 @@ public class ConfigBasedPathEntryStore implements IPathEntryStore, ICProjectDesc if(es != null){ List sysList = es[1]; List usrList = es[0]; -// for(int i = 0; i < entries.length; i++){ -// if(entries[i].getEntryKind() != IPathEntry.CDT_CONTAINER) -// usrList.add(entries[i]); -// } - - ICProjectDescription des = CoreModel.getDefault().getProjectDescription(fProject, true); - ICConfigurationDescription cfgDes = des.getDefaultSettingConfiguration(); - CConfigurationData data = cfgDes.getConfigurationData(); - PathEntryTranslator tr = new PathEntryTranslator(fProject, data); - IPathEntry[] usrEntries = (IPathEntry[])usrList.toArray(new IPathEntry[usrList.size()]); - IPathEntry[] sysEntries = (IPathEntry[])sysList.toArray(new IPathEntry[sysList.size()]); - ReferenceSettingsInfo rInfo = tr.applyPathEntries(usrEntries, sysEntries, PathEntryTranslator.OP_REPLACE); - cfgDes.removeExternalSettings(); - ICExternalSetting extSettings[] = rInfo.getExternalSettings(); - for(int i = 0; i < extSettings.length; i++){ - ICExternalSetting setting = extSettings[i]; - cfgDes.createExternalSetting(setting.getCompatibleLanguageIds(), - setting.getCompatibleContentTypeIds(), - setting.getCompatibleExtensions(), - setting.getEntries()); + List newUsrList = new ArrayList(entries.length); + for(int i = 0; i < entries.length; i++){ + if(entries[i].getEntryKind() != IPathEntry.CDT_CONTAINER) + newUsrList.add(entries[i]); } - Map refMap = rInfo.getRefProjectsMap(); - cfgDes.setReferenceInfo(refMap); - CoreModel.getDefault().setProjectDescription(fProject, des); + if(!newUsrList.equals(usrList)){ + usrList = newUsrList; + ICProjectDescription des = CoreModel.getDefault().getProjectDescription(fProject, true); + ICConfigurationDescription cfgDes = des.getDefaultSettingConfiguration(); + CConfigurationData data = cfgDes.getConfigurationData(); + PathEntryTranslator tr = new PathEntryTranslator(fProject, data); + IPathEntry[] usrEntries = (IPathEntry[])usrList.toArray(new IPathEntry[usrList.size()]); + IPathEntry[] sysEntries = (IPathEntry[])sysList.toArray(new IPathEntry[sysList.size()]); + ReferenceSettingsInfo rInfo = tr.applyPathEntries(usrEntries, sysEntries, PathEntryTranslator.OP_REPLACE); + cfgDes.removeExternalSettings(); + ICExternalSetting extSettings[] = rInfo.getExternalSettings(); + for(int i = 0; i < extSettings.length; i++){ + ICExternalSetting setting = extSettings[i]; + cfgDes.createExternalSetting(setting.getCompatibleLanguageIds(), + setting.getCompatibleContentTypeIds(), + setting.getCompatibleExtensions(), + setting.getEntries()); + } + Map refMap = rInfo.getRefProjectsMap(); + cfgDes.setReferenceInfo(refMap); + + CoreModel.getDefault().setProjectDescription(fProject, des); + } } }