// Given a directive and the previous entry, create a new entry.
        protected override LineMappingEntry GetEntry(DirectiveTriviaSyntax directiveNode, SourceText sourceText, LineMappingEntry previous)
        {
            Debug.Assert(ShouldAddDirective(directiveNode));
            var directive = (LineDirectiveTriviaSyntax)directiveNode;

            // Get line number of NEXT line, hence the +1.
            var directiveLineNumber = sourceText.Lines.IndexOf(directive.SpanStart) + 1;

            // The default for the current entry does the same thing as the previous entry, except
            // resetting hidden.
            var           unmappedLine  = directiveLineNumber;
            var           mappedLine    = previous.MappedLine + directiveLineNumber - previous.UnmappedLine;
            var           mappedPathOpt = previous.MappedPathOpt;
            PositionState state         = PositionState.Unmapped;

            // Modify the current entry based on the directive.
            SyntaxToken lineToken = directive.Line;

            if (!lineToken.IsMissing)
            {
                switch (lineToken.Kind())
                {
                case SyntaxKind.HiddenKeyword:
                    state = PositionState.Hidden;
                    break;

                case SyntaxKind.DefaultKeyword:
                    mappedLine    = unmappedLine;
                    mappedPathOpt = null;
                    state         = PositionState.Unmapped;
                    break;

                case SyntaxKind.NumericLiteralToken:
                    // skip both the mapped line and the filename if the line number is not valid
                    if (!lineToken.ContainsDiagnostics)
                    {
                        object?value = lineToken.Value;
                        if (value is int)
                        {
                            // convert one-based line number into zero-based line number
                            mappedLine = ((int)value) - 1;
                        }

                        if (directive.File.Kind() == SyntaxKind.StringLiteralToken)
                        {
                            mappedPathOpt = (string?)directive.File.Value;
                        }

                        state = PositionState.Remapped;
                    }

                    break;
                }
            }

            return(new LineMappingEntry(
                       unmappedLine,
                       mappedLine,
                       mappedPathOpt,
                       state));
        }
Beispiel #2
0
 // Given a directive and the previous entry, create a new entry.
 protected abstract LineMappingEntry GetEntry(TDirective directive, SourceText sourceText, LineMappingEntry previous);