/// <summary> /// Combine one or more asset paths. /// </summary> /// <param name="firstPath">First asset path.</param> /// <param name="otherPaths">Other parts of asset path.</param> /// <returns> /// The combined asset path. /// </returns> /// <exception cref="System.ArgumentNullException"> /// <list type="bullet"> /// <item>If <paramref name="firstPath"/> is <c>null</c>.</item> /// <item>If one or more <paramref name="otherPaths"/> have a value of <c>null</c>.</item> /// </list> /// </exception> /// <exception cref="System.ArgumentException"> /// <list type="bullet"> /// <item>If <paramref name="firstPath"/> is not a valid asset path.</item> /// <item>If one or more <paramref name="otherPaths"/> are not valid.</item> /// </list> /// </exception> public static string CombineAssetPaths(string firstPath, params string[] otherPaths) { CheckAssetPathArgument(firstPath, "firstPath"); if (otherPaths == null || otherPaths.Length == 0) { return(firstPath); } var sb = new StringBuilder(firstPath); for (int i = 0; i < otherPaths.Length; ++i) { string otherPath = otherPaths[i]; if (otherPath == null) { throw new ArgumentNullException(string.Format("otherPaths[{0}]", i)); } if (otherPath == "" || !PathRegex.IsMatch(otherPath)) { throw new ArgumentException(string.Format("Invalid path '{0}'.", otherPath), string.Format("otherPaths[{0}]", i)); } sb.Append('/'); sb.Append(otherPath); } return(sb.ToString()); }
public RegexPathMarkerTraverser([NotNull] PathRegex <Item, Dependency> regex, int maxPathLength, bool backwards, bool ignorePrefixPaths, [NotNull] Action checkAbort, List <PathInfo> foundPaths, Dictionary <Item, HashSet <IMatchableObject> > countedObjectsPerItem) : base(regex, checkAbort, maxRecursionDepth: maxPathLength) { _maxPathLength = maxPathLength; _backwards = backwards; _foundPaths = foundPaths; _countedObjectsPerItem = countedObjectsPerItem; _ignorePrefixPaths = ignorePrefixPaths; }
public TestTraverser(IEnumerable <Dependency> deps, PathRegex regex) : base(regex, checkAbort: () => { }) { _outgoing = Item.CollectOutgoingDependenciesMap(deps); }
public static string FixInvalidPathCharacters(string path) { return(PathRegex.Replace(path, string.Empty)); }
public override int Transform([NotNull] GlobalContext globalContext, Ignore Ignore, [NotNull] TransformOptions transformOptions, [NotNull][ItemNotNull] IEnumerable <Dependency> dependencies, [NotNull] List <Dependency> transformedDependencies) { var foundPaths = new List <PathInfo>(); string regex = transformOptions.Regex ?? ":(.:)+"; var pathRegex = new PathRegex <Item, Dependency>(regex, transformOptions.DefinedItemMatches, transformOptions.DefinedDependencyMatches, globalContext.IgnoreCase); var countedObjectsPerItem = new Dictionary <Item, HashSet <IMatchableObject> >(); var traverser = new RegexPathMarkerTraverser(pathRegex, transformOptions.MaxPathLength ?? (pathRegex.ContainsLoops ? 1000 : regex.Length), transformOptions.Backwards, transformOptions.IgnorePrefixPaths, globalContext.CheckAbort, foundPaths, countedObjectsPerItem); traverser.Traverse(dependencies); Log.WriteInfo($"... marked {foundPaths.Count} paths"); if (pathRegex.ContainsCountSymbol) { foreach (var kvp in countedObjectsPerItem) { kvp.Value.Remove(null); kvp.Key.SetMarker(transformOptions.Marker, kvp.Value.Count); } } if (transformOptions.IgnoreSubpaths) { foundPaths.Sort((f1, f2) => f2.PathLength - f1.PathLength); var longPaths = new List <PathInfo>(); foreach (var f in foundPaths) { if (longPaths.All(lp => (lp.PathHash & f.PathHash) == f.PathHash && lp.AsArray.IndexOf(f.AsArray) < 0)) { longPaths.Add(f); } } foundPaths = longPaths; } if (transformOptions.AddTransitiveDependencyInsteadOfMarking) { var transitiveEdges = new HashSet <Dependency>(); foreach (var f in foundPaths) { if (f.Tail == null) { throw new Exception("Internal error - found path of length zero"); } IEnumerable <Dependency> path = f.PathNodes.Select(n => n.Dependency); transitiveEdges.Add(globalContext.CurrentGraph.CreateDependency(f.Root, f.Tail.Dependency.UsedItem, source: null, markers: transformOptions.Marker, ct: path.Max(p => p.Ct), questionableCt: path.Max(d => d.QuestionableCt), badCt: path.Max(d => d.BadCt), notOkReason: path.Select(d => d.NotOkReason).FirstOrDefault(), exampleInfo: path.Select(d => d.ExampleInfo).FirstOrDefault())); } transformedDependencies.AddRange(transformOptions.KeepOnlyPathEdges ? transitiveEdges : dependencies.Concat(transitiveEdges)); } else { int n = 0; string addIndexToMarkerFormat = transformOptions.AddIndex ? "D" + ("" + foundPaths.Count).Length : null; var pathDependencies = new HashSet <Dependency>(); foreach (var f in foundPaths) { string m = transformOptions.Marker + (addIndexToMarkerFormat == null ? "" : n++.ToString(addIndexToMarkerFormat)); int i = 0; foreach (var node in f.PathNodes) { pathDependencies.Add(node.Dependency); node.Dependency.MarkPathElement(m, posInPath: i, isStart: i == 0, isEnd: node.IsEnd, isMatchedByCountSymbol: node.IsMatchedByCountSymbol, isLoopBack: node.IsEndOfCycle); i++; } f.Root.MarkPathElement(m, 0, isStart: true, isEnd: f.Root.Equals(f.Tail?.Dependency.UsedItem), isMatchedByCountSymbol: f.RootIsCounted, isLoopBack: false /*??*/); } transformedDependencies.AddRange(transformOptions.KeepOnlyPathEdges ? pathDependencies : dependencies); } return(Program.OK_RESULT); }