123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- using FastReport.Design.PageDesigners.Code;
- using Microsoft.CodeAnalysis;
- using Microsoft.CodeAnalysis.CSharp;
- using RoslynPad.Roslyn;
- using System;
- using System.Collections.Generic;
- using System.Collections.Immutable;
- using System.IO;
- using System.Reflection;
- namespace FastReport.WPF.RoslynPad
- {
- internal class MyRoslynHost : RoslynHost
- {
- private ProjectId projectId;
- private DocumentId additionalDocumentId;
- private RoslynWorkspace workspace;
- private string languageName;
- private string FindLocalAssembly(string name)
- {
- if (name == null || name.Trim() == "")
- return null;
- // old report version
- if (string.Compare(name, "System.Windows.Forms.DataVisualization.dll", true) == 0)
- name = "FastReport.DataVisualization.dll";
- // WPF versions of FastReport assemblies
- if (string.Compare(name, "System.Windows.Forms.dll", true) == 0)
- name = "FastReport.Forms.WPF.dll";
- // See if the required assembly is present locally
- string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, name);
- if (File.Exists(path))
- return path;
- return null;
- }
- private string GetRefAssemblyPath(Type type)
- {
- // dlls located here (example paths, dependent on arch & fw version):
- //"C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.14\" or "C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\6.0.14\"
- // ref dlls with associated xml files located here:
- //"C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.14\ref\net6.0\"
- string dllPath = Path.GetDirectoryName(type.Assembly.Location);
- string refPath = "";
- if (dllPath.Contains(@"shared\Microsoft.NETCore.App", StringComparison.OrdinalIgnoreCase))
- {
- refPath = dllPath.Replace(@"shared\Microsoft.NETCore.App", @"packs\Microsoft.NETCore.App.Ref", StringComparison.OrdinalIgnoreCase);
- }
- else if (dllPath.Contains(@"shared\Microsoft.WindowsDesktop.App", StringComparison.OrdinalIgnoreCase))
- {
- refPath = dllPath.Replace(@"shared\Microsoft.WindowsDesktop.App", @"packs\Microsoft.WindowsDesktop.App.Ref", StringComparison.OrdinalIgnoreCase);
- }
- else
- {
- // no ref dlls installed? Return default dll path (no xml comments though)
- return dllPath;
- }
- refPath = Path.Combine(refPath, "ref", "net") + type.Assembly.GetName().Version.ToString(2);
- if (Directory.Exists(refPath))
- return refPath;
- return dllPath;
- }
- private string GetRefAssemblyFileName(Type type)
- {
- return Path.Combine(GetRefAssemblyPath(type), Path.GetFileName(type.Assembly.Location));
- }
- private MetadataReference[] GetRefAssemblies(string[] assemblies)
- {
- List<MetadataReference> refAssemblies = new List<MetadataReference>();
- // system assemblies. Add them all
- string refPath = GetRefAssemblyPath(typeof(Object));
- foreach (var fileName in Directory.GetFiles(refPath, "*.dll"))
- refAssemblies.Add(CreateMetadataReference(fileName));
- // System.Drawing.Common (xml doc: missing for some types such as Bitmap. VS has the same issue)
- string sysDrawingDll = GetRefAssemblyFileName(typeof(System.Drawing.Image));
- if (File.Exists(sysDrawingDll))
- refAssemblies.Add(CreateMetadataReference(sysDrawingDll));
- // assemblies from Report.ReferencedAssemblies. Search in the exe folder. Note that system assemblies in this list will be ignored
- foreach (string name in assemblies)
- {
- var asm = FindLocalAssembly(name);
- if (asm != null)
- refAssemblies.Add(CreateMetadataReference(asm));
- }
- // FastReport main assembly
- refAssemblies.Add(CreateMetadataReference(typeof(Report).Assembly.Location));
- return refAssemblies.ToArray();
- }
- protected override ParseOptions CreateDefaultParseOptions()
- {
- return new CSharpParseOptions(kind: SourceCodeKind.Regular, languageVersion: LanguageVersion.Default);
- }
- public override RoslynWorkspace CreateWorkspace()
- {
- workspace = new MyRoslynWorkspace(HostServices, roslynHost: this);
- return workspace;
- }
- private string HiddenClassName
- {
- get { return languageName == LanguageNames.CSharp ? "hiddenClass.cs" : "hiddenClass.vb"; }
- }
- private ParseOptions GetParseOptions()
- {
- if (languageName == LanguageNames.CSharp)
- return new CSharpParseOptions(kind: SourceCodeKind.Regular, languageVersion: LanguageVersion.Default);
- return new Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions(kind: SourceCodeKind.Regular);
- }
- protected override CompilationOptions CreateCompilationOptions(DocumentCreationArgs args, bool addDefaultImports)
- {
- if (languageName == LanguageNames.CSharp)
- return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
- usings: addDefaultImports ? DefaultImports : ImmutableArray<string>.Empty,
- allowUnsafe: true,
- sourceReferenceResolver: new SourceFileResolver(ImmutableArray<string>.Empty, args.WorkingDirectory),
- // all #r references are resolved by the editor/msbuild
- metadataReferenceResolver: DummyScriptMetadataResolver.Instance,
- nullableContextOptions: NullableContextOptions.Disable);
- return new Microsoft.CodeAnalysis.VisualBasic.VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
- sourceReferenceResolver: new SourceFileResolver(ImmutableArray<string>.Empty, args.WorkingDirectory),
- metadataReferenceResolver: DummyScriptMetadataResolver.Instance);
- }
- protected override Project CreateProject(Solution solution, DocumentCreationArgs args, CompilationOptions compilationOptions, Project previousProject = null)
- {
- var name = args.Name ?? "Program";
- projectId = ProjectId.CreateNewId(name);
- solution = solution.AddProject(ProjectInfo.Create(
- projectId,
- VersionStamp.Create(),
- name,
- name,
- languageName,
- isSubmission: false,
- parseOptions: GetParseOptions(),
- compilationOptions: compilationOptions,
- metadataReferences: previousProject != null ? ImmutableArray<MetadataReference>.Empty : DefaultReferences,
- projectReferences: previousProject != null ? new[] { new ProjectReference(previousProject.Id) } : null)
- );
- additionalDocumentId = DocumentId.CreateNewId(projectId);
- solution = solution.AddDocument(additionalDocumentId, HiddenClassName, " ");
- var project = solution.GetProject(projectId);
- return project;
- }
- public void SetAdditionalInfo(string hiddenClassText, string[] assemblies)
- {
- var solution = workspace.CurrentSolution;
- var project = solution.GetProject(projectId);
- project = project.WithMetadataReferences(GetRefAssemblies(assemblies));
- solution = project.Solution;
- solution = solution.RemoveDocument(additionalDocumentId);
- additionalDocumentId = DocumentId.CreateNewId(projectId);
- solution = solution.AddDocument(additionalDocumentId, HiddenClassName, hiddenClassText);
- workspace.TryApplyChanges(solution);
- }
- public MyRoslynHost(SyntaxType syntaxType) :
- base(syntaxType == SyntaxType.Cs ?
- new[] {
- Assembly.Load("RoslynPad.Roslyn.Windows"),
- Assembly.Load("RoslynPad.Editor.Windows"),
- } :
- new[] {
- Assembly.Load("RoslynPad.Roslyn.Windows"),
- Assembly.Load("RoslynPad.Editor.Windows"),
- Assembly.Load("Microsoft.CodeAnalysis.VisualBasic.Features"),
- Assembly.Load("Microsoft.CodeAnalysis.VisualBasic.Workspaces"),
- }, null)
- {
- this.languageName = syntaxType == SyntaxType.Cs ? LanguageNames.CSharp : LanguageNames.VisualBasic;
- }
- }
- }
|