mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-15 01:25:40 -05:00
* Created New ManagedBatchParser project in .NetStandard * Addressing PR Comments * Resolve 'No Repository' warning. * Move batch parser tests to integrations test project * Fix SLN file
119 lines
4.0 KiB
C#
119 lines
4.0 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
//
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.BatchParser
|
|
{
|
|
/// <summary>
|
|
/// This class gives information about lines being parsed by
|
|
/// the Batch Parser
|
|
/// </summary>
|
|
public class LineInfo
|
|
{
|
|
private IEnumerable<Token> tokens;
|
|
private IEnumerable<VariableReference> variableRefs;
|
|
|
|
/// <summary>
|
|
/// Constructor method for the LineInfo class
|
|
/// </summary>
|
|
public LineInfo(IEnumerable<Token> tokens, IEnumerable<VariableReference> variableRefs)
|
|
{
|
|
this.tokens = tokens;
|
|
this.variableRefs = variableRefs;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the stream position for offset and returns a PositionStruct
|
|
/// </summary>
|
|
public PositionStruct GetStreamPositionForOffset(int offset)
|
|
{
|
|
if (variableRefs != null)
|
|
{
|
|
offset = CalculateVarsUnresolvedOffset(offset);
|
|
}
|
|
int charCount = 0;
|
|
Token lastToken = null;
|
|
foreach (Token token in tokens)
|
|
{
|
|
lastToken = token;
|
|
if (charCount + token.Text.Length > offset)
|
|
{
|
|
int line, column;
|
|
CalculateLineColumnForOffset(token, offset - charCount, out line, out column);
|
|
return new PositionStruct(line, column, token.Begin.Offset + (offset - charCount), token.Filename);
|
|
}
|
|
charCount += token.Text.Length;
|
|
}
|
|
if (lastToken != null)
|
|
{
|
|
return new PositionStruct(lastToken.End.Line, lastToken.End.Column, lastToken.End.Offset, lastToken.Filename);
|
|
}
|
|
else
|
|
{
|
|
return new PositionStruct(1, 1, 0, string.Empty);
|
|
}
|
|
}
|
|
|
|
internal static void CalculateLineColumnForOffset(Token token, int offset, out int line, out int column)
|
|
{
|
|
CalculateLineColumnForOffset(token.Text, offset, 0, token.Begin.Line, token.Begin.Column, out line, out column);
|
|
}
|
|
|
|
internal static void CalculateLineColumnForOffset(string text, int offset,
|
|
int offsetDelta, int lineDelta, int columnDelta, out int line, out int column)
|
|
{
|
|
line = lineDelta;
|
|
column = columnDelta;
|
|
int counter = offsetDelta;
|
|
while (counter < offset)
|
|
{
|
|
bool newLineWithCR = false;
|
|
|
|
if (text[counter] == '\r')
|
|
{
|
|
newLineWithCR = true;
|
|
}
|
|
else if (text[counter] == '\n')
|
|
{
|
|
line++;
|
|
column = 0;
|
|
}
|
|
counter++;
|
|
if (newLineWithCR && counter < text.Length && text[counter] != '\n')
|
|
{
|
|
line++;
|
|
column = 0;
|
|
}
|
|
column++;
|
|
}
|
|
}
|
|
|
|
private int CalculateVarsUnresolvedOffset(int offset)
|
|
{
|
|
// find offset of the beginning of variable substitution (if offset points to the middle of it)
|
|
int diff = 0;
|
|
foreach (VariableReference reference in variableRefs)
|
|
{
|
|
if (reference.Start >= offset)
|
|
{
|
|
break;
|
|
}
|
|
else if (reference.VariableValue != null && offset < reference.Start + reference.VariableValue.Length)
|
|
{
|
|
offset = reference.Start;
|
|
break;
|
|
}
|
|
if (reference.VariableValue != null)
|
|
{
|
|
diff += reference.Length - reference.VariableValue.Length;
|
|
}
|
|
}
|
|
return offset + diff;
|
|
}
|
|
|
|
}
|
|
}
|