/// <summary>
 /// Adds diagnostics from useSiteDiagnostics into diagnostics and returns True if there were any errors.
 /// </summary>
 internal static bool Add(
     this DiagnosticBag diagnostics,
     CSharpSyntaxNode node,
     HashSet<DiagnosticInfo> useSiteDiagnostics)
 {
     return !useSiteDiagnostics.IsNullOrEmpty() && diagnostics.Add(node.Location, useSiteDiagnostics);
 }
        internal static bool Add(
            this DiagnosticBag diagnostics,
            Location location,
            HashSet<DiagnosticInfo> useSiteDiagnostics)
        {
            if (useSiteDiagnostics.IsNullOrEmpty())
            {
                return false;
            }

            bool haveErrors = false;

            foreach (var info in useSiteDiagnostics)
            {
                if (info.Severity == DiagnosticSeverity.Error)
                {
                    haveErrors = true;
                }

                diagnostics.Add(new CSDiagnostic(info, location));
            }

            return haveErrors;
        }
        /// <summary>
        /// Appends diagnostics from useSiteDiagnostics into diagnostics and returns True if there were any errors.
        /// </summary>
        internal static bool AppendUseSiteDiagnostics(
            SyntaxNode node,
            HashSet<DiagnosticInfo> useSiteDiagnostics,
            DiagnosticBag diagnostics)
        {
            if (useSiteDiagnostics.IsNullOrEmpty())
            {
                return false;
            }

            bool haveErrors = false;

            foreach (var info in useSiteDiagnostics)
            {
                if (info.Severity == DiagnosticSeverity.Error)
                {
                    haveErrors = true;
                }

                Error(diagnostics, info, node);
            }

            return haveErrors;
        }
Example #4
0
        private static bool AppendUseSiteDiagnostics(
            HashSet<DiagnosticInfo> useSiteDiagnostics,
            TypeParameterSymbol typeParameter,
            ref ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder)
        {
            if (useSiteDiagnostics.IsNullOrEmpty())
            {
                return false;
            }

            if (useSiteDiagnosticsBuilder == null)
            {
                useSiteDiagnosticsBuilder = new ArrayBuilder<TypeParameterDiagnosticInfo>();
            }

            bool hasErrors = false;

            foreach (var info in useSiteDiagnostics)
            {
                if (info.Severity == DiagnosticSeverity.Error)
                {
                    hasErrors = true;
                }

                useSiteDiagnosticsBuilder.Add(new TypeParameterDiagnosticInfo(typeParameter, info));
            }

            return hasErrors;
        }
        /// <summary>
        /// Select from DOM using index. First non-class/tag/id selector will result in this being passed off to GetMatches
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        public IEnumerable<IDomObject> Select(IDomDocument document, IEnumerable<IDomObject> context)
        {
            if (Selectors == null )
            {
                throw new ArgumentException("No selectors provided.");
            }
            if (Selectors.Count == 0)
            {
                yield break;
            }
            Document = document;
            IEnumerable<IDomObject> lastResult = null;
            HashSet<IDomObject> output = new HashSet<IDomObject>();
            IEnumerable<IDomObject> selectionSource = context;

            // Disable the index if there is no context (e.g. disconnected elements)
            bool useIndex = context.IsNullOrEmpty() || !context.First().IsDisconnected;

            // Copy the list because it may change during the process
            ActiveSelectors = new List<Selector>(Selectors);

            for (activeSelectorId = 0; activeSelectorId < ActiveSelectors.Count; activeSelectorId++)
            {
                var selector = ActiveSelectors[activeSelectorId];
                CombinatorType combinatorType = selector.CombinatorType;
                SelectorType selectorType = selector.SelectorType;
                TraversalType traversalType = selector.TraversalType;

                // Determine what kind of combining method we will use with previous selection results

                if (activeSelectorId != 0)
                {
                    switch (combinatorType)
                    {
                        case CombinatorType.Cumulative:
                            // do nothing
                            break;
                        case CombinatorType.Root:
                            selectionSource = context;
                            if (lastResult != null)
                            {
                                output.AddRange(lastResult);
                                lastResult = null;
                            }
                            break;
                        case CombinatorType.Chained:
                            selectionSource = lastResult;
                            lastResult = null;
                            break;
                        // default (chained): leave lastresult alone
                    }
                }

                HashSet<IDomObject> tempResult = null;
                IEnumerable<IDomObject> interimResult = null;

                string key = "";
                if (useIndex && !selector.NoIndex)
                {

            #if DEBUG_PATH

                    if (type.HasFlag(SelectorType.Attribute))
                    {
                        key = "!" + selector.AttributeName;
                        type &= ~SelectorType.Attribute;
                        if (selector.AttributeValue != null)
                        {
                            InsertAttributeValueSelector(selector);
                        }
                    }
                    else if (type.HasFlag(SelectorType.Tag))
                    {
                        key = "+"+selector.Tag;
                        type &= ~SelectorType.Tag;
                    }
                    else if (type.HasFlag(SelectorType.ID))
                    {
                        key = "#" + selector.ID;
                        type &= ~SelectorType.ID;
                    }
                    else if (type.HasFlag(SelectorType.Class))
                    {
                        key = "." + selector.Class;
                        type &= ~SelectorType.Class;
                    }

            #else
                    if (selectorType.HasFlag(SelectorType.Attribute))
                    {
                        key = "!" + (char)DomData.TokenID(selector.AttributeName);
                        selectorType &= ~SelectorType.Attribute;
                        if (selector.AttributeValue != null)
                        {
                            InsertAttributeValueSelector(selector);
                        }
                    }
                    else if (selectorType.HasFlag(SelectorType.Tag))
                    {
                        key = "+" + (char)DomData.TokenID(selector.Tag, true);
                        selectorType &= ~SelectorType.Tag;
                    }
                    else if (selectorType.HasFlag(SelectorType.ID))
                    {
                        key = "#" + (char)DomData.TokenID(selector.ID);
                        selectorType &= ~SelectorType.ID;
                    }
                    else if (selectorType.HasFlag(SelectorType.Class))
                    {
                        key = "." + (char)DomData.TokenID(selector.Class);
                        selectorType &= ~SelectorType.Class;
                    }
            #endif
                }

                // If part of the selector was indexed, key will not be empty. Return initial set from the
                // index. If any selectors remain after this they will be searched the hard way.

                if (key != String.Empty)
                {
                    int depth = 0;
                    bool descendants = true;

                    switch (traversalType)
                    {
                        case TraversalType.Child:
                            depth = selector.ChildDepth; ;
                            descendants = false;
                            break;
                        case TraversalType.Filter:
                            depth = 0;
                            descendants = false;
                            break;
                        case TraversalType.Descendent:
                            depth = 1;
                            descendants = true;
                            break;
                    }

                    if (selectionSource == null)
                    {
                        interimResult = document.QueryIndex(key + DomData.indexSeparator, depth, descendants);
                    }
                    else
                    {
                        interimResult = new HashSet<IDomObject>();
                        foreach (IDomObject obj in selectionSource)
                        {
                            ((HashSet<IDomObject>)interimResult)
                                .AddRange(document.QueryIndex(key + DomData.indexSeparator + obj.Path,
                                    depth, descendants));
                        }
                    }
                }
                else if (selectorType.HasFlag(SelectorType.Elements))
                {
                    selectorType &= ~SelectorType.Elements;
                    HashSet<IDomObject> source = new HashSet<IDomObject>(selectionSource);
                    interimResult = new HashSet<IDomObject>();

                    foreach (IDomObject obj in selectionSource)
                    {
                        key = DomData.indexSeparator + obj.Path;
                        HashSet<IDomObject> srcKeys = new HashSet<IDomObject>(document.QueryIndex(key));
                        foreach (IDomObject match in selector.SelectElements)
                        {
                            if (srcKeys.Contains(match))
                            {
                                ((HashSet<IDomObject>)interimResult).Add(match);
                            }
                        }
                    }
                }
                // TODO - GetMatch should work if passed with no selectors (returning nothing), now it returns everything
                // 12/10/11 - this todo is not verified, much has changed since it was written. TODO confirm this and
                // fix if needed. If having the conversation with self again, remove comments and forget it. This is
                // an example of why comments can do more harm than good.

                if ((selectorType & ~(SelectorType.SubSelectorNot | SelectorType.SubSelectorHas)) != 0)
                {
                    IEnumerable<IDomObject> finalSelectWithin =
                        interimResult
                        ?? (combinatorType == CombinatorType.Chained ? lastResult : null)
                        ?? selectionSource
                        ?? document.ChildElements;

                    // if there are no temporary results (b/c there was no indexed selector) then use the whole set
                    interimResult = GetMatches(finalSelectWithin, selector);

                }

                // Deal with subselectors: has() and not() test for the presence of a selector within the children of
                // an element. This is essentially similar to the manual selection above.

                if (selectorType.HasFlag(SelectorType.SubSelectorHas)
                    || selectorType.HasFlag(SelectorType.SubSelectorNot))
                {
                    bool isHasSelector = selectorType.HasFlag(SelectorType.SubSelectorHas);

                    IEnumerable<IDomObject> subSelectWithin = interimResult
                        ?? (combinatorType == CombinatorType.Chained ? lastResult : null)
                        ?? selectionSource;

                    // subselects are a filter. start a new interim result.

                    HashSet<IDomObject> filteredResults = new HashSet<IDomObject>();

                    foreach (IDomObject obj in subSelectWithin)
                    {
                        bool match = true;
                        foreach (var sub in selector.SubSelectors)
                        {
                            List<IDomObject> listOfOne = new List<IDomObject>();
                            listOfOne.Add(obj);

                            bool has = !sub.Select(document, listOfOne).IsNullOrEmpty();

                            match &= isHasSelector == has;
                        }
                        if (match)
                        {
                            filteredResults.Add(obj);
                        }
                    }
                    interimResult = filteredResults;
                }
                tempResult = new HashSet<IDomObject>();
                if (lastResult != null)
                {
                    tempResult.AddRange(lastResult);
                }
                if (interimResult != null)
                {
                    tempResult.AddRange(interimResult);
                }
                lastResult = tempResult;
            }

            if (lastResult != null)
            {
                output.AddRange(lastResult);
            }

            if (output.IsNullOrEmpty())
            {
                yield break;
            }
            else
            {
                // Selectors always return in DOM order. Selections may end up in a different order but
                // we always sort here.

                foreach (IDomObject item in output.OrderBy(item => item.Path, StringComparer.Ordinal))
                {
                    yield return item;
                }
            }
            ActiveSelectors.Clear();
        }