Obtenga Roslyn SyntaxToken de Visual Studio Text Selection (posición de intercalación)

Estoy intentando establecer un puente entre VSSDK y Roslyn SDK en un paquete de extensión de Visual Studio y he tenido dificultades con esto. El ActivePoint.AbsoluteCharOffset proporcionado por Visual Studio no coincide con el elemento que obtengo de Roslyn cuando uso FindToken (offset). Estoy bastante seguro de que esto tiene que ver con la forma en que cada lado cuenta los personajes EOL en función de mi truco de trabajo actual, pero no estoy 100% seguro de que mi truco se mantendrá a largo plazo.

Mi truco es esta línea:charOffset += point.Line;

Agrego el número de líneas en el desplazamiento de caracteres, esto parece funcionar, así que supongo que estoy agregando todos los caracteres de salto de línea que están siendo ignorados por el recuento de puntos activos.

Ayudantes

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>();
    }

Parte principal

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);