Example #1
0
        public XnaContentProject(Task task, string msBuildPath, string xnaInstallPath)
        {
            m_engine = new Engine(msBuildPath);
            m_engine.RegisterLogger(new XnaContentLogger(task));
            m_project = new Project(m_engine);

            m_project.AddNewUsingTaskFromAssemblyName("BuildContent", "Microsoft.Xna.Framework.Content.Pipeline, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d");
            m_project.AddNewUsingTaskFromAssemblyName("BuildXact", "Microsoft.Xna.Framework.Content.Pipeline, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d");

            // Add our Content Pipeline Assemblies
            m_pipelineGroup = m_project.AddNewItemGroup();
            m_contentGroup = m_project.AddNewItemGroup();

            m_contentTarget = m_project.Targets.AddNewTarget("_BuildXNAContentLists");

            // Add our Build target
            m_xnaTarget = m_project.Targets.AddNewTarget("Build");
            m_xnaTarget.DependsOnTargets = "_BuildXNAContentLists";

            // Add Default Pipeline Assemblies.
            AddPilepineAssembly(xnaInstallPath + "Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll");
            AddPilepineAssembly(xnaInstallPath + "Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll");
            AddPilepineAssembly(xnaInstallPath + "Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll");
            AddPilepineAssembly(xnaInstallPath + "Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll");
        }
        public void BasicProxying()
        {          
            BuildItemGroup ig = new BuildItemGroup();
            BuildItem i1 = new BuildItem("name1", "value1");
            i1.SetMetadata("myMetaName", "myMetaValue");
            BuildItem i2 = new BuildItem("name2", "value2");
            ig.AddItem(i1);
            ig.AddItem(i2);

            BuildItemGroupProxy proxy = new BuildItemGroupProxy(ig);

            // Gather everything into our own table
            Hashtable list = new Hashtable(StringComparer.OrdinalIgnoreCase);
            foreach (DictionaryEntry item in proxy)
            {
                list.Add(item.Key, item.Value);
            }

            // Check we got all the items
            Assertion.AssertEquals(2, list.Count);
            Assertion.AssertEquals("value1", ((TaskItem)list["name1"]).ItemSpec);
            Assertion.AssertEquals("value2", ((TaskItem)list["name2"]).ItemSpec);

            // Check they have all their metadata
            int builtInMetadata = FileUtilities.ItemSpecModifiers.All.Length;
            Assertion.AssertEquals(1 + builtInMetadata, ((TaskItem)list["name1"]).MetadataCount);
            Assertion.AssertEquals(0 + builtInMetadata, ((TaskItem)list["name2"]).MetadataCount);
            Assertion.AssertEquals("myMetaValue", ((TaskItem)list["name1"]).GetMetadata("myMetaName"));
        }
		public BuildWhen (XmlElement whenElement, Project parentProject)
		{
			this.parentProject = parentProject;
			this.groupingCollection = new GroupingCollection (parentProject);
			if (whenElement == null)
				throw new ArgumentNullException ("whenElement");
			this.whenElement = whenElement;
			foreach (XmlElement xe in whenElement.ChildNodes) {
				switch (xe.Name) {
					case "ItemGroup":
						BuildItemGroup big = new BuildItemGroup (xe, parentProject, null, true);
						//big.BindToXml (xe);
						groupingCollection.Add (big);
						break;
					case "PropertyGroup":
						BuildPropertyGroup bpg = new BuildPropertyGroup (xe, parentProject, null, true);
						//bpg.BindToXml (xe);
						groupingCollection.Add (bpg);
						break;
					case "Choose":
						BuildChoose bc = new BuildChoose (xe, parentProject);
						groupingCollection.Add (bc);
						break;
					default:
						throw new InvalidProjectFileException ( string.Format ("Invalid element '{0}' in When.", xe.Name));
				}
			}
		}
        public void TestFalseWhen () {
            Engine engine;
            Project project;
            BuildItemGroup[] groups = new BuildItemGroup[1];

            string documentString = @"
				<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
                    <Choose>
                        <When Condition=""'$(Configuration)' == 'False'"">
					        <ItemGroup>
						        <A Include='a' />
					        </ItemGroup>
                        </When>
                    </Choose>
				</Project>
			";

            engine = new Engine (Consts.BinPath);
            project = engine.CreateNewProject ();
            project.LoadXml (documentString);

            //Assert.AreEqual (1, project.ItemGroups.Count, "A1");
            Assert.AreEqual (0, project.PropertyGroups.Count, "A2");
            Assert.AreEqual (0, project.EvaluatedItems.Count, "A3");
            Assert.AreEqual (0, project.EvaluatedItemsIgnoringCondition.Count, "A4");
        }
        internal BuildItemProxy(object buildItem)
        {
            instance = (Microsoft.Build.BuildEngine.BuildItem)buildItem;

            // I am not sure what's going on here, but sometimes, in particular when the project is initialized
            // the build item is not what we are getting here, but rather the child element
            // 'get_ParentPersistedItem" gives us what we need
            var persisted_instance = (BuildItem)typeof(BuildItem)
                .InvokeMember("get_ParentPersistedItem", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, instance, new object[] { });
            if (persisted_instance != null)
                instance = persisted_instance;

            buildItemGroup = (BuildItemGroup)typeof(BuildItem)
                .InvokeMember("get_ParentPersistedItemGroup", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
                null, instance, new object[] { });

            int i = -1;
            foreach (BuildItem item in buildItemGroup)
            {
                i++;
                if (item == instance)
                {
                    index = i;
                    break;
                }
            }

            Include = instance.Include;
            Type = instance.Name;
        }
Example #6
0
        public void ExpandAllIntoTaskItems3()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();

            BuildItemGroup ig = new BuildItemGroup();
            ig.AddItem(new BuildItem("Compile", "foo.cs"));
            ig.AddItem(new BuildItem("Compile", "bar.cs"));

            BuildItemGroup ig2 = new BuildItemGroup();
            ig2.AddItem(new BuildItem("Resource", "bing.resx"));

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);
            itemsByType["Compile"] = ig;
            itemsByType["Resource"] = ig2;

            Expander expander = new Expander(pg, itemsByType);

            List<TaskItem> itemsOut = expander.ExpandAllIntoTaskItems("foo;bar;@(compile);@(resource)", null);

            ObjectModelHelpers.AssertItemsMatch(@"
                foo
                bar
                foo.cs
                bar.cs
                bing.resx
                ", itemsOut.ToArray());
        }
        protected override void ResolveReference()
        {
            if (this.ProjectMgr == null || this.ProjectMgr.IsClosed)
            {
                return;
            }

            MSBuild.BuildItemGroup group = this.ProjectMgr.BuildProject.GetEvaluatedItemsByName(ProjectFileConstants.ReferencePath);
            if (group != null)
            {
                IEnumerator enumerator = group.GetEnumerator();

                while (enumerator.MoveNext())
                {
                    MSBuild.BuildItem item = (MSBuild.BuildItem)enumerator.Current;

                    string fullPath = this.GetFullPathFromPath(item.FinalItemSpec);

                    System.Reflection.AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(fullPath);

                    // Try with full assembly name and then with weak assembly name.
                    if (String.Compare(name.FullName, this.assemblyName.FullName, StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(name.Name, this.assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        // set the full path now.
                        this.assemblyPath         = fullPath;
                        this.resolvedAssemblyName = name;

                        // No hint path is needed since the assembly path will always be resolved.
                        return;
                    }
                }
            }
        }
		public void TestCtor ()
		{
			BuildItemGroup big = new BuildItemGroup ();

			Assert.AreEqual (String.Empty, big.Condition, "A1");
			Assert.AreEqual (0, big.Count, "A2");
			Assert.IsFalse (big.IsImported, "A3");
		}
Example #9
0
 public void ParameterlessConstructor()
 {
     BuildItemGroup group = new BuildItemGroup();
     Assertion.AssertEquals(String.Empty, group.Condition);
     Assertion.AssertEquals(false, group.IsPersisted);
     Assertion.AssertEquals(0, group.Count);
     Assertion.AssertEquals(false, group.IsImported);
 }
Example #10
0
 public void XmlDocConstructor()
 {
     XmlDocument doc = new XmlDocument();
     BuildItemGroup group = new BuildItemGroup(doc, true, new Project());
     Assertion.AssertEquals(String.Empty, group.Condition);
     Assert.AreNotEqual(null, group.ItemGroupElement);
     Assertion.AssertEquals(0, group.Count);
     Assertion.AssertEquals(true, group.IsImported);
 }
		public void TestHintPath1 ()
		{
			engine = new Engine (Consts.BinPath);
			project = engine.CreateNewProject ();
			project.LoadXml (ResolveAssembly (null, @"Test\resources\test.dll"));
			
			Assert.IsTrue (project.Build ("A"), "A1");
			big = project.GetEvaluatedItemsByName ("ResolvedFiles");
			Assert.AreEqual (1, big.Count, "A2");
			Assert.IsTrue (big [0].Include.EndsWith (".dll"), "A3");
		}
Example #12
0
        public void SecondaryItemNotShadowedByPrimaryItem()
        {
            BuildItemGroup group1 = new BuildItemGroup();
            group1.AddNewItem("i1", "a1");
            Hashtable table1 = new Hashtable(StringComparer.OrdinalIgnoreCase);
            table1.Add("i1", group1);
            Lookup lookup = LookupHelpers.CreateLookup(table1);

            lookup.EnterScope();

            // Should return item from the secondary table.
            Assertion.AssertEquals("a1", lookup.GetItems("i1")[0].FinalItemSpec);
        }
Example #13
0
		internal BuildItem (XmlElement itemElement, BuildItemGroup parentItemGroup)
		{
			child_items = new List<BuildItem> ();
			isImported = parentItemGroup.IsImported;
			unevaluatedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
			evaluatedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
			this.parent_item_group = parentItemGroup;
			
			this.itemElement = itemElement;
			
			if (Include == String.Empty)
				throw new InvalidProjectFileException (String.Format ("The required attribute \"Include\" is missing from element <{0}>.", Name));
		}
		public void ResolveBinary_FancyStuff ()
		{
			engine = new Engine (Consts.BinPath);
			project = engine.CreateNewProject ();
			project.LoadXml (ResolveAssembly (null, @"Test\resources\binary\FancyStuff.dll"));
			
			Assert.IsTrue (project.Build ("A"), "A1");
			big = project.GetEvaluatedItemsByName ("ResolvedFiles");
			Assert.AreEqual (1, big.Count, "A2");
			Assert.IsTrue (big[0].Include.EndsWith ("FancyStuff.dll"), "A3");
			
			big = project.GetEvaluatedItemsByName ("ResolvedDependencyFiles");
			Assert.AreEqual (1, big.Count, "A4");
			Assert.IsTrue (big.Cast<BuildItem> ().Any (item => item.Include.EndsWith ("SimpleWrite.dll")), "A5");
		}
Example #15
0
        public void XmlElementConstructor()
        {
            XmlElement ig = CreatePersistedItemGroupElement();

            BuildItemGroup group = new BuildItemGroup(ig, false, new Project());
            Assertion.AssertEquals("c", group.Condition);
            Assertion.AssertEquals(ig, group.ItemGroupElement);
            Assertion.AssertEquals(ig.ParentNode, group.ParentElement);
            Assertion.AssertEquals(2, group.Count);
            Assertion.AssertEquals(false, group.IsImported);
            Assertion.AssertEquals("ci1", group[0].Condition);
            Assertion.AssertEquals("i1", group[0].Include);
            Assertion.AssertEquals("ci2", group[1].Condition);
            Assertion.AssertEquals("i2", group[1].Include);
        }
		public void TestGac1 ()
		{
			var gacDir = GetGacDir ();

			if (gacDir == null || !System.IO.Directory.Exists (gacDir))
				Assert.Ignore ("GAC not found.");

			engine = new Engine (Consts.BinPath);
			project = engine.CreateNewProject ();
			project.LoadXml (ResolveAssembly ("System", null));
			
			Assert.IsTrue (project.Build ("A"), "A1");
			big = project.GetEvaluatedItemsByName ("ResolvedFiles");
			Assert.AreEqual (1, big.Count, "A2");
			Assert.IsTrue (big [0].Include.EndsWith (".dll"), "A3");
		}
		public void TestAddNewItem1 ()
		{
			string name = "name";
			string include = "a;b;c";
			
			BuildItemGroup big = new BuildItemGroup ();
			BuildItem bi = big.AddNewItem (name, include);

			Assert.AreEqual (String.Empty, bi.Condition, "A1");
			Assert.AreEqual (String.Empty, bi.Exclude, "A2");
			Assert.AreEqual (include, bi.FinalItemSpec, "A3");
			Assert.AreEqual (include, bi.Include, "A4");
			Assert.IsFalse (bi.IsImported, "A5");
			Assert.AreEqual (name, bi.Name, "A6");
			Assert.AreEqual (1, big.Count, "A7");
		}
Example #18
0
        /// <summary>
        /// Reevaluate all properties for the current item
        /// This should be call if you believe the property for this item
        /// may have changed since it was created/refreshed, or global properties
        /// this items depends on have changed.
        /// Be aware that there is a perf cost in calling this function.
        /// </summary>
        public void RefreshProperties()
        {
            if (this.IsVirtual)
            {
                return;
            }

            MSBuild.BuildItemGroup items = itemProject.BuildProject.EvaluatedItems;
            foreach (MSBuild.BuildItem projectItem in items)
            {
                if (projectItem.Include == item.Include)
                {
                    item = projectItem;
                    return;
                }
            }
        }
Example #19
0
        /// <summary>
        /// Adds references to this container from a MSBuild project.
        /// </summary>
        public void LoadReferencesFromBuildProject(MSBuild.Project buildProject)
        {
            foreach (string referenceType in SupportedReferenceTypes)
            {
                MSBuild.BuildItemGroup refererncesGroup = buildProject.GetEvaluatedItemsByName(referenceType);

                ReferenceNode node;

                bool isComReference      = referenceType == ProjectFileConstants.COMReference;
                bool isAssemblyReference = referenceType == ProjectFileConstants.Reference;
                bool isProjectReference  = referenceType == ProjectFileConstants.ProjectReference;

                if (isAssemblyReference && this.ProjectMgr.Build(MsBuildTarget.ResolveAssemblyReferences) != MSBuildResult.Sucessful)
                {
                    continue;
                }

                foreach (MSBuild.BuildItem item in refererncesGroup)
                {
                    ProjectElement element = new ProjectElement(this.ProjectMgr, item, false);
                    if (isComReference)
                    {
                        node = this.CreateComReferenceNode(element);
                    }
                    else if (isAssemblyReference)
                    {
                        node = this.CreateAssemblyReferenceNode(element);
                    }
                    else if (isProjectReference)
                    {
                        node = this.CreateProjectReferenceNode(element);
                    }
                    else
                    {
                        // JRock: Added support for other references
                        node = this.CreateOtherReferenceNode(element);
                    }

                    if (node != null)
                    {
                        this.AddChild(node);
                    }
                }
            }
        }
Example #20
0
        /// <summary>
        /// Generate a hashtable of items by type with a bunch of sample items, so that we can exercise
        /// ItemExpander.ItemizeItemVector.
        /// </summary>
        /// <returns></returns>
        /// <owner>RGoel</owner>
        private Hashtable GenerateTestItems()
        {
            Hashtable itemGroupsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            // Set up our item group programmatically.
            BuildItemGroup itemGroup = new BuildItemGroup();
            itemGroupsByType["Compile"] = itemGroup;
            BuildItem a = itemGroup.AddNewItem("Compile", "a.cs");
            a.SetMetadata("WarningLevel", "4");
            BuildItem b = itemGroup.AddNewItem("Compile", "b.cs");
            b.SetMetadata("WarningLevel", "3");

            BuildItemGroup itemGroup2 = new BuildItemGroup();
            itemGroupsByType["Resource"] = itemGroup2;
            BuildItem c = itemGroup2.AddNewItem("Resource", "c.resx");

            return itemGroupsByType;
        }
Example #21
0
        /// <summary>
        /// Adds references to this container from a MSBuild project.
        /// </summary>
        public void LoadReferencesFromBuildProject(MSBuild.Project buildProject)
        {
            foreach (string referenceType in SupportedReferenceTypes)
            {
                MSBuild.BuildItemGroup refererncesGroup = buildProject.GetEvaluatedItemsByName(referenceType);

                bool isAssemblyReference = referenceType == ProjectFileConstants.Reference;
                // If the project was loaded for browsing we should still create the nodes but as not resolved.
                if (this.ProjectMgr.HasPassedSecurityChecks && isAssemblyReference && this.ProjectMgr.Build(MsBuildTarget.ResolveAssemblyReferences) != MSBuildResult.Successful)
                {
                    continue;
                }

                foreach (MSBuild.BuildItem item in refererncesGroup)
                {
                    ProjectElement element = new ProjectElement(this.ProjectMgr, item, false);

                    ReferenceNode node = CreateReferenceNode(referenceType, element);

                    if (node != null)
                    {
                        // Make sure that we do not want to add the item twice to the ui hierarchy
                        // We are using here the UI representation of the Node namely the Caption to find that out, in order to
                        // avoid different representation problems.
                        // Example :<Reference Include="EnvDTE80, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
                        //		  <Reference Include="EnvDTE80" />
                        bool found = false;
                        for (HierarchyNode n = this.FirstChild; n != null && !found; n = n.NextSibling)
                        {
                            if (String.Compare(n.Caption, node.Caption, StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                found = true;
                            }
                        }

                        if (!found)
                        {
                            this.AddChild(node);
                        }
                    }
                }
            }
        }
        private void SetHintPathAndPrivateValue()
        {
            // Private means local copy; we want to know if it is already set to not override the default
            string privateValue = this.ItemNode.GetMetadata(ProjectFileConstants.Private);

            // Get the list of items which require HintPath
            Microsoft.Build.BuildEngine.BuildItemGroup references = this.ProjectMgr.BuildProject.GetEvaluatedItemsByName(MsBuildGeneratedItemType.ReferenceCopyLocalPaths);

            // Remove the HintPath, we will re-add it below if it is needed
            if (!String.IsNullOrEmpty(this.assemblyPath))
            {
                this.ItemNode.SetMetadata(ProjectFileConstants.HintPath, null);
            }

            // Now loop through the generated References to find the corresponding one
            foreach (Microsoft.Build.BuildEngine.BuildItem reference in references)
            {
                string fileName = Path.GetFileNameWithoutExtension(reference.FinalItemSpec);
                if (String.Compare(fileName, this.assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    // We found it, now set some properties based on this.

                    string hintPath = reference.GetMetadata(ProjectFileConstants.HintPath);
                    if (!String.IsNullOrEmpty(hintPath))
                    {
                        if (Path.IsPathRooted(hintPath))
                        {
                            hintPath = PackageUtilities.GetPathDistance(this.ProjectMgr.BaseURI.Uri, new Uri(hintPath));
                        }

                        this.ItemNode.SetMetadata(ProjectFileConstants.HintPath, hintPath);
                        // If this is not already set, we default to true
                        if (String.IsNullOrEmpty(privateValue))
                        {
                            this.ItemNode.SetMetadata(ProjectFileConstants.Private, true.ToString());
                        }
                    }
                    break;
                }
            }
        }
        /// <summary>
        /// Does the actual job of resolving an assembly reference. We need a private method that does not violate
        /// calling virtual method from the constructor.
        /// </summary>
        private void ResolveAssemblyReference()
        {
            if (this.ProjectMgr == null || this.ProjectMgr.IsClosed || !this.ProjectMgr.HasPassedSecurityChecks)
            {
                return;
            }

            MSBuild.BuildItemGroup group = this.ProjectMgr.BuildProject.GetEvaluatedItemsByName(ProjectFileConstants.ReferencePath);
            if (group != null)
            {
                IEnumerator enumerator = group.GetEnumerator();

                while (enumerator.MoveNext())
                {
                    MSBuild.BuildItem item = (MSBuild.BuildItem)enumerator.Current;

                    string fullPath = this.GetFullPathFromPath(item.FinalItemSpec);

                    System.Reflection.AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(fullPath);

                    // Try with full assembly name and then with weak assembly name.
                    if (String.Compare(name.FullName, this.assemblyName.FullName, StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(name.Name, this.assemblyName.Name, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        if (!NativeMethods.IsSamePath(fullPath, this.assemblyPath))
                        {
                            // set the full path now.
                            this.assemblyPath = fullPath;

                            // We have a new item to listen too, since the assembly reference is resolved from a different place.
                            this.fileChangeListener.ObserveItem(this.assemblyPath);
                        }

                        this.resolvedAssemblyName = name;

                        // No hint path is needed since the assembly path will always be resolved.
                        return;
                    }
                }
            }
        }
		public void TestGac1 ()
		{
			string documentString = @"
                                <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
					<ItemGroup>
						<Reference Include='System' />
					</ItemGroup>
					<PropertyGroup>
						<SearchPaths>
							{CandidateAssemblyFiles};
							$(ReferencePath);
							{HintPathFromItem};
							{TargetFrameworkDirectory};
							{AssemblyFolders};
							{GAC};
							{RawFileName};
							$(OutputPath)
						</SearchPaths>
					</PropertyGroup>
					<Target Name='A'>
						<ResolveAssemblyReference
							Assemblies='@(Reference)'
							SearchPaths='$(SearchPaths)'
						>
							<Output TaskParameter='ResolvedFiles' ItemName='ResolvedFiles'/>
						</ResolveAssemblyReference>
					</Target>
				</Project>
			";
			
			engine = new Engine (Consts.BinPath);
			project = engine.CreateNewProject ();
			project.LoadXml (documentString);

			Assert.IsTrue (project.Build ("A"), "A1");
			big = project.GetEvaluatedItemsByName ("ResolvedFiles");
			Assert.AreEqual (1, big.Count, "A2");
			Assert.IsTrue (big [0].Include.EndsWith (".dll"), "A3");
		}
Example #25
0
 internal static void AddItemToGroup(MSBuild.BuildItemGroup group, ProjectItem item)
 {
     if (group == null)
     {
         throw new ArgumentNullException("group");
     }
     if (item == null)
     {
         throw new ArgumentNullException("item");
     }
     if (item.IsAddedToProject)
     {
         throw new ArgumentException("item is already added to project", "item");
     }
     MSBuild.BuildItem newItem = group.AddNewItem(item.ItemType.ToString(), item.Include, item.TreatIncludeAsLiteral);
     foreach (string name in item.MetadataNames)
     {
         newItem.SetMetadata(name, item.GetMetadata(name));
     }
     item.BuildItem = newItem;
     Debug.Assert(item.IsAddedToProject);
 }
Example #26
0
        public void InitiallyNoItemsInBucketOfTypesInItemNames()
        {
            // This bucket is for items of type "i"
            string[] itemNames = new string[] { "i" };

            // There are items of type "i" and "j" available in the project, though
            BuildItemGroup group1 = new BuildItemGroup();
            BuildItemGroup group2 = new BuildItemGroup();
            group1.AddNewItem("i", "i1");
            group2.AddNewItem("j", "j1");
            Hashtable items = new Hashtable(StringComparer.OrdinalIgnoreCase);
            items.Add("i", group1);
            items.Add("j", group2);
            Lookup lookup = LookupHelpers.CreateLookup(items);

            ItemBucket bucket = new ItemBucket(itemNames, new Dictionary<string, string>(), lookup, 0);

            // No items of type i
            Assertion.AssertEquals(0, bucket.Lookup.GetItems("i1").Count);
            // Items of type j, however, are visible
            Assertion.AssertEquals(1, bucket.Lookup.GetItems("j").Count);
        }
Example #27
0
        // Gets metadata values from build item @group and adds as ITaskItem
        // objects to @items
        // @only_one: Batched case, all item lists would have same metadata values,
        //	      just return first one
        void BuildItemGroupToITaskItems(BuildItemGroup group, List <ITaskItem> items, bool only_one)
        {
            foreach (BuildItem item in group)
            {
                if (!item.HasMetadata(metadataName))
                {
                    continue;
                }

                string metadata = item.GetMetadata(metadataName);
                if (HasTaskItem(items, metadata))
                {
                    //return only unique metadata values
                    continue;
                }

                items.Add(new TaskItem(metadata));
                if (only_one)
                {
                    break;
                }
            }
        }
Example #28
0
        /// <summary>
        /// Clones the BuildItemGroup.  A shallow clone here is one that references
        /// the same BuildItem objects as the original, whereas a deep clone actually
        /// clones the BuildItem objects as well.  If this is a persisted BuildItemGroup,
        /// only deep clones are allowed, because you can't have the same XML
        /// element belonging to two parents.
        /// </summary>
        public BuildItemGroup Clone(bool deepClone)
        {
            BuildItemGroup clone;

            if (IsPersisted)
            {
                // Only deep clones are permitted when dealing with a persisted <ItemGroup>.
                // This is because a shallow clone would attempt to add the same item
                // elements to two different parent <ItemGroup> elements, and this is
                // not allowed.
                ErrorUtilities.VerifyThrowInvalidOperation(deepClone, "ShallowCloneNotAllowed");

                // Do not set the ParentProject on the cloned BuildItemGroup, because it isn't really
                // part of the project.
                clone           = new BuildItemGroup(xml.OwnerDocument, importedFromAnotherProject, null);
                clone.Condition = Condition;
            }
            else
            {
                clone = new BuildItemGroup();
            }

            // Loop through every BuildItem in our collection, and add those same Items
            // to the cloned collection.

            clone.EnsureCapacity(this.Count); // PERF: important to pre-size

            foreach (BuildItem item in this)
            {
                // If the caller requested a deep clone, then clone the BuildItem object,
                // and add the new BuildItem to the new BuildItemGroup.  Otherwise, just add
                // a reference to the existing BuildItem object to the new BuildItemGroup.
                clone.AddItem(deepClone ? item.Clone() : item);
            }

            return(clone);
        }
        public void CantModifyThroughEnumerator()
        {
            BuildItemGroup ig = new BuildItemGroup();
            BuildItem i1 = new BuildItem("name1", "value1");
            i1.SetMetadata("myMetaName", "myMetaValue");
            ig.AddItem(i1);

            BuildItemGroupProxy proxy = new BuildItemGroupProxy(ig);

            Hashtable list = new Hashtable(StringComparer.OrdinalIgnoreCase);
            foreach (DictionaryEntry item in proxy)
            {
                list.Add(item.Key, item.Value);
            }

            // Change the item
            Assertion.AssertEquals("value1", ((TaskItem)list["name1"]).ItemSpec);
            ((TaskItem)list["name1"]).ItemSpec = "newItemSpec";
            ((TaskItem)list["name1"]).SetMetadata("newMetadata", "newMetadataValue");

            // We did change our copy
            Assertion.AssertEquals("newItemSpec", ((TaskItem)list["name1"]).ItemSpec);
            Assertion.AssertEquals("newMetadataValue", ((TaskItem)list["name1"]).GetMetadata("newMetadata"));
            Assertion.AssertEquals("myMetaValue", ((TaskItem)list["name1"]).GetMetadata("myMetaName"));

            // But get the item again
            list = new Hashtable(StringComparer.OrdinalIgnoreCase);
            foreach (DictionaryEntry item in proxy)
            {
                list.Add(item.Key, item.Value);
            }

            // Item value and metadata hasn't changed
            Assertion.AssertEquals("value1", ((TaskItem)list["name1"]).ItemSpec);
            Assertion.AssertEquals("", ((TaskItem)list["name1"]).GetMetadata("newMetadata"));
            Assertion.AssertEquals("myMetaValue", ((TaskItem)list["name1"]).GetMetadata("myMetaName"));
        }
Example #30
0
        /// <summary>
        /// Extracts the items in the given item vector.
        /// </summary>
        /// <owner>SumedhK</owner>
        /// <param name="itemVector"></param>
        /// <returns>The contents of the item vector (with transforms applied).</returns>
        private BuildItemGroup ItemizeItemVector(Match itemVector)
        {
            ErrorUtilities.VerifyThrow(itemVector.Success, "Need a valid item vector.");

            string itemType  = itemVector.Groups["TYPE"].Value;
            string transform = (itemVector.Groups["TRANSFORM_SPECIFICATION"].Length > 0)
                ? itemVector.Groups["TRANSFORM"].Value
                : null;

            BuildItemGroup items = null;

            if (readOnlyLookup != null)
            {
                items = readOnlyLookup.GetItems(itemType);
            }

            if (items == null)
            {
                items = new BuildItemGroup();
            }
            else
            {
                items = items.Clone(transform != null /* deep clone on transforms because we're actually creating new items */);
            }

            if (transform != null)
            {
                foreach (BuildItem item in items)
                {
                    itemUnderTransformation = item;
                    item.SetFinalItemSpecEscaped(itemMetadataPattern.Replace(transform, new MatchEvaluator(ExpandItemMetadata)));
                }
            }

            return(items);
        }
        private void SetupMembers()
        {
            pg1 = new BuildPropertyGroup();
            pg1.SetProperty("foo", "bar");
            pg1.SetProperty("abc", "true");
            pg1.SetProperty("Unit", "inches");

            pg2 = new BuildPropertyGroup();
            pg2.SetProperty("foo", "bar");
            pg2.SetProperty("abc", "true");

            pg3 = new BuildPropertyGroup();

            // These Choose objects are only suitable for
            // holding a place in the GroupingCollection.
            choose1 = new Choose();
            choose2 = new Choose();
            choose3 = new Choose();

            ig1 = new BuildItemGroup();
            ig1.AddNewItem("x", "x1");
            ig1.AddNewItem("x", "x2");
            ig1.AddNewItem("y", "y1");
            ig1.AddNewItem("y", "y2");
            ig1.AddNewItem("y", "y3");
            ig1.AddNewItem("y", "y4");

            ig2 = new BuildItemGroup();
            ig2.AddNewItem("jacksonfive", "germaine");
            ig2.AddNewItem("jacksonfive", "tito");
            ig2.AddNewItem("jacksonfive", "michael");
            ig2.AddNewItem("jacksonfive", "latoya");
            ig2.AddNewItem("jacksonfive", "janet");

            ig3 = new BuildItemGroup();
        }
Example #32
0
        /// <summary>
        /// Of all the item lists that are referenced in this batchable object, which ones should we
        /// batch on, and which ones should we just pass in wholesale to every invocation of the
        /// target/task?
        ///
        /// Rule #1.  If the user has referenced any *qualified* item metadata such as %(EmbeddedResource.Culture),
        /// then that item list "EmbeddedResource" will definitely get batched.
        ///
        /// Rule #2.  For all the unqualified item metadata such as %(Culture), we make sure that
        /// every single item in every single item list being passed into the task contains a value
        /// for that metadata.  If not, it's an error.  If so, we batch all of those item lists.
        ///
        /// All other item lists will not be batched, and instead will be passed in wholesale to all buckets.
        /// </summary>
        /// <returns>Hashtable containing the item names that should be batched.</returns>
        private static Hashtable GetItemListsToBeBatched
        (
            XmlNode parentNode,
            Dictionary <string, MetadataReference> consumedMetadataReferences, // Key is [string] potentially qualified metadata name
            // Value is [struct MetadataReference]
            Hashtable consumedItemReferenceNames,                              // Key is [string] item name.
            // Value is always String.Empty (unused).
            Lookup lookup
        )
        {
            // The keys in this hashtable are the names of the items that we will batch on.
            // The values are always String.Empty (not used).
            Hashtable itemListsToBeBatched = new Hashtable(StringComparer.OrdinalIgnoreCase);

            // Loop through all the metadata references and find the ones that are qualified
            // with an item name.
            foreach (MetadataReference consumedMetadataReference in consumedMetadataReferences.Values)
            {
                if (consumedMetadataReference.itemName != null)
                {
                    // Rule #1.  Qualified metadata reference.
                    // For metadata references that are qualified with an item name
                    // (e.g., %(EmbeddedResource.Culture) ), we add that item name to the list of
                    // consumed item names, even if the item name wasn't otherwise referenced via
                    // @(...) syntax, and even if every item in the list doesn't necessary contain
                    // a value for this metadata.  This is the special power that you get by qualifying
                    // the metadata reference with an item name.
                    itemListsToBeBatched[consumedMetadataReference.itemName] = String.Empty;

                    // Also add this qualified item to the consumed item references list, because
                    // %(EmbeddedResource.Culture) effectively means that @(EmbeddedResource) is
                    // being consumed, even though we may not see literally "@(EmbeddedResource)"
                    // in the tag anywhere.  Adding it to this list allows us (down below in this
                    // method) to check that every item in this list has a value for each
                    // unqualified metadata reference.
                    consumedItemReferenceNames = Utilities.CreateTableIfNecessary(consumedItemReferenceNames);
                    consumedItemReferenceNames[consumedMetadataReference.itemName] = String.Empty;
                }
            }

            // Loop through all the metadata references and find the ones that are unqualified.
            foreach (MetadataReference consumedMetadataReference in consumedMetadataReferences.Values)
            {
                if (consumedMetadataReference.itemName == null)
                {
                    // Rule #2.  Unqualified metadata reference.
                    // For metadata references that are unqualified, every single consumed item
                    // must contain a value for that metadata.  If any item doesn't, it's an error
                    // to use unqualified metadata.
                    if (consumedItemReferenceNames != null)
                    {
                        foreach (string consumedItemName in consumedItemReferenceNames.Keys)
                        {
                            // Loop through all the items in the item list.
                            BuildItemGroup items = lookup.GetItems(consumedItemName);

                            if (items != null)
                            {
                                // Loop through all the items in the BuildItemGroup.
                                foreach (BuildItem item in items)
                                {
                                    ProjectErrorUtilities.VerifyThrowInvalidProject(
                                        item.HasMetadata(consumedMetadataReference.metadataName),
                                        parentNode, "ItemDoesNotContainValueForUnqualifiedMetadata",
                                        item.Include, consumedItemName, consumedMetadataReference.metadataName);
                                }
                            }

                            // This item list passes the test of having every single item containing
                            // a value for this metadata.  Therefore, add this item list to the batching list.
                            // Also, to save doing lookup.GetItems again, put the items in the table as the value.
                            itemListsToBeBatched[consumedItemName] = items;
                        }
                    }
                }
            }

            return(itemListsToBeBatched);
        }
Example #33
0
        internal BuildItem(XmlElement itemElement, BuildItemGroup parentItemGroup)
        {
            child_items            = new List <BuildItem> ();
            isImported             = parentItemGroup.IsImported;
            unevaluatedMetadata    = CollectionsUtil.CreateCaseInsensitiveHashtable();
            evaluatedMetadata      = CollectionsUtil.CreateCaseInsensitiveHashtable();
            this.parent_item_group = parentItemGroup;

            this.itemElement = itemElement;
            isDynamic        = parentItemGroup.IsDynamic;

            if (IsDynamic)
            {
                if (!string.IsNullOrEmpty(Remove))
                {
                    if (!string.IsNullOrEmpty(Include) || !string.IsNullOrEmpty(Exclude))
                    {
                        throw new InvalidProjectFileException(string.Format("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
                    }
                    if (itemElement.HasChildNodes)
                    {
                        throw new InvalidProjectFileException("Children are not allowed below an item remove element.");
                    }
                }
                if (string.IsNullOrEmpty(Include) && !string.IsNullOrEmpty(Exclude))
                {
                    throw new InvalidProjectFileException(string.Format("The attribute \"Exclude\" in element <{0}> is unrecognized.", Name));
                }
            }
            else
            {
                if (string.IsNullOrEmpty(Include))
                {
                    throw new InvalidProjectFileException(string.Format("The required attribute \"Include\" is missing from element <{0}>.", Name));
                }
                if (!string.IsNullOrEmpty(Remove))
                {
                    throw new InvalidProjectFileException(string.Format("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
                }
            }

            foreach (XmlAttribute attr in itemElement.Attributes)
            {
                if (attr.Name == "Include" || attr.Name == "Exclude" || attr.Name == "Condition")
                {
                    continue;
                }
                if (!IsDynamic)
                {
                    throw new InvalidProjectFileException(string.Format("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));
                }

                switch (attr.Name)
                {
                case "Remove":
                    Remove = attr.Value;
                    break;

                case "KeepDuplicates":
                    KeepDuplicates = bool.Parse(attr.Value);
                    break;

                case "RemoveMetadata":
                    removeMetadata = attr.Value;
                    break;

                case "KeepMetadata":
                    keepMetadata = attr.Value;
                    break;

                default:
                    throw new InvalidProjectFileException(string.Format("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));
                }
            }
        }
Example #34
0
        /// <summary>
        /// Removes items from the group from the table.
        /// Assumes all the items in the group have the same, provided, type.
        /// </summary>
        private void RemoveItemsFromTableWithBackup(Hashtable table, string name, BuildItemGroup group)
        {
            BuildItemGroup existing = (BuildItemGroup)table[name];

            existing?.RemoveItemsWithBackup(group);
        }
Example #35
0
		internal BuildItem (XmlElement itemElement, BuildItemGroup parentItemGroup)
		{
			child_items = new List<BuildItem> ();
			isImported = parentItemGroup.IsImported;
			unevaluatedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
			evaluatedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable ();
			this.parent_item_group = parentItemGroup;
			
			this.itemElement = itemElement;
			isDynamic = parentItemGroup.IsDynamic;

			if (IsDynamic) {
				if (!string.IsNullOrEmpty (Remove)) {
					if (!string.IsNullOrEmpty (Include) || !string.IsNullOrEmpty (Exclude))
						throw new InvalidProjectFileException (string.Format ("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
					if (itemElement.HasChildNodes)
						throw new InvalidProjectFileException ("Children are not allowed below an item remove element.");
				}
				if (string.IsNullOrEmpty (Include) && !string.IsNullOrEmpty (Exclude))
					throw new InvalidProjectFileException (string.Format ("The attribute \"Exclude\" in element <{0}> is unrecognized.", Name));
			} else {
				if (string.IsNullOrEmpty (Include))
					throw new InvalidProjectFileException (string.Format ("The required attribute \"Include\" is missing from element <{0}>.", Name));
				if (!string.IsNullOrEmpty (Remove))
					throw new InvalidProjectFileException (string.Format ("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
			}

			foreach (XmlAttribute attr in itemElement.Attributes) {
				if (attr.Name == "Include" || attr.Name == "Exclude" || attr.Name == "Condition")
					continue;
				if (!IsDynamic)
					throw new InvalidProjectFileException (string.Format ("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));

				switch (attr.Name) {
				case "Remove":
					Remove = attr.Value;
					break;
				case "KeepDuplicates":
					KeepDuplicates = bool.Parse (attr.Value);
					break;
				case "RemoveMetadata":
					removeMetadata = attr.Value;
					break;
				case "KeepMetadata":
					keepMetadata = attr.Value;
					break;
				default:
					throw new InvalidProjectFileException (string.Format ("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));
				}
			}
		}
Example #36
0
		BuildItem (BuildItem parent)
		{
			isImported = parent.isImported;
			name = parent.Name;
			parent_item = parent;
			parent_item.child_items.Add (this);
			parent_item_group = parent.parent_item_group;
			unevaluatedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable (parent.unevaluatedMetadata);
			evaluatedMetadata = CollectionsUtil.CreateCaseInsensitiveHashtable (parent.evaluatedMetadata);
		}
Example #37
0
        public void InvalidUnqualifiedMetadataReference()
        {
            List<string> parameters = new List<string>();
            parameters.Add("@(File)");
            parameters.Add("%(Culture)");

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            BuildItemGroup items = new BuildItemGroup();
            itemsByType["FILE"] = items;

            BuildItem a = items.AddNewItem("File", "a.foo");
            BuildItem b = items.AddNewItem("File", "b.foo");
            a.SetMetadata("Culture", "fr-fr");

            BuildPropertyGroup properties = new BuildPropertyGroup();

            // This is expected to throw because not all items contain a value for metadata "Culture".
            // Only a.foo has a Culture metadata.  b.foo does not.
            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));
        }
Example #38
0
        public void ValidUnqualifiedMetadataReference()
        {
            List<string> parameters = new List<string>();
            parameters.Add("@(File)");
            parameters.Add("%(Culture)");

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            BuildItemGroup items = new BuildItemGroup();
            itemsByType["FILE"] = items;

            BuildItem a = items.AddNewItem("File", "a.foo");
            BuildItem b = items.AddNewItem("File", "b.foo");
            a.SetMetadata("Culture", "fr-fr");
            b.SetMetadata("Culture", "en-en");

            BuildPropertyGroup properties = new BuildPropertyGroup();

            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));
            Assertion.AssertEquals(2, buckets.Count);
        }
Example #39
0
        /// <summary>
        /// Helper method for processing the children of a When. Only parses Choose,
        /// PropertyGroup, and ItemGroup. All other tags result in an error.
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <owner>DavidLe</owner>
        /// <param name="parentNode"></param>
        /// <param name="parentProjectForChildren"></param>
        /// <param name="importedFromAnotherProject"></param>
        /// <param name="options"></param>
        /// <param name="nestingDepth">Number of parent &lt;Choose&gt; elements this is nested inside</param>
        private void ProcessWhenChildren
        (
            XmlElement parentNode,
            Project parentProjectForChildren, bool importedFromAnotherProject,
            int nestingDepth
        )
        {
            // Loop through the child nodes of the <When> element.
            foreach (XmlNode whenChildNode in parentNode)
            {
                switch (whenChildNode.NodeType)
                {
                // Handle XML comments under the <When> node (just ignore them).
                case XmlNodeType.Comment:
                // fall through
                case XmlNodeType.Whitespace:
                    // ignore whitespace
                    break;

                case XmlNodeType.Element:
                {
                    // Make sure this element doesn't have a custom namespace
                    ProjectXmlUtilities.VerifyThrowProjectValidNamespace((XmlElement)whenChildNode);

                    // The only three types of child nodes that a <When> element can contain
                    // are <PropertyGroup>, <ItemGroup> and <Choose>.
                    switch (whenChildNode.Name)
                    {
                    case XMakeElements.itemGroup:
                        BuildItemGroup newItemGroup = new BuildItemGroup((XmlElement)whenChildNode, importedFromAnotherProject, parentProjectForChildren);
                        this.propertyAndItemLists.InsertAtEnd(newItemGroup);
                        break;

                    // Process the <PropertyGroup> element.
                    case XMakeElements.propertyGroup:
                        BuildPropertyGroup newPropertyGroup = new BuildPropertyGroup(parentProjectForChildren, (XmlElement)whenChildNode, importedFromAnotherProject);
                        newPropertyGroup.EnsureNoReservedProperties();
                        this.propertyAndItemLists.InsertAtEnd(newPropertyGroup);
                        break;

                    // Process the <Choose> element.
                    case XMakeElements.choose:
                        Choose newChoose = new Choose(parentProjectForChildren, this.PropertyAndItemLists, (XmlElement)whenChildNode,
                                                      importedFromAnotherProject, nestingDepth);
                        this.propertyAndItemLists.InsertAtEnd(newChoose);
                        break;

                    default:
                    {
                        ProjectXmlUtilities.ThrowProjectInvalidChildElement(whenChildNode);
                        break;
                    }
                    }
                }
                break;

                default:
                {
                    ProjectXmlUtilities.ThrowProjectInvalidChildElement(whenChildNode);
                    break;
                }
                }
            }
        }
Example #40
0
		void CheckBuildItemGroup (BuildItemGroup group, string[] names, string prefix)
		{
			try {
				Assert.AreEqual (group.Count, names.Length / 2, "Number of items in group");
				for (int i = 0; i < group.Count; i++) {
					Assert.AreEqual (names[i * 2], group[i].Name, String.Format ("{0}#{1} : item name", prefix, i));
					Assert.AreEqual (names[(i * 2) + 1], group[i].FinalItemSpec, String.Format ("{0}#{1} : FinalItemSpec", prefix, i));
				}
			} catch (AssertionException) {
				for (int i = 0; i < group.Count; i++) {
					Console.WriteLine ("group[{0}] = {1}", i, group[i].Name);
					Console.WriteLine ("group[{0}] = {1}", i, group[i].FinalItemSpec);
				}
				throw;
			}
		}
Example #41
0
        /// <summary>
        /// Evaluates an item group that's *outside* of a Target.
        /// Metadata is not allowed on conditions, and we against the parent project.
        /// </summary>
        internal void Evaluate
        (
            BuildPropertyGroup existingProperties,
            Hashtable existingItemsByName,
            bool collectItemsIgnoringCondition,
            bool collectItemsRespectingCondition,
            ProcessingPass pass
        )
        {
            ErrorUtilities.VerifyThrow(pass == ProcessingPass.Pass2, "Pass should be Pass2 for ItemGroups.");
            ErrorUtilities.VerifyThrow(collectItemsIgnoringCondition || collectItemsRespectingCondition, "collectItemsIgnoringCondition and collectItemsRespectingCondition can't both be false.");

            Expander expander = new Expander(existingProperties, existingItemsByName, ExpanderOptions.ExpandAll);

            bool itemGroupCondition = Utilities.EvaluateCondition(Condition,
                                                                  (IsPersisted ? xml.ConditionAttribute : null),
                                                                  expander,
                                                                  ParserOptions.AllowPropertiesAndItemLists,
                                                                  parentProject);

            if (!itemGroupCondition && !collectItemsIgnoringCondition)
            {
                // Neither list needs updating
                return;
            }

            foreach (BuildItem currentItem in this)
            {
                bool itemCondition = Utilities.EvaluateCondition(currentItem.Condition,
                                                                 currentItem.ConditionAttribute,
                                                                 expander,
                                                                 ParserOptions.AllowPropertiesAndItemLists,
                                                                 parentProject);

                if (!itemCondition && !collectItemsIgnoringCondition)
                {
                    // Neither list needs updating
                    continue;
                }

                if (collectItemsIgnoringCondition)
                {
                    // Since we're re-evaluating the project, clear out the previous list of child items
                    // for each persisted item tag.
                    currentItem.ChildItems.Clear();
                }

                currentItem.EvaluateAllItemMetadata(expander, ParserOptions.AllowPropertiesAndItemLists, parentProject.ParentEngine.LoggingServices, parentProject.ProjectBuildEventContext);
                BuildItemGroup items = BuildItemGroup.ExpandItemIntoItems(parentProject.ProjectDirectory, currentItem, expander, false /* do not expand metadata */);

                foreach (BuildItem item in items)
                {
                    BuildItem newItem = BuildItem.CreateClonedParentedItem(item, currentItem);

                    if (itemGroupCondition && itemCondition && collectItemsRespectingCondition)
                    {
                        parentProject.AddToItemListByName(newItem);
                    }

                    if (collectItemsIgnoringCondition)
                    {
                        parentProject.AddToItemListByNameIgnoringCondition(newItem);

                        // Set up the other half of the parent/child relationship.
                        newItem.ParentPersistedItem.ChildItems.AddItem(newItem);
                    }
                }
            }
        }
Example #42
0
        ICollection <Dictionary <string, BuildItemGroup> > Bucketize()
        {
            var buckets = new Dictionary <string, Dictionary <string, BuildItemGroup> > (
                StringComparer.InvariantCultureIgnoreCase);

            // For each item list represented in "BatchedItemNames", and then for each item
            // within that list, get the values for that item for each of the metadata in
            // "ConsumedMetadataReferences". In the table of metadata values, "%(MyItem.MyMetadata)"
            // would get a separate entry than "%(MyMetadata)", even though the metadata name is the same.

            foreach (KeyValuePair <string, BuildItemGroup> pair in batchedItemsByName)
            {
                string         itemName = pair.Key;
                BuildItemGroup group    = pair.Value;
                foreach (BuildItem item in group)
                {
                    StringBuilder key_sb = new StringBuilder();
                    string        value  = String.Empty;

                    // build the bucket key, unique set of metadata values
                    foreach (MetadataReference mr in consumedMetadataReferences)
                    {
                        value = String.Empty;
                        if (mr.IsQualified)
                        {
                            if (String.Compare(mr.ItemName, itemName) == 0)
                            {
                                value = item.GetEvaluatedMetadata(mr.MetadataName);
                            }
                        }
                        else
                        {
                            if (item.HasMetadata(mr.MetadataName))
                            {
                                value = item.GetEvaluatedMetadata(mr.MetadataName);
                            }
                        }

                        key_sb.AppendFormat("{0}.{1}:{2},",
                                            mr.IsQualified ? mr.ItemName : "",
                                            mr.MetadataName,
                                            value);
                    }

                    // Every bucket corresponds to a unique _set_ of metadata values
                    // So, every bucket would have itemGroups with same set of metadata
                    // values

                    string bucket_key = key_sb.ToString();
                    Dictionary <string, BuildItemGroup> bucket;
                    if (!buckets.TryGetValue(bucket_key, out bucket))
                    {
                        // new bucket
                        buckets [bucket_key] = bucket = new Dictionary <string, BuildItemGroup> (
                            StringComparer.InvariantCultureIgnoreCase);
                    }

                    string         itemGroup_key = item.Name;
                    BuildItemGroup itemGroup;
                    if (!bucket.TryGetValue(itemGroup_key, out itemGroup))
                    {
                        bucket [itemGroup_key] = itemGroup = new BuildItemGroup();
                    }

                    itemGroup.AddItem(item);
                }
            }

            if (buckets.Values.Count == 0)
            {
                // no buckets
                buckets.Add("none", new Dictionary <string, BuildItemGroup> ());
                AddEmptyGroups(buckets);
                if (buckets ["none"].Values.Count == 0)
                {
                    buckets.Remove("none");
                }
            }
            else
            {
                AddEmptyGroups(buckets);
            }

            return(buckets.Values);
        }
Example #43
0
 internal void Add(BuildItemGroup buildItemGroup)
 {
     buildItemGroup.GroupingCollection = this.groupingCollection;
     groupingCollection.Add(buildItemGroup);
 }
Example #44
0
        public override void Execute()
        {
            if (!(hostContext.Data["EnabledRenderers"] as StringCollection).Contains(this.Identifier))
            {
                return;
            }

            // Get parameters
            Dictionary <String, StringCollection> parameters = hostContext.Data["CommandParameters"] as Dictionary <String, StringCollection>;

            System.Diagnostics.Trace.WriteLine("\r\nStarting RIMBA Renderer", "information");
            StringCollection genFormatters = new StringCollection();
            bool             makeWP7Proj   = false;

            if (hostContext.Mode == Pipeline.OperationModeType.Quirks)
            {
                System.Diagnostics.Trace.WriteLine("--- WARNING ---\r\n Host context is operating in Quirks mode, GPMR cannot guarantee output will be accurate\r\n--- WARNING ---");
            }

            #region Validate all parameters
            // Validate parameters
            if (!parameters.ContainsKey("rimbapi-api-ns"))
            {
                parameters.Add("rimbapi-api-ns", new StringCollection());
                parameters["rimbapi-api-ns"].Add("MARC.Everest");
            }
            if (!parameters.ContainsKey("rimbapi-target-ns"))
            {
                parameters.Add("rimbapi-target-ns", new StringCollection());
                parameters["rimbapi-target-ns"].Add("output");
            }
            if (parameters.ContainsKey("rimbapi-root-class"))
            {
                RootClass = parameters["rimbapi-root-class"][0];
            }
            if (parameters.ContainsKey("rimbapi-gen-vocab"))
            {
                GenerateVocab = Convert.ToBoolean(parameters["rimbapi-gen-vocab"][0]);
            }
            if (parameters.ContainsKey("rimbapi-gen-rim"))
            {
                GenerateRim = Convert.ToBoolean(parameters["rimbapi-gen-rim"][0]);
            }
            if (parameters.ContainsKey("rimbapi-profileid"))
            {
                InteractionRenderer.profileId = parameters["rimbapi-profileid"][0];
            }
            if (parameters.ContainsKey("rimbapi-oid-profileid"))
            {
                InteractionRenderer.profileIdOid = parameters["rimbapi-oid-profileid"][0];
            }
            if (parameters.ContainsKey("rimbapi-oid-interactionid"))
            {
                InteractionRenderer.interactionIdOid = parameters["rimbapi-oid-interactionid"][0];
            }
            if (parameters.ContainsKey("rimbapi-oid-triggerevent"))
            {
                InteractionRenderer.triggerEventOid = parameters["rimbapi-oid-triggerevent"][0];
            }
            if (parameters.ContainsKey("rimbapi-gen-its"))
            {
                genFormatters = parameters["rimbapi-gen-its"];
            }
            if (parameters.ContainsKey("rimbapi-phone"))
            {
                makeWP7Proj = bool.Parse(parameters["rimbapi-phone"][0]);
            }

            #endregion

            // Initialize Heuristics
            MohawkCollege.EHR.gpmr.Pipeline.Renderer.RimbaCS.HeuristicEngine.Datatypes.Initialize(parameters["rimbapi-api-ns"][0]);
            MohawkCollege.EHR.gpmr.Pipeline.Renderer.RimbaCS.HeuristicEngine.Interfaces.Initialize(parameters["rimbapi-api-ns"][0]);

            // Get our repository ready
            ClassRepository classRep = hostContext.Data["SourceCR"] as ClassRepository;

            string ProjectFileName = "output.csproj"; // Set the output file name
            if (parameters.ContainsKey("rimbapi-target-ns"))
            {
                ProjectFileName = parameters["rimbapi-target-ns"][0];
            }
            if (parameters.ContainsKey("rimbapi-partials"))
            {
                RenderPartials = Boolean.Parse(parameters["rimbapi-partials"][0]);
            }
            if (parameters.ContainsKey("rimbapi-realm-pref"))
            {
                prefRealm = parameters["rimbapi-realm-pref"][0];
            }
            if (parameters.ContainsKey("rimbapi-max-literals"))
            {
                MaxLiterals = Int32.Parse(parameters["rimbapi-max-literals"][0]);
            }
            if (parameters.ContainsKey("rimbapi-suppress-doc"))
            {
                SuppressDoc = Boolean.Parse(parameters["rimbapi-suppress-doc"][0]);
            }
            // Setup the template parameters
            string[][] templateFields = new string[][]
            {
                new string[] { "$license$", parameters.ContainsKey("rimbapi-license") ? Licenses.ResourceManager.GetString(parameters["rimbapi-license"][0].ToUpper()) : "" },
                new string[] { "$org$", parameters.ContainsKey("rimbapi-org") ? parameters["rimbapi-org"][0] : "" },
                new string[] { "$date$", DateTime.Now.ToString("yyyy-MM-dd") },
                new string[] { "$clrversion$", Environment.Version.ToString() },
                new string[] { "$time$", DateTime.Now.ToString("HH:mm:ss") },
                new string[] { "$author$", SystemInformation.UserName },
                new string[] { "$year$", DateTime.Now.Year.ToString() },
                new string[] { "$version$", Assembly.GetEntryAssembly().GetName().Version.ToString() },
                new string[] { "$guid$", Guid.NewGuid().ToString() },
                new string[] { "$name$", ProjectFileName },
                new string[] { "$mrversion$", InteractionRenderer.profileId ?? "" }
            };

            // Now we want to scan our assembly for FeatureRenderers
            List <KeyValuePair <FeatureRendererAttribute, IFeatureRenderer> > renderers = new List <KeyValuePair <FeatureRendererAttribute, IFeatureRenderer> >();
            foreach (Type t in this.GetType().Assembly.GetTypes())
            {
                if (t.GetInterface("MohawkCollege.EHR.gpmr.Pipeline.Renderer.RimbaCS.Interfaces.IFeatureRenderer") != null &&
                    t.GetCustomAttributes(typeof(FeatureRendererAttribute), true).Length > 0)
                {
                    foreach (FeatureRendererAttribute feature in (t.GetCustomAttributes(typeof(FeatureRendererAttribute), true)))
                    {
                        // Only one feature renderer per feature, so if the dictionary throws an exception
                        // on the add it is ok
                        renderers.Add(new KeyValuePair <FeatureRendererAttribute, IFeatureRenderer>(feature, (IFeatureRenderer)t.Assembly.CreateInstance(t.FullName)));
                    }
                }
            }

            #region Setup the project
            // Create engine reference
            Microsoft.Build.BuildEngine.Engine engine = new Microsoft.Build.BuildEngine.Engine(
                Path.Combine(Path.Combine(Path.Combine(System.Environment.SystemDirectory, "..\\Microsoft.NET"), "Framework"), "v3.5")),
                                               phoneEngine = new Microsoft.Build.BuildEngine.Engine(
                Path.Combine(Path.Combine(Path.Combine(System.Environment.SystemDirectory, "..\\Microsoft.NET"), "Framework"), "v4.0.30319"));

            // Create MSPROJ
            Microsoft.Build.BuildEngine.Project project   = new Microsoft.Build.BuildEngine.Project(engine),
                                                phoneProj = new Project(phoneEngine, "4.0");


            phoneProj.DefaultTargets = project.DefaultTargets = "Build";


            // Setup project attributes
            Microsoft.Build.BuildEngine.BuildPropertyGroup pg = project.AddNewPropertyGroup(false);

            Microsoft.Build.BuildEngine.BuildProperty property = pg.AddNewProperty("Configuration", "Release");

            property.Condition = "'$(Configuration)' == ''";
            property           = pg.AddNewProperty("Platform", "AnyCPU");
            property.Condition = "'$(Platform)' == ''";
            pg.AddNewProperty("ProductVersion", "10.0.20506");
            pg.AddNewProperty("SchemaVersion", "2.0");
            pg.AddNewProperty("ProjectGuid", Guid.NewGuid().ToString());
            pg.AddNewProperty("OutputType", "Library");
            pg.AddNewProperty("AppDesignerFolder", "Properties");
            pg.AddNewProperty("RootNamespace", parameters["rimbapi-target-ns"][0]);
            pg.AddNewProperty("AssemblyName", parameters["rimbapi-target-ns"][0]);

            // Release AnyCPU
            pg           = project.AddNewPropertyGroup(false);
            pg.Condition = "'$(Configuration)|$(Platform)' == 'Release|AnyCPU'";
            pg.AddNewProperty("DebugType", "pdbonly");
            pg.AddNewProperty("Optimize", "true");
            pg.AddNewProperty("OutputPath", "bin\\release");
            pg.AddNewProperty("DefineConstants", "TRACE");
            pg.AddNewProperty("ErrorReport", "prompt");
            pg.AddNewProperty("WarningLevel", "4");
            pg.AddNewProperty("DocumentationFile", "bin\\release\\" + parameters["rimbapi-target-ns"][0] + ".xml");

            // Create Dir Structure
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "bin"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "lib"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "Properties"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "Vocabulary"));
            Directory.CreateDirectory(Path.Combine(hostContext.Output, "Interaction"));

            // Add reference structure
            Microsoft.Build.BuildEngine.BuildItemGroup refItemGroup = project.AddNewItemGroup();

            // Add References
            File.Copy(Path.Combine(System.Windows.Forms.Application.StartupPath, "MARC.Everest.dll"), Path.Combine(Path.Combine(hostContext.Output, "lib"), "MARC.Everest.dll"), true);

            if (makeWP7Proj)
            {
                File.Copy(Path.Combine(Path.Combine(System.Windows.Forms.Application.StartupPath, "lib"), "MARC.Everest.Phone.dll"), Path.Combine(Path.Combine(hostContext.Output, "lib"), "MARC.Everest.Phone.dll"), true);
            }

            File.Copy(Path.Combine(System.Windows.Forms.Application.StartupPath, "MARC.Everest.xml"), Path.Combine(Path.Combine(hostContext.Output, "lib"), "MARC.Everest.xml"), true);
            refItemGroup.AddNewItem("Reference", "System");
            refItemGroup.AddNewItem("Reference", "System.Drawing");
            refItemGroup.AddNewItem("Reference", "System.Xml");
            Microsoft.Build.BuildEngine.BuildItem buildItem = refItemGroup.AddNewItem("Reference", @"MARC.Everest");
            buildItem.SetMetadata("SpecificVersion", "false");
            buildItem.SetMetadata("HintPath", "lib\\MARC.Everest.dll");

            project.AddNewImport("$(MSBuildBinPath)\\Microsoft.CSharp.targets", null);

            Microsoft.Build.BuildEngine.BuildItemGroup fileItemGroup      = project.AddNewItemGroup(),
                                                       phoneFileItemGroup = phoneProj.AddNewItemGroup();

            #region Assembly Info
            try
            {
                TextWriter tw = File.CreateText(Path.Combine(Path.Combine(hostContext.Output, "Properties"), "AssemblyInfo.cs"));
                try
                {
                    string Header = Template.AssemblyInfo; // Set the header to the default

                    // Populate template fields
                    foreach (String[] st in templateFields)
                    {
                        Header = Header.Replace(st[0], st[1]);
                    }

                    // Write header
                    tw.Write(Header);
                }
                finally
                {
                    tw.Close();
                }
                fileItemGroup.AddNewItem("Compile", Path.Combine("Properties", "AssemblyInfo.cs"));
                phoneFileItemGroup.AddNewItem("Compile", Path.Combine("Properties", "AssemblyInfo.cs"));
            }
            catch (Exception)
            {
                System.Diagnostics.Trace.WriteLine("Couldn't generate the AssemblyInfo.cs file for this project", "warn");
            }
            #endregion
            #endregion

            #region Code Create
            // Convert class rep to list
            List <Feature> features = new List <Feature>();
            foreach (KeyValuePair <String, Feature> kv in classRep)
            {
                features.Add(kv.Value);
            }
            // Sort so classes are processed first
            features.Sort(delegate(Feature a, Feature b)
            {
                if ((a is SubSystem) && !(b is SubSystem))
                {
                    return(-1);
                }
                else if ((b is SubSystem) && !(a is SubSystem))
                {
                    return(1);
                }
                else
                {
                    return(a.GetType().Name.CompareTo(b.GetType().Name));
                }
            });

            RenderFeatureList(features, templateFields, renderers, fileItemGroup, phoneFileItemGroup, parameters);

            // Any added features?
            // HACK: This should be fixed soon, but meh... I'll get around to it
            List <Feature> addlFeatures = new List <Feature>();
            foreach (KeyValuePair <String, Feature> kv in classRep)
            {
                if (!features.Contains(kv.Value))
                {
                    addlFeatures.Add(kv.Value);
                }
            }
            RenderFeatureList(addlFeatures, templateFields, renderers, fileItemGroup, phoneFileItemGroup, parameters);

            // Save the project
            project.Save(Path.Combine(hostContext.Output, ProjectFileName) + ".csproj");
            #endregion

            // Compile?
            #region Compile this project

            // Does the user want to compile?
            if (parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-compile"][0]))
            {
                string logPath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); // Create log
                Microsoft.Build.BuildEngine.FileLogger logger = new Microsoft.Build.BuildEngine.FileLogger();
                logger.Parameters = "logfile=" + logPath;
                engine.RegisterLogger(logger);

                System.Diagnostics.Trace.Write(String.Format("Compiling project (Build log {0})...", logPath), "information");

                // Compile
                if (engine.BuildProject(project))
                {
                    System.Diagnostics.Trace.WriteLine("Success!", "information");
                }
                else
                {
                    System.Diagnostics.Trace.WriteLine("Fail", "information");
                    throw new InvalidOperationException("Failed compilation, operation cannot continue");
                }
                engine.UnregisterAllLoggers();
            }
            #endregion

            #region Windows Phone

            if (makeWP7Proj)
            {
                // Setup project attributes
                pg                 = phoneProj.AddNewPropertyGroup(false);
                property           = pg.AddNewProperty("Configuration", "Release");
                property.Condition = "'$(Configuration)' == ''";
                property           = pg.AddNewProperty("Platform", "AnyCPU");
                property.Condition = "'$(Platform)' == ''";
                pg.AddNewProperty("ProductVersion", "10.0.20506");
                pg.AddNewProperty("SchemaVersion", "2.0");
                pg.AddNewProperty("ProjectGuid", Guid.NewGuid().ToString());
                pg.AddNewProperty("OutputType", "Library");
                pg.AddNewProperty("AppDesignerFolder", "Properties");
                pg.AddNewProperty("RootNamespace", parameters["rimbapi-target-ns"][0]);
                pg.AddNewProperty("AssemblyName", parameters["rimbapi-target-ns"][0] + ".Phone");
                pg.AddNewProperty("ProjectTypeGuids", "{C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}");
                pg.AddNewProperty("TargetFrameworkVersion", "v4.0");
                pg.AddNewProperty("SilverlightVersion", "$(TargetFrameworkVersion)");
                pg.AddNewProperty("TargetFrameworkProfile", "WindowsPhone71");
                pg.AddNewProperty("TargetFrameworkIdentifier", "Silverlight");
                pg.AddNewProperty("SilverlightApplication", "false");
                pg.AddNewProperty("ValidateXaml", "true");
                pg.AddNewProperty("ThrowErrorsInValidation", "true");

                // Release AnyCPU
                pg           = phoneProj.AddNewPropertyGroup(false);
                pg.Condition = "'$(Configuration)|$(Platform)' == 'Release|AnyCPU'";
                pg.AddNewProperty("DebugType", "pdbonly");
                pg.AddNewProperty("Optimize", "true");
                pg.AddNewProperty("OutputPath", "bin\\release");
                pg.AddNewProperty("DefineConstants", "TRACE;SILVERLIGHT;WINDOWS_PHONE");
                pg.AddNewProperty("ErrorReport", "prompt");
                pg.AddNewProperty("NoStdLib", "true");
                pg.AddNewProperty("NoConfig", "true");
                pg.AddNewProperty("WarningLevel", "4");
                pg.AddNewProperty("DocumentationFile", "bin\\release\\" + parameters["rimbapi-target-ns"][0] + ".Phone.xml");

                // Add reference structure
                refItemGroup = phoneProj.AddNewItemGroup();
                refItemGroup.AddNewItem("Reference", "System");
                refItemGroup.AddNewItem("Reference", "System.Xml");

                BuildItem evReference = refItemGroup.AddNewItem("Reference", @"MARC.Everest.Phone");
                evReference.SetMetadata("SpecificVersion", "false");
                evReference.SetMetadata("HintPath", "lib\\MARC.Everest.Phone.dll");

                // Add WP7 Imports
                phoneProj.AddNewImport(@"$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.$(TargetFrameworkProfile).Overrides.targets", null);
                phoneProj.AddNewImport(@"$(MSBuildExtensionsPath)\Microsoft\Silverlight for Phone\$(TargetFrameworkVersion)\Microsoft.Silverlight.CSharp.targets", null);

                // HACK: Add tools version
                string fileName = Path.Combine(hostContext.Output, ProjectFileName) + ".Phone.csproj";
                phoneProj.Save(fileName);
                XmlDocument doc = new XmlDocument();
                doc.Load(fileName);
                doc.DocumentElement.Attributes.Append(doc.CreateAttribute("ToolsVersion"));
                doc.DocumentElement.Attributes["ToolsVersion"].Value = "4.0";
                doc.Save(fileName);

                if (parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-compile"][0]))
                {
                    System.Diagnostics.Trace.Write(String.Format("Compiling phone project..."), "information");

                    // Compile
                    if (phoneEngine.BuildProjectFile(fileName))
                    {
                        System.Diagnostics.Trace.WriteLine("Success!", "information");
                    }
                    else
                    {
                        System.Diagnostics.Trace.WriteLine("Fail", "information");
                        throw new InvalidOperationException("Failed compilation, operation cannot continue");
                    }
                }
            }

            #endregion

            #region Generate Formatter Assemblies

            // Generate the formatter assemblies
            if (genFormatters.Count > 0 && parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-compile"][0]))
            {
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
                Trace.WriteLine("Generating ITS Formatter Types:", "information");

                // Load the assembly
                Assembly genAsm = Assembly.LoadFile(Path.Combine(Path.Combine(Path.Combine(hostContext.Output, "bin"), "release"), ProjectFileName + ".dll"));
                foreach (string s in genFormatters)
                {
                    GenerateFormatterAssembly(s, genAsm, InteractionRenderer.profileId ?? "formatter");
                }

                // Assembly resolve
                AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            }
            else if (genFormatters.Count > 0)
            {
                Trace.WriteLine("Can't use --rimbapi-gen-its when --rimbapi-compile is not true, skipping ITS generation", "warn");
            }
            #endregion

            // Does the user only want asm?
            #region dllonly
            if (parameters.ContainsKey("rimbapi-dllonly") && parameters.ContainsKey("rimbapi-compile") && Convert.ToBoolean(parameters["rimbapi-dllonly"][0]))
            {
                try
                {
                    // Move the assemblies up to root
                    foreach (string file in Directory.GetFiles(Path.Combine(Path.Combine(hostContext.Output, "bin"), "release")))
                    {
                        if (File.Exists(Path.Combine(hostContext.Output, Path.GetFileName(file))))
                        {
                            File.Delete(Path.Combine(hostContext.Output, Path.GetFileName(file)));
                        }
                        File.Move(file, Path.Combine(hostContext.Output, Path.GetFileName(file)));
                    }

                    // Clean all in the projects and remove all directories
                    List <String> directories = new List <string>(new string[] {
                        Path.Combine(Path.Combine(hostContext.Output, "bin"), "release"),
                        Path.Combine(hostContext.Output, "bin"),
                        Path.Combine(hostContext.Output, "lib"),
                        Path.Combine(hostContext.Output, "Vocabulary"),
                        Path.Combine(hostContext.Output, "Interaction"),
                        Path.Combine(hostContext.Output, "obj")
                    });

                    // Gather files and clean
                    foreach (Microsoft.Build.BuildEngine.BuildItem fi in fileItemGroup)
                    {
                        // Add directory on the "to be deleted"
                        string dirName = Path.GetDirectoryName(Path.Combine(hostContext.Output, fi.Include));
                        if (!directories.Contains(dirName))
                        {
                            directories.Add(dirName);
                        }

                        Trace.WriteLine(String.Format("Deleting {0}...", fi.Include), "debug");
                        File.Delete(Path.Combine(hostContext.Output, fi.Include));
                    }
                    // Clean dirs
                    foreach (string s in directories)
                    {
                        Directory.Delete(s, true);
                    }
                    File.Delete(project.FullFileName);
                }
                catch (Exception)
                {
                    System.Diagnostics.Trace.WriteLine("Could not clean working files!", "warn");
                }
            }
            #endregion
        }
Example #45
0
        public void Regress_Mutation_DuplicateBatchingBucketsAreFoldedTogether()
        {
            List<string> parameters = new List<string>();
            parameters.Add("%(File.Culture)");

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);
            
            BuildItemGroup items = new BuildItemGroup();
            items.AddNewItem("File", "a.foo");
            items.AddNewItem("File", "b.foo"); // Need at least two items for this test case to ensure multiple buckets might be possible
            itemsByType["FILE"] = items;

            BuildPropertyGroup properties = new BuildPropertyGroup();

            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));

            // If duplicate buckes have been folded correctly, then there will be exactly one bucket here
            // containing both a.foo and b.foo.
            Assertion.AssertEquals(1, buckets.Count);
        }
Example #46
0
		void AddEvaluatedItem (Project project, bool evaluatedTo, ITaskItem taskitem)
		{
			if (IsDynamic && evaluatedTo && !KeepDuplicates && ContainsItem (project, taskitem))
				return;

			BuildItemGroup big;			
			BuildItem bi = new BuildItem (this);
			bi.finalItemSpec = taskitem.ItemSpec;

			foreach (DictionaryEntry de in taskitem.CloneCustomMetadata ()) {
				bi.unevaluatedMetadata.Add ((string) de.Key, (string) de.Value);
				bi.evaluatedMetadata.Add ((string) de.Key, (string) de.Value);
			}

			project.EvaluatedItemsIgnoringCondition.AddItem (bi);

			if (evaluatedTo) {
				project.EvaluatedItems.AddItem (bi);
	
				if (!project.EvaluatedItemsByName.ContainsKey (bi.Name)) {
					big = new BuildItemGroup (null, project, null, true);
					project.EvaluatedItemsByName.Add (bi.Name, big);
				} else {
					big = project.EvaluatedItemsByName [bi.Name];
				}

				big.AddItem (bi);
			}

			if (!project.EvaluatedItemsByNameIgnoringCondition.ContainsKey (bi.Name)) {
				big = new BuildItemGroup (null, project, null, true);
				project.EvaluatedItemsByNameIgnoringCondition.Add (bi.Name, big);
			} else {
				big = project.EvaluatedItemsByNameIgnoringCondition [bi.Name];
			}

			big.AddItem (bi);

			if (IsDynamic)
				AddAndRemoveMetadata (project, bi);
		}
Example #47
0
        public void GetBuckets()
        {
            List<string> parameters = new List<string>();
            parameters.Add("@(File);$(unittests)");
            parameters.Add("$(obj)\\%(Filename).ext");
            parameters.Add("@(File->'%(extension)')");  // attributes in transforms don't affect batching

            Hashtable itemsByType = new Hashtable(StringComparer.OrdinalIgnoreCase);

            BuildItemGroup items = new BuildItemGroup();
            items.AddNewItem("File", "a.foo");
            items.AddNewItem("File", "b.foo");
            items.AddNewItem("File", "c.foo");
            items.AddNewItem("File", "d.foo");
            items.AddNewItem("File", "e.foo");
            itemsByType["FILE"] = items;

            items = new BuildItemGroup();
            items.AddNewItem("Doc", "a.doc");
            items.AddNewItem("Doc", "b.doc");
            items.AddNewItem("Doc", "c.doc");
            items.AddNewItem("Doc", "d.doc");
            items.AddNewItem("Doc", "e.doc");
            itemsByType["DOC"] = items;

            BuildPropertyGroup properties = new BuildPropertyGroup();
            properties.SetProperty("UnitTests", "unittests.foo");
            properties.SetProperty("OBJ", "obj");

            ArrayList buckets = BatchingEngine.PrepareBatchingBuckets(new XmlDocument().CreateElement("Foo"), parameters, CreateLookup(itemsByType, properties));

            Assertion.AssertEquals(5, buckets.Count);

            foreach (ItemBucket bucket in buckets)
            {
                // non-batching data -- same for all buckets
                XmlAttribute tempXmlAttribute = (new XmlDocument()).CreateAttribute("attrib");
                tempXmlAttribute.Value = "'$(Obj)'=='obj'";

                Assertion.Assert(BuildEngine.Utilities.EvaluateCondition(tempXmlAttribute.Value,
                    tempXmlAttribute, bucket.Expander, null, ParserOptions.AllowAll, null, null));
                Assertion.AssertEquals("a.doc;b.doc;c.doc;d.doc;e.doc", ExpandItemsIntoString(bucket, "@(doc)"));
                Assertion.AssertEquals("unittests.foo", ExpandMetadataAndProperties(bucket, "$(bogus)$(UNITTESTS)"));
            }

            Assertion.AssertEquals("a.foo", ExpandItemsIntoString((ItemBucket)buckets[0], "@(File)"));
            Assertion.AssertEquals(".foo", ExpandItemsIntoString((ItemBucket)buckets[0], "@(File->'%(Extension)')"));
            Assertion.AssertEquals("obj\\a.ext", ExpandMetadataAndProperties((ItemBucket)buckets[0], "$(obj)\\%(Filename).ext"));

            // we weren't batching on this attribute, so it has no value
            Assertion.AssertEquals(String.Empty, ExpandMetadataAndProperties((ItemBucket)buckets[0], "%(Extension)"));

            items = ((ItemBucket)buckets[0]).Expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped("@(file)", null);
            Assertion.AssertNotNull(items);
            Assertion.AssertEquals(1, items.Count);

            int invalidProjectFileExceptions = 0;
            try
            {
                // This should throw because we don't allow item lists to be concatenated
                // with other strings.
                items = ((ItemBucket)buckets[0]).Expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped("@(file);$(unitests)", null);
            }
            catch (InvalidProjectFileException)
            {
                invalidProjectFileExceptions++;
            }

            // We do allow separators in item vectors, this results in an item group with a single flattened item
            items = ((ItemBucket)buckets[0]).Expander.ExpandSingleItemListExpressionIntoItemsLeaveEscaped("@(file, ',')", null);
            Assertion.AssertNotNull(items);
            Assertion.AssertEquals(1, items.Count);
            Assertion.AssertEquals("a.foo", items[0].FinalItemSpec);

            Assertion.AssertEquals(1, invalidProjectFileExceptions);
        }
Example #48
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="itemGroup">Item group this class should proxy</param>
 public BuildItemGroupProxy(BuildItemGroup itemGroup)
 {
     this.backingItemGroup = itemGroup;
 }
Example #49
0
        /// <summary>
        /// Applies a list of modifications to the appropriate BuildItemGroup in a main table.
        /// If any modifications conflict, these modifications win.
        /// </summary>
        private void ApplyModificationsToTable(Hashtable table, string name, Dictionary <BuildItem, Dictionary <string, string> > modify)
        {
            BuildItemGroup existing = (BuildItemGroup)table[name];

            existing?.ModifyItemsUsingVirtualMetadata(modify);
        }
        /// <summary>
        /// Determines if the target needs to be built/rebuilt/skipped if its inputs and outputs can be correlated.
        /// </summary>
        /// <owner>SumedhK</owner>
        /// <param name="itemVectorsInTargetInputs"></param>
        /// <param name="itemVectorsInTargetOutputs"></param>
        /// <param name="itemVectorsReferencedInBothTargetInputsAndOutputs"></param>
        /// <param name="changedTargetInputs"></param>
        /// <param name="upToDateTargetInputs"></param>
        /// <returns>Indication of how to build the target.</returns>
        private DependencyAnalysisResult PerformDependencyAnalysisIfCorrelatedInputsOutputs
        (
            Hashtable itemVectorsInTargetInputs,
            Hashtable itemVectorsInTargetOutputs,
            ArrayList itemVectorsReferencedInBothTargetInputsAndOutputs,
            out Hashtable changedTargetInputs,
            out Hashtable upToDateTargetInputs
        )
        {
            DependencyAnalysisResult result = DependencyAnalysisResult.SkipUpToDate;

            changedTargetInputs = new Hashtable(StringComparer.OrdinalIgnoreCase);
            upToDateTargetInputs = new Hashtable(StringComparer.OrdinalIgnoreCase);

            // indicates if an incremental build is really just a full build, because all input items have changed
            int numberOfInputItemVectorsWithAllChangedItems = 0;

            foreach (string itemVectorType in itemVectorsReferencedInBothTargetInputsAndOutputs)
            {
                Hashtable inputItemVectors = (Hashtable)itemVectorsInTargetInputs[itemVectorType];
                Hashtable outputItemVectors = (Hashtable)itemVectorsInTargetOutputs[itemVectorType];

                // NOTE: recall that transforms have been separated out already
                ErrorUtilities.VerifyThrow(inputItemVectors.Count == 1,
                    "There should only be one item vector of a particular type in the target inputs that can be filtered.");

                // NOTE: this loop only makes one iteration
                foreach (BuildItemGroup inputItems in inputItemVectors.Values)
                {
                    if (inputItems.Count > 0)
                    {
                        BuildItemGroup changedInputItems = new BuildItemGroup();
                        BuildItemGroup upToDateInputItems = new BuildItemGroup();

                        BuildItem[] inputItemsAssumedToBeUpToDate = inputItems.ToArray();

                        foreach (DictionaryEntry outputEntry in outputItemVectors)
                        {
                            BuildItemGroup outputItems = (BuildItemGroup)outputEntry.Value;
                            // Get the metadata name so if it is missing we can print out a nice error message.
                            string outputItemExpression = (string)outputEntry.Key;

                            ErrorUtilities.VerifyThrow(inputItems.Count == outputItems.Count,
                                "An item vector of a particular type must always contain the same number of items.");

                            for (int i = 0; i < inputItemsAssumedToBeUpToDate.Length; i++)
                            {

                                // if we haven't already determined that this input item has changed
                                if (inputItemsAssumedToBeUpToDate[i] != null)
                                {
                                    // Check to see if the outputItem specification is null or empty, if that is the case we need to error out saying that some metadata
                                    // on one of the items used in the target output is missing.
                                    bool outputEscapedValueIsNullOrEmpty = String.IsNullOrEmpty(outputItems[i].FinalItemSpecEscaped);
                                    ProjectErrorUtilities.VerifyThrowInvalidProject(!outputEscapedValueIsNullOrEmpty,
                                                                                    this.TargetToAnalyze.TargetElement,
                                                                                    "TargetOutputsSpecifiedAreMissing",
                                                                                    inputItemsAssumedToBeUpToDate[i].FinalItemSpecEscaped,
                                                                                    outputItems[i].Name,
                                                                                    outputItemExpression,
                                                                                    TargetToAnalyze.Name);

                                    // check if it has changed
                                    bool outOfDate = IsOutOfDate(inputItemsAssumedToBeUpToDate[i].FinalItemSpecEscaped, outputItems[i].FinalItemSpecEscaped, inputItemsAssumedToBeUpToDate[i].Name, outputItems[i].Name);
                                    if (outOfDate)
                                    {
                                        changedInputItems.AddItem(inputItemsAssumedToBeUpToDate[i]);
                                        inputItemsAssumedToBeUpToDate[i] = null;

                                        result = DependencyAnalysisResult.IncrementalBuild;
                                    }
                                }
                            }

                            if (changedInputItems.Count == inputItems.Count)
                            {
                                numberOfInputItemVectorsWithAllChangedItems++;
                                break;
                            }
                        }

                        if (changedInputItems.Count < inputItems.Count)
                        {
                            foreach (BuildItem item in inputItemsAssumedToBeUpToDate)
                            {
                                if (item != null)
                                {
                                    upToDateInputItems.AddItem(item);
                                }
                            }
                        }

                        changedTargetInputs[itemVectorType] = changedInputItems;
                        upToDateTargetInputs[itemVectorType] = upToDateInputItems;
                    }
                }
            }

            ErrorUtilities.VerifyThrow(numberOfInputItemVectorsWithAllChangedItems <= itemVectorsReferencedInBothTargetInputsAndOutputs.Count,
                "The number of vectors containing all changed items cannot exceed the number of correlated vectors.");

            // if all correlated input items have changed
            if (numberOfInputItemVectorsWithAllChangedItems == itemVectorsReferencedInBothTargetInputsAndOutputs.Count)
            {
                ErrorUtilities.VerifyThrow(result == DependencyAnalysisResult.IncrementalBuild,
                    "If inputs have changed, this must be an incremental build.");

                // then the incremental build is really a full build
                result = DependencyAnalysisResult.FullBuild;
            }

            return result;
        }
Example #51
0
        /// <summary>
        /// Gets the items of the specified type that are visible in the current scope.
        /// If no match is found, returns null.
        /// Caller must not modify the group returned.
        /// </summary>
        internal BuildItemGroup GetItems(string name)
        {
            // The visible items consist of the adds (accumulated as we go down)
            // plus the first set of regular items we encounter
            // minus any removes
            BuildItemGroup allAdds    = null;
            BuildItemGroup allRemoves = null;
            Dictionary <BuildItem, Dictionary <string, string> > allModifies = null;
            BuildItemGroup groupFound = null;

            foreach (LookupEntry entry in lookupEntries)
            {
                // Accumulate adds while we look downwards
                if (entry.Adds != null)
                {
                    BuildItemGroup adds = (BuildItemGroup)entry.Adds[name];
                    if (adds != null)
                    {
                        allAdds = CreateItemGroupIfNecessary(allAdds);
                        allAdds.ImportItems(adds);
                    }
                }

                // Accumulate removes while we look downwards
                if (entry.Removes != null)
                {
                    BuildItemGroup removes = (BuildItemGroup)entry.Removes[name];
                    if (removes != null)
                    {
                        allRemoves = CreateItemGroupIfNecessary(allRemoves);
                        allRemoves.ImportItems(removes);
                    }
                }

                // Accumulate modifications as we look downwards
                if (entry.Modifies != null)
                {
                    Dictionary <BuildItem, Dictionary <string, string> > modifies;
                    if (entry.Modifies.TryGetValue(name, out modifies))
                    {
                        if (allModifies == null)
                        {
                            allModifies = new Dictionary <BuildItem, Dictionary <string, string> >();
                        }

                        // We already have some modifies for this type
                        foreach (KeyValuePair <BuildItem, Dictionary <string, string> > modify in modifies)
                        {
                            // If earlier scopes modify the same metadata on the same item,
                            // they have priority
                            MergeModificationsIntoModificationTable(allModifies, modify, ModifyMergeType.FirstWins);
                        }
                    }
                }

                if (entry.Items != null)
                {
                    groupFound = (BuildItemGroup)entry.Items[name];
                    if (groupFound != null)
                    {
                        // Found a group: we go no further
                        break;
                    }
                }

                if (entry.TruncateLookupsAtThisScope)
                {
                    break;
                }
            }

            if ((allAdds == null || allAdds.Count == 0) &&
                (allRemoves == null || allRemoves.Count == 0) &&
                (allModifies == null || allModifies.Count == 0))
            {
                // We can just hand out this group verbatim -
                // that avoids any importing
                if (groupFound == null)
                {
                    groupFound = new BuildItemGroup();
                }

                return(groupFound);
            }

            // We have adds and/or removes and/or modifies to incorporate.
            // We can't modify the group, because that might
            // be visible to other batches; we have to create
            // a new one.
            BuildItemGroup result = new BuildItemGroup();

            if (groupFound != null)
            {
                result.ImportItems(groupFound);
            }
            // Removes are processed after adds; this means when we remove there's no need to concern ourselves
            // with the case where the item being removed is in an add table somewhere. The converse case is not possible
            // using a project file: a project file cannot create an item that was already removed, it can only create
            // a unique new item.
            if (allAdds != null)
            {
                result.ImportItems(allAdds);
            }

            if (allRemoves != null)
            {
                result.RemoveItems(allRemoves);
            }

            // Modifies can be processed last; if a modified item was removed, the modify will be ignored
            if (allModifies != null)
            {
                ApplyModifies(result, allModifies);
            }

            return(result);
        }