Получить Roslyn SyntaxToken из Visual Studio Text Selection (позиция каретки)

Я пытаюсь соединить VSSDK и Roslyn SDK в пакете расширения Visual Studio, и мне было тяжело с этим. ActivePoint.AbsoluteCharOffset, заданный из Visual Studio, не соответствует элементу, который я получаю из Roslyn при использовании FindToken (смещение). Я вполне уверен, что это связано с тем, как каждая сторона считает символы EOL, основываясь на моем текущем рабочем хаке, но я не на 100%, что мой хак выдержит в долгосрочной перспективе.

Мой хак это строка:charOffset += point.Line;

Я добавляю количество строк в смещение символа, это, кажется, работает, поэтому я предполагаю, что я добавляю во все символы разрыва строки, которые игнорируются при подсчете активной точки.

Помощники

private VisualStudioWorkspace workspace = null;
public RoslynUtilities(VisualStudioWorkspace workspace)
{
    this.workspace = workspace;
}
public Solution Solution { get { return workspace.CurrentSolution; } }
public Document GetDocumentFromPath(string fullPath)
{
    foreach (Project proj in this.Solution.Projects)
    {               
        foreach (Document doc in proj.Documents)
        {
            if (doc.FilePath == fullPath)
                return doc;                   
        }
    }
    return null;
}
public SyntaxTree GetSyntaxTreeFromDocumentPath(string fullPath)
{
    Document doc = GetDocumentFromPath(fullPath);
    if (doc != null)
        return doc.GetSyntaxTreeAsync().Result;
    else
        return null;
}
public SyntaxNode GetNodeByFilePosition(string fullPath, int absoluteChar)
{
    SyntaxTree tree = GetSyntaxTreeFromDocumentPath(fullPath);
    if(tree != null)
    {
        var compUnit = tree.GetCompilationUnitRoot();
        if(compUnit != null)
        {
            return compUnit.FindToken(absoluteChar, true).Parent;
        }
    }
    return null;                        
}
private VisualStudioWorkspace GetRoslynWorkspace()
    {
        var componentModel = (IComponentModel)GetGlobalService(typeof(SComponentModel));
        return componentModel.GetService<VisualStudioWorkspace>();
    }

Основная часть

EnvDTE80.DTE2 applicationObject = (EnvDTE80.DTE2)GetService(typeof(SDTE));
EnvDTE.TextSelection ts = applicationObject.ActiveWindow.Selection as EnvDTE.TextSelection;
if (ts == null)
    return;

EnvDTE.VirtualPoint point = ts.ActivePoint;
int charOffset = point.AbsoluteCharOffset;
charOffset += point.Line;//HACK ALERT

Parse.Roslyn.RoslynUtilities roslyn = new Parse.Roslyn.RoslynUtilities(GetRoslynWorkspace());
SyntaxNode node = roslyn.GetNodeByFilePosition(applicationObject.ActiveDocument.FullName, charOffset);

Ответы на вопрос(1)

Ваш ответ на вопрос