public void GetMetadataBeforeEvaluate()
        {
            XmlElement group = XmlTestUtilities.CreateBasicElement("ItemDefinitionGroup");

            ItemDefinitionLibrary library = new ItemDefinitionLibrary(new Project());
            library.Add(group);
            library.GetDefaultMetadataValue("ccompile", "defines");
        } 
Exemple #2
0
        internal Lookup(Hashtable itemsByName, BuildItemGroup projectItems, BuildPropertyGroup properties, ItemDefinitionLibrary itemDefinitionLibrary)
        {
            ErrorUtilities.VerifyThrow(itemDefinitionLibrary != null, "Expect library");

            this.projectItems          = projectItems;
            this.itemDefinitionLibrary = itemDefinitionLibrary;
            LookupEntry entry = new LookupEntry(itemsByName, properties);

            lookupEntries.AddFirst(entry);
        }
        public void Basic()
        {
            XmlElement group = XmlTestUtilities.CreateBasicElement("ItemDefinitionGroup");
            XmlElement item = XmlTestUtilities.AddChildElement(group, "CCompile");
            XmlElement meta = XmlTestUtilities.AddChildElementWithInnerText(item, "Defines", "DEBUG");

            ItemDefinitionLibrary library = new ItemDefinitionLibrary(new Project());
            library.Add(group);
            library.Evaluate(null);

            Assertion.AssertEquals("DEBUG", library.GetDefaultMetadataValue("ccompile", "defines"));
        }        
Exemple #4
0
        /// <summary>
        /// Copy constructor (called via Clone() - clearer semantics)
        /// </summary>
        private Lookup(Lookup that)
        {
            // Add the same tables from the original
            foreach (LookupEntry entry in that.lookupEntries)
            {
                this.lookupEntries.AddLast(entry);
            }
            this.projectItems          = that.projectItems;
            this.itemDefinitionLibrary = that.itemDefinitionLibrary;

            // Clones need to share an (item)clone table; the batching engine asks for items from the lookup,
            // then populates buckets with them, which have clone lookups.
            this.cloneTable = that.cloneTable;
        }
        public void SameGroupTwoChildrenSameItemTypeDifferentMetadata()
        {
            XmlElement group = XmlTestUtilities.CreateBasicElement("ItemDefinitionGroup");
            XmlElement item1 = XmlTestUtilities.AddChildElement(group, "CCompile");
            XmlElement meta1 = XmlTestUtilities.AddChildElementWithInnerText(item1, "Defines", "DEBUG");
            XmlElement item2 = XmlTestUtilities.AddChildElement(group, "CCompile");
            XmlElement meta2 = XmlTestUtilities.AddChildElementWithInnerText(item1, "WarningLevel", "W4");

            ItemDefinitionLibrary library = new ItemDefinitionLibrary(new Project());
            library.Add(group);
            library.Evaluate(null);

            Assertion.AssertEquals("DEBUG", library.GetDefaultMetadataValue("ccompile", "defines"));
            Assertion.AssertEquals("W4", library.GetDefaultMetadataValue("ccompile", "warninglevel"));
        }
Exemple #6
0
        /// <summary>
        /// Creates an IntrinsicTask object around a "task" node
        /// </summary>
        internal IntrinsicTask(XmlElement taskNodeXmlElement, EngineLoggingServices loggingServices, BuildEventContext eventContext, string executionDirectory, ItemDefinitionLibrary itemDefinitionLibrary)
        {
            this.taskNodeXmlElement = taskNodeXmlElement;
            this.conditionAttribute = taskNodeXmlElement.Attributes[XMakeAttributes.condition];
            this.loggingServices = loggingServices;
            this.buildEventContext = eventContext;
            this.executionDirectory = executionDirectory;
            this.itemDefinitionLibrary = itemDefinitionLibrary;
            
            ErrorUtilities.VerifyThrow(IsIntrinsicTaskName(taskNodeXmlElement.Name), "Only PropertyGroup and ItemGroup are known intrinsic tasks");

            switch (taskNodeXmlElement.Name)
            {
                case XMakeElements.propertyGroup:
                    backingType = BackingType.PropertyGroup;
                    // If the backing type is a property group, we can just use a property group object; its semantics aren't
                    // tangled up with the project object. Put another way, we only really need the code that understands the XML
                    // format of a property group, and we can get that without the rest of BuildPropertyGroup getting in the way.
                    // Specify that these properties are output properties, so they get reverted when the project is reset.
                    backingPropertyGroup = new BuildPropertyGroup(null /* no parent project */, taskNodeXmlElement, PropertyType.OutputProperty);
                    break;
                case XMakeElements.itemGroup:
                    backingType = BackingType.ItemGroup;
                    // If the backing type is an item group, we just re-use the code that understands the XML format of an item group;
                    // the semantics of BuildItemGroup are too coupled to its current use in the Project object for us to re-use it.
                    backingItemGroupXml = new BuildItemGroupXml(taskNodeXmlElement);
                    List<XmlElement> children = backingItemGroupXml.GetChildren();
                    backingBuildItemGroupChildren = new List<BuildItemGroupChildXml>(children.Count);

                    foreach (XmlElement child in children)
                    {
                        BuildItemGroupChildXml childXml = new BuildItemGroupChildXml(child, ChildType.Any);
                        backingBuildItemGroupChildren.Add(childXml);
                    }
                    break;
            }
        }
Exemple #7
0
 /// <summary>
 /// Creates a new item with an XML element backing it. Use this to add a new persisted item to the project file.
 /// </summary>
 /// <param name="ownerDocument">can be null</param>
 /// <param name="name">can be null</param>
 internal BuildItem(XmlDocument ownerDocument, string name, string include, ItemDefinitionLibrary itemDefinitionLibrary)
     : this(ownerDocument, name, include, true /* create custom metadata cache */, itemDefinitionLibrary)
 {
 }
Exemple #8
0
 /// <summary>
 /// Verifies that an item definition library is supplied.
 /// This is for internal error checking only.
 /// </summary>
 private void MustHaveItemDefinitionLibrary(ItemDefinitionLibrary library)
 {
     ErrorUtilities.VerifyThrow(library != null, "Item definition library required when item is owned by project");
 }
 /// <summary>
 /// Constructor
 /// </summary>
 internal SpecificItemDefinitionLibrary(string itemType, ItemDefinitionLibrary itemDefinitionLibrary)
 {
     this.itemType = itemType;
     this.itemDefinitionLibrary = itemDefinitionLibrary;
 }
Exemple #10
0
 private static BuildItem CreateBuildItemFromXmlDocument(XmlDocument doc)
 {
     ItemDefinitionLibrary itemDefinitionLibrary = new ItemDefinitionLibrary(new Project());
     itemDefinitionLibrary.Evaluate(new BuildPropertyGroup());
     BuildItem item = new BuildItem((XmlElement)doc.FirstChild, false, itemDefinitionLibrary);
     return item;
 }
Exemple #11
0
        internal Lookup(Hashtable itemsByName, BuildItemGroup projectItems, BuildPropertyGroup properties, ItemDefinitionLibrary itemDefinitionLibrary)
        {
            ErrorUtilities.VerifyThrow(itemDefinitionLibrary != null, "Expect library");

            this.projectItems = projectItems;
            this.itemDefinitionLibrary = itemDefinitionLibrary;
            LookupEntry entry = new LookupEntry(itemsByName, properties);
            lookupEntries.AddFirst(entry);
        }
Exemple #12
0
        /// <summary>
        /// Copy constructor (called via Clone() - clearer semantics)
        /// </summary>
        private Lookup(Lookup that)
        {
            // Add the same tables from the original
            foreach (LookupEntry entry in that.lookupEntries)
            {
                this.lookupEntries.AddLast(entry);
            }
            this.projectItems = that.projectItems;
            this.itemDefinitionLibrary = that.itemDefinitionLibrary;

            // Clones need to share an (item)clone table; the batching engine asks for items from the lookup,
            // then populates buckets with them, which have clone lookups.
            this.cloneTable = that.cloneTable;
        }
        private static ItemDefinitionLibrary NewAndEvaluateItemDefinitionLibraryXml(XmlElement group)
        {
            ItemDefinitionLibrary library = new ItemDefinitionLibrary(new Project());
            library.Add(group);

            BuildPropertyGroup properties = new BuildPropertyGroup();
            properties.SetProperty("p1", "v1");            
            library.Evaluate(properties);

            return library;
        }
Exemple #14
0
 /// <summary>
 /// This constructor initializes a persisted item from an existing item
 /// element which exists either in the main project file or one of the
 /// imported files.
 /// </summary>
 internal BuildItem(XmlElement itemElement, bool importedFromAnotherProject, ItemDefinitionLibrary itemDefinitionLibrary)
     : this(itemElement, importedFromAnotherProject, true /* part of project manifest */, itemDefinitionLibrary)
 {
 }
Exemple #15
0
 /// <summary>
 /// Creates either a new item with an XML element backing it, or a virtual
 /// item. To conserve memory, this constructor does not allocate storage
 /// for custom metadata, unless told to do so.
 /// </summary>
 /// <remarks>
 /// PERF WARNING: Allocating memory for the custom metadata cache is expensive
 /// when a build generates a large number of items.
 /// </remarks>
 /// <param name="ownerDocument">can be null</param>
 /// <param name="name">can be null</param> 
 private BuildItem(XmlDocument ownerDocument, string name, string include, bool createCustomMetadataCache, ItemDefinitionLibrary itemDefinitionLibrary)
 {
     BuildItemHelper(ownerDocument, name, include, createCustomMetadataCache, itemDefinitionLibrary);
 }
Exemple #16
0
 internal static ItemDefinitionLibrary CreateEmptyEvaluatedItemDefinitionLibrary()
 {
     ItemDefinitionLibrary itemDefinitionLibrary = new ItemDefinitionLibrary(new Project());
     itemDefinitionLibrary.Evaluate(new BuildPropertyGroup());
     return itemDefinitionLibrary;
 }    
        public void PropertyInMetadataValue()
        {
            XmlElement group = XmlTestUtilities.CreateBasicElement("ItemDefinitionGroup");
            XmlElement item = XmlTestUtilities.AddChildElement(group, "CCompile");
            XmlElement meta = XmlTestUtilities.AddChildElementWithInnerText(item, "Defines", "$(p1)");

            ItemDefinitionLibrary library = new ItemDefinitionLibrary(new Project());
            library.Add(group);
            BuildPropertyGroup pg1 = new BuildPropertyGroup();
            pg1.SetProperty("p1", "v1");
            library.Evaluate(pg1);

            Assertion.AssertEquals("v1", library.GetDefaultMetadataValue("ccompile", "defines"));

            // Change the original property group -- should not affect the metadata value which was
            // already evaluated
            pg1.SetProperty("p1", "v1b");

            Assertion.AssertEquals("v1", library.GetDefaultMetadataValue("ccompile", "defines"));

            // Reevaluate with another property value
            BuildPropertyGroup pg2 = new BuildPropertyGroup();
            pg2.SetProperty("p1", "v2");
            library.Evaluate(pg2);

            Assertion.AssertEquals("v2", library.GetDefaultMetadataValue("ccompile", "defines"));
        }
Exemple #18
0
        /// <summary>
        /// Common code for constructors. If an ownerDocument is passed in, it's a persisted element.
        /// </summary>
        /// <param name="itemName">can be null</param>
        /// <param name="itemDefinitionLibrary">can only be null if ownerDocument is null</param>
        private void BuildItemHelper(XmlDocument ownerDocument, string itemName, string itemInclude, bool createCustomMetadataCache, ItemDefinitionLibrary itemDefinitionLibraryToUse)
        {
            // Only check for null. It's legal to make BuildItems with empty
            // item specs -- this is to be consistent with how we shipped TaskItem.
            // See #567058.
            ErrorUtilities.VerifyThrowArgumentNull(itemInclude, "itemInclude");

            // Validate that the item name doesn't contain any illegal characters.
            if (itemName != null)
            {
                XmlUtilities.VerifyThrowValidElementName(itemName);
                ErrorUtilities.VerifyThrowInvalidOperation(XMakeElements.IllegalItemPropertyNames[itemName] == null, "CannotModifyReservedItem", itemName);
            }

            // If no owner document was passed in, then it's not going to have an
            // XML element backing it.
            if (ownerDocument == null)
            {
                this.include = itemInclude;
                this.isPartOfProjectManifest = false;
            }
            else
            {
                ErrorUtilities.VerifyThrowArgumentLength(itemName, "itemType");
                MustHaveItemDefinitionLibrary(itemDefinitionLibraryToUse);

                // The caller has given us an owner document, so we're going to create a
                // new item element associated with that document.  The new item element
                // doesn't actually get added to the XML document automatically.
                this.xml = new BuildItemGroupChildXml(ownerDocument, itemName, itemInclude);
                this.isPartOfProjectManifest = true;
            }

            if (createCustomMetadataCache)
            {
                // PERF NOTE: only create cache if told to do so, because creating
                // this cache for a large number of items is expensive
                InitializeCustomMetadataCache();
            }

            this.name = itemName;

            // The evaluated and final item specs start off initialized to the "Include" attribute.
            this.evaluatedItemSpecEscaped = itemInclude;
            this.finalItemSpecEscaped = itemInclude;

            this.importedFromAnotherProject = false;
            this.itemDefinitionLibrary = itemDefinitionLibraryToUse;
        }
Exemple #19
0
        /// <summary>
        /// Creates an instance of this class for the given engine, specifying a tools version to
        /// use during builds of this project.
        /// </summary>
        /// <owner>RGoel</owner>
        /// <param name="engine">Engine that will build this project. May be null if the global engine is expected.</param>
        /// <param name="toolsVersion">Tools version to use during builds of this project instance. May be null,
        /// in which case we will use the value in the Project's ToolsVersion attribute, or else the engine
        /// default value.</param>
        public Project
        (
            Engine engine,
            string toolsVersion
        )
        {
#if MSBUILDENABLEVSPROFILING 
            try
            {
                DataCollection.CommentMarkProfile(8808, "Construct Project Using Old OM - Start");
#endif 
#if (!STANDALONEBUILD)
            using (new CodeMarkerStartEnd(CodeMarkerEvent.perfMSBuildProjectConstructBegin, CodeMarkerEvent.perfMSBuildProjectConstructEnd))
#endif
            {
                if (engine == null)
                {
                    engine = Engine.GlobalEngine;
                }

                this.parentEngine = engine;
                this.projectId = parentEngine.GetNextProjectId();
                this.projectBuildEventContext = new BuildEventContext(parentEngine.NodeId, BuildEventContext.InvalidTargetId, parentEngine.GetNextProjectId(), BuildEventContext.InvalidTaskId);

                this.isLoadedByHost = true;
                this.buildEnabled = BuildEnabledSetting.UseParentEngineSetting;

                this.isValidated = false;

                // Create a new XML document and add a <Project> element.  This way, the
                // project is always in a valid state from the beginning, and now somebody
                // can start programmatically adding stuff to the <Project>.
                this.mainProjectEntireContents = new XmlDocument();
                this.mainProjectElement = mainProjectEntireContents.CreateElement(XMakeElements.project, XMakeAttributes.defaultXmlNamespace);
                this.mainProjectEntireContents.AppendChild(mainProjectElement);


                // initialize all case-insensitive hash-tables
                this.conditionedPropertiesTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
                this.evaluatedItemsByName = new Hashtable(StringComparer.OrdinalIgnoreCase);
                this.evaluatedItemsByNameIgnoringCondition = new Hashtable(StringComparer.OrdinalIgnoreCase);

                // Create the group collection.  All collection elements are stored here.
                this.rawGroups = new GroupingCollection(null /* null parent means this is the master collection */);

                // Initialize all property-related objects.
                // (see above for initialization of this.conditionedPropertiesTable)
                this.globalProperties = null;
                this.environmentProperties = null;
                this.reservedProperties = null;
                // We still create the rawPropertyGroups collection, but
                // it's just a facade over rawGroups
                this.rawPropertyGroups = new BuildPropertyGroupCollection(this.rawGroups);
                this.evaluatedProperties = new BuildPropertyGroup();

                // Initialize all item-related objects.
                // (see above for initialization of this.evaluatedItemsByName and this.evaluatedItemsByNameIgnoringCondition
                // We still create the rawItemGroups collection, but it's just a facade over rawGroups
                this.rawItemGroups = new BuildItemGroupCollection(this.rawGroups);
                this.evaluatedItems = new BuildItemGroup();
                this.evaluatedItemsIgnoringCondition = new BuildItemGroup();

                this.itemDefinitionLibrary = new ItemDefinitionLibrary(this);

                // Initialize all target- and task-related objects.
                this.usingTasks = new UsingTaskCollection();
                this.imports = new ImportCollection(this);
                this.taskRegistry = new TaskRegistry();
                this.targets = new TargetCollection(this);

                // Initialize the default targets, initial targets, and project file name.
                this.defaultTargetNames = new string[0];
                this.initialTargetNamesInMainProject = new ArrayList();
                this.initialTargetNamesInImportedProjects = new ArrayList();
                this.FullFileName = String.Empty;
                this.projectDirectory = String.Empty;

                this.projectExtensionsNode = null;

                // If the toolsVersion is null, we will use the value specified in
                // the Project element's ToolsVersion attribute, or else the default if that
                // attribute is not present.
                if (null != toolsVersion)
                {
                    this.ToolsVersion = toolsVersion;
                }

                this.MarkProjectAsDirtyForReprocessXml();
                // The project doesn't really need to be saved yet; there's nothing in it!
                this.dirtyNeedToSaveProjectFile = false;
                this.IsReset = false;

                // Grab some initial properties from the Engine.
                // Global properties and reserved properties need to be cloned, because
                // different projects may have different sets of properties or values
                // for these.  Environment properties don't have to be cloned, because
                // the environment is captured once at engine instantiation, and
                // shared by all projects thereafter.
                this.GlobalProperties = this.parentEngine.GlobalProperties;
                this.EnvironmentProperties = this.parentEngine.EnvironmentProperties;
            }
#if MSBUILDENABLEVSPROFILING 
            }
            finally
            {
                DataCollection.CommentMarkProfile(8809, "Construct Project Using Old OM - End");
            }
#endif
        }
Exemple #20
0
        /// <summary>
        /// This constructor initializes an item from an item element.
        /// It is part of the project manifest or not as specified.
        /// </summary>
        internal BuildItem(XmlElement itemElement, bool importedFromAnotherProject, bool isPartOfProjectManifest, ItemDefinitionLibrary itemDefinitionLibrary)
        {
            MustHaveItemDefinitionLibrary(itemDefinitionLibrary);

            InitializeFromItemElement(itemElement);
            this.importedFromAnotherProject = importedFromAnotherProject;
            this.isPartOfProjectManifest = isPartOfProjectManifest;
            this.itemDefinitionLibrary = itemDefinitionLibrary;

            ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[name] == null, ItemElement, "CannotModifyReservedItem", name);
        }
Exemple #21
0
        /// <summary>
        /// Creates an IntrinsicTask object around a "task" node
        /// </summary>
        internal IntrinsicTask(XmlElement taskNodeXmlElement, EngineLoggingServices loggingServices, BuildEventContext eventContext, string executionDirectory, ItemDefinitionLibrary itemDefinitionLibrary)
        {
            this.taskNodeXmlElement    = taskNodeXmlElement;
            this.conditionAttribute    = taskNodeXmlElement.Attributes[XMakeAttributes.condition];
            this.loggingServices       = loggingServices;
            this.buildEventContext     = eventContext;
            this.executionDirectory    = executionDirectory;
            this.itemDefinitionLibrary = itemDefinitionLibrary;

            ErrorUtilities.VerifyThrow(IsIntrinsicTaskName(taskNodeXmlElement.Name), "Only PropertyGroup and ItemGroup are known intrinsic tasks");

            switch (taskNodeXmlElement.Name)
            {
            case XMakeElements.propertyGroup:
                backingType = BackingType.PropertyGroup;
                // If the backing type is a property group, we can just use a property group object; its semantics aren't
                // tangled up with the project object. Put another way, we only really need the code that understands the XML
                // format of a property group, and we can get that without the rest of BuildPropertyGroup getting in the way.
                // Specify that these properties are output properties, so they get reverted when the project is reset.
                backingPropertyGroup = new BuildPropertyGroup(null /* no parent project */, taskNodeXmlElement, PropertyType.OutputProperty);
                break;

            case XMakeElements.itemGroup:
                backingType = BackingType.ItemGroup;
                // If the backing type is an item group, we just re-use the code that understands the XML format of an item group;
                // the semantics of BuildItemGroup are too coupled to its current use in the Project object for us to re-use it.
                backingItemGroupXml = new BuildItemGroupXml(taskNodeXmlElement);
                List <XmlElement> children = backingItemGroupXml.GetChildren();
                backingBuildItemGroupChildren = new List <BuildItemGroupChildXml>(children.Count);

                foreach (XmlElement child in children)
                {
                    BuildItemGroupChildXml childXml = new BuildItemGroupChildXml(child, ChildType.Any);
                    backingBuildItemGroupChildren.Add(childXml);
                }
                break;
            }
        }
Exemple #22
0
 internal Lookup(Hashtable itemsByName, BuildPropertyGroup properties, ItemDefinitionLibrary itemDefinitionLibrary)
     : this(itemsByName, new BuildItemGroup(), properties, itemDefinitionLibrary)
 {
 }
 /// <summary>
 /// Constructor
 /// </summary>
 internal SpecificItemDefinitionLibrary(string itemType, ItemDefinitionLibrary itemDefinitionLibrary)
 {
     this.itemType = itemType;
     this.itemDefinitionLibrary = itemDefinitionLibrary;
 }
Exemple #24
0
        internal static BuildItem GetXmlBackedItemWithDefinitionLibrary()
        {
            string content = @"<i  xmlns='http://schemas.microsoft.com/developer/msbuild/2003' Include='i1'/>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(content);

            XmlElement groupElement = XmlTestUtilities.CreateBasicElement("ItemDefinitionGroup");
            XmlElement itemElement = XmlTestUtilities.AddChildElement(groupElement, "i");
            XmlElement metaElement = XmlTestUtilities.AddChildElementWithInnerText(itemElement, "m", "m1");
            XmlElement metaElement2 = XmlTestUtilities.AddChildElementWithInnerText(itemElement, "o", "o1");

            ItemDefinitionLibrary library = new ItemDefinitionLibrary(new Project());
            library.Add(groupElement);
            library.Evaluate(null);

            BuildItem item = new BuildItem((XmlElement)doc.FirstChild, false, library);
            item.SetMetadata("n", "n1");
            return item;
        }
Exemple #25
0
 internal Lookup(Hashtable itemsByName, BuildPropertyGroup properties, ItemDefinitionLibrary itemDefinitionLibrary)
     : this(itemsByName, new BuildItemGroup(), properties, itemDefinitionLibrary)
 { }