コード例 #1
0
        /// <summary>
        ///     Add an unresolved SDK-style import (i.e. condition is false).
        /// </summary>
        /// <param name="import">
        ///     The declaring import element.
        /// </param>
        void AddUnresolvedSdkImport(ProjectImportElement import)
        {
            if (import == null)
            {
                throw new ArgumentNullException(nameof(import));
            }

            Position importStart = import.Location.ToNative();

            XmlLocation importLocation = _projectXmlLocator.Inspect(importStart);

            if (importLocation == null)
            {
                return;
            }

            XSElement importElement;

            if (!importLocation.IsElement(out importElement))
            {
                return;
            }

            XSAttribute sdkAttribute = importElement["Sdk"];

            Add(
                new MSBuildUnresolvedSdkImport(import, sdkAttribute)
                );
        }
コード例 #2
0
        /// <summary>
        ///     Does the location represent a place where an attribute value can be created or replaced by a completion?
        /// </summary>
        /// <param name="location">
        ///     The XML location.
        /// </param>
        /// <param name="targetAttribute">
        ///     The attribute (if any) whose value will be replaced by the completion.
        /// </param>
        /// <param name="onElementWithPath">
        ///     If specified, attribute's element must have the specified path.
        /// </param>
        /// <param name="forAttributeNamed">
        ///     If specified, the attribute must have one of the specified names.
        /// </param>
        /// <returns>
        ///     <c>true</c>, if the location represents an attribute whose value can be replaced by a completion; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanCompleteAttributeValue(this XmlLocation location, out XSAttribute targetAttribute, XSPath onElementWithPath = null, params string[] forAttributeNamed)
        {
            if (location == null)
            {
                throw new ArgumentNullException(nameof(location));
            }

            targetAttribute = null;

            XSAttribute attribute;

            if (!location.IsAttributeValue(out attribute))
            {
                return(false);
            }

            if (onElementWithPath != null && !attribute.HasParentPath(onElementWithPath))
            {
                return(false);
            }

            if (forAttributeNamed.Length > 0 && Array.IndexOf(forAttributeNamed, attribute.Name) == -1)
            {
                return(false);
            }

            targetAttribute = attribute;

            return(true);
        }
コード例 #3
0
        /// <summary>
        ///     Does the location represent an attribute's value?
        /// </summary>
        /// <param name="location">
        ///     The XML location.
        /// </param>
        /// <param name="attribute">
        ///     Receives the attribute whose value is represented by the location.
        /// </param>
        /// <returns>
        ///     <c>true</c>, if the location represents an attribute's name; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsAttributeValue(this XmlLocation location, out XSAttribute attribute)
        {
            if (location.IsAttributeValue())
            {
                attribute = (XSAttribute)location.Node;

                return(true);
            }

            attribute = null;

            return(false);
        }
コード例 #4
0
        /// <summary>
        ///     Does the location represent an attribute?
        /// </summary>
        /// <param name="location">
        ///     The XML location.
        /// </param>
        /// <param name="attribute">
        ///     Receives the <see cref="XSAttribute"/>.
        /// </param>
        /// <returns>
        ///     <c>true</c>, if the location represents an attribute; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsAttribute(this XmlLocation location, out XSAttribute attribute)
        {
            if (location == null)
            {
                throw new ArgumentNullException(nameof(location));
            }

            if (!location.IsAttribute())
            {
                attribute = null;

                return(false);
            }

            attribute = (XSAttribute)location.Node;

            return(true);
        }
コード例 #5
0
        /// <summary>
        ///     Add an SDK-style import.
        /// </summary>
        /// <param name="resolvedImports">
        ///     The resolved imports resulting from the import declaration.
        /// </param>
        void AddSdkImport(IEnumerable <ResolvedImport> resolvedImports)
        {
            if (resolvedImports == null)
            {
                throw new ArgumentNullException(nameof(resolvedImports));
            }

            ResolvedImport firstImport = resolvedImports.First();
            Position       importStart = firstImport.ImportingElement.Location.ToNative();

            // If the Sdk attribute is on the Project element rather than an import element, then the location reported by MSBuild will be invalid (go figure).
            if (importStart == Position.Invalid)
            {
                importStart = Position.Origin;
            }

            XmlLocation importLocation = _projectXmlLocator.Inspect(importStart);

            if (importLocation == null)
            {
                return;
            }

            XSElement importElement;

            if (!importLocation.IsElement(out importElement))
            {
                return;
            }

            XSAttribute sdkAttribute = importElement["Sdk"];

            if (sdkAttribute == null)
            {
                return;
            }

            Add(
                new MSBuildSdkImport(resolvedImports.ToArray(), sdkAttribute)
                );
        }
コード例 #6
0
            /// <summary>
            ///     Visit an <see cref="XmlAttributeSyntax"/>.
            /// </summary>
            /// <param name="attribute">
            ///     The <see cref="XmlAttributeSyntax"/>.
            /// </param>
            /// <returns>
            ///     The <see cref="XmlAttributeSyntax"/> (unchanged).
            /// </returns>
            public override SyntaxNode VisitXmlAttribute(XmlAttributeSyntax attribute)
            {
                if (!HaveCurrentElement)
                {
                    return(attribute);
                }

                Range attributeRange = attribute.Span.ToNative(_textPositions);
                Range nameRange      = attribute.NameNode?.Span.ToNative(_textPositions) ?? attributeRange;
                Range valueRange     = attribute.ValueNode?.Span.ToNative(_textPositions) ?? Range.Zero;

                if (valueRange != Range.Zero && valueRange.End.ColumnNumber - valueRange.Start.ColumnNumber >= 2)
                {
                    valueRange = valueRange.Transform(moveStartColumns: 1, moveEndColumns: -1); // Trim off quotes.
                }
                else
                {
                    valueRange = nameRange;
                }

                XSAttribute xsAttribute;

                if (String.IsNullOrWhiteSpace(attribute.Name) || nameRange == attributeRange || valueRange == attributeRange)
                {
                    xsAttribute = new XSInvalidAttribute(attribute, CurrentElement, attributeRange, nameRange, valueRange);
                }
                else
                {
                    xsAttribute = new XSAttribute(attribute, CurrentElement, attributeRange, nameRange, valueRange);
                }

                CurrentElement.Attributes = CurrentElement.Attributes.Add(xsAttribute);
                DiscoveredNodes.Add(xsAttribute);

                return(attribute);
            }
コード例 #7
0
        /// <summary>
        ///     Does the location represent a place where an attribute can be created or replaced by a completion?
        /// </summary>
        /// <param name="location">
        ///     The XML location.
        /// </param>
        /// <param name="element">
        ///     The element whose attribute will be completed.
        /// </param>
        /// <param name="replaceAttribute">
        ///     The attribute (if any) that will be replaced by the completion.
        /// </param>
        /// <param name="needsPadding">
        ///     An <see cref="PaddingType"/> value indicating what sort of padding (if any) is required before / after the attribute.
        /// </param>
        /// <param name="onElementWithPath">
        ///     If specified, the location's element must have the specified path.
        /// </param>
        /// <returns>
        ///     <c>true</c>, if the location represents an element that can be replaced by completion; otherwise, <c>false</c>.
        /// </returns>
        public static bool CanCompleteAttribute(this XmlLocation location, out XSElement element, out XSAttribute replaceAttribute, out PaddingType needsPadding, XSPath onElementWithPath = null)
        {
            if (location == null)
            {
                throw new ArgumentNullException(nameof(location));
            }

            replaceAttribute = null;
            needsPadding     = PaddingType.None;

            XSAttribute attribute;

            if (location.IsAttribute(out attribute) && !location.IsValue())
            {
                element = attribute.Element;
                if (location.Position == attribute.Start)
                {
                    // Since we're on an existing attribute, we'll add a new attribute after it.
                    attribute    = null;
                    needsPadding = PaddingType.Trailing;
                }
            }
            else if (location.IsElementBetweenAttributes(out element))
            {
                if (element.Attributes.Count > 0)
                {
                    // Check if we're directly before an attribute.
                    foreach (XSAttribute currentAttribute in element.Attributes)
                    {
                        if (location.Position == currentAttribute.End)
                        {
                            needsPadding = PaddingType.Leading;
                        }
                        else
                        {
                            continue;
                        }

                        break;
                    }
                }
                else if (location.Position == element.NameRange.End) // We're directly after the name.
                {
                    needsPadding = PaddingType.Leading;
                }
            }
            else if (location.IsElement(out element))
            {
                // Check if we're directly after the name.
                if (location.Position != element.NameRange.End)
                {
                    return(false);
                }

                needsPadding = PaddingType.Leading;
            }
            else
            {
                return(false);
            }

            if (onElementWithPath != null && !element.Path.Matches(onElementWithPath))
            {
                return(false);
            }

            replaceAttribute = attribute;

            return(true);
        }
コード例 #8
0
        /// <summary>
        ///     Does the location represent an element that has the specified attribute?
        /// </summary>
        /// <param name="location">
        ///     The XML location.
        /// </param>
        /// <param name="attributeName">
        ///     The attribute name.
        /// </param>
        /// <param name="attribute">
        ///     Receives the attribute.
        /// </param>
        /// <returns>
        ///     <c>true</c>, if the location represents an element with the specified attribute; otherwise, <c>false</c>.
        /// </returns>
        public static bool HasAttribute(this XmlLocation location, string attributeName, out XSAttribute attribute)
        {
            if (location.IsElement(out XSElement element))
            {
                attribute = element[attributeName];

                return(attribute != null);
            }

            attribute = null;

            return(false);
        }
コード例 #9
0
 /// <summary>
 ///     Create a new <see cref="MSBuildImport"/>.
 /// </summary>
 /// <param name="imports">
 ///     A read-only list of underlying MSBuild <see cref="ResolvedImport"/>s representing the imports resulting from the SDK import.
 /// </param>
 /// <param name="sdkAttribute">
 ///     An <see cref="XSAttribute"/> representing the import's "Sdk" attribute.
 /// </param>
 public MSBuildSdkImport(IReadOnlyList <ResolvedImport> imports, XSAttribute sdkAttribute)
     : base(imports, sdkAttribute)
 {
 }
コード例 #10
0
 /// <summary>
 ///     Create a new <see cref="MSBuildUnresolvedSdkImport"/>.
 /// </summary>
 /// <param name="import">
 ///     The underlying MSBuild <see cref="ProjectImportElement"/>.
 /// </param>
 /// <param name="sdkAttribute">
 ///     An <see cref="XSAttribute"/> representing the import's "Sdk" attribute.
 /// </param>
 public MSBuildUnresolvedSdkImport(ProjectImportElement import, XSAttribute sdkAttribute)
     : base(import, sdkAttribute)
 {
 }