diff --git a/build/org.eclipse.cdt.managedbuilder.core/ChangeLog b/build/org.eclipse.cdt.managedbuilder.core/ChangeLog index da23a568865..3d3ae177b49 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/ChangeLog +++ b/build/org.eclipse.cdt.managedbuilder.core/ChangeLog @@ -1,3 +1,15 @@ +2004-03-12 Sean Evoy + Commit for Jeremiah Lott. + Allows the managed build system to resolve "forward references" within its + extensions. In practice this is necessary to allow references between + extensions in different plugins. + + Partial fix for bugzilla 54202: + No longer use the cdtbuild file for persisting the default target and + configuration settings for a project. This is assumed to be an individual + workspace level setting so the choices are persisted in the project's + persistent settings store. + 2004-03-09 Sean Evoy Fix for bugzilla 45311: "CVS tries to check in contents of build output" diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java index 3793efb550c..0bc952db459 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/ManagedBuildManager.java @@ -16,6 +16,7 @@ import java.io.InputStream; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; @@ -69,6 +70,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI private static Map extensionTargetMap; private static List extensionTargets; private static Map extensionToolMap; + private static Map configElementMap; // Listeners interested in build model changes private static Map buildModelListeners; @@ -338,32 +340,12 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI // Find out the parent of the configuration IConfiguration parentConfig = configuration.getParent(); - // Find the parent target the configuration - ITarget parentTarget = parentConfig.getTarget(); - // Get the extension point information - IExtensionPoint extensionPoint = ManagedBuilderCorePlugin.getDefault().getDescriptor().getExtensionPoint(EXTENSION_POINT_ID); - IExtension[] extensions = extensionPoint.getExtensions(); - for (int i = 0; i < extensions.length; ++i) { - IExtension extension = extensions[i]; - IConfigurationElement[] elements = extension.getConfigurationElements(); - for (int j = 0; j < elements.length; ++j) { - IConfigurationElement element = elements[j]; - if (element.getName().equals(ITarget.TARGET_ELEMENT_NAME) && - element.getAttribute(ITarget.ID).equals(parentTarget.getId())) { - // We have the parent target so get the definition for the parent config - IConfigurationElement[] targetElements = element.getChildren(); - for (int k = 0; k < targetElements.length; ++k) { - IConfigurationElement targetElement = targetElements[k]; - if (targetElement.getName().equals(IConfiguration.CONFIGURATION_ELEMENT_NAME) && - targetElement.getAttribute(IConfiguration.ID).equals(parentConfig.getId())) { - // We now have the plugin element the target was originally based on - ((Configuration)configuration).reset(targetElement); - } - } - } - } - } + // Get the config element for the parent from the map + IConfigurationElement configElement = getConfigElement(parentConfig); + + // reset the configuration + ((Configuration)configuration).reset(configElement); } @@ -463,25 +445,46 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI */ // We can read the manifest IExtensionPoint extensionPoint = descriptor.getExtensionPoint(EXTENSION_POINT_ID); IExtension[] extensions = extensionPoint.getExtensions(); + // First call the constructors for (int i = 0; i < extensions.length; ++i) { IExtension extension = extensions[i]; IConfigurationElement[] elements = extension.getConfigurationElements(); - // Load the tools first for (int toolIndex = 0; toolIndex < elements.length; ++toolIndex) { - IConfigurationElement element = elements[toolIndex]; - // Load the targets - if (element.getName().equals(ITool.TOOL_ELEMENT_NAME)) { - new Tool(element); - } - } - for (int targetIndex = 0; targetIndex < elements.length; ++targetIndex) { - IConfigurationElement element = elements[targetIndex]; - // Load the targets - if (element.getName().equals(ITarget.TARGET_ELEMENT_NAME)) { - new Target(element); + try { + IConfigurationElement element = elements[toolIndex]; + // Load the targets + if (element.getName().equals(ITool.TOOL_ELEMENT_NAME)) { + new Tool(element); + } else if (element.getName().equals(ITarget.TARGET_ELEMENT_NAME)) { + new Target(element); + } + } catch (Exception ex) { + // TODO: log + ex.printStackTrace(); } } } + // Then call resolve. + Iterator toolIter = getExtensionToolMap().values().iterator(); + while (toolIter.hasNext()) { + try { + Tool tool = (Tool)toolIter.next(); + tool.resolveReferences(); + } catch (Exception ex) { + // TODO: log + ex.printStackTrace(); + } + } + Iterator targetIter = getExtensionTargetMap().values().iterator(); + while (targetIter.hasNext()) { + try { + Target target = (Target)targetIter.next(); + target.resolveReferences(); + } catch (Exception ex) { + // TODO: log + ex.printStackTrace(); + } + } // Let's never do that again extensionTargetsLoaded = true; } @@ -642,5 +645,28 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI map.put(project, list); } } + + private static Map getConfigElementMap() { + if (configElementMap == null) { + configElementMap = new HashMap(); + } + return configElementMap; + } + + /** + * This method public for implementation reasons. Not intended for use + * by clients. + */ + public static void putConfigElement(IBuildObject buildObj, IConfigurationElement configElement) { + getConfigElementMap().put(buildObj, configElement); + } + /** + * This method public for implementation reasons. Not intended for use + * by clients. + */ + public static IConfigurationElement getConfigElement(IBuildObject buildObj) { + return (IConfigurationElement)getConfigElementMap().get(buildObj); + } + } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java index 90c5b7e3d89..c9e65438b12 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Configuration.java @@ -22,6 +22,7 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.ITarget; import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; @@ -36,6 +37,7 @@ public class Configuration extends BuildObject implements IConfiguration { private ITarget target; private IConfiguration parent; private List toolReferences; + private boolean resolved = true; /** * Build a configuration from the project manifest file. @@ -152,6 +154,10 @@ public class Configuration extends BuildObject implements IConfiguration { public Configuration(Target target, IConfigurationElement element) { this.target = target; + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + // id setId(element.getAttribute(IConfiguration.ID)); @@ -183,6 +189,18 @@ public class Configuration extends BuildObject implements IConfiguration { target.addConfiguration(this); } + public void resolveReferences() { + if (!resolved) { + resolved = true; +// IConfigurationElement element = ManagedBuildManager.getConfigElement(this); + Iterator refIter = getLocalToolReferences().iterator(); + while (refIter.hasNext()) { + ToolReference ref = (ToolReference)refIter.next(); + ref.resolveReferences(); + } + } + } + /** * Adds a tool reference to the receiver. * @@ -371,7 +389,8 @@ public class Configuration extends BuildObject implements IConfiguration { for (int l = 0; l < configElements.length; ++l) { IConfigurationElement configElement = configElements[l]; if (configElement.getName().equals(IConfiguration.TOOLREF_ELEMENT_NAME)) { - new ToolReference(this, configElement); + ToolReference ref = new ToolReference(this, configElement); + ref.resolveReferences(); } } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java index c24df65e641..44e9527d84b 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ManagedBuildInfo.java @@ -16,7 +16,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.ListIterator; import java.util.Map; import org.eclipse.cdt.core.CCProjectNature; @@ -28,11 +27,13 @@ import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.ITarget; import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.QualifiedName; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -40,12 +41,16 @@ import org.w3c.dom.Node; public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { // Local variables + public static final String MAJOR_SEPERATOR = ";"; //$NON-NLS-1$ + public static final String MINOR_SEPERATOR = "::"; //$NON-NLS-1$ + private static final QualifiedName defaultConfigProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "defaultConfig"); //$NON-NLS-1$ + private static final QualifiedName defaultTargetProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "defaultTarget"); //$NON-NLS-1$ + private Map defaultConfigMap; + private ITarget defaultTarget; private boolean isDirty; private IResource owner; private Map targetMap; - private List targets; - private Map defaultConfigurations; - private ITarget defaultTarget; + private List targetList; /** * Create a new managed build information for the IResource specified in the argument @@ -53,9 +58,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { * @param owner */ public ManagedBuildInfo(IResource owner) { - targetMap = new HashMap(); - targets = new ArrayList(); - defaultConfigurations = new HashMap(); + targetList = new ArrayList(); this.owner = owner; } @@ -67,47 +70,81 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { * @param element */ public ManagedBuildInfo(IResource owner, Element element) { + // Store the IProject the info is for this(owner); - Node child = element.getFirstChild(); - // The id of the default configuration - String defaultTargetId = null; - List configIds = new ArrayList(); + // Read in the top-level info objects + Node child = element.getFirstChild(); while (child != null) { if (child.getNodeName().equals(ITarget.TARGET_ELEMENT_NAME)) { new Target(this, (Element)child); - } else if (child.getNodeName().equals(DEFAULT_CONFIGURATION)) { - // We may not have read the config in yet, so just cache it - configIds.add(((Element)child).getAttribute(IConfiguration.ID)); - } else if (child.getNodeName().equals(DEFAULT_TARGET)) { - defaultTargetId = ((Element)child).getAttribute(ITarget.ID); } child = child.getNextSibling(); } - // All the available targets have been read in - defaultTarget = (ITarget) targetMap.get(defaultTargetId); - // Now we have a miserable O(N^2) operation (oh well, the data sets are small) + + // The id of the default configuration from the persistent store + IProject project = (IProject)getOwner(); + String defaultTargetId = null; + try { + defaultTargetId = project.getPersistentProperty(defaultTargetProperty); + } catch (CoreException e) { + // We have all the build elements so we can stop if this occurs + return; + } + + // All targets have been read in so set the default from the persisted ID + if (defaultTargetId != null) { + defaultTarget = (ITarget) getTargetMap().get(defaultTargetId); + } + + // Get the string of all default config IDs from the store + String defaultIds = null; + try { + defaultIds = project.getPersistentProperty(defaultConfigProperty); + } catch (CoreException e1) { + // Again, hitting this error just means the default config is not set + return; + } + if (defaultIds != null) { + String[] majorTokens = defaultIds.split(MAJOR_SEPERATOR); + for (int index = majorTokens.length - 1; index >= 0; --index) { + // Now split each token into the target and config id component + String idToken = majorTokens[index]; + if (idToken != null) { + String[] minorTokens = idToken.split(MINOR_SEPERATOR); + // The first token is the target ID + ITarget target = getTarget(minorTokens[0]); + // The second is the configuration ID + IConfiguration config = target.getConfiguration(minorTokens[1]); + if (config != null) { + getDefaultConfigMap().put(target.getId(), config); + } + } + } + } + +/* // Now we have a miserable O(N^2) operation (oh well, the data sets are small) ListIterator stringIter = configIds.listIterator(); while (stringIter.hasNext()){ String confId = (String) stringIter.next(); - ListIterator targIter = targets.listIterator(); + ListIterator targIter = targetList.listIterator(); while (targIter.hasNext()) { Target targ = (Target) targIter.next(); IConfiguration conf = targ.getConfiguration(confId); if (conf != null) { - defaultConfigurations.put(targ.getId(), conf); + defaultConfigMap.put(targ.getId(), conf); break; } } } - } +*/ } /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#addTarget(org.eclipse.cdt.core.build.managed.ITarget) */ public void addTarget(ITarget target) { - targetMap.put(target.getId(), target); - targets.add(target); + getTargetMap().put(target.getId(), target); + targetList.add(target); } /* (non-Javadoc) @@ -206,12 +243,23 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { return (String[])configNames.toArray(new String[configNames.size()]); } + /* (non-Javadoc) + * + * @return Returns the map of ITarget ids to IConfigurations. + */ + private Map getDefaultConfigMap() { + if (defaultConfigMap == null) { + defaultConfigMap = new HashMap(); + } + return defaultConfigMap; + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getDefaultConfiguration() */ public IConfiguration getDefaultConfiguration(ITarget target) { // Get the default config associated with the defalt target - IConfiguration config = (IConfiguration) defaultConfigurations.get(target.getId()); + IConfiguration config = (IConfiguration) getDefaultConfigMap().get(target.getId()); // If null, look up the first configuration associated with the target if (config == null) { @@ -228,7 +276,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { */ public ITarget getDefaultTarget() { if (defaultTarget == null) { - defaultTarget = (ITarget) targets.get(0); + defaultTarget = (ITarget) targetList.get(0); } return defaultTarget; } @@ -631,6 +679,9 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { return flags; } + /** + * @return + */ public IResource getOwner() { return owner; } @@ -639,14 +690,26 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTarget(org.eclipse.cdt.core.build.managed.IConfiguration) */ public ITarget getTarget(String id) { - return (ITarget) targetMap.get(id); + return (ITarget) getTargetMap().get(id); + } + + /* (non-Javadoc) + * Safe accessor. + * + * @return Returns the map of IDs to ITargets. + */ + private Map getTargetMap() { + if (targetMap == null) { + targetMap = new HashMap(); + } + return targetMap; } /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.IManagedBuildInfo#getTargets(org.eclipse.cdt.core.build.managed.IConfiguration) */ public List getTargets() { - return targets; + return targetList; } /* (non-Javadoc) @@ -822,8 +885,29 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { * @param element */ public void serialize(Document doc, Element element) { + // Create a buffer of the default configuration IDs + StringBuffer defaultConfigs = new StringBuffer(); + // Write out each target and their default config - for (int i = 0; i < targets.size(); ++i) { + Iterator iter = targetList.listIterator(); + while (iter.hasNext()) { + // Get the target + Target targ = (Target)iter.next(); + // Create an XML element to hold the target settings + Element targetElement = doc.createElement(ITarget.TARGET_ELEMENT_NAME); + element.appendChild(targetElement); + targ.serialize(doc, targetElement); + // Persist the default target configuration pair as :: + IConfiguration config = getDefaultConfiguration((ITarget)targ); + if (config != null) { + defaultConfigs.append(targ.getId()); + defaultConfigs.append(MINOR_SEPERATOR); + defaultConfigs.append(config.getId()); + defaultConfigs.append(MAJOR_SEPERATOR); + } + } + +/* for (int i = 0; i < targets.size(); ++i) { Element targetElement = doc.createElement(ITarget.TARGET_ELEMENT_NAME); element.appendChild(targetElement); ((Target)targets.get(i)).serialize(doc, targetElement); @@ -834,12 +918,25 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { configEl.setAttribute(IConfiguration.ID, config.getId()); } } - // Persist the default target - if (getDefaultTarget() != null){ - Element targEl = doc.createElement(DEFAULT_TARGET); - element.appendChild(targEl); - targEl.setAttribute(ITarget.ID, getDefaultTarget().getId()); +*/ // Persist the default target as a project setting + IProject project = (IProject) getOwner(); + ITarget defTarget = getDefaultTarget(); + if (defTarget != null){ + try { + project.setPersistentProperty(defaultTargetProperty, defTarget.getId()); + } catch (CoreException e) { + // There is no point in storing the default configurations + return; + } } + + try { + // Persist the default configurations + project.setPersistentProperty(defaultConfigProperty, defaultConfigs.toString().trim()); + } catch (CoreException e) { + // Too bad + } + } /* (non-Javadoc) @@ -850,7 +947,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { ITarget target = configuration.getTarget(); // Make sure it is the default setDefaultTarget(target); - defaultConfigurations.put(target.getId(), configuration); + getDefaultConfigMap().put(target.getId(), configuration); } /* (non-Javadoc) @@ -871,6 +968,9 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { } /** + * Sets the owner of the receiver to be the IResource specified + * in the argument. + * * @param resource */ public void updateOwner(IResource resource) { @@ -879,7 +979,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo { if (!owner.equals(resource)) { owner = resource; // Do the same for the targets - Iterator iter = targets.listIterator(); + Iterator iter = targetList.listIterator(); while(iter.hasNext()) { ITarget target = (ITarget) iter.next(); target.updateOwner(resource); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java index bae19fae5d0..c26134dadf2 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Option.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.core.runtime.IConfigurationElement; @@ -37,7 +38,7 @@ public class Option extends BuildObject implements IOption { private ITool tool; private Object value; private int valueType; - + private boolean resolved = true; public Option(ITool tool) { this.tool = tool; @@ -45,6 +46,9 @@ public class Option extends BuildObject implements IOption { public Option(Tool tool, IConfigurationElement element) { this(tool); + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; // Get the unique id of the option setId(element.getAttribute(ID)); @@ -55,11 +59,6 @@ public class Option extends BuildObject implements IOption { // Get the option Name (this is what the user will see in the UI) setName(element.getAttribute(NAME)); - // Options can be grouped into categories - String categoryId = element.getAttribute(CATEGORY); - if (categoryId != null) - setCategory(tool.getOptionCategory(categoryId)); - // Get the command defined for the option command = element.getAttribute(COMMAND); @@ -135,6 +134,17 @@ public class Option extends BuildObject implements IOption { } } + public void resolveReferences() { + if (!resolved) { + resolved = true; + IConfigurationElement element = ManagedBuildManager.getConfigElement(this); + // Options can be grouped into categories + String categoryId = element.getAttribute(CATEGORY); + if (categoryId != null) + setCategory(((Tool)tool).getOptionCategory(categoryId)); + } + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.IOption#getApplicableValues() */ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionCategory.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionCategory.java index 87dbf54afde..ed7f007e0fc 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionCategory.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionCategory.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.ITool; import org.eclipse.cdt.managedbuilder.core.IToolReference; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.core.runtime.IConfigurationElement; /** @@ -27,6 +28,8 @@ public class OptionCategory extends BuildObject implements IOptionCategory { private IOptionCategory owner; private List children; + private Tool tool; + private boolean resolved = true; private static final IOptionCategory[] emtpyCategories = new IOptionCategory[0]; @@ -35,11 +38,10 @@ public class OptionCategory extends BuildObject implements IOptionCategory { } public OptionCategory(Tool tool, IConfigurationElement element) { - String parentId = element.getAttribute(IOptionCategory.OWNER); - if (parentId != null) - owner = tool.getOptionCategory(parentId); - else - owner = tool; + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + this.tool = tool; // id setId(element.getAttribute(IOptionCategory.ID)); @@ -47,15 +49,28 @@ public class OptionCategory extends BuildObject implements IOptionCategory { // Name setName(element.getAttribute(IOptionCategory.NAME)); - // Hook me in - if (owner instanceof Tool) - ((Tool)owner).addChildCategory(this); - else - ((OptionCategory)owner).addChildCategory(this); tool.addOptionCategory(this); } + public void resolveReferences() { + if (!resolved) { + resolved = true; + IConfigurationElement element = ManagedBuildManager.getConfigElement(this); + String parentId = element.getAttribute(IOptionCategory.OWNER); + if (parentId != null) + owner = tool.getOptionCategory(parentId); + else + owner = tool; + + // Hook me in + if (owner instanceof Tool) + ((Tool)owner).addChildCategory(this); + else + ((OptionCategory)owner).addChildCategory(this); + } + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.IOptionCategory#getChildCategories() */ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java index 72dff910f13..0c5090d4cee 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/OptionReference.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.managedbuilder.core.BuildException; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.IOptionCategory; import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin; import org.eclipse.core.runtime.IConfigurationElement; import org.w3c.dom.Document; @@ -41,6 +42,7 @@ public class OptionReference implements IOption { private ToolReference owner; // The actual value of the reference private Object value; + private boolean resolved = true; /** * This constructor will be called when the receiver is created from @@ -50,49 +52,14 @@ public class OptionReference implements IOption { * @param element */ public OptionReference(ToolReference owner, IConfigurationElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + this.owner = owner; - option = owner.getTool().getOption(element.getAttribute(ID)); owner.addOptionReference(this); - // value - switch (option.getValueType()) { - case BOOLEAN: - value = new Boolean(element.getAttribute(DEFAULT_VALUE)); - break; - case STRING: - value = element.getAttribute(DEFAULT_VALUE); - break; - case ENUMERATED: - String temp = element.getAttribute(DEFAULT_VALUE); - if (temp == null) { - try { - temp = option.getSelectedEnum(); - } catch (BuildException e) { - temp = new String(); - } - } - value = temp; - break; - case STRING_LIST: - case INCLUDE_PATH: - case PREPROCESSOR_SYMBOLS: - case LIBRARIES: - case OBJECTS: - List valueList = new ArrayList(); - IConfigurationElement[] valueElements = element.getChildren(LIST_VALUE); - for (int i = 0; i < valueElements.length; ++i) { - IConfigurationElement valueElement = valueElements[i]; - Boolean isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); - if (isBuiltIn.booleanValue()) { - getBuiltInList().add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } - else { - valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); - } } - value = valueList; - break; - } } /** @@ -161,6 +128,60 @@ public class OptionReference implements IOption { } + public void resolveReferences() { + if (!resolved) { + resolved = true; + IConfigurationElement element = ManagedBuildManager.getConfigElement(this); + + // resolve parent (recursively) before calling methods on it. + option = owner.getTool().getOption(element.getAttribute(ID)); + if (option instanceof Option) { + ((Option)option).resolveReferences(); + } else if (option instanceof OptionReference) { + ((OptionReference)option).resolveReferences(); + } + + // value + switch (option.getValueType()) { + case BOOLEAN: + value = new Boolean(element.getAttribute(DEFAULT_VALUE)); + break; + case STRING: + value = element.getAttribute(DEFAULT_VALUE); + break; + case ENUMERATED: + String temp = element.getAttribute(DEFAULT_VALUE); + if (temp == null) { + try { + temp = option.getSelectedEnum(); + } catch (BuildException e) { + temp = new String(); + } + } + value = temp; + break; + case STRING_LIST: + case INCLUDE_PATH: + case PREPROCESSOR_SYMBOLS: + case LIBRARIES: + case OBJECTS: + List valueList = new ArrayList(); + IConfigurationElement[] valueElements = element.getChildren(LIST_VALUE); + for (int i = 0; i < valueElements.length; ++i) { + IConfigurationElement valueElement = valueElements[i]; + Boolean isBuiltIn = new Boolean(valueElement.getAttribute(LIST_ITEM_BUILTIN)); + if (isBuiltIn.booleanValue()) { + getBuiltInList().add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } + else { + valueList.add(valueElement.getAttribute(LIST_ITEM_VALUE)); + } } + value = valueList; + break; + } + } + } + /** * Persist receiver to project file. * diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java index 6c8586df81b..8ce66c321ea 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Target.java @@ -51,6 +51,7 @@ public class Target extends BuildObject implements ITarget { private Map toolMap; private List toolList; private List toolReferences; + private boolean resolved = true; private static final IConfiguration[] emptyConfigs = new IConfiguration[0]; private static final String EMPTY_STRING = new String(); @@ -103,6 +104,10 @@ public class Target extends BuildObject implements ITarget { * @param element */ public Target(IConfigurationElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + // id setId(element.getAttribute(ID)); @@ -122,16 +127,6 @@ public class Target extends BuildObject implements ITarget { // Get the default extension defaultExtension = element.getAttribute(DEFAULT_EXTENSION); - // parent - String parentId = element.getAttribute(PARENT); - if (parentId != null) { - parent = ManagedBuildManager.getTarget(null, parentId); - // copy over the parents configs - IConfiguration[] parentConfigs = parent.getConfigurations(); - for (int i = 0; i < parentConfigs.length; ++i) - addConfiguration(parentConfigs[i]); - } - // isAbstract isAbstract = ("true".equals(element.getAttribute(IS_ABSTRACT))); //$NON-NLS-1$ @@ -230,6 +225,43 @@ public class Target extends BuildObject implements ITarget { } } + public void resolveReferences() { + if (!resolved) { + resolved = true; + IConfigurationElement element = ManagedBuildManager.getConfigElement(this); + // parent + String parentId = element.getAttribute(PARENT); + if (parentId != null) { + parent = ManagedBuildManager.getTarget(null, parentId); + // should resolve before calling methods on it + ((Target)parent).resolveReferences(); + // copy over the parents configs + IConfiguration[] parentConfigs = parent.getConfigurations(); + for (int i = 0; i < parentConfigs.length; ++i) + addConfiguration(parentConfigs[i]); + } + + // call resolve references on any children + Iterator toolIter = getToolList().iterator(); + while (toolIter.hasNext()) { + Tool current = (Tool)toolIter.next(); + current.resolveReferences(); + } + Iterator refIter = getLocalToolReferences().iterator(); + while (refIter.hasNext()) { + ToolReference current = (ToolReference)refIter.next(); + current.resolveReferences(); + } + if (configurations != null) { + Iterator configIter = configurations.iterator(); + while (configIter.hasNext()) { + Configuration current = (Configuration)configIter.next(); + current.resolveReferences(); + } + } + } + } + /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.ITarget#removeConfiguration(java.lang.String) */ @@ -302,6 +334,35 @@ public class Target extends BuildObject implements ITarget { return toolReferences; } + /* (non-javadoc) + * + * @param tool + * @return List + */ + protected List getOptionReferences(ITool tool) { + List references = new ArrayList(); + + // Get all the option references I add for this tool + ToolReference toolRef = getToolReference(tool); + if (toolRef != null) { + references.addAll(toolRef.getOptionReferenceList()); + } + + // See if there is anything that my parents add that I don't + if (parent != null) { + List temp = ((Target)parent).getOptionReferences(tool); + Iterator iter = temp.listIterator(); + while (iter.hasNext()) { + OptionReference ref = (OptionReference) iter.next(); + if (!references.contains(ref)) { + references.add(ref); + } + } + } + + return references; + } + /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.ITarget#getMakeArguments() */ @@ -655,7 +716,7 @@ public class Target extends BuildObject implements ITarget { public void addToolReference(ToolReference toolRef) { getLocalToolReferences().add(toolRef); } - + /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.core.ITarget#setArtifactExtension(java.lang.String) */ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java index 9cd6b35f589..63b25b812a5 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/Tool.java @@ -12,6 +12,7 @@ package org.eclipse.cdt.managedbuilder.internal.core; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; @@ -48,6 +49,7 @@ public class Tool extends BuildObject implements ITool, IOptionCategory { private String outputExtension; private String outputFlag; private String outputPrefix; + private boolean resolved = true; public Tool(IConfigurationElement element) { @@ -330,6 +332,10 @@ public class Tool extends BuildObject implements ITool, IOptionCategory { } protected void loadFromManifest(IConfigurationElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + this.resolved = false; + // id setId(element.getAttribute(ITool.ID)); @@ -403,6 +409,29 @@ public class Tool extends BuildObject implements ITool, IOptionCategory { } } + + public void resolveReferences() { + if (!resolved) { + resolved = true; +// IConfigurationElement element = ManagedBuildManager.getConfigElement(this); + // Tool doesn't have any references, but children might + Iterator optionIter = options.iterator(); + while (optionIter.hasNext()) { + Option current = (Option)optionIter.next(); + current.resolveReferences(); + } + Iterator catIter = categoryMap.values().iterator(); + while (catIter.hasNext()) { + IOptionCategory current = (IOptionCategory)catIter.next(); + if (current instanceof Tool) { + ((Tool)current).resolveReferences(); + } else if (current instanceof OptionCategory) { + ((OptionCategory)current).resolveReferences(); + } + } + } + } + /* (non-Javadoc) * @see org.eclipse.cdt.core.build.managed.ITool#producesFileType(java.lang.String) */ diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java index 18ae67a6131..624f500cd42 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/ToolReference.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.managedbuilder.core.IBuildObject; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IOption; import org.eclipse.cdt.managedbuilder.core.ITool; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.core.runtime.IConfigurationElement; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -30,6 +31,7 @@ public class ToolReference extends AbstractToolReference { private String command; private List optionReferences; private IBuildObject owner; + private boolean resolved = true; /** * Create a new tool reference based on information contained in @@ -76,15 +78,20 @@ public class ToolReference extends AbstractToolReference { * @param element The element containing build information for the reference. */ public ToolReference(BuildObject owner, IConfigurationElement element) { + // setup for resolving + ManagedBuildManager.putConfigElement(this, element); + resolved = false; + this.owner = owner; + + // hook me up if (owner instanceof Configuration) { - Target target = (Target) ((Configuration)owner).getTarget(); - parent = target.getTool(element.getAttribute(ID)); ((Configuration)owner).addToolReference(this); } else if (owner instanceof Target) { - parent = ((Target)owner).getTool(element.getAttribute(ID)); ((Target)owner).addToolReference(this); } + + IConfigurationElement[] toolElements = element.getChildren(); for (int m = 0; m < toolElements.length; ++m) { @@ -112,6 +119,32 @@ public class ToolReference extends AbstractToolReference { } } + public void resolveReferences() { + if (!resolved) { + resolved = true; + IConfigurationElement element = ManagedBuildManager.getConfigElement(this); + // resolve my parent + if (owner instanceof Configuration) { + Target target = (Target) ((Configuration)owner).getTarget(); + parent = target.getTool(element.getAttribute(ID)); + } else if (owner instanceof Target) { + parent = ((Target)owner).getTool(element.getAttribute(ID)); + } + // recursively resolve my parent + if (parent instanceof Tool) { + ((Tool)parent).resolveReferences(); + } else if (parent instanceof ToolReference) { + ((ToolReference)parent).resolveReferences(); + } + + Iterator it = getOptionReferenceList().iterator(); + while (it.hasNext()) { + OptionReference optRef = (OptionReference)it.next(); + optRef.resolveReferences(); + } + } + } + /** * Adds the option reference specified in the argument to the receiver. * @@ -120,6 +153,17 @@ public class ToolReference extends AbstractToolReference { public void addOptionReference(OptionReference optionRef) { getOptionReferenceList().add(optionRef); } + + private OptionReference getOptionReference(String id) { + Iterator it = getOptionReferenceList().iterator(); + while (it.hasNext()) { + OptionReference current = (OptionReference)it.next(); + if (current.getId().equals(id)) { + return current; + } + } + return null; + } /** * Answers a reference to the option. If the reference does not exist, @@ -228,7 +272,14 @@ public class ToolReference extends AbstractToolReference { protected List getAllOptionRefs() { // First get all the option references this tool reference contains - return ((Configuration)owner).getOptionReferences(parent); + if (owner instanceof Configuration) { + return ((Configuration)owner).getOptionReferences(parent); + } else if (owner instanceof Target) { + return ((Target)owner).getOptionReferences(parent); + } else { + // this shouldn't happen + return null; + } } /* (non-javadoc) @@ -262,7 +313,13 @@ public class ToolReference extends AbstractToolReference { * @see org.eclipse.cdt.core.build.managed.ITool#getOption(java.lang.String) */ public IOption getOption(String id) { - //TODO Implement this + IOption[] options = getOptions(); + for (int i = 0; i < options.length; i++) { + IOption current = options[i]; + if (current.getId().equals(id)) { + return current; + } + } return null; }