Search code examples
c#roslynmicrosoft.codeanalysisroslynpad

Is it possible to include intellisense for the object global of globalsType in the RoslynPad RoslynCodeEditor control?


I've been working with the RoslynCodeEditor control and attempting to find a way to pass my globals object to the RoslynCodeEditor and have intellisense within my scripts.

Does anyone know how I can grant access to the context object properties or methods when editing my script using RoslynCodeEditor control?

MyContext context = new MyContext();
context.Data = data;
ScriptOptions scriptOptions = ScriptOptions.Default;
scriptOptions = scriptOptions.WithReferences(ReferencesAndImports.References);
scriptOptions = scriptOptions.WithImports(ReferencesAndImports.Imports);
var scriptState = await CSharpScript.EvaluateAsync<string>("int i = 0;", scriptOptions, context, typeof(MyContext));

Solution

  • You need to add the globals type to the design-time compilation. To do that, you'll need a custom RoslynHost (supported in version 2.4 and up):

    public class CustomRoslynHost : RoslynHost
    {   
        protected override Project CreateProject(Solution solution, DocumentCreationArgs args, CompilationOptions compilationOptions, Project previousProject = null)
        {
            var name = args.Name ?? "Program";
            var id = ProjectId.CreateNewId(name);
    
            var parseOptions = new CSharpParseOptions(kind: SourceCodeKind.Script, languageVersion: LanguageVersion.Latest);
    
            compilationOptions = compilationOptions.WithScriptClassName(name);
    
            solution = solution.AddProject(ProjectInfo.Create(
                id,
                VersionStamp.Create(),
                name,
                name,
                LanguageNames.CSharp,
                isSubmission: true,
                parseOptions: parseOptions,
                hostObjectType: typeof(MyContext),
                compilationOptions: compilationOptions,
                metadataReferences: previousProject != null ? ImmutableArray<MetadataReference>.Empty : DefaultReferences,
                projectReferences: previousProject != null ? new[] { new ProjectReference(previousProject.Id) } : null));
    
            var project = solution.GetProject(id);
    
            return project;
        }
    }
    

    Then add a reference to the assembly the type resides in. For example:

    new CutomRoslynHost(
        references: RoslynHostReferences.Default.With(
            typeNamespaceImports: new[] { typeof(MyContext) }),
        additionalAssemblies: ...);