Roslyn Ploteervice不会推断for for for for for for for each变量的类型

发布于 2025-02-06 16:03:25 字数 2348 浏览 2 评论 0原文

我正在使用Roslyn's nofollow noreionservice 我的应用程序中的自动完成功能,该功能允许用户编写和执行C#脚本。

当编写诸如(管道表示镜头位置)之类的表达式时:

var m = Selected.Measure;
m.|

罗斯琳(Roslyn等等。对于预期的是自动完成。

但是,在以下表达式中,其中测量iEnumerable< measues>

foreach(var m in Selected.Measures)
{
    m.|
}

... Roslyn完成服务不提供任何建议。具体来说,此代码返回0个positionInItems:

sourceText = SourceText.From(text);
document = document.WithText(sourceText);
var completionService = CompletionService.GetService(document);
return await completionService.GetCompletionsAsync(document, position).ConfigureAwait(false);

我是否缺少完整服务或mefhostservice的某些配置,以便允许键入隐式变量的推断(Visual Studio似乎可以做得很好)?

我正在使用以下代码来配置Roslyn:

var assemblies = new List<Assembly>(MefHostServices.DefaultAssemblies);
assemblies.Add(typeof(ScriptEngine).Assembly); // This is the assembly that contains the Selected class, the Measure class, etc.
var host = MefHostServices.Create(assemblies);
this.workspace = new AdhocWorkspace(host);

var compilationOptions = new CSharpCompilationOptions(
    OutputKind.DynamicallyLinkedLibrary,
    usings: new[] { "System" })
    .WithUsings(ScriptEngine.DefaultUsings);
var scriptProjectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), 
    VersionStamp.Create(), "Script", "Script",
    LanguageNames.CSharp, isSubmission: true, hostObjectType: typeof(ScriptHost))
    .WithMetadataReferences(new[] { 
        MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(ScriptEngine).Assembly.Location
    })
    .WithParseOptions(new CSharpParseOptions(LanguageVersion.Latest, kind: SourceCodeKind.Script))
    .WithCompilationOptions(compilationOptions);

sourceText = SourceText.From("");
var scriptProject = workspace.AddProject(scriptProjectInfo);
var scriptDocumentInfo = DocumentInfo.Create(
    DocumentId.CreateNewId(scriptProject.Id), "Script",
    sourceCodeKind: SourceCodeKind.Script,
    loader: TextLoader.From(TextAndVersion.Create(sourceText, VersionStamp.Create())));
document = workspace.AddDocument(scriptDocumentInfo);

I'm using Roslyn's CompletionService for autocomplete functionality in my app, that allows users to write and execute c# scripts.

When writing an expression such as (pipe denotes the caret position):

var m = Selected.Measure;
m.|

Roslyn is perfectly able to infer that m is a variable of the same type as the Measure property, and it suggests all of its properties, methods, etc. for autocomplete, as expected.

However, in the following expression, where Measures is an IEnumerable<Measure>:

foreach(var m in Selected.Measures)
{
    m.|
}

...the Roslyn CompletionService does not provide any suggestions. Specifically, this code returns 0 CompletionItems:

sourceText = SourceText.From(text);
document = document.WithText(sourceText);
var completionService = CompletionService.GetService(document);
return await completionService.GetCompletionsAsync(document, position).ConfigureAwait(false);

Am I missing some configuration of the CompletionService or the MefHostService in order to allow type inference of implicit foreach variables (which is something that Visual Studio seems to do just fine)?

I'm using the following code to configure Roslyn:

var assemblies = new List<Assembly>(MefHostServices.DefaultAssemblies);
assemblies.Add(typeof(ScriptEngine).Assembly); // This is the assembly that contains the Selected class, the Measure class, etc.
var host = MefHostServices.Create(assemblies);
this.workspace = new AdhocWorkspace(host);

var compilationOptions = new CSharpCompilationOptions(
    OutputKind.DynamicallyLinkedLibrary,
    usings: new[] { "System" })
    .WithUsings(ScriptEngine.DefaultUsings);
var scriptProjectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), 
    VersionStamp.Create(), "Script", "Script",
    LanguageNames.CSharp, isSubmission: true, hostObjectType: typeof(ScriptHost))
    .WithMetadataReferences(new[] { 
        MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(ScriptEngine).Assembly.Location
    })
    .WithParseOptions(new CSharpParseOptions(LanguageVersion.Latest, kind: SourceCodeKind.Script))
    .WithCompilationOptions(compilationOptions);

sourceText = SourceText.From("");
var scriptProject = workspace.AddProject(scriptProjectInfo);
var scriptDocumentInfo = DocumentInfo.Create(
    DocumentId.CreateNewId(scriptProject.Id), "Script",
    sourceCodeKind: SourceCodeKind.Script,
    loader: TextLoader.From(TextAndVersion.Create(sourceText, VersionStamp.Create())));
document = workspace.AddDocument(scriptDocumentInfo);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

思念绕指尖 2025-02-13 16:03:25

在向罗斯林提供元数据时,我们必须明确提供瞬态依赖性。不足以传达对typeof(object).sembly的引用。

替换此代码:

.WithMetadataReferences(new[] { 
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(ScriptEngine).Assembly.Location
})

用:

var metadataReferences = ((String)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator)
    .Select(l => MetadataReference.CreateFromFile(l)).ToList();
metadataReferences.Add(MetadataReference.CreateFromFile(typeof(ScriptEngine).Assembly.Location));
// ...
.WithMetadataReferences(metadataReferences)

做到了!

另请参阅:

When providing MetadataReferences to Roslyn, we must explicitly provide transient dependencies. It is not enough to pass a reference to the typeof(object).Assembly.

Replacing this code:

.WithMetadataReferences(new[] { 
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(ScriptEngine).Assembly.Location
})

with:

var metadataReferences = ((String)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")).Split(Path.PathSeparator)
    .Select(l => MetadataReference.CreateFromFile(l)).ToList();
metadataReferences.Add(MetadataReference.CreateFromFile(typeof(ScriptEngine).Assembly.Location));
// ...
.WithMetadataReferences(metadataReferences)

did the trick!

See also:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文