如何将 C# 编译器错误位置(行、列)映射到 Roslyn API 生成的语法树上?
How to map C# compiler error location (line, column) onto the SyntaxTree produced by Roslyn API?
所以:
- C# 编译器输出(行,列)样式位置。
- Roslyn API 需要顺序文本位置
如何将前者映射到后者?
C# 代码可以是带或不带 BOM 的 UTF8,甚至可以是 UTF16。它可以包含注释或嵌入字符串形式的各种字符。
让我们假设我们知道编码并且手边有相应的 Encoding
对象。我可以将文件字节转换为 char[]
。问题是某些字符可能对最终顺序位置的贡献为零。我知道 BOM 字符确实如此。我不知道其他人是否也可以。
现在,如果我们确定 BOM 是唯一对长度贡献 0 的字符,那么我可以跳过它并计算字符数,我的问题就变得微不足道了。这就是我今天所做的——我只是假设 BOM 是唯一的“坏”玩家。
但也许有更好的方法?也许 Roslyn API 包含一些隐藏的 gem 知道更改接受(行,列)并吐出顺序位置?或者可能是某些 Microsoft.Build
库?
编辑 1
根据接受的答案,以下给出了位置:
var srcText = SourceText.From(File.ReadAllText(err.FilePath));
int location = srcText.Lines[err.Line - 1].Start + err.Column - 1;
您已经发现 SourceText 类型存在于 roslyn api 中的原因。它的全部目的是处理字符串的编码和行、列和跨度的预成型计算。
由于 .NET 处理 unicode 的方式以及根据您 OS 中安装的代码页的不同,在某些情况下 SourceText
可能无法满足您的需要。不过,对于我们的目的而言,它通常被证明“足够好”。
所以:
- C# 编译器输出(行,列)样式位置。
- Roslyn API 需要顺序文本位置
如何将前者映射到后者?
C# 代码可以是带或不带 BOM 的 UTF8,甚至可以是 UTF16。它可以包含注释或嵌入字符串形式的各种字符。
让我们假设我们知道编码并且手边有相应的 Encoding
对象。我可以将文件字节转换为 char[]
。问题是某些字符可能对最终顺序位置的贡献为零。我知道 BOM 字符确实如此。我不知道其他人是否也可以。
现在,如果我们确定 BOM 是唯一对长度贡献 0 的字符,那么我可以跳过它并计算字符数,我的问题就变得微不足道了。这就是我今天所做的——我只是假设 BOM 是唯一的“坏”玩家。
但也许有更好的方法?也许 Roslyn API 包含一些隐藏的 gem 知道更改接受(行,列)并吐出顺序位置?或者可能是某些 Microsoft.Build
库?
编辑 1
根据接受的答案,以下给出了位置:
var srcText = SourceText.From(File.ReadAllText(err.FilePath));
int location = srcText.Lines[err.Line - 1].Start + err.Column - 1;
您已经发现 SourceText 类型存在于 roslyn api 中的原因。它的全部目的是处理字符串的编码和行、列和跨度的预成型计算。
由于 .NET 处理 unicode 的方式以及根据您 OS 中安装的代码页的不同,在某些情况下 SourceText
可能无法满足您的需要。不过,对于我们的目的而言,它通常被证明“足够好”。