Пример #1
0
        public void PropertyCollectorEvaluationContextTest()
        {
            var collector = new PropertyValueCollector(false);

            collector.Mark("Hello");
            collector.Collect("Hello", new ExpressionText(0, "One", true));
            collector.Collect("Hello", new ExpressionText(0, "Two", true));

            var ctx = new MSBuildCollectedValuesEvaluationContext(
                new TestEvaluationContext(),
                collector
                );

            var vals = ctx.EvaluateWithPermutation("$(Hello)").ToList();

            Assert.AreEqual(2, vals.Count);
            Assert.AreEqual("One", vals[0]);
            Assert.AreEqual("Two", vals[1]);
        }
Пример #2
0
        // FIXME: need to make this more efficient. can we ignore results where a property was simply not found?
        // can we tokenize it and check each level of the path exists before drilling down?
        internal IEnumerable <string> EvaluatePathWithPermutation(string path, string basePath, PropertyValueCollector propVals)
        {
            //fast path for imports without properties, will generally be true for SDK imports
            if (path.IndexOf('$') < 0)
            {
                yield return(EvaluatePath(path, basePath));

                yield break;
            }

            if (propVals != null)
            {
                //ensure each of the properties is fully evaluated
                //FIXME this is super hacky, use real MSBuild evaluation
                foreach (var p in propVals)
                {
                    if (p.Value != null && !readonlyProps.Contains(p.Key))
                    {
                        for (int i = 0; i < p.Value.Count; i++)
                        {
                            var val      = p.Value [i];
                            int recDepth = 0;
                            try {
                                while (val.IndexOf('$') > -1 && (recDepth++ < 10))
                                {
                                    val = Evaluate(val);
                                }
                                if (val != null && val.IndexOf('$') < 0)
                                {
                                    SetPropertyValue(p.Key, val);
                                }
                                if (string.IsNullOrEmpty(val))
                                {
                                    p.Value.RemoveAt(i);
                                    i--;
                                }
                                else
                                {
                                    p.Value [i] = val;
                                }
                            } catch {
                                //this happens a lot with things like property functions that
                                //index into null values, so make it quiet
                                //LoggingService.LogDebug ($"Error evaluating property {p.Key}={val}");
                                //FIXME stop ignoring these errors
                            }
                        }
                    }
                }

                //TODO: use a new context instead of altering this one?
                foreach (var p in propVals)
                {
                    if (p.Value != null && p.Value.Count > 0 && !readonlyProps.Contains(p.Key))
                    {
                        SetPropertyValue(p.Key, p.Value [0]);
                    }
                }
            }

            //permute on properties for which we have multiple values
            var expr           = ExpressionParser.Parse(path, ExpressionOptions.None);
            var propsToPermute = new List <(string, List <string>)> ();

            foreach (var prop in expr.WithAllDescendants().OfType <ExpressionProperty> ())
            {
                if (readonlyProps.Contains(prop.Name))
                {
                    continue;
                }
                if (propVals != null && propVals.TryGetValues(prop.Name, out List <string> values) && values != null)
                {
                    if (values.Count > 1)
                    {
                        propsToPermute.Add((prop.Name, values));
                    }
                }
                else if (extensionPaths != null && string.Equals(prop.Name, "MSBuildExtensionsPath", StringComparison.OrdinalIgnoreCase) || string.Equals(prop.Name, "MSBuildExtensionsPath32", StringComparison.OrdinalIgnoreCase))
                {
                    propsToPermute.Add((prop.Name, extensionPaths));
                }
            }

            if (propsToPermute.Count == 0)
            {
                yield return(EvaluatePath(path, basePath));
            }
            else
            {
                foreach (var ctx in PermuteProperties(this, propsToPermute))
                {
                    yield return(EvaluatePath(path, basePath));
                }
            }
        }
 public MSBuildCollectedValuesEvaluationContext(IMSBuildEvaluationContext fileContext, PropertyValueCollector collector)
 {
     this.collector   = collector;
     this.fileContext = fileContext;
 }