public static IEnumerable <string> EvaluateExpressionAsPaths(ExpressionNode expression, MSBuildRootDocument doc, int skipEndChars = 0)
        {
            if (expression == null)
            {
                yield return(Path.GetDirectoryName(doc.Filename));

                yield break;
            }

            if (expression is ListExpression list)
            {
                expression = list.Nodes[list.Nodes.Count - 1];
            }

            if (expression is ExpressionText lit)
            {
                var path = TrimEndChars(lit.GetUnescapedValue());
                //FIXME handle encoding
                yield return(MSBuildEscaping.FromMSBuildPath(path, Path.GetDirectoryName(doc.Filename)));

                yield break;
            }

            if (!(expression is ConcatExpression expr))
            {
                yield break;
            }

            //FIXME evaluate directly without the MSBuildEvaluationContext
            var sb = new StringBuilder();

            for (int i = 0; i < expr.Nodes.Count; i++)
            {
                var node = expr.Nodes[i];
                if (node is ExpressionText l)
                {
                    var val = l.GetUnescapedValue();
                    if (i == expr.Nodes.Count - 1)
                    {
                        val = TrimEndChars(val);
                    }
                    sb.Append(val);
                }
                else if (node is ExpressionProperty p)
                {
                    sb.Append($"$({p.Name})");
                }
                else
                {
                    yield break;
                }
            }

            foreach (var variant in doc.FileEvaluationContext.EvaluatePathWithPermutation(sb.ToString(), Path.GetDirectoryName(doc.Filename)))
            {
                yield return(variant);
            }

            string TrimEndChars(string s) => s.Substring(0, Math.Min(s.Length, s.Length - skipEndChars));
        }
示例#2
0
        public static IEnumerable <string> EvaluateExpressionAsPaths(ExpressionNode expression, MSBuildRootDocument doc, int skipEndChars = 0, string baseDir = null)
        {
            baseDir = baseDir ?? Path.GetDirectoryName(doc.Filename);

            if (expression == null)
            {
                yield return(baseDir);

                yield break;
            }

            if (expression is ListExpression list)
            {
                expression = list.Nodes[list.Nodes.Count - 1];
            }

            if (expression is ExpressionText lit)
            {
                if (lit.Length == 0)
                {
                    yield return(baseDir);

                    yield break;
                }
                var path = TrimEndChars(lit.GetUnescapedValue());
                if (string.IsNullOrEmpty(path))
                {
                    yield return(baseDir);

                    yield break;
                }
                //FIXME handle encoding
                if (MSBuildEscaping.FromMSBuildPath(path, baseDir, out var res))
                {
                    yield return(res);
                }
                yield break;
            }

            if (!(expression is ConcatExpression expr && expr.Nodes.All(n => n is ExpressionText || (n is ExpressionProperty p && p.IsSimpleProperty))))
            {
                yield break;
            }

            foreach (var variant in doc.FileEvaluationContext.EvaluatePathWithPermutation(expr, baseDir))
            {
                yield return(variant);
            }

            string TrimEndChars(string s) => s.Substring(0, Math.Min(s.Length, s.Length - skipEndChars));
        }
示例#3
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?
 // can we cache the filesystem lookups?
 public static IEnumerable <string> EvaluatePathWithPermutation(
     this IMSBuildEvaluationContext context,
     ExpressionNode pathExpression,
     string baseDirectory)
 {
     foreach (var p in EvaluateWithPermutation(context, null, pathExpression, 0))
     {
         if (p == null)
         {
             continue;
         }
         yield return(MSBuildEscaping.FromMSBuildPath(p, baseDirectory));
     }
 }
示例#4
0
#pragma warning disable 0169
        #region Functions
        // FIXME imported projects
        static bool Exists(string file, IExpressionContext context)
        {
            if (string.IsNullOrEmpty(file))
            {
                return(false);
            }

            string directory = context.FullDirectoryName;

            file = MSBuildEscaping.FromMSBuildPath(file, directory);
            bool res;

            lock (context.ExistsEvaluationCache) {
                if (context.ExistsEvaluationCache.TryGetValue(file, out res))
                {
                    return(res);
                }

                res = File.Exists(file) || Directory.Exists(file);
                context.ExistsEvaluationCache [file] = res;
            }
            return(res);
        }
示例#5
0
 public static string EvaluatePath(
     this IMSBuildEvaluationContext context,
     ExpressionNode expression,
     string baseDirectory)
 => MSBuildEscaping.FromMSBuildPath(context.Evaluate(expression), baseDirectory);