Example #1
0
        public void ExpandAllIntoStringLeaveEscapedComplex()
        {
            ReadOnlyLookup lookup;
            Dictionary<string, string> itemMetadata;
            CreateComplexPropertiesItemsMetadata(out lookup, out itemMetadata);

            Expander expander = new Expander(lookup, itemMetadata);

            XmlAttribute xmlattribute = (new XmlDocument()).CreateAttribute("dummy");
            xmlattribute.Value = "@(Resource->'%(Filename)') ; @(Content) ; @(NonExistent) ; $(NonExistent) ; %(NonExistent) ; " +
                "$(OutputPath) ; $(TargetPath) ; %(Language)_%(Culture)";

            Assertion.AssertEquals(
                @"string$(p);dialogs%253b ; splash.bmp ;  ;  ;  ; \jk ; l\mno%253bpqr\stu ; subdir1\;subdir2\ ; english_abc%253bdef;ghi",
                expander.ExpandAllIntoStringLeaveEscaped(xmlattribute.Value, xmlattribute));

            Assertion.AssertEquals(
                @"string$(p);dialogs%253b ; splash.bmp ;  ;  ;  ; \jk ; l\mno%253bpqr\stu ; subdir1\;subdir2\ ; english_abc%253bdef;ghi",
                expander.ExpandAllIntoStringLeaveEscaped(xmlattribute));
        }
Example #2
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates 
            /// this specific item definition child element and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definition is incorrectly defined</exception>
            private void EvaluateItemDefinitionChildElement(XmlElement itemDefinitionChildElement, BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(itemDefinitionChildElement);
                ProjectErrorUtilities.VerifyThrowInvalidProject(!FileUtilities.IsItemSpecModifier(itemDefinitionChildElement.Name), itemDefinitionChildElement, "ItemSpecModifierCannotBeCustomMetadata", itemDefinitionChildElement.Name);
                ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[itemDefinitionChildElement.Name] == null, itemDefinitionChildElement, "CannotModifyReservedItemMetadata", itemDefinitionChildElement.Name);

                XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(itemDefinitionChildElement, /* sole attribute */ true);
                string condition = ProjectXmlUtilities.GetAttributeValue(conditionAttribute);

                MetadataDictionary metadataDictionary = null;
                string itemType = itemDefinitionChildElement.ParentNode.Name;
                itemDefinitionsDictionary.TryGetValue(itemType, out metadataDictionary);

                Expander expander = new Expander(properties, itemType, metadataDictionary);

                if (!Utilities.EvaluateCondition(condition, conditionAttribute, expander, ParserOptions.AllowPropertiesAndItemMetadata, parentProject))
                {
                    return;
                }

                string unevaluatedMetadataValue = Utilities.GetXmlNodeInnerContents(itemDefinitionChildElement);

                bool containsItemVector = ItemExpander.ExpressionContainsItemVector(unevaluatedMetadataValue);

                // We don't allow expressions like @(foo) in the value, as no items exist at this point.
                ProjectErrorUtilities.VerifyThrowInvalidProject(!containsItemVector, itemDefinitionChildElement, "MetadataDefinitionCannotContainItemVectorExpression", unevaluatedMetadataValue, itemDefinitionChildElement.Name);

                string evaluatedMetadataValue = expander.ExpandAllIntoStringLeaveEscaped(unevaluatedMetadataValue, itemDefinitionChildElement);

                if (metadataDictionary == null)
                {
                    metadataDictionary = new MetadataDictionary(StringComparer.OrdinalIgnoreCase);
                    itemDefinitionsDictionary.Add(itemType, metadataDictionary);
                }

                // We only store the evaluated value; build items store the unevaluated value as well, but apparently only to 
                // gather recursive portions (its re-evaluation always goes back to the XML).
                // Overwrite any existing default value for this particular metadata
                metadataDictionary[itemDefinitionChildElement.Name] = evaluatedMetadataValue;
            }
Example #3
0
        /// <summary>
        /// Determines if the new item spec that the user is trying to add to the project
        /// already matches an existing wildcarded item declared in the project.  We only
        /// consider it a "match" in very specific circumstances... if there's anything
        /// weird or not-mainline about the new item spec or the existing item, we fail
        /// the match in order to "play it safe".
        /// </summary>
        internal bool NewItemSpecMatchesExistingWildcard(string newItemSpec)
        {
            Project parentProject = GetParentProject();
            ErrorUtilities.VerifyThrow(parentProject != null, "This method should only get called on persisted items.");
            BuildPropertyGroup evaluatedProperties = parentProject.evaluatedProperties;

            if (
                    // The original item spec should have had at least one "*" or "?" in it.
                    FileMatcher.HasWildcards(this.Include) &&

                    // The original item should not have a Condition.
                    (this.Condition.Length == 0) &&

                    // The original item should not have an Exclude.
                    (this.Exclude.Length == 0) &&

                    // The new item spec should NOT have any wildcards.
                    !FileMatcher.HasWildcards(newItemSpec)
                )
            {
                Expander propertyExpander = new Expander(evaluatedProperties);
                string newItemSpecExpandedEscaped = propertyExpander.ExpandAllIntoStringLeaveEscaped(newItemSpec, null);
                // New item spec should not have any unescaped semicolons ... this can really mess us up.
                if (-1 == newItemSpecExpandedEscaped.IndexOf(';'))
                {
                    // Expand any properties in the new item spec that the user gave us.
                    string newItemSpecExpandedUnescaped = EscapingUtilities.UnescapeAll(newItemSpecExpandedEscaped);

                    // Loop over each piece separated by semicolons.
                    List<string> itemIncludePieces = propertyExpander.ExpandAllIntoStringListLeaveEscaped(this.Include, this.IncludeAttribute);
                    foreach (string itemIncludePiece in itemIncludePieces)
                    {
                        bool containsEscapedWildcards = EscapingUtilities.ContainsEscapedWildcards(itemIncludePiece);
                        bool containsRealWildcards = FileMatcher.HasWildcards(itemIncludePiece);

                        // If this is the piece that has the wildcards ...
                        if (containsRealWildcards && !containsEscapedWildcards)
                        {
                            string itemIncludePieceContainingWildcardUnescaped = EscapingUtilities.UnescapeAll(itemIncludePiece);

                            FileMatcher.Result match = FileMatcher.FileMatch(itemIncludePieceContainingWildcardUnescaped, newItemSpecExpandedUnescaped);

                            if (match.isLegalFileSpec && match.isMatch)
                            {
                                // The wildcard in the original item spec will match the new item that
                                // user is trying to add.
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }
Example #4
0
        public void PropertyFunctionConstructor1()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("ver1", @"1.2.3.4");


            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped(@"$([System.Version]::new($(ver1)))", null);

            Version v = new Version(result);

            Assertion.AssertEquals(1, v.Major);
            Assertion.AssertEquals(2, v.Minor);
            Assertion.AssertEquals(3, v.Build);
            Assertion.AssertEquals(4, v.Revision);
        }
Example #5
0
        public void PropertyFunctionStaticMethodMakeRelative()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("ParentPath", @"c:\abc\def");
            pg.SetProperty("FilePath", @"c:\abc\def\foo.cpp");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped(@"$([MSBuild]::MakeRelative($(ParentPath), `$(FilePath)`))", null);

            Assertion.AssertEquals(@"foo.cpp", result);
        }
Example #6
0
        public void PropertyFunctionInvalid7()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("[$(SomeStuff.Substring(-10))]", null);
        }
Example #7
0
        public void PropertyFunctionInvalidNoMetadataFunctions()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("[%(LowerLetterList.Identity.ToUpper())]", null);

            Assertion.AssertEquals("[%(LowerLetterList.Identity.ToUpper())]", result);
        }
Example #8
0
        public void PropertyFunctionPropertyManualGet()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(SomeStuff.get_Length())", null);

            Assertion.AssertEquals("18", result);
        }
Example #9
0
        public void PropertyFunctionPropertyNoArgumentsConcat()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(SomeStuff.ToLower())_goop", null);

            Assertion.AssertEquals("this is some stuff_goop", result);
        }
Example #10
0
        public void PropertyFunctionNoArguments()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(SomeStuff.ToUpper())", null);

            Assertion.AssertEquals("THIS IS SOME STUFF", result);
        }
Example #11
0
        public void PropertyFunctionNoArgumentsTrim()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("FileName", "    foobar.baz   ");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(FileName.Trim())", null);

            Assertion.AssertEquals("foobar.baz", result);
        }
Example #12
0
        public void PropertyFunctionNullReturn()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$([System.Convert]::ChangeType(,$(SomeStuff.GetType())))", null);

            Assertion.AssertEquals("", result);
        }
Example #13
0
        public void PropertyFunctionNullArgument()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$([System.Convert]::ChangeType('null',$(SomeStuff.GetType())))", null);

            Assertion.AssertEquals("null", result);
        }
Example #14
0
        public void ExpandAllIntoStringExpectIdenticalReference()
        {
            ReadOnlyLookup lookup;
            Dictionary<string, string> itemMetadata;
            CreateComplexPropertiesItemsMetadata(out lookup, out itemMetadata);

            Expander expander = new Expander(lookup, itemMetadata);

            XmlAttribute xmlattribute = (new XmlDocument()).CreateAttribute("dummy");

            // Create a *non-literal* string. If we used a literal string, the CLR might (would) intern
            // it, which would mean that Expander would inevitably return a reference to the same string.
            // In real builds, the strings will never be literals, and we want to test the behavior in
            // that situation. 
            xmlattribute.Value = "abc123" + new Random().Next();
            string expandedString = expander.ExpandAllIntoStringLeaveEscaped(xmlattribute.Value, xmlattribute);

            // Verify neither string got interned, so that this test is meaningful
            Assertion.Assert(null == string.IsInterned(xmlattribute.Value));
            Assertion.Assert(null == string.IsInterned(expandedString));
            
            // Finally verify Expander indeed didn't create a new string.
            Assertion.Assert(Object.ReferenceEquals(xmlattribute.Value, expandedString));
        }
Example #15
0
        public void PropertyFunctionInvalid3()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("Value", "3");
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(SomeStuff.ToUpper().Foo)", null);
        }
Example #16
0
        public void PropertyFunctionPropertyPathRootSubtraction()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("RootPath", @"c:\this\is\the\root");
            pg.SetProperty("MyPath", @"c:\this\is\the\root\my\project\is\here.proj");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(MyPath.SubString($(RootPath.Length)))", null);

            Assertion.AssertEquals(@"\my\project\is\here.proj", result);
        }
Example #17
0
        public void PropertyFunctionInvalid4()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("Value", "3");
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("[$(SomeStuff($(System.DateTime.Now)))]", null);
        }
Example #18
0
        public void PropertyFunctionPropertyWithArgumentExpandedProperty()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("Value", "3");
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(SomeStuff.SubString(1$(Value)))", null);

            Assertion.AssertEquals("STUff", result);
        }
Example #19
0
        public void PropertyFunctionInvalid8()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(([System.DateTime]::Now).ToString(\"MM.dd.yyyy\"))", null);
        }
Example #20
0
        public void PropertyFunctionPropertyWithArgumentBooleanReturn()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("PathRoot", @"c:\goo");
            pg.SetProperty("PathRoot2", @"c:\goop\");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped(@"$(PathRoot2.Endswith(\))", null);
            Assertion.AssertEquals("True", result);
            result = expander.ExpandAllIntoStringLeaveEscaped(@"$(PathRoot.Endswith(\))", null);
            Assertion.AssertEquals("False", result);
        }
Example #21
0
        public void PropertyFunctionNoCollisionsOnType()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("System", "The System Namespace");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(System)", null);

            Assertion.AssertEquals("The System Namespace", result);
        }
Example #22
0
        public void PropertyFunctionPropertyWithArgumentChained()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("Value", "3");
            pg.SetProperty("SomeStuff", "This IS SOME STUff");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(SomeStuff.ToUpper().ToLower())", null);
            Assertion.AssertEquals("this is some stuff", result);
        }
Example #23
0
        public void PropertyFunctionConstructor2()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("ver1", @"1.2.3.4");
            pg.SetProperty("ver2", @"2.2.3.4");

            Expander expander = new Expander(pg);
            string result = expander.ExpandAllIntoStringLeaveEscaped(@"$([System.Version]::new($(ver1)).CompareTo($([System.Version]::new($(ver2)))))", null);

            Assertion.AssertEquals(@"-1", result);
        }
Example #24
0
        public void PropertyFunctionPropertyWithArgumentNested()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("Value", "12345");
            pg.SetProperty("SomeStuff", "1234567890");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(SomeStuff.SubString($(Value.get_Length())))", null);

            Assertion.AssertEquals("67890", result);
        }
Example #25
0
        /// <summary>
        /// Sets the project's default targets from the given list of semi-colon-separated target names after expanding all
        /// embedded properties in the list.
        /// </summary>
        /// <owner>SumedhK</owner>
        /// <param name="defaultTargetsList"></param>
        /// <param name="propertyBag"></param>
        private void SetDefaultTargets(string defaultTargetsList, BuildPropertyGroup propertyBag)
        {
            Expander propertyExpander = new Expander(propertyBag);

            this.defaultTargetNames = propertyExpander.ExpandAllIntoStringListLeaveEscaped(defaultTargetsList, null).ToArray();

            BuildProperty defaultTargetsProperty = new BuildProperty(ReservedPropertyNames.projectDefaultTargets,
                                                           propertyExpander.ExpandAllIntoStringLeaveEscaped(defaultTargetsList, null),
                                                           PropertyType.ReservedProperty);

            this.ReservedProperties.SetProperty(defaultTargetsProperty);

            // we also need to push this property directly into the evaluatedProperties bucket
            // since this property was computed "late", i.e. after the initial evaluation.
            this.evaluatedProperties.SetProperty(defaultTargetsProperty);
        }
Example #26
0
        public void PropertyFunctionGenericListReturn()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$([MSBuild]::__GetListTest())", null);

            Assertion.AssertEquals("A;B;C;D", result);
        }
Example #27
0
        /// <summary>
        /// Populate the lists of evaluated and unevaluated metadata with all metadata that have true conditions.
        /// </summary>
        /// <remarks>
        /// FUTURE: Currently this isn't done when the item is constructed; so for example HasMetadata will always return
        /// false until EvaluatedAllItemMetadata is explicitly called. The reason for this is that Metadata are
        /// not first class objects, they are merely string pairs produced by running over the child XML with a particular expander.
        /// When Metadata are first class objects this method can be changed to merely evaluate them, 
        /// just as BuildItemGroup.Evaluate does for BuildItem, then methods like HasMetadata behave more sanely. Of course this
        /// could be a breaking change.
        /// </remarks>
        internal void EvaluateAllItemMetadata
        (
            Expander expander,
            ParserOptions parserOptions,
            EngineLoggingServices loggingServices,
            BuildEventContext buildEventContext
        )
        {
            ErrorUtilities.VerifyThrow(expander != null, "Null expander passed in.");

            // Cache all custom attributes on the item. For a persisted item, this will walk the item's child nodes, and
            // cache the custom attributes using a "last one wins" policy. For a virtual item, this method does nothing.

            // We only evaluate metadata by reading XML
            if (IsBackedByXml)
            {
                ErrorUtilities.VerifyThrow((this.evaluatedCustomMetadata != null) && (this.unevaluatedCustomMetadata != null),
                    "Item is not initialized properly.");

                // We're evaluating from scratch, so clear out any old cached attributes.
                this.evaluatedCustomMetadata.Clear();
                this.unevaluatedCustomMetadata.Clear();

                // Let the expander know about our own item type, so it can
                // expand unqualified metadata expressions
                SpecificItemDefinitionLibrary specificItemDefinitionLibrary = new SpecificItemDefinitionLibrary(name, itemDefinitionLibrary);
                expander = new Expander(expander, specificItemDefinitionLibrary);

                List<XmlElement> metadataElements = xml.GetChildren();

                // look at all the item's child nodes
                foreach (XmlElement metadataElement in metadataElements)
                {
                    // confirm that the child node is not conditionally disabled
                    bool condition = true;
                    XmlAttribute conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(metadataElement, true /*no other attributes allowed*/);

                    if (conditionAttribute != null)
                    {
                        condition = Utilities.EvaluateCondition(conditionAttribute.Value,
                            conditionAttribute, expander, null, parserOptions,
                            loggingServices, buildEventContext);
                    }

                    if (condition)
                    {
                        // cache its value, both the evaluated and unevaluated.
                        string unevaluatedMetadataValue = Utilities.GetXmlNodeInnerContents(metadataElement);
                        unevaluatedCustomMetadata[metadataElement.Name] = unevaluatedMetadataValue;
                        string evaluatedMetadataValue = expander.ExpandAllIntoStringLeaveEscaped(unevaluatedMetadataValue, metadataElement);
                        evaluatedCustomMetadata[metadataElement.Name] = evaluatedMetadataValue;

                        // Add this metadata to the running table we're using, so that one piece of metadata can refer to another one above
                        expander.SetMetadataInMetadataTable(name, metadataElement.Name, evaluatedMetadataValue);

                    }
                }
            }
        }
Example #28
0
        public void PropertyFunctionArrayReturnManualSplitter()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            pg.SetProperty("List", "A-B-C-D");
            pg.SetProperty("Splitter", "-");

            Expander expander = new Expander(pg);

            string result = expander.ExpandAllIntoStringLeaveEscaped("$(List.Split($(Splitter.ToCharArray())))", null);

            Assertion.AssertEquals("A;B;C;D", result);
        }
Example #29
0
        /// <summary>
        /// Given a property bag, this method evaluates the current property, 
        /// expanding any property references contained within.  It stores this
        /// evaluated value in the "finalValue" member.
        /// </summary>
        /// <owner>RGoel</owner>
        internal void Evaluate
        (
            Expander expander
        )
        {
            ErrorUtilities.VerifyThrow(expander != null, "Expander required to evaluated property.");

            this.finalValueEscaped = expander.ExpandAllIntoStringLeaveEscaped(this.Value, this.propertyElement);
        }
Example #30
0
        public void RegistryPropertyMultiString()
        {
            try
            {
                BuildPropertyGroup pg = new BuildPropertyGroup();

                Expander expander = new Expander(pg);
                RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\MSBuild_test");

                key.SetValue("Value", new string[] { "A", "B", "C", "D" }, RegistryValueKind.MultiString);
                string result = expander.ExpandAllIntoStringLeaveEscaped(@"$(Registry:HKEY_CURRENT_USER\Software\Microsoft\MSBuild_test@Value)", null);

                Assertion.AssertEquals("A;B;C;D", result);
            }
            finally
            {
                Registry.CurrentUser.DeleteSubKey(@"Software\Microsoft\MSBuild_test");
            }
        }