示例#1
0
 public static ExpressionNode Find(this ExpressionNode node, int offset)
 {
     return(node.ContainsOffset(offset) ? FindInternal(node, offset) : null);
 }
示例#2
0
        static ExpressionNode FindInternal(this ExpressionNode node, int offset)
        {
            switch (node)
            {
            case Expression expr:
                //TODO: binary search?
                foreach (var c in expr.Nodes)
                {
                    if (c.ContainsOffset(offset))
                    {
                        return(c.FindInternal(offset));
                    }
                }
                break;

            case ExpressionItem item:
                if (item.HasTransform && item.Transform.ContainsOffset(offset))
                {
                    return(item.Transform.FindInternal(offset));
                }
                break;

            case ExpressionProperty prop:
                if (prop.Expression != null && prop.Expression.ContainsOffset(offset))
                {
                    return(prop.Expression.FindInternal(offset));
                }
                break;

            case IncompleteExpressionError err:
                if (err.IncompleteNode != null && err.IncompleteNode.ContainsOffset(offset))
                {
                    return(err.IncompleteNode.FindInternal(offset));
                }
                break;

            case ExpressionPropertyFunctionInvocation prop:
                if (prop.Target != null && prop.Target.ContainsOffset(offset))
                {
                    return(prop.Target.FindInternal(offset));
                }
                if (prop.Arguments != null && prop.Arguments.ContainsOffset(offset))
                {
                    return(prop.Arguments.FindInternal(offset));
                }
                break;

            case ExpressionArgumentList argumentList:
                if (argumentList.Arguments != null)
                {
                    //TODO: binary search?
                    foreach (var c in argumentList.Arguments)
                    {
                        if (c.ContainsOffset(offset))
                        {
                            return(c.FindInternal(offset));
                        }
                    }
                }
                break;
            }
            return(node);
        }
示例#3
0
        public static IEnumerable <ExpressionNode> WithAllDescendants(this ExpressionNode node)
        {
            yield return(node);

            switch (node)
            {
            case Expression expr:
                foreach (var c in expr.Nodes)
                {
                    foreach (var n in c.WithAllDescendants())
                    {
                        yield return(n);
                    }
                }
                break;

            case ExpressionItem item:
                if (item.HasTransform)
                {
                    foreach (var n in item.Transform.WithAllDescendants())
                    {
                        yield return(n);
                    }
                }
                break;

            case ExpressionProperty property:
                if (property.Expression != null)
                {
                    foreach (var n in property.Expression.WithAllDescendants())
                    {
                        yield return(n);
                    }
                }
                break;

            case ExpressionPropertyFunctionInvocation invocation:
                if (invocation.Target != null)
                {
                    foreach (var n in invocation.Target.WithAllDescendants())
                    {
                        yield return(n);
                    }
                }
                if (invocation.Arguments != null)
                {
                    foreach (var n in invocation.Arguments.WithAllDescendants())
                    {
                        yield return(n);
                    }
                }
                break;

            case ExpressionArgumentList argumentList:
                if (argumentList.Arguments != null)
                {
                    foreach (var a in argumentList.Arguments)
                    {
                        foreach (var n in a.WithAllDescendants())
                        {
                            yield return(n);
                        }
                    }
                }
                break;
            }
        }
示例#4
0
 public static bool ContainsOffset(this ExpressionNode node, int offset)
 {
     return(node.Offset <= offset && node.End >= offset);
 }
示例#5
0
 public IncompleteExpressionError(int offset, bool wasEOF, ExpressionErrorKind kind, ExpressionNode incompleteNode)
     : base(offset, wasEOF? 0 : 1, kind)
 {
     IncompleteNode = incompleteNode;
 }
示例#6
0
 internal void SetParent(ExpressionNode parent) => Parent = parent;
示例#7
0
 public ExpressionItem(int offset, int length, string name, ExpressionNode transform) : base(offset, length)
 {
     Transform = transform;
     transform?.SetParent(this);
     Name = name;
 }
示例#8
0
 public ExpressionProperty(int offset, int length, ExpressionNode expression) : base(offset, length)
 {
     Expression = expression;
 }
示例#9
0
            protected override void VisitValueExpression(
                XElement element, XAttribute attribute,
                MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute,
                ValueInfo info, MSBuildValueKind kind, ExpressionNode node)
            {
                switch (node.Find(offset))
                {
                case ExpressionItem ei:
                    rr.ReferenceKind   = MSBuildReferenceKind.Item;
                    rr.ReferenceOffset = ei.NameOffset;
                    rr.ReferenceLength = ei.Name.Length;
                    rr.Reference       = ei.Name;
                    break;

                case ExpressionPropertyName propName:
                    rr.ReferenceKind   = MSBuildReferenceKind.Property;
                    rr.ReferenceOffset = propName.Offset;
                    rr.Reference       = propName.Name;
                    rr.ReferenceLength = propName.Length;
                    break;

                case ExpressionMetadata em:
                    if (em.ItemName == null || offset >= em.MetadataNameOffset)
                    {
                        rr.ReferenceKind   = MSBuildReferenceKind.Metadata;
                        rr.ReferenceOffset = em.MetadataNameOffset;
                        rr.Reference       = (em.GetItemName(), em.MetadataName);
                        rr.ReferenceLength = em.MetadataName.Length;
                    }
                    else
                    {
                        rr.ReferenceKind   = MSBuildReferenceKind.Item;
                        rr.ReferenceOffset = em.ItemNameOffset;
                        rr.Reference       = em.ItemName;
                        rr.ReferenceLength = em.ItemName.Length;
                    }
                    break;

                case ExpressionText lit:
                    kind = kind.GetScalarType();
                    if (lit.IsPure)
                    {
                        VisitPureLiteral(info, kind, lit);
                        if (kind == MSBuildValueKind.TaskOutputParameterName)
                        {
                            rr.ReferenceKind   = MSBuildReferenceKind.TaskParameter;
                            rr.ReferenceOffset = lit.Offset;
                            rr.ReferenceLength = lit.Value.Length;
                            rr.Reference       = (element.ParentElement().Name.Name, lit.Value);
                            break;
                        }
                    }
                    switch (kind)
                    {
                    case MSBuildValueKind.File:
                    case MSBuildValueKind.FileOrFolder:
                    case MSBuildValueKind.ProjectFile:
                    case MSBuildValueKind.TaskAssemblyFile:
                        var pathNode = lit.Parent as Expression ?? (ExpressionNode)lit;
                        var path     = MSBuildNavigation.GetPathFromNode(pathNode, (MSBuildRootDocument)Document);
                        if (path != null)
                        {
                            rr.ReferenceKind   = MSBuildReferenceKind.FileOrFolder;
                            rr.ReferenceOffset = path.Offset;
                            rr.ReferenceLength = path.Length;
                            rr.Reference       = path.Paths;
                        }
                        break;
                    }
                    break;
                }
            }
            protected override void VisitValueExpression(
                XElement element, XAttribute attribute,
                MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute,
                ValueInfo info, MSBuildValueKind kind, ExpressionNode node)
            {
                switch (node.Find(offset))
                {
                case ExpressionItemName ei:
                    rr.ReferenceKind   = MSBuildReferenceKind.Item;
                    rr.ReferenceOffset = ei.Offset;
                    rr.ReferenceLength = ei.Name.Length;
                    rr.Reference       = ei.Name;
                    break;

                case ExpressionPropertyName propName:
                    rr.ReferenceKind   = MSBuildReferenceKind.Property;
                    rr.ReferenceOffset = propName.Offset;
                    rr.Reference       = propName.Name;
                    rr.ReferenceLength = propName.Length;
                    break;

                case ExpressionMetadata em:
                    if (em.ItemName == null || offset >= em.MetadataNameOffset)
                    {
                        rr.ReferenceKind   = MSBuildReferenceKind.Metadata;
                        rr.ReferenceOffset = em.MetadataNameOffset;
                        rr.Reference       = (em.GetItemName(), em.MetadataName);
                        rr.ReferenceLength = em.MetadataName.Length;
                    }
                    else
                    {
                        rr.ReferenceKind   = MSBuildReferenceKind.Item;
                        rr.ReferenceOffset = em.ItemNameOffset;
                        rr.Reference       = em.ItemName;
                        rr.ReferenceLength = em.ItemName.Length;
                    }
                    break;

                case ExpressionFunctionName name:
                    rr.ReferenceOffset = name.Offset;
                    rr.ReferenceLength = name.Name.Length;
                    if (name.Parent is ExpressionItemNode item)
                    {
                        rr.ReferenceKind = MSBuildReferenceKind.ItemFunction;
                        rr.Reference     = name.Name;
                    }
                    else if (name.Parent is ExpressionPropertyFunctionInvocation prop)
                    {
                        if (prop.Target is ExpressionClassReference classRef)
                        {
                            rr.ReferenceKind = MSBuildReferenceKind.StaticPropertyFunction;
                            rr.Reference     = (classRef.Name, name.Name);
                        }
                        else
                        {
                            var type = FunctionCompletion.ResolveType(prop.Target);
                            rr.ReferenceKind = MSBuildReferenceKind.PropertyFunction;
                            rr.Reference     = (type, name.Name);
                        }
                    }
                    break;

                case ExpressionClassReference cr:
                    if (!string.IsNullOrEmpty(cr.Name))
                    {
                        if (cr.Parent is ExpressionArgumentList)
                        {
                            rr.ReferenceKind = MSBuildReferenceKind.Enum;
                        }
                        else if (cr.Parent is ExpressionPropertyFunctionInvocation)
                        {
                            rr.ReferenceKind = MSBuildReferenceKind.ClassName;
                        }
                        else
                        {
                            break;
                        }
                        rr.ReferenceOffset = cr.Offset;
                        rr.Reference       = cr.Name;
                        rr.ReferenceLength = cr.Length;
                    }
                    break;

                case ExpressionText lit:
                    kind = kind.GetScalarType();
                    if (lit.IsPure)
                    {
                        VisitPureLiteral(element, info, kind, lit);
                        if (kind == MSBuildValueKind.TaskOutputParameterName)
                        {
                            rr.ReferenceKind   = MSBuildReferenceKind.TaskParameter;
                            rr.ReferenceOffset = lit.Offset;
                            rr.ReferenceLength = lit.Value.Length;
                            rr.Reference       = (element.ParentElement().Name.Name, lit.Value);
                            break;
                        }
                    }
                    switch (kind)
                    {
                    case MSBuildValueKind.File:
                    case MSBuildValueKind.FileOrFolder:
                    case MSBuildValueKind.ProjectFile:
                    case MSBuildValueKind.TaskAssemblyFile:
                        var pathNode = lit.Parent as Expression ?? (ExpressionNode)lit;
                        var path     = MSBuildNavigation.GetPathFromNode(pathNode, (MSBuildRootDocument)Document);
                        if (path != null)
                        {
                            rr.ReferenceKind   = MSBuildReferenceKind.FileOrFolder;
                            rr.ReferenceOffset = path.Offset;
                            rr.ReferenceLength = path.Length;
                            rr.Reference       = path.Paths;
                        }
                        break;
                    }
                    break;
                }
            }
示例#11
0
            protected override void VisitValueExpression(XElement element, XAttribute attribute, MSBuildLanguageElement resolvedElement, MSBuildLanguageAttribute resolvedAttribute, ValueInfo info, MSBuildValueKind kind, ExpressionNode node)
            {
                switch (kind.GetScalarType())
                {
                case MSBuildValueKind.TargetName:
                    foreach (var n in node.WithAllDescendants())
                    {
                        if (n is ExpressionText lit && lit.IsPure)
                        {
                            Navigations.Add(new MSBuildNavigationResult(
                                                MSBuildReferenceKind.Target, lit.Value, lit.Offset, lit.Length
                                                ));
                        }
                    }
                    break;

                case MSBuildValueKind.File:
                case MSBuildValueKind.FileOrFolder:
                case MSBuildValueKind.ProjectFile:
                case MSBuildValueKind.TaskAssemblyFile:
                case MSBuildValueKind.Unknown:
                    if (node is ExpressionList list)
                    {
                        foreach (var n in list.Nodes)
                        {
                            var p = GetPathFromNode(n, (MSBuildRootDocument)Document);
                            if (p != null)
                            {
                                Navigations.Add(p);
                            }
                        }
                    }
                    var path = GetPathFromNode(node, (MSBuildRootDocument)Document);
                    if (path != null)
                    {
                        Navigations.Add(path);
                    }
                    break;
                }
            }