示例#1
0
        /// <nodoc />
        public static int FitsOnOneLine(INodeArray <INode> nodes, int separatorSize, int remainingSpace)
        {
            if (nodes.IsNullOrEmpty())
            {
                return(remainingSpace);
            }

            if (nodes.Count > 5)
            {
                // Always print more than 5 nodes on separate lines.
                return(-1);
            }

            int space = remainingSpace;

            foreach (var node in nodes.AsStructEnumerable())
            {
                if (space != remainingSpace)
                {
                    // Subtract space for separators on subsequent nodes
                    space -= separatorSize;
                }

                space = FitsOnOneLine(node, space);
                if (space < 0)
                {
                    // if it already doesn't fit, the rest won't fit either
                    return(space);
                }
            }

            return(space);
        }
示例#2
0
        /// <nodoc/>
        public NodeOrNodesOrNull([NotNull] INode node)
        {
            Contract.Requires(node != null);

            Node  = node;
            Nodes = null;
        }
示例#3
0
        private static int CompareNodeArrays <T>(INodeArray <T> left, INodeArray <T> right, Comparison <T> comparer)
        {
            var leftCount  = left.Count;
            var rightCount = right.Count;

            for (int i = 0; i < leftCount; i++)
            {
                if (i >= rightCount)
                {
                    return(1); // right is smaller
                }

                var result = comparer(left[i], right[i]);
                if (result != 0)
                {
                    return(result);
                }
            }

            if (rightCount > leftCount)
            {
                return(-1); // left is smaller;
            }

            return(0);
        }
示例#4
0
        public static AccessorDeclarations GetAllAccessorDeclarations(INodeArray <IDeclaration> declarations, IAccessorDeclaration accessor)
        {
            IAccessorDeclaration firstAccessor  = null;
            IAccessorDeclaration secondAccessor = null;
            IAccessorDeclaration getAccessor    = null;
            IAccessorDeclaration setAccessor    = null;

            if (HasDynamicName(accessor))
            {
                firstAccessor = accessor;
                if (accessor.Kind == SyntaxKind.GetAccessor)
                {
                    getAccessor = accessor;
                }
                else if (accessor.Kind == SyntaxKind.SetAccessor)
                {
                    setAccessor = accessor;
                }
                else
                {
                    Contract.Assert(false, "Accessor has wrong kind");
                }
            }
            else
            {
                NodeArrayExtensions.ForEach(declarations, member =>
                {
                    if ((member.Kind == SyntaxKind.GetAccessor || member.Kind == SyntaxKind.SetAccessor) &&
                        (member.Flags & NodeFlags.Static) == (accessor.Flags & NodeFlags.Static))
                    {
                        var memberName   = GetPropertyNameForPropertyNameNode(member.Name);
                        var accessorName = GetPropertyNameForPropertyNameNode(accessor.Name);
                        if (memberName == accessorName)
                        {
                            if (firstAccessor == null)
                            {
                                firstAccessor = member.Cast <IAccessorDeclaration>();
                            }
                            else if (secondAccessor == null)
                            {
                                secondAccessor = member.Cast <IAccessorDeclaration>();
                            }

                            if (member.Kind == SyntaxKind.GetAccessor && getAccessor == null)
                            {
                                getAccessor = member.Cast <IAccessorDeclaration>();
                            }

                            if (member.Kind == SyntaxKind.SetAccessor && setAccessor == null)
                            {
                                setAccessor = member.Cast <IAccessorDeclaration>();
                            }
                        }
                    }
                });
            }

            return(new AccessorDeclarations(firstAccessor, secondAccessor, getAccessor, setAccessor));
        }
示例#5
0
        public static T First <T>(this INodeArray <T> @this)
        {
            if (@this.Count == 0)
            {
                throw new InvalidOperationException("The sequence contains no elements");
            }

            return(@this[0]);
        }
示例#6
0
        /// <nodoc />
        public static T ElementAtOrDefault <T>(this INodeArray <T> @this, int index)
        {
            if (index < @this.Count)
            {
                return(@this[index]);
            }

            return(default(T));
        }
示例#7
0
        private static T VisitNodeArray <T>(Func <NodeOrNodesOrNull, T> cbNodes, INodeArray <INode> nodes)
        {
            if (nodes != null)
            {
                return(cbNodes(new NodeOrNodesOrNull(nodes)));
            }

            return(default(T));
        }
示例#8
0
        /// <summary>
        /// Calls a given callback for every element in a <paramref name="sequence"/>.
        /// </summary>
        public static void ForEach <TElement, TState>([CanBeNull] INodeArray <TElement> sequence, TState state, Action <TElement, TState> callback)
        {
            if (sequence == null)
            {
                return;
            }

            for (int i = 0; i < sequence.Count; i++)
            {
                callback(sequence[i], state);
            }
        }
示例#9
0
        private List <Expression> EnumerateTaggedExpressionsForPathAtomInterpolation(
            ITemplateLiteralFragment headNode,
            INodeArray <ITemplateSpan> templateSpans,
            FunctionScope escapes,
            QualifierSpaceId currentQualifierSpaceId)
        {
            // Creating a list that will hold all potential expressions
            List <Expression> result = new List <Expression>((templateSpans.Length * 2) + 1);

            string head = headNode.Text;

            if (!string.IsNullOrEmpty(head))
            {
                var convertedPathAtomLiteral = m_literalConverter.ConvertPathAtomLiteral(head, Location(headNode));

                if (convertedPathAtomLiteral == null)
                {
                    // Error has been reported.
                    return(null);
                }

                result.Add(convertedPathAtomLiteral);
            }

            foreach (var span in templateSpans.AsStructEnumerable())
            {
                if (span.Expression != null)
                {
                    var convertedExpression = m_converter.ConvertExpression(span.Expression, escapes, currentQualifierSpaceId);
                    if (convertedExpression != null)
                    {
                        result.Add(convertedExpression);
                    }
                }

                var fragment = span.Literal.Text;

                if (!string.IsNullOrEmpty(fragment))
                {
                    var convertedPathAtomLiteral = m_literalConverter.ConvertPathAtomLiteral(fragment, Location(span.Literal));

                    if (convertedPathAtomLiteral == null)
                    {
                        // Error has been reported.
                        return(null);
                    }

                    result.Add(convertedPathAtomLiteral);
                }
            }

            return(result);
        }
示例#10
0
        private static T VisitEachNode <T>(Func <NodeOrNodesOrNull, T> cbNode, INodeArray <INode> nodes) where T : class
        {
            if (nodes != null)
            {
                foreach (var node in nodes.AsStructEnumerable())
                {
                    var result = cbNode(new NodeOrNodesOrNull(node));
                    if (result != null)
                    {
                        return(result);
                    }
                }
            }

            return(default(T));
        }
示例#11
0
        /// <summary>
        /// Iterates through <paramref name="array"/> and performs the callback on each element of array until the callback
        /// returns a truthy value, then returns that value.
        /// If no such value is found, the callback is applied to each element of array and default(T) is returned.
        /// </summary>
        public static TResult ForEachUntil <TElement, TResult>([CanBeNull] INodeArray <TElement> array, Func <TElement, TResult> callback)
        {
            if (array != null)
            {
                for (int i = 0; i < array.Count; i++)
                {
                    var result = callback(array[i]);
                    if (result != null)
                    {
                        return(result);
                    }
                }
            }

            return(default(TResult));
        }
示例#12
0
        /// <summary>
        /// Custom implementation for 'Any' LINQ-like method that accepts <code>null</code> as a collection value
        /// and avoid allocations during collection enumeration.
        /// </summary>
        public static bool Any <TElement>([CanBeNull] INodeArray <TElement> sequence, Func <TElement, bool> callback)
        {
            if (sequence == null)
            {
                return(false);
            }

            for (int i = 0; i < sequence.Count; i++)
            {
                var result = callback(sequence[i]);
                if (result)
                {
                    return(true);
                }
            }

            return(false);
        }
示例#13
0
            public ProcessedTagTemplateExpression(
                ITaggedTemplateExpression taggedTemplate,
                InterpolationKind kind,
                ILiteralExpression literal,
                ITemplateLiteralFragment head,
                INodeArray <ITemplateSpan> templateSpans)
            {
                Contract.Requires(taggedTemplate != null);
                Contract.Requires(
                    kind == InterpolationKind.Unknown || (literal != null || (head != null && templateSpans != null)),
                    "If interpolation is a well-known factory method, then Literal or Head+Templates should be valid.");

                TaggedTemplate = taggedTemplate;
                Kind           = kind;
                Literal        = literal;
                Head           = head;
                TemplateSpans  = templateSpans;
            }
示例#14
0
 /// <summary>
 /// Returns the first
 /// </summary>
 public static T First <T>(this INodeArray <T> array)
 {
     return(NodeArrayExtensions.First(array));
 }
示例#15
0
文件: Graph.cs 项目: DragonXYZ/cilpe
            public Enumerator(Switch sw)
            {
                this.sw = sw;
                nextArray = sw.NextArray;

                index = sw.curIndex;
                sw.curIndex++;

                position = 0;
            }
示例#16
0
        private List <Expression> EnumerateTemplateSpans(
            ITemplateLiteralFragment headNode,
            INodeArray <ITemplateSpan> templateSpans,
            FunctionScope escapes,
            QualifierSpaceId currentQualifierSpaceId,
            bool isRelativePath)
        {
            Contract.Requires(headNode != null);
            Contract.Requires(templateSpans != null);

            // Creating a list that will hold all potential expressions
            List <Expression> result = new List <Expression>((templateSpans.Length * 2) + 1);

            // Example: 'path/to/{x}/abc/{y}'.
            // - Head is 'path/to/'
            // - Spans:
            //   1. '{x}/abc/': expr 'x', literal '/abc/'
            //   2. '{y}': expr 'y', no literal.

            // For instance in this case: p`foo/${x}/${y}` the result equals p`foo`.combine(x).combine(y);
            // and for this case: p`${x}` the result equals x.
            // Note that  p`path/to/abc` equals as p`./path/to/abc`. Thus for p`${x}/path/to/abc`, x should evaluate to an absolute path,
            // and such a construct equals x.combine("path").combine("to"). combine("abc").
            string head = headNode.Text;

            if (!string.IsNullOrEmpty(head))
            {
                // Example: 'path/to/'
                if (!HasTailingPathSeparator(head))
                {
                    string message = I($"Path fragment '{head}' does not have a tailing path separator.");
                    RuntimeModelContext.Logger.ReportInvalidPathInterpolationExpression(
                        RuntimeModelContext.LoggingContext,
                        Location(headNode).AsLoggingLocation(),
                        message);
                    return(null);
                }

                if (!isRelativePath)
                {
                    // Tagged expression is expected to be an absolute path.
                    var convertedPathLiteral =
                        m_literalConverter.ConvertPathLiteral(
                            RemoveLeadingAndTailingPathSeparatorIfNeeded(head, isAbsolutePath: true),
                            Location(headNode));

                    if (convertedPathLiteral == null)
                    {
                        // Error has been reported.
                        return(null);
                    }

                    result.Add(convertedPathLiteral);
                }
                else
                {
                    // Tagged expression is expected to be a relative path.
                    var convertedRelativePathLiteral = m_literalConverter.ConvertRelativePathLiteral(
                        RemoveLeadingAndTailingPathSeparatorIfNeeded(head, isAbsolutePath: false),
                        Location(headNode));

                    if (convertedRelativePathLiteral == null)
                    {
                        // Error has been reported.
                        return(null);
                    }

                    result.Add(convertedRelativePathLiteral);
                }
            }

            for (int i = 0; i < templateSpans.Length; i++)
            {
                //// TODO: Currently fragment is string literal. This somehow defeats the purpose of paths.
                //// TODO: We need to find a syntactic representation of relative path that differs from string.
                var span = templateSpans[i];

                // Example: span is '{x}/abc/'.
                if (span.Expression != null)
                {
                    // Grab 'x' from '{x}/abc/'.
                    var convertedExpression = m_converter.ConvertExpression(span.Expression, escapes, currentQualifierSpaceId);
                    if (convertedExpression != null)
                    {
                        result.Add(convertedExpression);
                    }
                }

                // Fragment is '/abc/'.
                var fragment = span.Literal.Text;

                // For every expression (except last one), interpolated path should have a separator
                if (string.IsNullOrEmpty(fragment) && span.Expression != null)
                {
                    // Fragment is empty or consists only of whitespaces, but expression is present, e.g., span (2) -- '{y}'.
                    if (i == templateSpans.Length - 1)
                    {
                        // Last template span, nothing to do, separator could be empty.
                        continue;
                    }

                    // Not the last template span, thus needs a path separator.
                    string message = "Each path fragment in interpolated path literal should have a path separator between expressions.";
                    RuntimeModelContext.Logger.ReportInvalidPathInterpolationExpression(
                        RuntimeModelContext.LoggingContext,
                        Location(span.Literal).AsLoggingLocation(),
                        message);
                    return(null);
                }

                // Skip if fragment is only a separator, e.g., '{w}/{z}'.
                if (IsPathSeparator(fragment))
                {
                    continue;
                }

                // Fragments should start with path separator, e.g., '/abc/'.
                if (!HasLeadingPathSeparator(fragment))
                {
                    string message = I($"Path fragment '{fragment}' does not have a leading path separator.");
                    RuntimeModelContext.Logger.ReportInvalidPathInterpolationExpression(
                        RuntimeModelContext.LoggingContext,
                        Location(span.Literal).AsLoggingLocation(),
                        message);
                    return(null);
                }

                // All fragments except last one must have a trailing separator, e.g., '/abc/'.
                if (i != templateSpans.Length - 1 && !HasTailingPathSeparator(fragment))
                {
                    string message = I($"Path fragment '{fragment}' does not have a trailing path separator.");
                    RuntimeModelContext.Logger.ReportInvalidPathInterpolationExpression(
                        RuntimeModelContext.LoggingContext,
                        Location(span.Literal).AsLoggingLocation(),
                        message);
                    return(null);
                }

                // Remove '/' from '/abc/'.
                var    textFragment = RemoveLeadingAndTailingPathSeparatorIfNeeded(fragment, isAbsolutePath: false);
                string literal      = textFragment.Length == fragment.Length ? fragment : textFragment.ToString();
                result.Add(new StringLiteral(literal, LineInfo(span.Literal)));
            }

            return(result);
        }
示例#17
0
 /// <nodoc/>
 public NodeOrNodesOrNull([NotNull] INodeArray <INode> nodes)
 {
     Contract.Requires(nodes != null);
     Node  = null;
     Nodes = nodes;
 }
示例#18
0
 /// <nodoc />
 public static NodeArray.NodeArraySelectorEnumerable <TSource, TResult> Select <TSource, TResult>(this INodeArray <TSource> sequence, Func <TSource, TResult> selector)
 {
     return(new NodeArray.NodeArraySelectorEnumerable <TSource, TResult>(sequence, selector));
 }
示例#19
0
 /// <nodoc />
 public NodeOrNodeArray(INodeArray <INode> nodes)
     : this()
 {
     Nodes = nodes;
 }
示例#20
0
 private static NodeOrNodeArray Nodes([NotNull] INodeArray <INode> nodes)
 {
     return(new NodeOrNodeArray(nodes));
 }
示例#21
0
 /// <summary>
 /// Returns true when <paramref name="array"/> is null or empty.
 /// </summary>
 public static bool IsNullOrEmpty <T>([CanBeNull] this INodeArray <T> array)
 {
     return(array == null || array.Count == 0);
 }
示例#22
0
 /// <summary>
 /// Returns true when <paramref name="array"/> is null or empty.
 /// </summary>
 public static bool IsNullOrEmpty <T>(this INodeArray <T> array)
 {
     return(NodeArrayExtensions.IsNullOrEmpty(array));
 }
示例#23
0
        /// <summary>
        /// Deconstructs a template expression.
        /// </summary>
        /// <remarks>
        /// "pattern matches" a tagged template expression into two cases:
        /// 1. Literal case like <code>p`string literal`</code> (in this case <paramref name="literal"/> would not be null).
        /// 2. Template expression case like <code>p`{foo}</code> (in this case <paramref name="head"/> and <paramref name="templateSpans"/> are not null).
        /// </remarks>
        public static void Deconstruct(
            [CanBeNull] this ITaggedTemplateExpression node,
            out InterpolationKind kind,
            out ILiteralExpression literal,
            out ITemplateLiteralFragment head,
            out INodeArray <ITemplateSpan> templateSpans)
        {
            kind          = InterpolationKind.Unknown;
            literal       = null;
            head          = null;
            templateSpans = null;

            if (node == null)
            {
                return;
            }

            if (node.Tag.Kind != SyntaxKind.Identifier)
            {
                // Looks like the tagged expression is invalid.
                return;
            }

            var text = node.Tag.Cast <IIdentifier>().Text;

            kind = GetInterpolationKind(text);

            if (kind == InterpolationKind.Unknown)
            {
                return;
            }

            literal = node.TemplateExpression.As <ILiteralExpression>();
            if (literal == null)
            {
                // This is another case: tagged template actually has template expressions.
                var template = node.TemplateExpression.Cast <ITemplateExpression>();
                head          = template.Head;
                templateSpans = template?.TemplateSpans;

                Contract.Assert(head != null);
                Contract.Assert(templateSpans != null);
            }

            InterpolationKind GetInterpolationKind(string factoryName)
            {
                if (factoryName.Length == 0)
                {
                    return(InterpolationKind.StringInterpolation);
                }

                var c = factoryName[0];

                switch (c)
                {
                case Names.PathInterpolationFactory:
                    return(InterpolationKind.PathInterpolation);

                case Names.DirectoryInterpolationFactory:
                    return(InterpolationKind.DirectoryInterpolation);

                case Names.FileInterpolationFactory:
                    return(InterpolationKind.FileInterpolation);

                case Names.RelativePathInterpolationFactory:
                    return(InterpolationKind.RelativePathInterpolation);

                case Names.PathAtomInterpolationFactory:
                    return(InterpolationKind.PathAtomInterpolation);

                default:
                    return(InterpolationKind.Unknown);
                }
            }
        }
示例#24
0
 /// <nodoc />
 public static T FirstOrDefault <T>(this INodeArray <T> @this)
 {
     return(@this.Count == 0 ? default(T) : @this[0]);
 }