/// <summary> /// Creates a new instance of <see cref="BinaryFilter"/>. /// </summary> public BinaryFilter(PipFilter left, FilterOperator op, PipFilter right) { Left = left; FilterOperator = op; Right = right; m_cachedHashCode = HashCodeHelper.Combine(Left.GetHashCode() ^ Right.GetHashCode(), FilterOperator.GetHashCode()); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { ValueFilter valueFilter; return((valueFilter = pipFilter as ValueFilter) != null && m_value == valueFilter.m_value && m_valueTransitive == valueFilter.m_valueTransitive); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { SpecFileFilter specFileFilter; return((specFileFilter = pipFilter as SpecFileFilter) != null && m_valueTransitive == specFileFilter.m_valueTransitive && m_specDependencies == specFileFilter.m_specDependencies && base.CanonicallyEquals(specFileFilter)); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { PathBasedFilter pathBasedFilter; return((pathBasedFilter = pipFilter as PathBasedFilter) != null && m_path == pathBasedFilter.m_path && m_matchMode == pathBasedFilter.m_matchMode && m_pathWildcardUpper == pathBasedFilter.m_pathWildcardUpper && PathFromMount == pathBasedFilter.PathFromMount); }
private static IEnumerable <StringId> GetTags(PipFilter filter) { if (filter is MultiTagsOrFilter multiFilter) { return(multiFilter.Tags); } else { return(new[] { ((TagFilter)filter).Tag }); } }
/// <summary> /// Creates a RootFilter /// </summary> public RootFilter(PipFilter filter, string filterExpression = null) { Contract.Requires(filter != null); PipFilter = filter; if (filterExpression != null) { FilterExpression = filterExpression; } m_valuesToResolve = new Lazy <IReadOnlyList <FullSymbol> >(ComputeValuesToResolve); m_pathsRootsToResolve = new Lazy <IReadOnlyList <AbsolutePath> >(ComputePathsRootsToResolve); m_modulesToResolve = new Lazy <IReadOnlyList <StringId> >(ComputeModulesToResolve); }
// General convention in parsing methods: All whitespaces are consumed immediately after advancing the position. // Methods can assume they do not need to advance past whitespace when they are called. #region Parsing methods private RootFilter ParseRootFilter() { bool includeDependents = false; // Parse dependency selection. This may only be specified at the beginning of the root filter, outside any grouping if (MatchesNext(LegacyDependentsFlag)) { includeDependents = true; m_position++; } SkipWhitespace(); PipFilter filter = ParseExpression(); if (includeDependents) { filter = new DependentsFilter(filter); } filter = m_canonicalize ? filter.Canonicalize(new FilterCanonicalizer()) : filter; return(new RootFilter(filter, m_expression)); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { PipIdFilter pipIdFilter; return((pipIdFilter = pipFilter as PipIdFilter) != null && m_semiStableHash == pipIdFilter.m_semiStableHash); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { NegatingFilter negatingFilter; return((negatingFilter = pipFilter as NegatingFilter) != null && ReferenceEquals(Inner, negatingFilter.Inner)); }
/// <summary> /// Checks if this filter is canonically equal to the given one. /// </summary> public abstract bool CanonicallyEquals(PipFilter pipFilter);
/// <inheritdoc /> public override bool CanonicallyEquals(PipFilter pipFilter) { MultiTagsOrFilter multiTagsFilter; return((multiTagsFilter = pipFilter as MultiTagsOrFilter) != null && m_tags.SetEquals(multiTagsFilter.m_tags)); }
/// <summary> /// Tries get a canonicalized <see cref="PipFilter"/>. /// </summary> public bool TryGet(PipFilter filter, out PipFilter canonicalizedFilter) { return(m_canonFilters.TryGetValue(filter, out canonicalizedFilter)); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { OutputFileFilter outputFileFilter; return((outputFileFilter = pipFilter as OutputFileFilter) != null && base.CanonicallyEquals(outputFileFilter)); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { InputFileFilter inputFileFilter; return((inputFileFilter = pipFilter as InputFileFilter) != null && base.CanonicallyEquals(inputFileFilter)); }
/// <summary> /// Gets or adds a canonicalized <see cref="PipFilter"/>. /// </summary> public PipFilter GetOrAdd(PipFilter filter) { return(m_canonFilters.GetOrAdd(filter, pipFilter => pipFilter)); }
/// <summary> /// Class constructor /// </summary> public CopyDependentsFilter(PipFilter inner) : base(inner) { }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { TagFilter tagFilter; return((tagFilter = pipFilter as TagFilter) != null && Tag == tagFilter.Tag); }
private PipFilter ParseBinary() { // Iteratively collect filters and operators used to combine filters LinkedList <PipFilter> filters = new LinkedList <PipFilter>(); LinkedList <FilterOperator> filterOperators = new LinkedList <FilterOperator>(); while (true) { PipFilter left = ParseFilterGroup(); filters.AddFirst(left); if (MatchesNext(AndOperator)) { AdvancePast(AndOperator); SkipWhitespace(); filterOperators.AddFirst(FilterOperator.And); continue; } else if (MatchesNext(OrOperator)) { AdvancePast(OrOperator); SkipWhitespace(); filterOperators.AddFirst(FilterOperator.Or); continue; } break; } // In precedence order, combine the filter using the operators foreach (var filterOperator in s_filterOperatorsPrecedenceOrder) { LinkedListNode <PipFilter> filterNode = filters.First; LinkedListNode <FilterOperator> filterOperatorNode = filterOperators.First; while (filterOperatorNode != null) { var nextFilterOperatorNode = filterOperatorNode.Next; var nextFilterNode = filterNode.Next; // Check operator if the operator matches the current type of operator being combined if (filterOperatorNode.Value == filterOperator) { // Combine the filters and replace the two filter nodes with a node for the combined filter // This is done by replacing the value in one node and removing the other node filterNode.Next.Value = new BinaryFilter( left: filterNode.Next.Value, op: filterOperator, right: filterNode.Value); filters.Remove(filterNode); // Remove the operator now that it is processed filterOperators.Remove(filterOperatorNode); } filterOperatorNode = nextFilterOperatorNode; filterNode = nextFilterNode; } } Contract.Assert(filters.Count == 1); return(filters.First.Value); }
/// <summary> /// Creates a new instance of <see cref="NegatingFilter"/>. /// </summary> public NegatingFilter(PipFilter inner) { Inner = inner; m_cachedHashCode = ~Inner.GetHashCode(); }
/// <summary> /// Class constructor /// </summary> public DependenciesFilter(PipFilter inner, ClosureMode closureMode = ClosureMode.TransitiveIncludingSelf) : base(inner, closureMode) { }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { ModuleFilter moduleFilter; return((moduleFilter = pipFilter as ModuleFilter) != null && m_modules.SetEquals(moduleFilter.m_modules)); }
/// <inheritdoc/> protected override DependenciesFilter CreateFilter(PipFilter inner) { return(new DependenciesFilter(inner, ClosureMode)); }
private PipFilter ParseFilterGroup() { string matched; if (TryMatch(DependentsFunction, out matched) || TryMatch(DependenciesFunction, out matched) || TryMatch(RequiredInputsFunction, out matched) || TryMatch(CopyDependentsFunction, out matched)) { AdvancePast(matched); SkipWhitespace(); // Filter functions (i.e. dpt) is only allowed outside of group operators (). Check that the next character is the start // of a group but don't consume is since that is handled by the recursive call if (!MatchesNext(StartGroup)) { throw CreateException(ErrorMessages.FilterFunctionMustBeOustideOfGroupDelimiters, StartGroup, EndGroup, DependentsFunction); } PipFilter result = ParseFilterGroup(); switch (matched) { case DependentsFunction: result = new DependentsFilter(result); break; case DependenciesFunction: result = new DependenciesFilter(result); break; case RequiredInputsFunction: result = new DependenciesFilter(result, ClosureMode.DirectExcludingSelf); break; case CopyDependentsFunction: default: Contract.Assert(matched == CopyDependentsFunction, "Unexpected match"); result = new CopyDependentsFilter(result); break; } return(result); } else if (MatchesNext(Negation)) { ExpectAndAdvancePast(Negation); SkipWhitespace(); // Negation is only allowed outside of group operators (). Check that the next character is the start // of a group but don't consume is since that is handled by the recursive call if (!MatchesNext(StartGroup)) { throw CreateException(ErrorMessages.NetagionMustBeOustideOfGroupDelimiters, StartGroup, EndGroup); } PipFilter result = ParseFilterGroup(); result = result.Negate(); return(result); } else if (MatchesNext(StartGroup)) { ExpectAndAdvancePast(StartGroup); SkipWhitespace(); PipFilter result = ParseExpression(); ExpectAndAdvancePast(EndGroup); SkipWhitespace(); return(result); } else { return(ParseFilterTuple()); } }
/// <summary> /// Class constructor /// </summary> protected ClosureFunctionFilter(PipFilter inner, ClosureMode closureMode = ClosureMode.TransitiveIncludingSelf) { Inner = inner; ClosureMode = closureMode; m_cachedHashCode = HashCodeHelper.Combine(Inner.GetHashCode(), GetType().GetHashCode(), (int)ClosureMode); }
/// <inheritdoc/> protected override CopyDependentsFilter CreateFilter(PipFilter inner) { return(new CopyDependentsFilter(inner)); }
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { return(pipFilter is TFilter closureFilter && ReferenceEquals(Inner, closureFilter.Inner)); }
/// <summary> /// Creates a new instance of the given filter type with the given inner filter /// </summary> protected abstract TFilter CreateFilter(PipFilter inner);
/// <inheritdoc/> public override bool CanonicallyEquals(PipFilter pipFilter) { return(pipFilter is EmptyFilter); }