Exemplo n.º 1
0
 internal ConditionEvaluationState(XmlAttribute conditionAttribute, Expander expanderToUse, Hashtable conditionedPropertiesInProject, string parsedCondition)
 {
     this.conditionAttribute = conditionAttribute;
     this.expanderToUse = expanderToUse;
     this.conditionedPropertiesInProject = conditionedPropertiesInProject;
     this.parsedCondition = parsedCondition;
 }
Exemplo n.º 2
0
        internal TargetExecutionWrapper
        (
            Target targetClass,
            ArrayList taskElementList,
            List<string> targetParameters,
            XmlElement targetElement,
            Expander expander,
            BuildEventContext targetBuildEventContext
        )
        {
            // Initialize the data about the target XML that has been calculated in the target class
            this.targetClass   = targetClass;
            this.parentEngine  = targetClass.ParentEngine;
            this.parentProject = targetClass.ParentProject;
            this.targetElement   = targetElement;
            this.taskElementList = taskElementList;
            this.targetParameters = targetParameters;
            this.targetBuildEventContext = targetBuildEventContext;

            // Expand the list of depends on targets
            dependsOnTargetNames = expander.ExpandAllIntoStringList(targetClass.DependsOnTargets, targetClass.DependsOnTargetsAttribute);

            // Starting to build the target
            inProgressBuildState = InProgressBuildState.StartingBuild;
            // No messages have been logged
            loggedTargetStart = false;
        }
Exemplo n.º 3
0
        public void ExpandAllIntoTaskItems3()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();

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

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

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

            Expander expander = new Expander(pg, itemsByType);

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

            ObjectModelHelpers.AssertItemsMatch(@"
                foo
                bar
                foo.cs
                bar.cs
                bing.resx
                ", itemsOut.ToArray());
        }
Exemplo n.º 4
0
        public void Metadata()
        {
            string content = @"
            <i Include='i1' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
               <m>$(p)</m>
               <n>n1</n>
            </i>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(content);
            BuildItem item = CreateBuildItemFromXmlDocument(doc);
            Assertion.AssertEquals("i", item.Name);
            BuildPropertyGroup properties = new BuildPropertyGroup();
            properties.SetProperty("p", "p1");

            // Evaluated
            Expander expander = new Expander(properties, null, ExpanderOptions.ExpandAll);
            item.EvaluateAllItemMetadata(expander, ParserOptions.AllowPropertiesAndItemLists, null, null);
            Assertion.AssertEquals("p1", item.GetEvaluatedMetadata("m"));

            // Unevaluated
            Assertion.AssertEquals("$(p)", item.GetMetadata("m"));
            Assertion.AssertEquals("n1", item.GetMetadata("n"));

            // All custom metadata
            ArrayList metadataNames = new ArrayList(item.CustomMetadataNames);
            Assertion.Assert(metadataNames.Contains("n"));
            Assertion.Assert(metadataNames.Contains("m"));

            // Custom metadata count only
            Assertion.AssertEquals(2, item.CustomMetadataCount);
            
            // All metadata count
            Assertion.AssertEquals(2 + FileUtilities.ItemSpecModifiers.All.Length, item.MetadataCount);
        }
Exemplo n.º 5
0
 /// <summary>
 /// Helper method so we can keep the real Expander.ExpandMetadataAndProperties private.
 /// </summary>
 /// <param name="bucket"></param>
 /// <param name="expression"></param>
 /// <returns></returns>
 /// <owner>RGoel</owner>
 private static string ExpandMetadataAndProperties
     (
     ItemBucket bucket,
     string expression
     )
 {
     Expander itemExpander = new Expander(bucket.Expander, ExpanderOptions.ExpandPropertiesAndMetadata);
     return itemExpander.ExpandAllIntoString(expression, (new XmlDocument()).CreateAttribute("foo"));
 }
Exemplo n.º 6
0
        public void ExpandAllIntoTaskItems1()
        {
            BuildPropertyGroup pg = new BuildPropertyGroup();
            Expander expander = new Expander(pg);

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

            ObjectModelHelpers.AssertItemsMatch(@"foo", itemsOut.ToArray());
        }
Exemplo n.º 7
0
 /// <summary>
 /// Helper method so we can keep the real Expander.ExpandItemsIntoString private.
 /// </summary>
 /// <param name="bucket"></param>
 /// <param name="expression"></param>
 /// <returns></returns>
 /// <owner>RGoel</owner>
 private static string ExpandItemsIntoString
     (
     ItemBucket bucket,
     string expression
     )
 {
     
     Expander itemExpander = new Expander(new ReadOnlyLookup(bucket.Lookup), null, ExpanderOptions.ExpandItems);
     return itemExpander.ExpandAllIntoString(expression, (new XmlDocument()).CreateAttribute("foo"));
 }
Exemplo n.º 8
0
        public void SimpleEvaluationTests()
        {
            Parser p = new Parser();
            Expander expander = new Expander(new BuildPropertyGroup());
            Hashtable conditionedProperties = null;
            ConditionEvaluationState state = new ConditionEvaluationState(DummyAttribute, expander, conditionedProperties, string.Empty);

            AssertParseEvaluate(p, "true", state, true);
            AssertParseEvaluate(p, "on", state, true);
            AssertParseEvaluate(p, "yes", state, true);
            AssertParseEvaluate(p, "false", state, false);
            AssertParseEvaluate(p, "off", state, false);
            AssertParseEvaluate(p, "no", state, false);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
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);

                    }
                }
            }
        }
Exemplo n.º 11
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;
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Evaluates the item and returns a virtual group containing any resulting items.
        /// This allows an item to be evaluated without it belonging to an item group.
        /// </summary>
        internal BuildItemGroup Evaluate(Expander expander, 
                                        string baseDirectory, 
                                        bool expandMetadata,
                                        ParserOptions parserOptions,
                                        EngineLoggingServices loggingServices, 
                                        BuildEventContext buildEventContext)
        {
            BuildItemGroup result = new BuildItemGroup();
            bool itemCondition = Utilities.EvaluateCondition(Condition,
                                                             ConditionAttribute,
                                                             expander,
                                                             parserOptions,
                                                             loggingServices,
                                                             buildEventContext);
            if (!itemCondition)
            {
                return result;
            }

            EvaluateAllItemMetadata(expander, parserOptions, loggingServices, buildEventContext);
            BuildItemGroup items = BuildItemGroup.ExpandItemIntoItems(baseDirectory, this, expander, expandMetadata);

            for (int i = 0; i < items.Count; i++)
            {
                BuildItem newItem = CreateClonedParentedItem(items[i], this);
                result.AddExistingItem(newItem);
            }

            return result;
        }
Exemplo n.º 14
0
        /// <summary>
        /// Builds this target if it has not already been built as part of its parent project. Before we actually execute the
        /// tasks for this target, though, we first call on all the dependent targets to build themselves.
        /// This function may throw InvalidProjectFileException
        /// </summary>
        internal void Build
        (
            ProjectBuildState buildContext
        )
        {
            // Depending on the build state, we may do different things.
            switch (buildState)
            {
                case BuildState.InProgress:
                    // In single proc mode if the build state was already "in progress" 
                    // and somebody just told us to build ourselves, it means that there is 
                    // a loop (circular dependency) in the target dependency graph. In multi
                    // proc mode we need to analyze the dependency graph before we can
                    // tell if there a circular dependency or if two independent chains
                    // of targets happen to need the result of this target.
                    if (parentEngine.Router.SingleThreadedMode || buildContext.ContainsCycle(this.Name))
                    {
                        ProjectErrorUtilities.VerifyThrowInvalidProject(false, TargetElement, "CircularDependency", targetName);
                    }
                    else
                    {
                        buildContext.CurrentBuildContextState = ProjectBuildState.BuildContextState.WaitingForTarget;
                        this.executionState.AddWaitingBuildContext(buildContext);
                    }
                    break;

                case BuildState.CompletedSuccessfully:
                case BuildState.CompletedUnsuccessfully:
                    // If this target has already been built as part of this project,
                    // we're not going to build it again.  Just return the result
                    // from when it was built previously.  Note:  This condition
                    // could really only ever hold true if the user specifically
                    // requested us to build multiple targets and there existed
                    // a direct or indirect dependency relationship between two or
                    // more of those top-level targets.
                    // Note: we aren't really entering the target in question here, so don't use the target
                    // event context. Using the target ID for skipped messages would force us to
                    // cache the individual target IDs for unloaded projects and it's not really worth the trouble.
                    // Just use the parent event context.
                    parentEngine.LoggingServices.LogComment(buildContext.ProjectBuildEventContext,
                        ((buildState == BuildState.CompletedSuccessfully) ? "TargetAlreadyCompleteSuccess" : "TargetAlreadyCompleteFailure"),
                        this.targetName);

                    // Only contexts which are generated from an MSBuild task could need 
                    // the outputs of this target, such contexts have a non-null evaluation
                    // request
                    if ((buildState == BuildState.CompletedSuccessfully) && 
                        (buildContext.BuildRequest.OutputsByTarget != null &&
                         buildContext.NameOfBlockingTarget == null))
                    {
                        error.VerifyThrow(
                            String.Compare(EscapingUtilities.UnescapeAll(buildContext.NameOfTargetInProgress), this.Name, StringComparison.OrdinalIgnoreCase) == 0,
                            "The name of the target in progress is inconsistent with the target being built");

                        error.VerifyThrow(targetOutputItems != null,
                            "If the target built successfully, we must have its outputs.");

                        buildContext.BuildRequest.OutputsByTarget[Name] = targetOutputItems.ToArray();
                    }

                    if (buildContext.NameOfBlockingTarget == null)
                    {
                        buildContext.BuildRequest.ResultByTarget[Name] = buildState;
                    }
                    break;

                case BuildState.NotStarted:
                case BuildState.Skipped:
                    {
                        // Always have to create a new context in build as other projects or targets may try and build this target
                        BuildEventContext targetBuildEventContext = new BuildEventContext
                                                        (
                                                            buildContext.ProjectBuildEventContext.NodeId,
                                                            this.id,
                                                            buildContext.ProjectBuildEventContext.ProjectContextId,
                                                            buildContext.ProjectBuildEventContext.TaskId
                                                        );

                        Expander expander = new Expander(this.parentProject.evaluatedProperties, this.parentProject.evaluatedItemsByName);

                        // We first make sure no batching was attempted with the target's condition.
                        if (!conditionCheckedForInvalidMetadataReferences)
                        {
                            if (ExpressionShredder.ContainsMetadataExpressionOutsideTransform(this.Condition))
                            {
                                ProjectErrorUtilities.ThrowInvalidProject(this.conditionAttribute, "TargetConditionHasInvalidMetadataReference", targetName, this.Condition);
                            }
                            conditionCheckedForInvalidMetadataReferences = true;
                        }

                        // If condition is false (based on propertyBag), set this target's state to
                        // "Skipped" since we won't actually build it.
                        if (!Utilities.EvaluateCondition(this.Condition, this.conditionAttribute,
                                expander, null, ParserOptions.AllowProperties | ParserOptions.AllowItemLists,
                                parentEngine.LoggingServices, targetBuildEventContext))
                        {
                            buildState = BuildState.Skipped;

                            if (buildContext.NameOfBlockingTarget == null)
                            {
                                buildContext.BuildRequest.ResultByTarget[Name] = buildState;
                            }

                            if (!parentEngine.LoggingServices.OnlyLogCriticalEvents)
                            {
                                // Expand the expression for the Log.
                                string expanded = expander.ExpandAllIntoString(this.Condition, this.conditionAttribute);
                                // By design: Not building dependencies. This is what NAnt does too.
                                parentEngine.LoggingServices.LogComment(targetBuildEventContext, "TargetSkippedFalseCondition",
                                                        this.targetName, this.Condition, expanded);
                            }
                        }
                        else
                        {
                            // This target has not been built yet.  So build it!
                            // Change our state to "in progress". TargetParameters will need to be re-calculated if Inputs and Outputs attribute has changed.
                            buildState = BuildState.InProgress;
                            List<string> batchableTargetParameters = GetBatchableTargetParameters();
                            executionState = new TargetExecutionWrapper(this, taskElementList, batchableTargetParameters, targetElement, expander, targetBuildEventContext);
                            ContinueBuild(buildContext, null);
                        }
                    }
                    break;
                default:
                    error.VerifyThrow(false, "Build state {0} not handled in Target.Build method", buildState);
                    break;
            }
        }
Exemplo n.º 15
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);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Creates a list of targets to execute for the OnErrorClause
        /// </summary>
        private void InitializeOnErrorClauseExecution()
        {
            // Give default values;
            currentErrorTarget = 0;
            onErrorTargets = null;

            // Loop through each of the child nodes of the <target> element.
            List<XmlElement> childElements = ProjectXmlUtilities.GetValidChildElements(targetElement);

            foreach (XmlElement childElement in childElements)
            {
                switch (childElement.Name)
                {
                    case XMakeElements.onError:
                        ProjectXmlUtilities.VerifyThrowProjectNoChildElements(childElement);

                        XmlAttribute condition = null;
                        XmlAttribute executeTargets = null;

                        foreach (XmlAttribute onErrorAttribute in childElement.Attributes)
                        {
                            switch (onErrorAttribute.Name)
                            {
                                case XMakeAttributes.condition:
                                    condition = childElement.Attributes[XMakeAttributes.condition];
                                    break;
                                case XMakeAttributes.executeTargets:
                                    executeTargets = childElement.Attributes[XMakeAttributes.executeTargets];
                                    break;
                                default:
                                    ProjectXmlUtilities.ThrowProjectInvalidAttribute(onErrorAttribute);
                                    break;
                            }
                        }

                        ProjectErrorUtilities.VerifyThrowInvalidProject(executeTargets != null, childElement, "MissingRequiredAttribute", XMakeAttributes.executeTargets, XMakeElements.onError);

                        Expander expander = new Expander(this.parentProject.evaluatedProperties, this.parentProject.evaluatedItemsByName);

                        bool runErrorTargets = true;
                        if (condition != null)
                        {
                            if
                            (
                                !Utilities.EvaluateCondition
                                (
                                    condition.InnerText, condition, expander,
                                    null, ParserOptions.AllowProperties | ParserOptions.AllowItemLists,
                                    parentEngine.LoggingServices, targetBuildEventContext
                                )
                            )
                            {
                                runErrorTargets = false;
                            }
                        }

                        if (runErrorTargets)
                        {
                            if (onErrorTargets == null)
                            {
                                onErrorTargets = expander.ExpandAllIntoStringList(executeTargets.InnerText, executeTargets);
                            }
                            else
                            {
                                onErrorTargets.AddRange(expander.ExpandAllIntoStringList(executeTargets.InnerText, executeTargets));
                            }
                        }
                        break;

                    default:
                        // Ignore
                        break;
                }
            }
        }
Exemplo n.º 17
0
        public void MetadataIncludesItemDefinitionMetadata()
        {
            // Get an item of type "i" that has an item definition library 
            // for type "i" that has default value "m1" for metadata "m"
            // and has value "n1" for metadata "n"
            BuildItem item = GetXmlBackedItemWithDefinitionLibrary();

            // Evaluated
            Expander expander = new Expander(new BuildPropertyGroup(), null, ExpanderOptions.ExpandAll);
            item.EvaluateAllItemMetadata(expander, ParserOptions.AllowPropertiesAndItemLists, null, null);
            Assertion.AssertEquals("m1", item.GetEvaluatedMetadata("m"));
            Assertion.AssertEquals("n1", item.GetEvaluatedMetadata("n"));

            // Unevaluated
            Assertion.AssertEquals("m1", item.GetMetadata("m"));
            Assertion.AssertEquals("n1", item.GetMetadata("n"));

            // All custom metadata
            List<string> metadataNames = new List<string>((IList<string>)item.CustomMetadataNames);
            Assertion.AssertEquals("n", (string)metadataNames[0]);
            Assertion.AssertEquals("m", (string)metadataNames[1]);

            // Custom metadata count only
            Assertion.AssertEquals(3, item.CustomMetadataCount);

            // All metadata count
            Assertion.AssertEquals(item.CustomMetadataCount + FileUtilities.ItemSpecModifiers.All.Length, item.MetadataCount);
        }
Exemplo n.º 18
0
 internal Expander(Expander expander, SpecificItemDefinitionLibrary itemDefinitionLibrary)
     : this(expander.lookup, null , expander.options)
 {
     if (implicitMetadataItemType == null)
     {
         this.itemMetadata = expander.itemMetadata;
     }
     this.specificItemDefinitionLibrary = itemDefinitionLibrary;
 }
Exemplo n.º 19
0
        public UsingTaskInfo CopyAndExpand(Expander expander)
        {
            string newTaskName = expander.ExpandAllIntoString(UsingTask.TaskName, UsingTask.TaskNameAttribute);
            string newCondition = null;
            string newAssemblyName = null;
            string newAssemblyFile = null;

            if (UsingTask.Condition != null)
            {
                newCondition = expander.ExpandAllIntoString(UsingTask.Condition, UsingTask.ConditionAttribute);
            }
            if (UsingTask.AssemblyName != null)
            {
                newAssemblyName = expander.ExpandAllIntoString(UsingTask.AssemblyName, UsingTask.AssemblyNameAttribute);
            }
            if (UsingTask.AssemblyFile != null)
            {
                newAssemblyFile = expander.ExpandAllIntoString(UsingTask.AssemblyFile, UsingTask.AssemblyFileAttribute);
            }

            return new UsingTaskInfo(newTaskName, newAssemblyName, newAssemblyFile, newCondition);
        }
Exemplo n.º 20
0
 /// <summary>
 /// Create an expander from another expander, but with different
 /// options
 /// </summary>
 internal Expander(Expander expander, ExpanderOptions options)
     : this(expander.lookup, expander.itemMetadata, options)
 {
 }
Exemplo n.º 21
0
            /// <summary>
            /// Execute the function on the given instance
            /// </summary>
            public object Execute(Expander expander, object objectInstance, BuildPropertyGroup properties, ExpanderOptions options)
            {
                object functionResult = String.Empty;

                object[] args = null;

                try
                {
                    // If there is no object instance, then the method invocation will be a static
                    if (objectInstance == null)
                    {
                        // Check that the function that we're going to call is valid to call
                        if (!IsStaticMethodAvailable(ObjectType, name))
                        {
                            ProjectErrorUtilities.ThrowInvalidProject(null, "InvalidFunctionMethodUnavailable", name, ObjectType.FullName);
                        }

                        bindingFlags |= BindingFlags.Static;

                        // For our intrinsic function we need to support calling of internal methods
                        // since we don't want them to be public
                        if (objectType == typeof(Microsoft.Build.BuildEngine.IntrinsicFunctions))
                        {
                            bindingFlags |= BindingFlags.NonPublic;
                        }
                    }
                    else
                    {
                        bindingFlags |= BindingFlags.Instance;
                    }

                    // We have a methodinfo match, need to plug in the arguments

                    args = new object[arguments.Length];

                    // Assemble our arguments ready for passing to our method
                    for (int n = 0; n < arguments.Length; n++)
                    {
                        object argument = expander.ExpandPropertiesLeaveTypedAndEscaped(this.arguments[n], null);
                        string argumentValue = argument as string;

                        if (argumentValue != null)
                        {
                            // remove our 'quotes' from the escaped string, leaving escaped quotes intact
                            args[n] = EscapingUtilities.UnescapeAll(argumentValue.Trim('`', '"', '\''));
                        }
                        else
                        {
                            args[n] = argument;
                        }
                    }

                    // Handle special cases where the object type needs to affect the choice of method
                    // The default binder and method invoke, often chooses the incorrect Equals and CompareTo and 
                    // fails the comparison, because what we have on the right is generally a string.
                    // This special casing is to realize that its a comparison that is taking place and handle the
                    // argument type coercion accordingly; effectively pre-preparing the argument type so 
                    // that it matches the left hand side ready for the default binder�s method invoke.
                    if (objectInstance != null && args.Length == 1 && (String.Equals("Equals", this.name, StringComparison.OrdinalIgnoreCase) || String.Equals("CompareTo", this.name, StringComparison.OrdinalIgnoreCase)))
                    {
                        // change the type of the final unescaped string into the destination
                        args[0] = Convert.ChangeType(args[0], objectInstance.GetType(), CultureInfo.InvariantCulture);
                    }
                    
                    // If we've been asked for and instance to be constructed, then we
                    // need to locate an appropriate constructor and invoke it
                    if (String.Equals("new", this.name, StringComparison.OrdinalIgnoreCase))
                    {
                        functionResult = LateBindExecute(null /* no previous exception */, BindingFlags.Public | BindingFlags.Instance, null /* no instance for a constructor */, args, true /* is constructor */);
                    }
                    else
                    {
                        // Execute the function given converted arguments
                        // The only exception that we should catch to try a late bind here is missing method
                        // otherwise there is the potential of running a function twice!
                        try
                        {
                            // First use InvokeMember using the standard binder - this will match and coerce as needed
                            functionResult = objectType.InvokeMember(this.name, bindingFlags, Type.DefaultBinder, objectInstance, args, CultureInfo.InvariantCulture);
                        }
                        catch (MissingMethodException ex) // Don't catch and retry on any other exception
                        {
                            // If we're invoking a method, then there are deeper attempts that
                            // can be made to invoke the method
                            if ((bindingFlags & BindingFlags.InvokeMethod) == BindingFlags.InvokeMethod)
                            {
                                // The standard binder failed, so do our best to coerce types into the arguments for the function
                                // This may happen if the types need coercion, but it may also happen if the object represents a type that contains open type parameters, that is, ContainsGenericParameters returns true. 
                                functionResult = LateBindExecute(ex, bindingFlags, objectInstance, args, false /* is not constructor */);
                            }
                            else
                            {
                                // We were asked to get a property or field, and we found that we cannot
                                // locate it. Since there is no further argument coersion possible
                                // we'll throw right now.
                                throw;
                            }
                        }
                    }

                    // If the result of the function call is a string, then we need to escape the result
                    // so that we maintain the "engine contains escaped data" state.
                    // The exception is that the user is explicitly calling MSBuild::Unescape or MSBuild::Escape
                    if (functionResult is string && !String.Equals("Unescape", name, StringComparison.OrdinalIgnoreCase) && !String.Equals("Escape", name, StringComparison.OrdinalIgnoreCase))
                    {
                        functionResult = EscapingUtilities.Escape((string)functionResult);
                    }
                    
                    // There's nothing left to deal within the function expression, return the result from the execution
                    if (String.IsNullOrEmpty(remainder))
                    {
                        return functionResult;
                    }

                    // Recursively expand the remaining property body after execution
                    return expander.ExpandPropertyBody(remainder, functionResult, properties, options);
                }
                // Exceptions coming from the actual function called are wrapped in a TargetInvocationException
                catch (TargetInvocationException ex)
                {
                    // We ended up with something other than a function expression
                    string partiallyEvaluated = GenerateStringOfMethodExecuted(expression, objectInstance, name, args);
                    ProjectErrorUtilities.ThrowInvalidProject(null, "InvalidFunctionPropertyExpression", partiallyEvaluated, ex.InnerException.Message.Replace("\r\n", " "));
                    return null;
                }
                // Any other exception was thrown by trying to call it
                catch (Exception ex)
                {
                    if (ExceptionHandling.NotExpectedFunctionException(ex))
                    {
                        throw;
                    }

                    // We ended up with something other than a function expression
                    string partiallyEvaluated = GenerateStringOfMethodExecuted(expression, objectInstance, name, args);
                    ProjectErrorUtilities.ThrowInvalidProject(null, "InvalidFunctionPropertyExpression", partiallyEvaluated, ex.Message);
                    return null;
                }
            }
Exemplo n.º 22
0
        /// <summary>
        /// This processes the &lt;UsingTask&gt; elements in the project file as well
        /// as the imported project files, by adding the necessary data to the
        /// task registry.
        /// </summary>
        /// <owner>RGoel</owner>
        private void EvaluateAllUsingTasks()
        {
            Expander expander = new Expander(evaluatedProperties, evaluatedItemsByName);

            foreach (UsingTask usingTask in this.usingTasks)
            {
                taskRegistry.RegisterTask(usingTask, expander, ParentEngine.LoggingServices, projectBuildEventContext);
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Creates an instance of this class using the given bucket data.
        /// </summary>
        /// <param name="itemNames">Item types being batched on: null indicates no batching is occurring</param>
        /// <param name="itemMetadata">Hashtable of item metadata values: null indicates no batching is occurring</param>
        internal ItemBucket
        (
            ICollection itemNames,
            Dictionary<string, string> itemMetadata,
            Lookup lookup,
            int bucketSequenceNumber
        )
        {
            ErrorUtilities.VerifyThrow(lookup != null, "Need lookup.");

            // Create our own lookup just for this bucket
            this.lookup = lookup.Clone();

            // Push down the items, so that item changes in this batch are not visible to parallel batches
            this.lookup.EnterScope();

            // Add empty item groups for each of the item names, so that (unless items are added to this bucket) there are
            // no item types visible in this bucket among the item types being batched on
            if (itemNames != null)
            {
                foreach (string name in itemNames)
                {
                    this.lookup.PopulateWithItems(name, new BuildItemGroup());
                }
            }

            this.expander = new Expander(this.lookup.ReadOnlyLookup, itemMetadata);
            this.bucketSequenceNumber = bucketSequenceNumber;
        }
Exemplo n.º 24
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates 
            /// this group of item definitions and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definitions are incorrectly defined</exception>
            internal void Evaluate(BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                Expander expander = new Expander(properties);

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

                List<XmlElement> childElements = ProjectXmlUtilities.GetValidChildElements(element);

                foreach (XmlElement child in childElements)
                {
                    EvaluateItemDefinitionElement(child, properties, itemDefinitionsDictionary);
                }
            }
Exemplo n.º 25
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);
        }
Exemplo n.º 26
0
            /// <summary>
            /// Given the properties and dictionary of previously encountered item definitions, evaluates 
            /// this specific item definition element and adds to the dictionary as necessary.
            /// </summary>
            /// <exception cref="InvalidProjectFileException">If the item definition is incorrectly defined</exception>
            private void EvaluateItemDefinitionElement(XmlElement itemDefinitionElement, BuildPropertyGroup properties, ItemDefinitionsDictionary itemDefinitionsDictionary)
            {
                ProjectXmlUtilities.VerifyThrowProjectValidNameAndNamespace(itemDefinitionElement);

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

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

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

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

                List<XmlElement> childElements = ProjectXmlUtilities.GetValidChildElements(itemDefinitionElement);

                foreach (XmlElement child in childElements)
                {
                    EvaluateItemDefinitionChildElement(child, properties, itemDefinitionsDictionary);
                }
            }
Exemplo n.º 27
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);
        }
Exemplo n.º 28
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;
            }
Exemplo n.º 29
0
        /// <summary>
        /// Parses the target's "Inputs" and "Outputs" attributes and gathers up referenced items.
        /// </summary>
        /// <param name="bucket"></param>
        /// <param name="itemVectorsInTargetInputs"></param>
        /// <param name="itemVectorTransformsInTargetInputs"></param>
        /// <param name="discreteItemsInTargetInputs"></param>
        /// <param name="itemVectorsInTargetOutputs"></param>
        /// <param name="discreteItemsInTargetOutputs"></param>
        /// <param name="targetOutputItemSpecs"></param>
        /// <owner>SumedhK</owner>
        private void ParseTargetInputOutputSpecifications
        (
            ItemBucket bucket,
            out Hashtable itemVectorsInTargetInputs,
            out Hashtable itemVectorTransformsInTargetInputs,
            out Hashtable discreteItemsInTargetInputs,
            out Hashtable itemVectorsInTargetOutputs,
            out Hashtable discreteItemsInTargetOutputs,
            out ArrayList targetOutputItemSpecs
        )
        {
            // break down the input/output specifications along the standard separator, after expanding all embedded properties
            // and item metadata
            Expander propertyAndMetadataExpander = new Expander(bucket.Expander, ExpanderOptions.ExpandPropertiesAndMetadata);
            List<string> targetInputs = propertyAndMetadataExpander.ExpandAllIntoStringListLeaveEscaped(TargetInputSpecification, this.targetInputsAttribute);
            List<string> targetOutputs = propertyAndMetadataExpander.ExpandAllIntoStringListLeaveEscaped(TargetOutputSpecification, this.targetOutputsAttribute);

            itemVectorTransformsInTargetInputs = new Hashtable(StringComparer.OrdinalIgnoreCase);

            // figure out which of the inputs are:
            // 1) item vectors
            // 2) item vectors with transforms
            // 3) "discrete" items i.e. items that do not reference item vectors
            SeparateItemVectorsFromDiscreteItems(this.targetInputsAttribute, targetInputs, bucket,
                out itemVectorsInTargetInputs,
                itemVectorTransformsInTargetInputs,
                out discreteItemsInTargetInputs);

            // figure out which of the outputs are:
            // 1) item vectors (with or without transforms)
            // 2) "discrete" items i.e. items that do not reference item vectors
            SeparateItemVectorsFromDiscreteItems(this.targetOutputsAttribute, targetOutputs, bucket,
                out itemVectorsInTargetOutputs,
                null /* don't want transforms separated */,
                out discreteItemsInTargetOutputs);

            // list out all the output item-specs
            targetOutputItemSpecs = GetItemSpecsFromItemVectors(itemVectorsInTargetOutputs);
            targetOutputItemSpecs.AddRange(discreteItemsInTargetOutputs.Values);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Evaluates condition on property group, and if true, evaluates
        /// on each contained property.  If that's true as well, adds property
        /// to evaluatedPropertyBag.
        /// </summary>
        /// <owner>DavidLe</owner>
        /// <param name="evaluatedPropertyBag"></param>
        /// <param name="conditionedPropertiesTable"></param>
        /// <param name="pass"></param>
        internal void Evaluate
            (
            BuildPropertyGroup evaluatedPropertyBag,
            Hashtable conditionedPropertiesTable,
            ProcessingPass pass
            )
        {
            ErrorUtilities.VerifyThrow(pass == ProcessingPass.Pass1, "Pass should be Pass1 for PropertyGroups.");

            Expander expander = new Expander(evaluatedPropertyBag);

            if (!Utilities.EvaluateCondition(this.Condition, this.ConditionAttribute,
                expander, conditionedPropertiesTable, ParserOptions.AllowProperties,
                ParentProject.ParentEngine.LoggingServices, ParentProject.ProjectBuildEventContext))
            {
                return;
            }

            // Add all the properties to our project-level property bag.
            foreach (BuildProperty currentProperty in this.propertyList)
            {
                if (!Utilities.EvaluateCondition(currentProperty.Condition, currentProperty.ConditionAttribute,
                    expander, conditionedPropertiesTable, ParserOptions.AllowProperties,
                    ParentProject.ParentEngine.LoggingServices, parentProject.ProjectBuildEventContext))
                {
                    continue;
                }

                BuildProperty newProperty = currentProperty.Clone(false);
                newProperty.Evaluate(expander);
                evaluatedPropertyBag.SetProperty(newProperty);
            }
        }