public SourceSpan( Cci.DebugSourceDocument document, int startLine, int startColumn, int endLine, int endColumn) { Debug.Assert(document != null); StartLine = startLine; StartColumn = startColumn; EndLine = endLine; EndColumn = endColumn; Document = document; }
private static void AddDebugSourceDocumentsForChecksumDirectives( PEModuleBuilder moduleBeingBuilt, SyntaxTree tree, DiagnosticBag diagnostics) { var checksumDirectives = tree.GetRoot().GetDirectives(d => d.Kind == SyntaxKind.PragmaChecksumDirectiveTrivia && !d.ContainsDiagnostics); foreach (var directive in checksumDirectives) { var checkSumDirective = (PragmaChecksumDirectiveTriviaSyntax)directive; var path = checkSumDirective.File.ValueText; var checkSumText = checkSumDirective.Bytes.ValueText; var normalizedPath = moduleBeingBuilt.NormalizeDebugDocumentPath(path, basePath: tree.FilePath); var existingDoc = moduleBeingBuilt.TryGetDebugDocumentForNormalizedPath(normalizedPath); // duplicate checksum pragmas are valid as long as values match // if we have seen this document already, check for matching values. if (existingDoc != null) { // pragma matches a file path on an actual tree. // Dev12 compiler just ignores the pragma in this case which means that // checksum of the actual tree always wins and no warning is given. // We will continue doing the same. if (existingDoc.IsComputedChecksum) { continue; } if (CheckSumMatches(checkSumText, existingDoc.SourceHash)) { var guid = Guid.Parse(checkSumDirective.Guid.ValueText); if (guid == existingDoc.SourceHashKind) { // all parts match, nothing to do continue; } } // did not match to an existing document // produce a warning and ignore the pragma diagnostics.Add(ErrorCode.WRN_ConflictingChecksum, new SourceLocation(checkSumDirective), path); } else { var newDocument = new Cci.DebugSourceDocument( normalizedPath, Cci.DebugSourceDocument.CorSymLanguageTypeCSharp, MakeCheckSumBytes(checkSumDirective.Bytes.ValueText), Guid.Parse(checkSumDirective.Guid.ValueText)); moduleBeingBuilt.AddDebugDocument(newDocument); } } }
public uint GetSourceDocumentIndexForIL(Cci.DebugSourceDocument document) { return(_sourceDocumentsInILMap.GetOrAddTokenFor(document)); }
internal void EmitSourceDocumentIndexToken(Cci.DebugSourceDocument document) { this.GetCurrentWriter().WriteUInt32((module?.GetSourceDocumentIndexForIL(document) ?? 0xFFFF) | Cci.MetadataWriter.SourceDocumentIndex); }
internal void AddDebugDocument(Cci.DebugSourceDocument document) { _debugDocuments.Add(document.Location, document); }
public void GetSequencePoints( DebugDocumentProvider documentProvider, ArrayBuilder <Cci.SequencePoint> builder) { bool lastPathIsMapped = false; string lastPath = null; Cci.DebugSourceDocument lastDebugDocument = null; FileLinePositionSpan?firstReal = FindFirstRealSequencePoint(); if (!firstReal.HasValue) { return; } lastPath = firstReal.Value.Path; lastPathIsMapped = firstReal.Value.HasMappedPath; lastDebugDocument = documentProvider(lastPath, basePath: lastPathIsMapped ? this._tree.FilePath : null); SequencePointList current = this; while (current != null) { SyntaxTree currentTree = current._tree; foreach (var offsetAndSpan in current._points) { TextSpan span = offsetAndSpan.Span; // if it's a hidden sequence point, or a sequence point with syntax that points to a position that is inside // of a hidden region (can be defined with #line hidden (C#) or implicitly by #ExternalSource (VB), make it // a hidden sequence point. bool isHidden = span == RawSequencePoint.HiddenSequencePointSpan; FileLinePositionSpan fileLinePositionSpan = default; if (!isHidden) { fileLinePositionSpan = currentTree.GetMappedLineSpanAndVisibility(span, out isHidden); } if (isHidden) { if (lastPath == null) { lastPath = currentTree.FilePath; lastDebugDocument = documentProvider(lastPath, basePath: null); } if (lastDebugDocument != null) { builder.Add(new Cci.SequencePoint( lastDebugDocument, offset: offsetAndSpan.Offset, startLine: Cci.SequencePoint.HiddenLine, startColumn: 0, endLine: Cci.SequencePoint.HiddenLine, endColumn: 0)); } } else { if (lastPath != fileLinePositionSpan.Path || lastPathIsMapped != fileLinePositionSpan.HasMappedPath) { lastPath = fileLinePositionSpan.Path; lastPathIsMapped = fileLinePositionSpan.HasMappedPath; lastDebugDocument = documentProvider(lastPath, basePath: lastPathIsMapped ? currentTree.FilePath : null); } if (lastDebugDocument != null) { int startLine = (fileLinePositionSpan.StartLinePosition.Line == -1) ? 0 : fileLinePositionSpan.StartLinePosition.Line + 1; int endLine = (fileLinePositionSpan.EndLinePosition.Line == -1) ? 0 : fileLinePositionSpan.EndLinePosition.Line + 1; int startColumn = fileLinePositionSpan.StartLinePosition.Character + 1; int endColumn = fileLinePositionSpan.EndLinePosition.Character + 1; // Trim column number if necessary. // Column must be in range [0, 0xffff) and end column must be greater than start column if on the same line. // The Portable PDB specifies 0x10000, but System.Reflection.Metadata reader has an off-by-one error. // Windows PDBs allow the same range. const int MaxColumn = ushort.MaxValue - 1; if (startColumn > MaxColumn) { startColumn = (startLine == endLine) ? MaxColumn - 1 : MaxColumn; } if (endColumn > MaxColumn) { endColumn = MaxColumn; } builder.Add(new Cci.SequencePoint( lastDebugDocument, offset: offsetAndSpan.Offset, startLine: startLine, startColumn: (ushort)startColumn, endLine: endLine, endColumn: (ushort)endColumn )); } } } current = current._next; } }