/// <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; }
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(); }