/// <summary> /// Attempts to translate the string into an absolute path which has any tokens detokenized based on the logic in the /// expander. /// </summary> /// <param name="pathTable">the path table</param> /// <param name="path">the string representation of the path</param> /// <param name="absolutePath">the absolute path</param> /// <returns>true if the absolute path was successfully detokenized and retrieved or created from the path table</returns> public virtual bool TryCreatePath(PathTable pathTable, string path, out AbsolutePath absolutePath) { Contract.Requires(pathTable != null); Contract.Requires(path != null); return(AbsolutePath.TryCreate(pathTable, (StringSegment)path, out absolutePath)); }
/// <summary> /// Class constructor /// </summary> public RootExpander(PathTable pathTable) : base() { m_pathTable = pathTable; m_roots = new Dictionary <HierarchicalNameId, string>(); }
/// <summary> /// Gets the string representation of the given path. /// </summary> /// <param name="pathTable">the path table</param> /// <param name="path">the path</param> /// <returns>the string representation of the path</returns> public virtual string ExpandPath(PathTable pathTable, AbsolutePath path) { Contract.Requires(pathTable != null); return(path.ToString(pathTable)); }
/// <summary> /// Constructs an expanded absolute path. /// </summary> public ExpandedAbsolutePath(AbsolutePath path, PathTable pathTable, NameExpander nameExpander = null) { Contract.Requires(path.IsValid); Path = path; ExpandedPath = path.ToString(pathTable, nameExpander: nameExpander); }
/// <summary> /// Returns a string representation of the token. /// </summary> /// <param name="pathTable">The path table used when creating the AbsolutePath in the Path field.</param> public string ToString(PathTable pathTable) { Contract.RequiresNotNull(pathTable); return(string.Format(CultureInfo.InvariantCulture, "{0}({1}, {2})", Path.ToString(pathTable), Line, Position)); }
/// <summary> /// Filters the given directories so only paths that are not nested within any other path are returned /// </summary> public static ISet <AbsolutePath> CollapseDirectories(ICollection <AbsolutePath> directories, PathTable pathTable) { return(CollapseDirectories(directories, pathTable, out _)); }
/// <summary> /// <see cref="CollapseDirectories(ICollection{AbsolutePath}, PathTable)"/>, and additionaly returns a mapping from the original directories to their collapsed parent /// directory (or self). /// </summary> public static ISet <AbsolutePath> CollapseDirectories(ICollection <AbsolutePath> directories, PathTable pathTable, out IDictionary <AbsolutePath, AbsolutePath> originalToCollapsedMapping) { var dedupPaths = new HashSet <AbsolutePath>(); originalToCollapsedMapping = new Dictionary <AbsolutePath, AbsolutePath>(directories.Count); foreach (var directory in directories) { var skip = false; var parentDirectory = directory.GetParent(pathTable); if (parentDirectory.IsValid) { foreach (var parent in pathTable.EnumerateHierarchyBottomUp(parentDirectory.Value)) { var parentAsPath = new AbsolutePath(parent); if (directories.Contains(parentAsPath)) { originalToCollapsedMapping.Add(directory, parentAsPath); skip = true; break; } } } if (!skip) { dedupPaths.Add(directory); originalToCollapsedMapping.Add(directory, directory); } } return(dedupPaths); }
/// <summary> /// Returns a string representation of the token. /// </summary> /// <param name="pathTable">The path table used when creating the AbsolutePath in the Path field.</param> public string ToString(PathTable pathTable) { Contract.RequiresNotNull(pathTable); return(I($"{Path.ToString(pathTable)}({Line}, {Position})")); }
/// <summary> /// Helper to create directory artifacts /// </summary> public static DirectoryArtifact CreateWithZeroPartialSealId(PathTable pathTable, string path) { return(CreateWithZeroPartialSealId(AbsolutePath.Create(pathTable, path))); }
private static Task <ConcurrentBigMap <AbsolutePath, AbsolutePath> > LoadAsync(Stream stream, string fileName, PathTable pathTable) { return(ExceptionUtilities.HandleRecoverableIOException( async() => { s_fileEnvelope.ReadHeader(stream); using (BuildXLReader reader = new BuildXLReader(debug: false, stream: stream, leaveOpen: true)) { var stringTable = await StringTable.DeserializeAsync(reader); var loadedPathTable = await PathTable.DeserializeAsync(reader, Task.FromResult(stringTable)); var importedPathIndex = pathTable.Import(loadedPathTable); var pathMapping = new ConcurrentBigMap <AbsolutePath, AbsolutePath>(); var count = reader.ReadInt32(); for (int i = 0; i < count; i++) { var loadedKey = reader.ReadAbsolutePath(); var loadedValue = reader.ReadAbsolutePath(); var key = importedPathIndex[loadedKey.Value.Index]; var value = importedPathIndex[loadedValue.Value.Index]; pathMapping[key] = value; } return pathMapping; } }, ex => { throw new BuildXLException(I($"Failed to read '{fileName}'"), ex); })); }
/// <summary> /// Loads path map from a file. /// </summary> public static async Task <ConcurrentBigMap <AbsolutePath, AbsolutePath> > LoadAsync(string fileName, PathTable pathTable) { FileStream fileStream = ExceptionUtilities.HandleRecoverableIOException( () => new FileStream( fileName, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete, bufferSize: 4096, options: FileOptions.None), ex => { throw new BuildXLException(I($"Failed to open '{fileName}'"), ex); }); using (fileStream) { return(await LoadAsync(fileStream, fileName, pathTable)); } }
/// <summary> /// Parses a dotted identifier. All error logging is the responsibility of the caller /// </summary> /// <param name="token">The token to parse</param> /// <param name="context">Context with tables.</param> /// <param name="identifier">The parsed identifier if successful, null if not.</param> public static ParseResult TryParse <TChars>( ExpandedTokenData <TChars> token, PipExecutionContext context, out DottedIdentifier identifier) where TChars : struct, ICharSpan <TChars> { Contract.Requires(token.IsValid); Contract.Requires(context != null); PathTable pathTableForError = context.PathTable; SymbolTable symbolTable = context.SymbolTable; int position = 0; var text = token.Text; int textLength = text.Length; identifier = null; if (text.Length == 0) { return(new ParseResult() { Status = ParseStatus.InvalidDottedIdentifierCannotBeEmpty, Path = token.Path.ToString(pathTableForError), Line = token.Line, Position = token.Position, }); } TChars id; var parseIdenfierResult = TryParseIdentifier(token, context, ref position, out id); if (parseIdenfierResult.Status != ParseStatus.Success) { return(parseIdenfierResult); } identifier = DottedIdentifier.Create(symbolTable, id); DottedIdentifier currentIdentifier = identifier; while (position < textLength) { if (text[position] == '.') { if (position == textLength - 1) { // Last char is a dot. var updateToken = token.UpdateLineInformationForPosition(position); identifier = null; return(new ParseResult() { Status = ParseStatus.InvalidDottedIdentifierUnexpectedDot, Path = updateToken.Path.ToString(pathTableForError), Line = updateToken.Line, Position = updateToken.Position, Text = currentIdentifier != null?currentIdentifier.Head.ToString(symbolTable.StringTable) : string.Empty, }); } position++; TChars currentId; parseIdenfierResult = TryParseIdentifier(token, context, ref position, out currentId); if (parseIdenfierResult.Status != ParseStatus.Success) { identifier = null; return(parseIdenfierResult); } var tail = DottedIdentifier.Create(symbolTable, currentId); currentIdentifier.m_tail = tail; currentIdentifier = tail; } else { break; } } if (position < textLength) { var updateToken = token.UpdateLineInformationForPosition(position); identifier = null; return(new ParseResult() { Status = ParseStatus.InvalidDottedIdentifierUnexpectedCharacter, Path = updateToken.Path.ToString(pathTableForError), Line = updateToken.Line, Position = updateToken.Position, Text = text[position].ToString(), }); } return(new ParseResult() { Status = ParseStatus.Success }); }