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; }
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"); }
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); }
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"); }
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); }
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"); }
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"); }
/// <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; } } }
/// <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); } } } }
/// <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; }
/// <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"); }
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); }
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); }
// 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; } } }
/// <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")); }
/// <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(); }
/// <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); }
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)); } } }
/// <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); }
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)); } } }
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); }
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)); }
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); }
/// <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 <Choose> 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; } } } }
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; } }
/// <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); } } } }
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); }
internal void Add(BuildItemGroup buildItemGroup) { buildItemGroup.GroupingCollection = this.groupingCollection; groupingCollection.Add(buildItemGroup); }
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 }
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); }
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); }
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); }
/// <summary> /// Constructor /// </summary> /// <param name="itemGroup">Item group this class should proxy</param> public BuildItemGroupProxy(BuildItemGroup itemGroup) { this.backingItemGroup = itemGroup; }
/// <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; }
/// <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); }