有没有一种方法可以在使用.NET编译器SDK编译代码时启用“隐式Using”功能?

huangapple go评论72阅读模式
英文:

Is there a way to enable "Implicit Usings" feature when compiling code with .NET Compiler SDK?

问题

"ImplicitUsings" 功能允许代码省略标准命名空间的 using 语句。我需要分析一个随机的源文件,可能不知道适当的包含项集合。在 C# 10 中,可以隐式地包括一组标准命名空间,如帮助主题所述。是否有一种方式可以在创建编译时使用标准命名空间?

using System.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

var sourceText = "class C{" +
    "public void M(){" +
    " Console.Write(123);" +
    "}}";
var syntaxTree = CSharpSyntaxTree.ParseText(sourceText);

var coreReferences =
    ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES"))
    .Split(Path.PathSeparator)
    .Select(p => MetadataReference.CreateFromFile(p));
var compilation = CSharpCompilation.Create("MyAnalysis")
    .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
    .AddReferences(coreReferences)
    .AddSyntaxTrees(syntaxTree);

var diagnostics = compilation.GetDiagnostics();
Debug.Assert(diagnostics.Length == 0);
// diagnostics = "error CS0103: The name 'Console' does not exist in the current context"

为了澄清上面的示例,我正在编译 sourceText 变量中的源代码。diagnostics 变量包含了 Console 不存在的错误。如果在上面的 sourceText 中添加 "using System",则代码将无错误编译。是否有一种方式可以启用 Implicit Usings 功能,以便编译可以从标准命名空间中解析符号?

英文:

The "ImplicitUsings" feature allows code to omit usings statements for standard namespaces. I need to analyze a random source file(s) for which I may not know an appropriate set of includes. In C# 10 a standard set of namespaces could be included implicitly, as described in the help topic. Is there a way to use the standard namespaces when creating a compilation?

using System.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

var sourceText = "class C{" +
    "public void M(){" +
    " Console.Write(123);" +
    "}}";
var syntaxTree = CSharpSyntaxTree.ParseText(sourceText);

var coreReferences =
    ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES"))
    .Split(Path.PathSeparator)
    .Select(p => MetadataReference.CreateFromFile(p));
var compilation = CSharpCompilation.Create("MyAnalysis")
    .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
    .AddReferences(coreReferences)
    .AddSyntaxTrees(syntaxTree);

var diagnostics = compilation.GetDiagnostics();
Debug.Assert(diagnostics.Length == 0);
// diagnostics = "error CS0103: The name 'Console' does not exist in the current context"

To clarify the above example, I'm compiling the source in the sourceText variable. The diagnostics variable contains the error that Console does not exist. If I add "using System" in the sourceText above, the code compiles without the error. Is there a way to enable the Implicit Usings feature so that compilation resolves symbols from standard namespaces?

答案1

得分: 1

不是隐式使用,但你可以通过使用 CSharpCompilationOptions 类的 WithUsings 方法,将使用项添加到你的编译中。

英文:

Not implicit usings, but you can add usings to your compilation externally by using the WithUsings method of the CSharpCompilationOptions class.

答案2

得分: 0

Based on your request, here's the translated code portion:

根据建议,我正在尝试通过创建与特定已知SDK对应的全局usings文件来寻找可能的解决方案。可能会在项目文件中查找SDK或使用默认值。例如,对于Microsoft.NET.Sdk,我创建了以下文件(Microsoft.NET.Sdk.usings.cs):

global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Net.Http;
global using System.Threading;
global using System.Threading.Tasks;

有一篇[文档][1]描述了标准SDK的默认命名空间。然后,我可以加载它并解析为附加的语法树,以消除编译错误。有关不必要的using指令的警告。完整的代码如下:

using System.Diagnostics;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

var sourceText = "class C{" +
    "public void M(){" +
    " Console.Write(123);" +
    "}}";
var syntaxTree = CSharpSyntaxTree.ParseText(sourceText);

var globalUsings = File.ReadAllText("Microsoft.NET.Sdk.usings.cs");
var usingsTree = CSharpSyntaxTree.ParseText(globalUsings);

var coreReferences =
    ((string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES"))
    .Split(Path.PathSeparator)
    .Select(p => MetadataReference.CreateFromFile(p));
var compilation = CSharpCompilation.Create("MyAnalysis")
    .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
    .AddReferences(coreReferences)
    .AddSyntaxTrees(usingsTree, syntaxTree);

var diagnostics = compilation.GetDiagnostics();
Debug.Assert(!diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error);

<details>
<summary>英文:</summary>

Based on suggestions I&#39;m pursuing a possible solution by creating a global usings file(s) corresponding to specific known SDK(s). Will probably look up SDK in the project file or use a default. For example, for Microsoft.NET.Sdk I created the following file (Microsoft.NET.Sdk.usings.cs):

    global using System;
    global using System.Collections.Generic;
    global using System.IO;
    global using System.Linq;
    global using System.Net.Http;
    global using System.Threading;
    global using System.Threading.Tasks;

There is a [document][1] describing default namespaces for standard SDK(s). Then I can load it and parse as an additional syntax tree getting rid of the compilation error. There are warnings about unnecessary using directives. The complete code is this:

    using System.Diagnostics;
    using Microsoft.CodeAnalysis;
    using Microsoft.CodeAnalysis.CSharp;
    
    var sourceText = &quot;class C{&quot; +
        &quot;public void M(){&quot; +
        &quot; Console.Write(123);&quot; +
        &quot;}}&quot;;
    var syntaxTree = CSharpSyntaxTree.ParseText(sourceText);
    
    var globalUsings = File.ReadAllText(&quot;Microsoft.NET.Sdk.usings.cs&quot;);
    var usingsTree = CSharpSyntaxTree.ParseText(globalUsings);
    
    var coreReferences =
        ((string)AppContext.GetData(&quot;TRUSTED_PLATFORM_ASSEMBLIES&quot;))
        .Split(Path.PathSeparator)
        .Select(p =&gt; MetadataReference.CreateFromFile(p));
    var compilation = CSharpCompilation.Create(&quot;MyAnalysis&quot;)
        .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))
        .AddReferences(coreReferences)
        .AddSyntaxTrees(usingsTree, syntaxTree);
    
    var diagnostics = compilation.GetDiagnostics();
    Debug.Assert(!diagnostics.Any(d =&gt; d.Severity == DiagnosticSeverity.Error));


  [1]: https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#implicit-using-directives

</details>



huangapple
  • 本文由 发表于 2023年4月1日 00:58:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定