未验证 提交 4d0c2c0d 编写于 作者: T Tomáš Matoušek 提交者: GitHub

InteractiveHost for .NET Core (#45046)

* InteractiveHost for .NET Core

* Merge fix

* Fixes

* Typo

* Workaround for https://github.com/dotnet/interactive-window/issues/156

* Fix

* Update OptProf config

* Fix deployment of rsp files

* Fix signing.

* Clean up unit tests dependencies.

* Remove unnecessary references.

* Fix reset interactive command

* Fix OptProf config

* Add missing project refs

* Fix InteractiveHost deployment

* Process rsp file fully in InteractiveHost process and send back results.

* Fix build from VS.

* Retrieve metadata resolver parameters from InteractiveHost process.

Simplify keeping search paths in-sync between InteractiveHost and InteractiveEvaluator.

* Fixes

* Fixes

* Check for failures to create process in unit tests

* Test

* Pending buffers

* Fix submission project creation

* Logging

* Serialize exceution and process initialization

* Fix reference completion, resolution.

* MetadataReferenceResolver fixes

* Fix failing .NET Core tests

* Target netcoreapp.

* Set DOTNET_ROOT

* Fix NGEN/OptProf

* Avoid loading Microsoft.CodeAnalysis.Scripting

* Fix

* Feedback

* Feedback

* Feedback

* Comment on dependent target

* Disable interpreting of strings as DateTime during deserialization:

* Merge fix
上级 c9e34615
......@@ -169,7 +169,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roslyn.Services.Test.Utilit
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.CSharp.EditorFeatures.Wpf", "src\EditorFeatures\CSharp.Wpf\Microsoft.CodeAnalysis.CSharp.EditorFeatures.Wpf.csproj", "{FE2CBEA6-D121-4FAA-AA8B-FC9900BF8C83}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveHost32", "src\Interactive\DesktopHost\InteractiveHost32.csproj", "{EBA4DFA1-6DED-418F-A485-A3B608978906}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveHost32", "src\Interactive\HostProcess\InteractiveHost32.csproj", "{EBA4DFA1-6DED-418F-A485-A3B608978906}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveHost.UnitTests", "src\Interactive\HostTest\InteractiveHost.UnitTests.csproj", "{8CEE3609-A5A9-4A9B-86D7-33118F5D6B34}"
EndProject
......@@ -193,8 +193,6 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Microsoft.VisualStudio.Lang
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roslyn.VisualStudio.Setup", "src\VisualStudio\Setup\Roslyn.VisualStudio.Setup.csproj", "{201EC5B7-F91E-45E5-B9F2-67A266CCE6FC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roslyn.VisualStudio.InteractiveComponents", "src\VisualStudio\VisualStudioInteractiveComponents\Roslyn.VisualStudio.InteractiveComponents.csproj", "{2169F526-8A88-435D-8732-486ACA095A6A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Roslyn.VisualStudio.DiagnosticsWindow", "src\VisualStudio\VisualStudioDiagnosticsToolWindow\Roslyn.VisualStudio.DiagnosticsWindow.csproj", "{A486D7DE-F614-409D-BB41-0FFDF582E35C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExpressionEvaluatorPackage", "src\ExpressionEvaluator\Package\ExpressionEvaluatorPackage.csproj", "{B617717C-7881-4F01-AB6D-B1B6CC0483A0}"
......@@ -344,7 +342,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Pool
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.CodeAnalysis.Workspaces.MSBuild.UnitTests", "src\Workspaces\MSBuildTest\Microsoft.CodeAnalysis.Workspaces.MSBuild.UnitTests.csproj", "{037F06F0-3BE8-42D0-801E-2F74FC380AB8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveHost64", "src\Interactive\DesktopHost\InteractiveHost64.csproj", "{2F11618A-9251-4609-B3D5-CE4D2B3D3E49}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InteractiveHost64", "src\Interactive\HostProcess\InteractiveHost64.csproj", "{2F11618A-9251-4609-B3D5-CE4D2B3D3E49}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.VisualStudio.IntegrationTest.IntegrationService", "src\VisualStudio\IntegrationTest\IntegrationService\Microsoft.VisualStudio.IntegrationTest.IntegrationService.csproj", "{764D2C19-0187-4837-A2A3-96DDC6EF4CE2}"
EndProject
......@@ -825,10 +823,6 @@ Global
{201EC5B7-F91E-45E5-B9F2-67A266CCE6FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{201EC5B7-F91E-45E5-B9F2-67A266CCE6FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{201EC5B7-F91E-45E5-B9F2-67A266CCE6FC}.Release|Any CPU.Build.0 = Release|Any CPU
{2169F526-8A88-435D-8732-486ACA095A6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2169F526-8A88-435D-8732-486ACA095A6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2169F526-8A88-435D-8732-486ACA095A6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2169F526-8A88-435D-8732-486ACA095A6A}.Release|Any CPU.Build.0 = Release|Any CPU
{A486D7DE-F614-409D-BB41-0FFDF582E35C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A486D7DE-F614-409D-BB41-0FFDF582E35C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A486D7DE-F614-409D-BB41-0FFDF582E35C}.Release|Any CPU.ActiveCfg = Release|Any CPU
......@@ -1300,7 +1294,6 @@ Global
{91C574AD-0352-47E9-A019-EE02CC32A396} = {8DBA5174-B0AA-4561-82B1-A46607697753}
{A1455D30-55FC-45EF-8759-3AEBDB13D940} = {8DBA5174-B0AA-4561-82B1-A46607697753}
{201EC5B7-F91E-45E5-B9F2-67A266CCE6FC} = {8DBA5174-B0AA-4561-82B1-A46607697753}
{2169F526-8A88-435D-8732-486ACA095A6A} = {19148439-436F-4CDA-B493-70AF4FFC13E9}
{A486D7DE-F614-409D-BB41-0FFDF582E35C} = {8DBA5174-B0AA-4561-82B1-A46607697753}
{B617717C-7881-4F01-AB6D-B1B6CC0483A0} = {4C81EBB2-82E1-4C81-80C4-84CC40FA281B}
{FD6BA96C-7905-4876-8BCC-E38E2CA64F31} = {913A4C08-898E-49C7-9692-0EF9DC56CF6E}
......
......@@ -31,7 +31,11 @@
<FileSignInfo Include="SQLitePCLRaw.batteries_v2.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="SQLitePCLRaw.batteries_green.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="SQLitePCLRaw.provider.e_sqlite3.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="MessagePack.Annotations.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="MessagePack.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="Nerdbank.FullDuplexStream.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="Nerdbank.Streams.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="Newtonsoft.Json.dll" CertificateName="3PartySHA2" />
<FileSignInfo Include="Validation.dll" CertificateName="3PartySHA2" />
</ItemGroup>
</Project>
......@@ -18,22 +18,10 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.Text.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.Features.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/DesktopHost/System.Reflection.Metadata.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/DesktopHost/System.Numerics.Vectors.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.Xaml.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
......@@ -58,14 +46,6 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.CSharp.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/Microsoft.CodeAnalysis.CSharp.Features.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
......@@ -86,18 +66,10 @@
"filename": "/Microsoft.VisualStudio.LanguageServices.Implementation.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/DesktopHost/System.Collections.Immutable.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.SolutionExplorer.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/DesktopHost/System.Runtime.CompilerServices.Unsafe.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
},
{
"filename": "/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll",
"testCases":[ "Microsoft.Test.Performance.XamlOptProfCreateTests.WpfCreateProject_DesignerIsolated" ]
......@@ -123,22 +95,10 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.Text.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.Features.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/DesktopHost/System.Reflection.Metadata.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/DesktopHost/System.Numerics.Vectors.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/Microsoft.CodeAnalysis.VisualBasic.Features.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
......@@ -159,14 +119,6 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.CSharp.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/Microsoft.CodeAnalysis.CSharp.Features.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
......@@ -195,18 +147,10 @@
"filename": "/Microsoft.VisualStudio.LanguageServices.VisualBasic.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/DesktopHost/System.Collections.Immutable.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.SolutionExplorer.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/DesktopHost/System.Runtime.CompilerServices.Unsafe.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
},
{
"filename": "/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll",
"testCases":[ "WinForms.OptProfTests.winforms_largeform_vb" ]
......@@ -228,22 +172,10 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.Text.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.Features.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/System.Reflection.Metadata.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/System.Numerics.Vectors.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/Microsoft.CodeAnalysis.VisualBasic.Features.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
......@@ -264,14 +196,6 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.CSharp.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/Microsoft.CodeAnalysis.CSharp.Features.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
......@@ -292,22 +216,10 @@
"filename": "/Microsoft.VisualStudio.LanguageServices.Implementation.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/System.Collections.Immutable.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/System.Memory.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.SolutionExplorer.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/DesktopHost/System.Runtime.CompilerServices.Unsafe.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
},
{
"filename": "/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll",
"testCases":[ "TeamEng.OptProfTest.vs_debugger_start_no_build_cs_scribble" ]
......@@ -333,22 +245,10 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.Text.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.Features.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/System.Reflection.Metadata.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/System.Numerics.Vectors.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/Microsoft.CodeAnalysis.VisualBasic.Features.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment" ]
......@@ -365,14 +265,6 @@
"filename": "/Microsoft.CodeAnalysis.EditorFeatures.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.CSharp.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/Microsoft.CodeAnalysis.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/Microsoft.CodeAnalysis.CSharp.Features.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug" ]
......@@ -401,30 +293,14 @@
"filename": "/Microsoft.CodeAnalysis.VisualBasic.EditorFeatures.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/System.Text.Encoding.CodePages.dll",
"testCases":[ "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.VisualBasic.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/System.Collections.Immutable.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/System.Memory.dll",
"testCases":[ "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment" ]
},
{
"filename": "/Microsoft.VisualStudio.LanguageServices.SolutionExplorer.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/DesktopHost/System.Runtime.CompilerServices.Unsafe.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_cs_scenario", "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_DesignTime_solution_loadclose_cs_picasso", "VSPE.OptProfTests.vs_perf_designtime_editor_intellisense_globalcompletionlist_cs", "VSPE.OptProfTests.vs_perf_designtime_ide_searchtest", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Typing", "VSPE.OptProfTests.DDRIT_RPS_ManagedLangs_Debug", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
},
{
"filename": "/Microsoft.CodeAnalysis.VisualBasic.Workspaces.dll",
"testCases":[ "VSPE.OptProfTests.vs_asl_vb_scenario", "VSPE.OptProfTests.vs_perf_designtime_solution_build_vb_australiangovernment", "VSPE.OptProfTests.vs_perf_designtime_solution_loadclose_vb_australiangovernment" ]
......
......@@ -5,7 +5,7 @@
The inclusion of this file will cause the resulting .exe.config to contain redirects for all non-framework dependencies,
which is needed for plugins loaded into the compiler (e.g. analyzers) that might target lower versions of these dependencies.
-->
<PropertyGroup>
<PropertyGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
......
......@@ -17,13 +17,10 @@ namespace Microsoft.CodeAnalysis.Scripting.Hosting
/// </summary>
internal sealed class GacFileResolver : IEquatable<GacFileResolver>
{
// Consider a better availability check (perhaps the presence of Assembly.GlobalAssemblyCache once CoreCLR mscorlib is cleaned up).
// https://github.com/dotnet/roslyn/issues/5538
/// <summary>
/// Returns true if GAC is available on the platform.
/// Returns true if GAC is available on the current platform.
/// </summary>
public static bool IsAvailable => CoreClrShim.AssemblyLoadContext.Type == null;
public static bool IsAvailable => typeof(object).Assembly.GlobalAssemblyCache;
/// <summary>
/// Architecture filter used when resolving assembly references.
......@@ -43,7 +40,7 @@ internal sealed class GacFileResolver : IEquatable<GacFileResolver>
/// among the set filtered by <paramref name="architectures"/></param>
/// <exception cref="PlatformNotSupportedException">The platform doesn't support GAC.</exception>
public GacFileResolver(
ImmutableArray<ProcessorArchitecture> architectures = default(ImmutableArray<ProcessorArchitecture>),
ImmutableArray<ProcessorArchitecture> architectures = default,
CultureInfo preferredCulture = null)
{
if (!IsAvailable)
......
......@@ -38,12 +38,6 @@
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<IncludeOutputGroupsInVSIX>VSIXContainerProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
</ProjectReference>
<ProjectReference Include="..\VisualStudio\VisualStudioInteractiveComponents\Roslyn.VisualStudio.InteractiveComponents.csproj">
<Name>VisualStudioInteractiveComponents</Name>
<VSIXSubPath>Vsixes</VSIXSubPath>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<IncludeOutputGroupsInVSIX>VSIXContainerProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.SDK.Analyzers" Version="$(MicrosoftVisualStudioSDKAnalyzersVersion)" PrivateAssets="all" />
......
......@@ -29,15 +29,6 @@
Location="|VisualStudioSetup;VSIXContainerProjectOutputGroup|"
Id="0b5e8ddb-f12d-4131-a71d-77acc26a798f" />
<Dependency d:ProjectName="VisualStudioInteractiveComponents"
DisplayName="Roslyn Interactive Components"
Version="[|%CurrentProject%;GetVsixVersion|,)"
d:Source="Project"
d:InstallSource="Embed"
d:VsixSubPath="Vsixes"
Location="|VisualStudioInteractiveComponents;VSIXContainerProjectOutputGroup|"
Id="500fff63-afcf-4195-8db4-3fa8a5180e79" />
<Dependency d:ProjectName="ExpressionEvaluatorPackage"
DisplayName="Roslyn Expression Evaluators"
Version="[|%CurrentProject%;GetVsixVersion|,)"
......
......@@ -12,6 +12,7 @@
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
using Microsoft.CodeAnalysis.CSharp.Scripting.Hosting;
using Microsoft.CodeAnalysis.Shared.TestHooks;
namespace Microsoft.CodeAnalysis.Editor.CSharp.Interactive
{
......@@ -24,6 +25,7 @@ internal sealed class CSharpInteractiveEvaluator : InteractiveEvaluator
public CSharpInteractiveEvaluator(
IThreadingContext threadingContext,
IAsynchronousOperationListener listener,
HostServices hostServices,
IViewClassifierAggregatorService classifierAggregator,
IInteractiveWindowCommandsFactory commandsFactory,
......@@ -32,6 +34,7 @@ internal sealed class CSharpInteractiveEvaluator : InteractiveEvaluator
string initialWorkingDirectory)
: base(
threadingContext,
listener,
contentTypeRegistry.GetContentType(ContentTypeNames.CSharpContentType),
hostServices,
classifierAggregator,
......
......@@ -16,9 +16,19 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders
{
public abstract class AbstractCSharpCompletionProviderTests : AbstractCompletionProviderTests<CSharpTestWorkspaceFixture>
public abstract class AbstractCSharpCompletionProviderTests : AbstractCSharpCompletionProviderTests<CSharpTestWorkspaceFixture>
{
protected AbstractCSharpCompletionProviderTests(CSharpTestWorkspaceFixture workspaceFixture) : base(workspaceFixture)
protected AbstractCSharpCompletionProviderTests(CSharpTestWorkspaceFixture workspaceFixture)
: base(workspaceFixture)
{
}
}
public abstract class AbstractCSharpCompletionProviderTests<TWorkspaceFixture> : AbstractCompletionProviderTests<TWorkspaceFixture>
where TWorkspaceFixture : TestWorkspaceFixture, new()
{
protected AbstractCSharpCompletionProviderTests(TWorkspaceFixture workspaceFixture)
: base(workspaceFixture)
{
}
......@@ -135,11 +145,10 @@ protected static string AddUsingDirectives(string usingDirectives, string text)
text;
}
protected async Task VerifySendEnterThroughToEnterAsync(string initialMarkup, string textTypedSoFar, EnterKeyRule sendThroughEnterOption, bool expected, SourceCodeKind sourceCodeKind = SourceCodeKind.Regular)
protected async Task VerifySendEnterThroughToEnterAsync(string initialMarkup, string textTypedSoFar, EnterKeyRule sendThroughEnterOption, bool expected)
{
using var workspace = TestWorkspace.CreateCSharp(initialMarkup, exportProvider: ExportProvider);
using var workspace = CreateWorkspace(initialMarkup);
var hostDocument = workspace.DocumentWithCursor;
workspace.OnDocumentSourceCodeKindChanged(hostDocument.Id, sourceCodeKind);
var documentId = workspace.GetDocumentId(hostDocument);
var document = workspace.CurrentSolution.GetDocument(documentId);
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders
{
public abstract class AbstractInteractiveCSharpCompletionProviderTests : AbstractCSharpCompletionProviderTests<InteractiveCSharpTestWorkspaceFixture>
{
protected AbstractInteractiveCSharpCompletionProviderTests(InteractiveCSharpTestWorkspaceFixture workspaceFixture)
: base(workspaceFixture)
{
}
protected override TestWorkspace CreateWorkspace(string fileContents)
=> InteractiveCSharpTestWorkspaceFixture.CreateInteractiveWorkspace(fileContents, exportProvider: ExportProvider);
}
}
......@@ -19,9 +19,10 @@
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.Completion.CompletionProviders
{
[Trait(Traits.Feature, Traits.Features.Completion)]
public class ReferenceDirectiveCompletionProviderTests : AbstractCSharpCompletionProviderTests
public class ReferenceDirectiveCompletionProviderTests : AbstractInteractiveCSharpCompletionProviderTests
{
public ReferenceDirectiveCompletionProviderTests(CSharpTestWorkspaceFixture workspaceFixture) : base(workspaceFixture)
public ReferenceDirectiveCompletionProviderTests(InteractiveCSharpTestWorkspaceFixture workspaceFixture)
: base(workspaceFixture)
{
}
......@@ -66,7 +67,7 @@ public void IsTextualTriggerCharacterTest(string markup)
[InlineData(EnterKeyRule.AfterFullyTypedWord)]
[InlineData(EnterKeyRule.Always)] // note: GAC completion helper uses its own EnterKeyRule
public async Task SendEnterThroughToEditorTest(EnterKeyRule enterKeyRule)
=> await VerifySendEnterThroughToEnterAsync("#r \"System$$", "System", enterKeyRule, expected: false, SourceCodeKind.Script);
=> await VerifySendEnterThroughToEnterAsync("#r \"System$$", "System", enterKeyRule, expected: false);
[ConditionalFact(typeof(WindowsOnly))]
public async Task GacReference()
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
extern alias InteractiveHost;
using System;
using System.Collections.Generic;
......@@ -15,6 +16,8 @@
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
using InteractiveHost::Microsoft.CodeAnalysis.Interactive;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Editor.Interactive
{
......@@ -27,6 +30,11 @@ internal sealed class ResetCommand : IInteractiveWindowCommand
{
private const string CommandName = "reset";
private const string NoConfigParameterName = "noconfig";
private const string PlatformCore = "core";
private const string PlatformDesktop32 = "32";
private const string PlatformDesktop64 = "64";
private const string PlatformNames = PlatformCore + "|" + PlatformDesktop32 + "|" + PlatformDesktop64;
private static readonly int s_noConfigParameterNameLength = NoConfigParameterName.Length;
private readonly IStandardClassificationService _registry;
......@@ -36,44 +44,36 @@ public ResetCommand(IStandardClassificationService registry)
=> _registry = registry;
public string Description
{
get { return InteractiveEditorFeaturesResources.Reset_the_execution_environment_to_the_initial_state_keep_history; }
}
=> InteractiveEditorFeaturesResources.Reset_the_execution_environment_to_the_initial_state_keep_history;
public IEnumerable<string> DetailedDescription
{
get { return null; }
}
=> null;
public IEnumerable<string> Names
{
get { yield return CommandName; }
}
=> SpecializedCollections.SingletonEnumerable(CommandName);
public string CommandLine
{
get { return "[" + NoConfigParameterName + "] [32|64]"; }
}
=> "[" + NoConfigParameterName + "] [" + PlatformNames + "]";
public IEnumerable<KeyValuePair<string, string>> ParametersDescription
{
get
{
yield return new KeyValuePair<string, string>(NoConfigParameterName, InteractiveEditorFeaturesResources.Reset_to_a_clean_environment_only_mscorlib_referenced_do_not_run_initialization_script);
yield return new KeyValuePair<string, string>("32|64", $"Interactive host process bitness.");
yield return new KeyValuePair<string, string>(PlatformNames, InteractiveEditorFeaturesResources.Interactive_host_process_platform);
}
}
public Task<ExecutionResult> Execute(IInteractiveWindow window, string arguments)
{
if (!TryParseArguments(arguments, out var initialize, out var is64bit))
if (!TryParseArguments(arguments, out var initialize, out var platform))
{
ReportInvalidArguments(window);
return ExecutionResult.Failed;
}
var evaluator = (InteractiveEvaluator)window.Evaluator;
evaluator.ResetOptions = new InteractiveEvaluatorResetOptions(is64bit);
evaluator.ResetOptions = new InteractiveEvaluatorResetOptions(platform);
return window.Operations.ResetAsync(initialize);
}
......@@ -112,33 +112,42 @@ internal static IEnumerable<int> GetNoConfigPositions(string arguments)
/// <remarks>
/// Accessibility is internal for testing.
/// </remarks>
internal static bool TryParseArguments(string arguments, out bool initialize, out bool? is64bit)
internal static bool TryParseArguments(string arguments, out bool initialize, out InteractiveHostPlatform? platform)
{
is64bit = null;
platform = null;
initialize = true;
var noConfigSpecified = false;
foreach (var argument in arguments.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
{
switch (argument)
switch (argument.ToLowerInvariant())
{
case "32":
if (is64bit != null)
case PlatformDesktop32:
if (platform != null)
{
return false;
}
platform = InteractiveHostPlatform.Desktop32;
break;
case PlatformDesktop64:
if (platform != null)
{
return false;
}
is64bit = false;
platform = InteractiveHostPlatform.Desktop64;
break;
case "64":
if (is64bit != null)
case PlatformCore:
if (platform != null)
{
return false;
}
is64bit = true;
platform = InteractiveHostPlatform.Core;
break;
case NoConfigParameterName:
......@@ -159,8 +168,15 @@ internal static bool TryParseArguments(string arguments, out bool initialize, ou
return true;
}
internal static string GetCommandLine(bool initialize, bool? is64bit)
=> CommandName + (initialize ? "" : " " + NoConfigParameterName) + (is64bit == null ? "" : is64bit.Value ? " 64" : " 32");
internal static string GetCommandLine(bool initialize, InteractiveHostPlatform? platform)
=> CommandName + (initialize ? "" : " " + NoConfigParameterName) + platform switch
{
null => "",
InteractiveHostPlatform.Core => " " + PlatformCore,
InteractiveHostPlatform.Desktop64 => " " + PlatformDesktop64,
InteractiveHostPlatform.Desktop32 => " " + PlatformDesktop32,
_ => throw ExceptionUtilities.Unreachable
};
private void ReportInvalidArguments(IInteractiveWindow window)
{
......
......@@ -147,4 +147,7 @@
<data name="The_CurrentWindow_property_may_only_be_assigned_once" xml:space="preserve">
<value>The CurrentWindow property may only be assigned once.</value>
</data>
<data name="Interactive_host_process_platform" xml:space="preserve">
<value>Interactive host process platform</value>
</data>
</root>
\ No newline at end of file
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
extern alias InteractiveHost;
using InteractiveHost::Microsoft.CodeAnalysis.Interactive;
namespace Microsoft.CodeAnalysis.Editor.Interactive
{
internal sealed class InteractiveEvaluatorResetOptions
{
public bool? Is64Bit;
public readonly InteractiveHostPlatform? Platform;
public InteractiveEvaluatorResetOptions(bool? is64Bit)
=> Is64Bit = is64Bit;
public InteractiveEvaluatorResetOptions(InteractiveHostPlatform? platform)
=> Platform = platform;
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
extern alias InteractiveHost;
using System;
using System.Linq;
......@@ -14,7 +15,7 @@
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Editor.OptionsExtensionMethods;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using InteractiveHost::Microsoft.CodeAnalysis.Interactive;
namespace Microsoft.VisualStudio.LanguageServices.Interactive
{
......@@ -41,7 +42,7 @@ internal ResetInteractive(IEditorOptionsFactoryService editorOptionsFactoryServi
internal Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
{
if (GetProjectProperties(out var references, out var referenceSearchPaths, out var sourceSearchPaths, out var projectNamespaces, out var projectDirectory, out var is64Bit))
if (GetProjectProperties(out var references, out var referenceSearchPaths, out var sourceSearchPaths, out var projectNamespaces, out var projectDirectory, out var platform))
{
// Now, we're going to do a bunch of async operations. So create a wait
// indicator so the user knows something is happening, and also so they cancel.
......@@ -55,7 +56,7 @@ internal Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
sourceSearchPaths,
projectNamespaces,
projectDirectory,
is64Bit,
platform,
waitContext);
// Once we're done resetting, dismiss the wait indicator and focus the REPL window.
......@@ -78,7 +79,7 @@ internal Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
ImmutableArray<string> sourceSearchPaths,
ImmutableArray<string> projectNamespaces,
string projectDirectory,
bool? is64Bit,
InteractiveHostPlatform? platform,
IWaitContext waitContext)
{
// First, open the repl window.
......@@ -100,7 +101,7 @@ internal Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
// Then reset the REPL
waitContext.Message = InteractiveEditorFeaturesResources.Resetting_Interactive;
evaluator.ResetOptions = new InteractiveEvaluatorResetOptions(is64Bit);
evaluator.ResetOptions = new InteractiveEvaluatorResetOptions(platform);
await interactiveWindow.Operations.ResetAsync(initialize: true).ConfigureAwait(true);
// TODO: load context from an rsp file.
......@@ -136,7 +137,7 @@ internal Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
out ImmutableArray<string> sourceSearchPaths,
out ImmutableArray<string> projectNamespaces,
out string projectDirectory,
out bool? is64bit);
out InteractiveHostPlatform? platform);
/// <summary>
/// A method that should trigger an async project build.
......
......@@ -17,6 +17,11 @@
<target state="translated">Výběr se spouští v interaktivním okně.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Vytiskne seznam odkazovaných sestavení.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Die Auswahl wird in Interactive Window ausgeführt.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Gibt eine Liste der Assemblys aus, auf die verwiesen wird.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Ejecutando selección en ventana interactiva.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Imprima una lista de ensamblados de referencia.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Exécution de la sélection dans la fenêtre interactive.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Affichez la liste des assemblys référencés.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Esecuzione della selezione nella finestra interattiva.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Stampa un elenco di tutti gli assembly di riferimento.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">対話型ウィンドウで選択を実行します。</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">参照アセンブリの一覧を印刷します。</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">선택 영역을 대화형 창에서 실행하는 중입니다.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">참조된 어셈블리의 목록을 인쇄합니다.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Wykonywanie zaznaczenia w oknie interaktywnym.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Wydrukuj listę przywoływanych zestawów.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Executando seleção na Janela Interativa.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Imprima uma lista de assemblies referenciados.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Выполнение выделенного фрагмента в интерактивном окне.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Печать списка сборок, на которые указывают ссылки.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">Seçim, Etkileşimli Pencere'de yürütülüyor.</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">Başvurulan bütünleştirilmiş kodların listesini yazdırın.</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">在交互式窗口中执行所选内容。</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">打印引用程序集的列表。</target>
......
......@@ -17,6 +17,11 @@
<target state="translated">正在於互動式視窗中執行選取範圍。</target>
<note />
</trans-unit>
<trans-unit id="Interactive_host_process_platform">
<source>Interactive host process platform</source>
<target state="new">Interactive host process platform</target>
<note />
</trans-unit>
<trans-unit id="Print_a_list_of_referenced_assemblies">
<source>Print a list of referenced assemblies.</source>
<target state="translated">列印參考組件的清單。</target>
......
......@@ -6,6 +6,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Completion;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.Scripting.Hosting;
using Roslyn.Utilities;
......@@ -47,15 +48,25 @@ private static ImmutableArray<char> GetCommitCharacters()
protected override async Task ProvideCompletionsAsync(CompletionContext context, string pathThroughLastSlash)
{
if (GacFileResolver.IsAvailable && pathThroughLastSlash.IndexOfAny(s_pathIndicators) < 0)
var resolver = context.Document.Project.CompilationOptions.MetadataReferenceResolver as RuntimeMetadataReferenceResolver;
if (resolver != null && pathThroughLastSlash.IndexOfAny(s_pathIndicators) < 0)
{
var gacHelper = new GlobalAssemblyCacheCompletionHelper(s_rules);
context.AddItems(await gacHelper.GetItemsAsync(pathThroughLastSlash, context.CancellationToken).ConfigureAwait(false));
foreach (var (name, path) in resolver.TrustedPlatformAssemblies)
{
context.AddItem(CommonCompletionItem.Create(name, displayTextSuffix: "", glyph: Glyph.Assembly, rules: s_rules));
context.AddItem(CommonCompletionItem.Create(PathUtilities.GetFileName(path, includeExtension: true), displayTextSuffix: "", glyph: Glyph.Assembly, rules: s_rules));
}
if (resolver.GacFileResolver is object)
{
var gacHelper = new GlobalAssemblyCacheCompletionHelper(s_rules);
context.AddItems(await gacHelper.GetItemsAsync(pathThroughLastSlash, context.CancellationToken).ConfigureAwait(false));
}
}
if (pathThroughLastSlash.IndexOf(',') < 0)
{
var helper = GetFileSystemCompletionHelper(context.Document, Glyph.Assembly, ImmutableArray.Create(".dll", ".exe"), s_rules);
var helper = GetFileSystemCompletionHelper(context.Document, Glyph.Assembly, RuntimeMetadataReferenceResolver.AssemblyExtensions, s_rules);
context.AddItems(await helper.GetItemsAsync(pathThroughLastSlash, context.CancellationToken).ConfigureAwait(false));
}
}
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Xml.Linq;
using Microsoft.VisualStudio.Composition;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
{
public class InteractiveCSharpTestWorkspaceFixture : CSharpTestWorkspaceFixture
{
internal static TestWorkspace CreateInteractiveWorkspace(string fileContent, ExportProvider exportProvider)
{
var workspaceDefinition = $@"
<Workspace>
<Submission Language=""C#"" CommonReferences=""true"">
<![CDATA[{fileContent}]]>
</Submission>
</Workspace>
";
return TestWorkspace.Create(XElement.Parse(workspaceDefinition), exportProvider: exportProvider, workspaceKind: WorkspaceKind.Interactive);
}
protected override TestWorkspace CreateWorkspace(ExportProvider exportProvider = null)
=> CreateInteractiveWorkspace(fileContent: "", exportProvider);
}
}
......@@ -12,12 +12,14 @@
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.ServiceModel.Description;
using System.Threading;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.UnitTests.Extensions;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Scripting.Hosting;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.CodeAnalysis.Text;
......@@ -215,9 +217,13 @@ public static TestWorkspace Create(string xmlDefinition, bool openDocuments = fa
continue;
}
var metadataService = workspace.Services.GetService<IMetadataService>();
var metadataResolver = RuntimeMetadataReferenceResolver.CreateCurrentPlatformResolver(fileReferenceProvider: metadataService.GetReference);
var syntaxFactory = languageServices.GetService<ISyntaxTreeFactoryService>();
var compilationFactory = languageServices.GetService<ICompilationFactoryService>();
var compilationOptions = compilationFactory.GetDefaultCompilationOptions().WithOutputKind(OutputKind.DynamicallyLinkedLibrary);
var compilationOptions = compilationFactory.GetDefaultCompilationOptions()
.WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
.WithMetadataReferenceResolver(metadataResolver);
var parseOptions = syntaxFactory.GetDefaultParseOptions().WithKind(SourceCodeKind.Script);
......
......@@ -10,7 +10,7 @@ internal partial class InteractiveHost
{
private readonly struct InitializedRemoteService
{
public readonly RemoteService Service;
public readonly RemoteService? Service;
public readonly RemoteExecutionResult InitializationResult;
public InitializedRemoteService(RemoteService service, RemoteExecutionResult initializationResult)
......
......@@ -4,9 +4,13 @@
#nullable enable
extern alias Scripting;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;
......@@ -14,6 +18,7 @@
using Microsoft.CodeAnalysis.ErrorReporting;
using Roslyn.Utilities;
using StreamJsonRpc;
using Scripting::Microsoft.CodeAnalysis.Scripting.Hosting;
namespace Microsoft.CodeAnalysis.Interactive
{
......@@ -62,17 +67,28 @@ private async Task<InitializedRemoteService> TryStartAndInitializeProcessAsync(C
{
try
{
Host.ProcessStarting?.Invoke(Options.InitializationFile != null);
var remoteService = await TryStartProcessAsync(Options.GetHostPath(), Options.Culture, cancellationToken).ConfigureAwait(false);
var remoteService = await TryStartProcessAsync(Options.HostPath, Options.Culture, cancellationToken).ConfigureAwait(false);
if (remoteService == null)
{
return default;
}
RemoteExecutionResult result;
if (SkipInitialization)
{
return new InitializedRemoteService(remoteService, new RemoteExecutionResult(success: true));
result = new RemoteExecutionResult(
success: true,
sourcePaths: ImmutableArray<string>.Empty,
referencePaths: ImmutableArray<string>.Empty,
workingDirectory: Host._initialWorkingDirectory,
initializationResult: new RemoteInitializationResult(
initializationScript: null,
metadataReferencePaths: ImmutableArray.Create(typeof(object).Assembly.Location, typeof(InteractiveScriptGlobals).Assembly.Location),
imports: ImmutableArray<string>.Empty));
Host.ProcessInitialized?.Invoke(remoteService.PlatformInfo, Options, result);
return new InitializedRemoteService(remoteService, result);
}
bool initializing = true;
......@@ -87,9 +103,10 @@ private async Task<InitializedRemoteService> TryStartAndInitializeProcessAsync(C
// try to execute initialization script:
var isRestarting = InstanceId > 1;
var initializationResult = await InvokeRemoteAsync<RemoteExecutionResult>(remoteService, nameof(Service.InitializeContextAsync), Options.InitializationFile, isRestarting).ConfigureAwait(false);
result = await ExecuteRemoteAsync(remoteService, nameof(Service.InitializeContextAsync), Options.InitializationFilePath, isRestarting).ConfigureAwait(false);
initializing = false;
if (!initializationResult.Success)
if (!result.Success)
{
Host.ReportProcessExited(remoteService.Process);
remoteService.Dispose();
......@@ -97,12 +114,16 @@ private async Task<InitializedRemoteService> TryStartAndInitializeProcessAsync(C
return default;
}
Contract.ThrowIfNull(result.InitializationResult);
// Hook up a handler that initiates restart when the process exits.
// Note that this is just so that we restart the process as soon as we see it dying and it doesn't need to be 100% bullet-proof.
// If we don't receive the "process exited" event we will restart the process upon the next remote operation.
remoteService.HookAutoRestartEvent();
return new InitializedRemoteService(remoteService, initializationResult);
Host.ProcessInitialized?.Invoke(remoteService.PlatformInfo, Options, result);
return new InitializedRemoteService(remoteService, result);
}
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
......@@ -133,7 +154,20 @@ private async Task<InitializedRemoteService> TryStartAndInitializeProcessAsync(C
EnableRaisingEvents = true
};
newProcess.Start();
try
{
newProcess.Start();
}
catch (Exception e)
{
Host.WriteOutputInBackground(
isError: true,
string.Format(InteractiveHostResources.Failed_to_create_a_remote_process_for_interactive_code_execution, hostPath),
e.Message);
Host.InteractiveHostProcessCreationFailed?.Invoke(e, TryGetExitCode(newProcess));
return null;
}
Host.InteractiveHostProcessCreated?.Invoke(newProcess);
......@@ -148,38 +182,45 @@ private async Task<InitializedRemoteService> TryStartAndInitializeProcessAsync(C
}
var clientStream = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
JsonRpc jsonRpc;
JsonRpc? jsonRpc = null;
void ProcessExitedBeforeEstablishingConnection(object sender, EventArgs e)
=> _cancellationSource.Cancel();
{
Host.InteractiveHostProcessCreationFailed?.Invoke(null, TryGetExitCode(newProcess));
_cancellationSource.Cancel();
}
// Connecting the named pipe client would hang if the process exits before the connection is established,
// as the client waits for the server to become available. We signal the cancellation token to abort.
newProcess.Exited += ProcessExitedBeforeEstablishingConnection;
InteractiveHostPlatformInfo platformInfo;
try
{
if (!CheckAlive(newProcess, hostPath))
{
Host.InteractiveHostProcessCreationFailed?.Invoke(null, TryGetExitCode(newProcess));
return null;
}
await clientStream.ConnectAsync(cancellationToken).ConfigureAwait(false);
jsonRpc = CreateRpc(clientStream, incomingCallTarget: null);
jsonRpc = JsonRpc.Attach(clientStream);
await jsonRpc.InvokeWithCancellationAsync(
platformInfo = (await jsonRpc.InvokeWithCancellationAsync<InteractiveHostPlatformInfo.Data>(
nameof(Service.InitializeAsync),
new object[] { Host._replServiceProviderType.AssemblyQualifiedName, culture.Name },
cancellationToken).ConfigureAwait(false);
cancellationToken).ConfigureAwait(false)).Deserialize();
}
catch
catch (Exception e)
{
if (CheckAlive(newProcess, hostPath))
{
RemoteService.InitiateTermination(newProcess, newProcessId);
}
jsonRpc?.Dispose();
Host.InteractiveHostProcessCreationFailed?.Invoke(e, TryGetExitCode(newProcess));
return null;
}
finally
......@@ -187,8 +228,9 @@ void ProcessExitedBeforeEstablishingConnection(object sender, EventArgs e)
newProcess.Exited -= ProcessExitedBeforeEstablishingConnection;
}
return new RemoteService(Host, newProcess, newProcessId, jsonRpc);
return new RemoteService(Host, newProcess, newProcessId, jsonRpc, platformInfo);
}
private bool CheckAlive(Process process, string hostPath)
{
bool alive = process.IsAlive();
......@@ -204,6 +246,18 @@ private bool CheckAlive(Process process, string hostPath)
return alive;
}
private static int? TryGetExitCode(Process process)
{
try
{
return process.ExitCode;
}
catch
{
return null;
}
}
}
}
}
......@@ -7,7 +7,6 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Security.RightsManagement;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
......@@ -22,6 +21,8 @@ internal sealed class RemoteService
{
public readonly Process Process;
public readonly JsonRpc JsonRpc;
public readonly InteractiveHostPlatformInfo PlatformInfo;
private readonly int _processId;
private readonly SemaphoreSlim _disposeSemaphore = new SemaphoreSlim(initialCount: 1);
private readonly bool _joinOutputWritingThreadsOnDisposal;
......@@ -32,10 +33,11 @@ internal sealed class RemoteService
private Thread? _readErrorOutputThread; // nulled on dispose
private volatile ProcessExitHandlerStatus _processExitHandlerStatus; // set to Handled on dispose
internal RemoteService(InteractiveHost host, Process process, int processId, JsonRpc jsonRpc)
internal RemoteService(InteractiveHost host, Process process, int processId, JsonRpc jsonRpc, InteractiveHostPlatformInfo platformInfo)
{
Process = process;
JsonRpc = jsonRpc;
PlatformInfo = platformInfo;
_host = host;
_joinOutputWritingThreadsOnDisposal = _host._joinOutputWritingThreadsOnDisposal;
......
......@@ -7,14 +7,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.CodeAnalysis.ErrorReporting;
using Newtonsoft.Json;
using Roslyn.Utilities;
using StreamJsonRpc;
......@@ -28,7 +25,16 @@ namespace Microsoft.CodeAnalysis.Interactive
/// </remarks>
internal sealed partial class InteractiveHost : IDisposable
{
internal const bool DefaultIs64Bit = true;
internal const InteractiveHostPlatform DefaultPlatform = InteractiveHostPlatform.Desktop32;
private static readonly JsonRpcTargetOptions s_jsonRpcTargetOptions = new JsonRpcTargetOptions()
{
// Do not allow JSON-RPC to automatically subscribe to events and remote their calls.
NotifyClientOfEvents = false,
// Only allow public methods (may be on internal types) to be invoked remotely.
AllowNonPublicInvocation = false
};
private readonly Type _replServiceProviderType;
private readonly string _initialWorkingDirectory;
......@@ -53,7 +59,7 @@ internal sealed partial class InteractiveHost : IDisposable
/// </remarks>
private readonly bool _joinOutputWritingThreadsOnDisposal;
internal event Action<bool>? ProcessStarting;
internal event Action<InteractiveHostPlatformInfo, InteractiveHostOptions, RemoteExecutionResult>? ProcessInitialized;
public InteractiveHost(
Type replServiceProviderType,
......@@ -77,15 +83,18 @@ internal sealed partial class InteractiveHost : IDisposable
internal event Action<char[], int>? ErrorOutputReceived;
internal Process? TryGetProcess()
=> _lazyRemoteService?.TryGetInitializedService()?.Service.Process;
=> _lazyRemoteService?.TryGetInitializedService()?.Service?.Process;
internal async Task<RemoteService> TryGetServiceAsync()
internal async Task<RemoteService?> TryGetServiceAsync()
=> (await TryGetOrCreateRemoteServiceAsync().ConfigureAwait(false)).Service;
// Triggered whenever we create a fresh process.
// The ProcessExited event is not hooked yet.
internal event Action<Process>? InteractiveHostProcessCreated;
// Triggered whenever InteractiveHost process creation fails.
internal event Action<Exception?, int?>? InteractiveHostProcessCreationFailed;
#endregion
~InteractiveHost()
......@@ -250,6 +259,9 @@ private async Task<InitializedRemoteService> TryGetOrCreateRemoteServiceAsync()
return default;
}
private async Task<RemoteExecutionResult> ExecuteRemoteAsync(string targetName, params object?[] arguments)
=> (await InvokeRemoteAsync<RemoteExecutionResult.Data>(targetName, arguments).ConfigureAwait(false))?.Deserialize() ?? default;
private async Task<TResult> InvokeRemoteAsync<TResult>(string targetName, params object?[] arguments)
{
var initializedRemoteService = await TryGetOrCreateRemoteServiceAsync().ConfigureAwait(false);
......@@ -257,8 +269,13 @@ private async Task<TResult> InvokeRemoteAsync<TResult>(string targetName, params
{
return default!;
}
return await InvokeRemoteAsync<TResult>(initializedRemoteService.Service, targetName, arguments).ConfigureAwait(false);
}
private static async Task<RemoteExecutionResult> ExecuteRemoteAsync(RemoteService remoteService, string targetName, params object?[] arguments)
=> (await InvokeRemoteAsync<RemoteExecutionResult.Data>(remoteService, targetName, arguments).ConfigureAwait(false))?.Deserialize() ?? default;
private static async Task<TResult> InvokeRemoteAsync<TResult>(RemoteService remoteService, string targetName, params object?[] arguments)
{
try
......@@ -271,6 +288,28 @@ private static async Task<TResult> InvokeRemoteAsync<TResult>(RemoteService remo
}
}
private static JsonRpc CreateRpc(Stream stream, object? incomingCallTarget)
{
var jsonFormatter = new JsonMessageFormatter();
// disable interpreting of strings as DateTime during deserialization:
jsonFormatter.JsonSerializer.DateParseHandling = DateParseHandling.None;
var rpc = new JsonRpc(new HeaderDelimitedMessageHandler(stream, jsonFormatter))
{
CancelLocallyInvokedMethodsWhenConnectionIsClosed = true,
};
if (incomingCallTarget != null)
{
rpc.AddLocalRpcTarget(incomingCallTarget, s_jsonRpcTargetOptions);
}
rpc.StartListening();
return rpc;
}
#region Operations
public InteractiveHostOptions? OptionsOpt
......@@ -318,7 +357,7 @@ public async Task<RemoteExecutionResult> ResetAsync(InteractiveHostOptions optio
public Task<RemoteExecutionResult> ExecuteAsync(string code)
{
Contract.ThrowIfNull(code);
return InvokeRemoteAsync<RemoteExecutionResult>(nameof(Service.ExecuteAsync), code);
return ExecuteRemoteAsync(nameof(Service.ExecuteAsync), code);
}
/// <summary>
......@@ -333,9 +372,11 @@ public Task<RemoteExecutionResult> ExecuteAsync(string code)
public Task<RemoteExecutionResult> ExecuteFileAsync(string path)
{
Contract.ThrowIfNull(path);
return InvokeRemoteAsync<RemoteExecutionResult>(nameof(Service.ExecuteFileAsync), path);
return ExecuteRemoteAsync(nameof(Service.ExecuteFileAsync), path);
}
/// <summary> /// Asynchronously adds a reference to the set of available references for next submission.
/// <summary>
/// Asynchronously adds a reference to the set of available references for next submission.
/// </summary>
/// <param name="reference">The reference to add.</param>
/// <remarks>
......@@ -357,7 +398,7 @@ public Task<RemoteExecutionResult> SetPathsAsync(string[] referenceSearchPaths,
Contract.ThrowIfNull(sourceSearchPaths);
Contract.ThrowIfNull(baseDirectory);
return InvokeRemoteAsync<RemoteExecutionResult>(nameof(Service.SetPathsAsync), referenceSearchPaths, sourceSearchPaths, baseDirectory);
return ExecuteRemoteAsync(nameof(Service.SetPathsAsync), referenceSearchPaths, sourceSearchPaths, baseDirectory);
}
#endregion
......
......@@ -4,8 +4,6 @@
#nullable enable
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using Roslyn.Utilities;
......@@ -18,39 +16,52 @@ namespace Microsoft.CodeAnalysis.Interactive
internal sealed class InteractiveHostOptions
{
/// <summary>
/// Optional path to the .rsp file to process when initializing context of the process.
/// Path to interactive host executable.
/// </summary>
public string? InitializationFile { get; }
public string HostPath { get; }
/// <summary>
/// Host culture used for localization of doc comments, errors.
/// Optional file name of the .rsp file to use to initialize the REPL.
/// </summary>
public CultureInfo Culture { get; }
public string? InitializationFilePath { get; }
/// <summary>
/// Path to interactive host directory.
/// Host culture used for localization of doc comments, errors.
/// </summary>
public string HostDirectory { get; }
public CultureInfo Culture { get; }
/// <summary>
/// Host process bitness.
/// Host process platform.
/// </summary>
public bool Is64Bit { get; }
public InteractiveHostPlatform Platform { get; }
public InteractiveHostOptions(
string hostDirectory,
string? initializationFile = null,
CultureInfo? culture = null,
bool is64Bit = false)
string hostPath,
string? initializationFilePath,
CultureInfo culture,
InteractiveHostPlatform platform)
{
Contract.ThrowIfNull(hostDirectory);
HostDirectory = hostDirectory;
InitializationFile = initializationFile;
Culture = culture ?? CultureInfo.CurrentUICulture;
Is64Bit = is64Bit;
Contract.ThrowIfNull(hostPath);
HostPath = hostPath;
InitializationFilePath = initializationFilePath;
Culture = culture;
Platform = platform;
}
public string GetHostPath()
=> Path.Combine(HostDirectory, "InteractiveHost" + (Is64Bit ? "64" : "32") + ".exe");
public static InteractiveHostOptions CreateFromDirectory(
string hostDirectory,
string? initializationFileName,
CultureInfo culture,
InteractiveHostPlatform platform)
{
var hostSubdirectory = (platform == InteractiveHostPlatform.Core) ? "Core" : "Desktop";
var hostExecutableFileName = "InteractiveHost" + (platform == InteractiveHostPlatform.Desktop32 ? "32" : "64") + ".exe";
var hostPath = Path.Combine(hostDirectory, hostSubdirectory, hostExecutableFileName);
var initializationFilePath = (initializationFileName != null) ? Path.Combine(hostDirectory, hostSubdirectory, initializationFileName) : null;
return new InteractiveHostOptions(hostPath, initializationFilePath, culture, platform);
}
}
}
......@@ -3,29 +3,13 @@
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
namespace Microsoft.CodeAnalysis.Interactive
{
internal static class InteractiveHostEntryPoint
internal enum InteractiveHostPlatform
{
private static async Task<int> Main(string[] args)
{
FatalError.Handler = FailFast.OnFatalException;
try
{
await InteractiveHost.Service.RunServerAsync(args).ConfigureAwait(false);
return 0;
}
catch (Exception e)
{
Console.Error.WriteLine(e);
return 1;
}
}
Core = 1,
Desktop32 = 2,
Desktop64 = 3
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
extern alias Scripting;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Roslyn.Utilities;
using Scripting::Microsoft.CodeAnalysis.Scripting.Hosting;
namespace Microsoft.CodeAnalysis.Interactive
{
internal readonly struct InteractiveHostPlatformInfo
{
internal sealed class Data
{
public string[] PlatformAssemblyPaths = null!;
public bool HasGlobalAssemblyCache;
public InteractiveHostPlatformInfo Deserialize()
=> new InteractiveHostPlatformInfo(
PlatformAssemblyPaths.ToImmutableArray(),
HasGlobalAssemblyCache);
}
private static readonly string s_hostDirectory = PathUtilities.GetDirectoryName(typeof(InteractiveHostPlatformInfo).Assembly.Location)!;
public readonly ImmutableArray<string> PlatformAssemblyPaths;
public readonly bool HasGlobalAssemblyCache;
public InteractiveHostPlatformInfo(ImmutableArray<string> platformAssemblyPaths, bool hasGlobalAssemblyCache)
{
Debug.Assert(!platformAssemblyPaths.IsDefault);
HasGlobalAssemblyCache = hasGlobalAssemblyCache;
PlatformAssemblyPaths = platformAssemblyPaths;
}
public Data Serialize()
=> new Data()
{
HasGlobalAssemblyCache = HasGlobalAssemblyCache,
PlatformAssemblyPaths = PlatformAssemblyPaths.ToArray(),
};
public static InteractiveHostPlatformInfo GetCurrentPlatformInfo()
=> new InteractiveHostPlatformInfo(
RuntimeMetadataReferenceResolver.GetTrustedPlatformAssemblyPaths().Where(IsNotHostAssembly).ToImmutableArray(),
GacFileResolver.IsAvailable);
private static bool IsNotHostAssembly(string path)
=> !StringComparer.OrdinalIgnoreCase.Equals(PathUtilities.GetDirectoryName(path), s_hostDirectory);
}
}
......@@ -5,39 +5,71 @@
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
namespace Microsoft.CodeAnalysis.Interactive
{
[Serializable]
internal readonly struct RemoteExecutionResult
{
internal sealed class Data
{
public bool Success;
public string[] SourcePaths = null!;
public string[] ReferencePaths = null!;
public string WorkingDirectory = null!;
public RemoteInitializationResult.Data? InitializationResult;
public RemoteExecutionResult Deserialize()
=> new RemoteExecutionResult(
Success,
SourcePaths.ToImmutableArray(),
ReferencePaths.ToImmutableArray(),
WorkingDirectory,
InitializationResult?.Deserialize());
}
public readonly bool Success;
/// <summary>
/// New value of source search paths after execution, or null if not changed since the last execution.
/// New value of source search paths after execution.
/// </summary>
public readonly string[]? ChangedSourcePaths;
public readonly ImmutableArray<string> SourcePaths;
/// <summary>
/// New value of reference search paths after execution, or null if not changed since the last execution.
/// New value of reference search paths after execution.
/// </summary>
public readonly string[]? ChangedReferencePaths;
public readonly ImmutableArray<string> ReferencePaths;
/// <summary>
/// New value of working directory in the remote process after execution, or null if not changed since the last execution.
/// New value of working directory in the remote process after execution.
/// </summary>
public readonly string? ChangedWorkingDirectory;
public readonly string WorkingDirectory;
public readonly RemoteInitializationResult? InitializationResult;
public RemoteExecutionResult(
bool success,
string[]? changedSourcePaths = null,
string[]? changedReferencePaths = null,
string? changedWorkingDirectory = null)
ImmutableArray<string> sourcePaths,
ImmutableArray<string> referencePaths,
string workingDirectory,
RemoteInitializationResult? initializationResult)
{
Success = success;
ChangedSourcePaths = changedSourcePaths;
ChangedReferencePaths = changedReferencePaths;
ChangedWorkingDirectory = changedWorkingDirectory;
SourcePaths = sourcePaths;
ReferencePaths = referencePaths;
WorkingDirectory = workingDirectory;
InitializationResult = initializationResult;
}
public Data Serialize()
=> new Data()
{
Success = Success,
SourcePaths = SourcePaths.ToArray(),
ReferencePaths = ReferencePaths.ToArray(),
WorkingDirectory = WorkingDirectory,
InitializationResult = InitializationResult?.Serialize(),
};
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
namespace Microsoft.CodeAnalysis.Interactive
{
internal sealed class RemoteInitializationResult
{
internal sealed class Data
{
public string? ScriptPath;
public string[] MetadataReferencePaths = null!;
public string[] Imports = null!;
public RemoteInitializationResult Deserialize()
=> new RemoteInitializationResult(
ScriptPath,
ImmutableArray.Create(MetadataReferencePaths),
ImmutableArray.Create(Imports));
}
/// <summary>
/// Full path to the initialization script that has been executed as part of initialization process.
/// </summary>
public readonly string? ScriptPath;
public readonly ImmutableArray<string> MetadataReferencePaths;
public readonly ImmutableArray<string> Imports;
public RemoteInitializationResult(string? initializationScript, ImmutableArray<string> metadataReferencePaths, ImmutableArray<string> imports)
{
ScriptPath = initializationScript;
MetadataReferencePaths = metadataReferencePaths;
Imports = imports;
}
public Data Serialize()
=> new Data()
{
ScriptPath = ScriptPath,
MetadataReferencePaths = MetadataReferencePaths.ToArray(),
Imports = Imports.ToArray(),
};
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.CodeAnalysis.Interactive {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class InteractiveHostResources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal InteractiveHostResources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.CodeAnalysis.Interactive.InteractiveHostResources", typeof(InteractiveHostResources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Attempt to connect to process #{0} failed, retrying ....
/// </summary>
internal static string Attempt_to_connect_to_process_Sharp_0_failed_retrying {
get {
return ResourceManager.GetString("Attempt_to_connect_to_process_Sharp_0_failed_retrying", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cannot resolve reference &apos;{0}&apos;..
/// </summary>
internal static string Cannot_resolve_reference_0 {
get {
return ResourceManager.GetString("Cannot_resolve_reference_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to create a remote process for interactive code execution..
/// </summary>
internal static string Failed_to_create_a_remote_process_for_interactive_code_execution {
get {
return ResourceManager.GetString("Failed_to_create_a_remote_process_for_interactive_code_execution", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to initialize remote interactive process..
/// </summary>
internal static string Failed_to_initialize_remote_interactive_process {
get {
return ResourceManager.GetString("Failed_to_initialize_remote_interactive_process", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to launch &apos;{0}&apos; process (exit code: {1}) with output: .
/// </summary>
internal static string Failed_to_launch_0_process_exit_code_colon_1_with_output_colon {
get {
return ResourceManager.GetString("Failed_to_launch_0_process_exit_code_colon_1_with_output_colon", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Hosting process exited with exit code {0}..
/// </summary>
internal static string Hosting_process_exited_with_exit_code_0 {
get {
return ResourceManager.GetString("Hosting_process_exited_with_exit_code_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Interactive Host not initialized..
/// </summary>
internal static string Interactive_Host_not_initialized {
get {
return ResourceManager.GetString("Interactive_Host_not_initialized", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Loading context from &apos;{0}&apos;..
/// </summary>
internal static string Loading_context_from_0 {
get {
return ResourceManager.GetString("Loading_context_from_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to + additional {0} {1}.
/// </summary>
internal static string plus_additional_0_1 {
get {
return ResourceManager.GetString("plus_additional_0_1", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Searched in directories:.
/// </summary>
internal static string Searched_in_directories_colon {
get {
return ResourceManager.GetString("Searched_in_directories_colon", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Searched in directory:.
/// </summary>
internal static string Searched_in_directory_colon {
get {
return ResourceManager.GetString("Searched_in_directory_colon", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Specified file not found..
/// </summary>
internal static string Specified_file_not_found {
get {
return ResourceManager.GetString("Specified_file_not_found", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Specified file not found: {0}.
/// </summary>
internal static string Specified_file_not_found_colon_0 {
get {
return ResourceManager.GetString("Specified_file_not_found_colon_0", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Type &quot;#help&quot; for more information..
/// </summary>
internal static string Type_Sharphelp_for_more_information {
get {
return ResourceManager.GetString("Type_Sharphelp_for_more_information", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Unable to create hosting process..
/// </summary>
internal static string Unable_to_create_hosting_process {
get {
return ResourceManager.GetString("Unable_to_create_hosting_process", resourceCulture);
}
}
}
}
......@@ -154,7 +154,7 @@
<value>Failed to launch '{0}' process (exit code: {1}) with output: </value>
</data>
<data name="Failed_to_create_a_remote_process_for_interactive_code_execution" xml:space="preserve">
<value>Failed to create a remote process for interactive code execution.</value>
<value>Failed to create a remote process for interactive code execution: '{0}'</value>
</data>
<data name="Failed_to_initialize_remote_interactive_process" xml:space="preserve">
<value>Failed to initialize remote interactive process.</value>
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.CodeAnalysis.Interactive</RootNamespace>
<TargetFramework>net472</TargetFramework>
<TargetFramework>netstandard2.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GeneratePerformanceSensitiveAttribute>true</GeneratePerformanceSensitiveAttribute>
......@@ -14,12 +15,11 @@
.NET Compiler Platform ("Roslyn") interactive host implementation.
</PackageDescription>
</PropertyGroup>
<ItemGroup Label="Project References">
<ItemGroup>
<ProjectReference Include="..\..\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj" />
<ProjectReference Include="..\..\Scripting\Core\Microsoft.CodeAnalysis.Scripting.csproj">
<Aliases>global,Scripting</Aliases>
</ProjectReference>
<ProjectReference Include="..\vbi\vbi.vbproj" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="InteractiveHost32" />
......@@ -27,16 +27,12 @@
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.EditorFeatures.Wpf" />
<InternalsVisibleTo Include="InteractiveHost.UnitTests" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices.CSharp.UnitTests" />
</ItemGroup>
<ItemGroup>
<PublicAPI Include="PublicAPI.Unshipped.txt" />
<PublicAPI Include="PublicAPI.Shipped.txt" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Runtime.Remoting" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Compilers\Core\Portable\InternalUtilities\NonCopyableAttribute.cs" Link="Utilities\NonCopyableAttribute.cs" />
<Compile Include="..\..\Workspaces\SharedUtilitiesAndExtensions\Compiler\Core\TestHooks\IExpeditableDelaySource.cs" Link="Utilities\IExpeditableDelaySource.cs" />
......@@ -63,17 +59,7 @@
<ItemGroup>
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
</ItemGroup>
<ItemGroup> <Compile Update="InteractiveHostResources.Designer.cs">
<DependentUpon>InteractiveHostResources.resx</DependentUpon>
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="InteractiveHostResources.resx">
<SubType>Designer</SubType>
<LastGenOutput>InteractiveHostResources.Designer.cs</LastGenOutput>
<Generator>ResXFileCodeGenerator</Generator>
</EmbeddedResource>
<EmbeddedResource Update="InteractiveHostResources.resx" GenerateSource="true" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Nepodařilo se vytvořit vzdálený proces pro provádění interaktivního kódu.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Ein Remoteprozess für die interaktive Codeausführung konnte nicht erstellt werden.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Error al crear un proceso remoto para la ejecución de código interactivo.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Échec de la création d'un processus à distance pour l'exécution de code interactif.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Non è stato possibile creare un processo remoto per l'esecuzione di codice interattiva.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">対話型コードの実行のリモート プロセスを作成できませんでした。</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">대화형 코드 실행에 대한 원격 프로세스를 만들지 못했습니다.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Utworzenie procesu zdalnego dla wykonania kodu interaktywnego nie powiodło się.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Falha ao criar um processo remoto para a execução de código interativo.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Не удалось создать удаленный процесс для выполнения интерактивного кода.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">Etkileşimli kod yürütme için uzak işlem oluşturulamadı.</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">为交互代码的执行创建远程进程失败。</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
......@@ -13,8 +13,8 @@
<note />
</trans-unit>
<trans-unit id="Failed_to_create_a_remote_process_for_interactive_code_execution">
<source>Failed to create a remote process for interactive code execution.</source>
<target state="translated">無法為互動式程式碼執行,建立遠端處理序。</target>
<source>Failed to create a remote process for interactive code execution: '{0}'</source>
<target state="new">Failed to create a remote process for interactive code execution: '{0}'</target>
<note />
</trans-unit>
<trans-unit id="Failed_to_initialize_remote_interactive_process">
......
/r:Microsoft.CSharp
/r:System.Collections
/r:System.Collections.Concurrent
/r:System.Console
/r:System.Diagnostics.Debug
/r:System.Diagnostics.Process
/r:System.Diagnostics.StackTrace
/r:System.Dynamic.Runtime
/r:System.Globalization
/r:System.IO
/r:System.IO.FileSystem
/r:System.IO.FileSystem.Primitives
/r:System.Linq
/r:System.Linq.Expressions
/r:System.Reflection
/r:System.Reflection.Extensions
/r:System.Reflection.Primitives
/r:System.Runtime
/r:System.Runtime.Extensions
/r:System.Runtime.Numerics
/r:System.Runtime.InteropServices
/r:System.Text.Encoding
/r:System.Text.Encoding.CodePages
/r:System.Text.Encoding.Extensions
/r:System.Text.RegularExpressions
/r:System.Threading
/r:System.Threading.Tasks
/r:System.Threading.Tasks.Parallel
/r:System.Threading.Thread
/r:System.ValueTuple
/u:System
/u:System.IO
/u:System.Collections.Generic
/u:System.Console
/u:System.Diagnostics
/u:System.Dynamic
/u:System.Linq
/u:System.Linq.Expressions
/u:System.Text
/u:System.Threading.Tasks
<?xml version="1.0" encoding="utf-8"?>
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="$(RepositoryEngineeringDir)targets\GenerateCompilerExecutableBindingRedirects.targets" />
<PropertyGroup>
<Prefer32Bit>true</Prefer32Bit>
<OutputType>Exe</OutputType>
<TargetFramework>net472</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<Content Include="CSharpInteractive.rsp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj" />
<ProjectReference Include="..\..\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj" />
......@@ -19,4 +15,25 @@
<ProjectReference Include="..\..\Scripting\CSharp\Microsoft.CodeAnalysis.CSharp.Scripting.csproj" />
<ProjectReference Include="..\Host\Microsoft.CodeAnalysis.InteractiveHost.csproj" />
</ItemGroup>
<!--
InteractiveHost32 is deployed to the same directory as InteractiveHost64 as it shares the same dependencies.
Ideally this would just return @(BuiltProjectOutputGroupOutput) but that does not reliably include the generated App.config file.
See https://github.com/microsoft/msbuild/issues/5433.
Use BuiltProjectOutputGroup as the dependend target to ensure the targets has all dependencies that BuiltProjectOutputGroupOutput would have.
-->
<Target Name="PublishProjectOutputGroup" DependsOnTargets="BuiltProjectOutputGroup" Returns="@(_PublishProjectOutputGroup)">
<ItemGroup>
<_PublishProjectOutputGroup Include="$(TargetPath)">
<TargetPath>$(TargetFileName)</TargetPath>
<Ngen>true</Ngen>
<NgenPriority>3</NgenPriority>
<NgenArchitecture>X86</NgenArchitecture>
<NgenApplication>/InteractiveHost/Desktop/InteractiveHost32.exe</NgenApplication>
</_PublishProjectOutputGroup>
<_PublishProjectOutputGroup Include="$(TargetPath).config" TargetPath="$(TargetFileName).config"/>
</ItemGroup>
</Target>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Licensed to the .NET Foundation under one or more agreements. The .NET Foundation licenses this file to you under the MIT license. See the LICENSE file in the project root for more information. -->
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(RepositoryEngineeringDir)targets\GenerateCompilerExecutableBindingRedirects.targets" />
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<Import Project="$(RepositoryEngineeringDir)targets\GenerateCompilerExecutableBindingRedirects.targets"/>
<PropertyGroup>
<Prefer32Bit>false</Prefer32Bit>
<OutputType>Exe</OutputType>
<TargetFramework>net472</TargetFramework>
<TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<UseWindowsForms>true</UseWindowsForms>
<!-- Publishing (only precompile binaries when building on CI to avoid slowing down dev builds by ~10s) -->
<PublishReadyToRun Condition="'$(ContinuousIntegrationBuild)' == 'true'">true</PublishReadyToRun>
<SelfContained>false</SelfContained>
<PublishDocumentationFiles>false</PublishDocumentationFiles>
</PropertyGroup>
<ItemGroup>
<Content Include="CSharpInteractive.rsp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj" />
<ProjectReference Include="..\..\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj" />
......@@ -19,4 +21,28 @@
<ProjectReference Include="..\..\Scripting\CSharp\Microsoft.CodeAnalysis.CSharp.Scripting.csproj" />
<ProjectReference Include="..\Host\Microsoft.CodeAnalysis.InteractiveHost.csproj" />
</ItemGroup>
<Target Name="PublishProjectOutputGroup" DependsOnTargets="Publish" Returns="@(_PublishedFiles)">
<ItemGroup>
<!-- Need to include and then update items (https://github.com/microsoft/msbuild/issues/1053) -->
<_PublishedFiles Include="$(PublishDir)**\*.*" />
<_PublishedFiles Remove="@(_PublishedFiles)" Condition="'%(Extension)' == '.pdb'" />
<!-- Include .rsp file -->
<_PublishedFiles Include="$(MSBuildProjectDirectory)\Desktop\CSharpInteractive.rsp" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'" />
<_PublishedFiles Include="$(MSBuildProjectDirectory)\Core\CSharpInteractive.rsp" Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework'" />
<!-- Set TargetPath -->
<_PublishedFiles Update="@(_PublishedFiles)" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
<!-- Set NGEN metadata -->
<_PublishedFiles Update="@(_PublishedFiles)" Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework' and ('%(Extension)' == '.dll' or '%(Extension)' == '.exe')">
<Ngen>true</Ngen>
<NgenPriority>3</NgenPriority>
<NgenArchitecture Condition="'%(Filename)' != 'InteractiveHost64'">All</NgenArchitecture>
<NgenArchitecture Condition="'%(Filename)' == 'InteractiveHost64'">X64</NgenArchitecture>
<NgenApplication>/InteractiveHost/Desktop/InteractiveHost64.exe</NgenApplication>
</_PublishedFiles>
</ItemGroup>
</Target>
</Project>
\ No newline at end of file
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.CodeAnalysis.ErrorReporting;
namespace Microsoft.CodeAnalysis.Interactive
{
internal static class InteractiveHostEntryPoint
{
private static async Task<int> Main(string[] args)
{
FatalError.Handler = FailFast.OnFatalException;
// Disables Windows Error Reporting for the process, so that the process fails fast.
SetErrorMode(GetErrorMode() | ErrorMode.SEM_FAILCRITICALERRORS | ErrorMode.SEM_NOOPENFILEERRORBOX | ErrorMode.SEM_NOGPFAULTERRORBOX);
Control? control = null;
using (var resetEvent = new ManualResetEventSlim(false))
{
var uiThread = new Thread(() =>
{
control = new Control();
control.CreateControl();
resetEvent.Set();
Application.Run();
});
uiThread.SetApartmentState(ApartmentState.STA);
uiThread.IsBackground = true;
uiThread.Start();
resetEvent.Wait();
}
var invokeOnMainThread = new Func<Func<object>, object>(operation => control!.Invoke(operation));
try
{
await InteractiveHost.Service.RunServerAsync(args, invokeOnMainThread).ConfigureAwait(false);
return 0;
}
catch (Exception e)
{
Console.Error.WriteLine(e);
return 1;
}
}
[DllImport("kernel32", PreserveSig = true)]
internal static extern ErrorMode SetErrorMode(ErrorMode mode);
[DllImport("kernel32", PreserveSig = true)]
internal static extern ErrorMode GetErrorMode();
[Flags]
internal enum ErrorMode : int
{
/// <summary>
/// Use the system default, which is to display all error dialog boxes.
/// </summary>
SEM_FAILCRITICALERRORS = 0x0001,
/// <summary>
/// The system does not display the critical-error-handler message box. Instead, the system sends the error to the calling process.
/// Best practice is that all applications call the process-wide SetErrorMode function with a parameter of SEM_FAILCRITICALERRORS at startup.
/// This is to prevent error mode dialogs from hanging the application.
/// </summary>
SEM_NOGPFAULTERRORBOX = 0x0002,
/// <summary>
/// The system automatically fixes memory alignment faults and makes them invisible to the application.
/// It does this for the calling process and any descendant processes. This feature is only supported by
/// certain processor architectures. For more information, see the Remarks section.
/// After this value is set for a process, subsequent attempts to clear the value are ignored.
/// </summary>
SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
/// <summary>
/// The system does not display a message box when it fails to find a file. Instead, the error is returned to the calling process.
/// </summary>
SEM_NOOPENFILEERRORBOX = 0x8000,
}
}
}
......@@ -5,26 +5,217 @@
#nullable enable
extern alias InteractiveHost;
using System;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.CSharp.Scripting.Hosting;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests.Interactive
{
using System.IO;
using InteractiveHost::Microsoft.CodeAnalysis.Interactive;
public abstract class AbstractInteractiveHostTests : CSharpTestBase
public abstract class AbstractInteractiveHostTests : CSharpTestBase, IAsyncLifetime
{
internal static string GetInteractiveHostDirectory()
=> Path.GetDirectoryName(typeof(StressTests).Assembly.Location);
private SynchronizedStringWriter _synchronizedOutput = null!;
private SynchronizedStringWriter _synchronizedErrorOutput = null!;
private int[] _outputReadPosition = new int[] { 0, 0 };
internal readonly InteractiveHost Host;
// DOTNET_ROOT must be set in order to run host process on .NET Core on machines (like CI)
// that do not have the required version of the runtime installed globally.
//
// If it was not set the process would fail with exit code -2147450749:
// "A fatal error occurred. The required library hostfxr.dll could not be found."
//
// See https://github.com/dotnet/runtime/issues/38462.
static AbstractInteractiveHostTests()
{
if (Environment.GetEnvironmentVariable("DOTNET_ROOT") == null)
{
var dir = RuntimeEnvironment.GetRuntimeDirectory();
// find directory above runtime dir that contains dotnet.exe
while (dir != null && !File.Exists(Path.Combine(dir, "dotnet.exe")))
{
dir = Path.GetDirectoryName(dir);
}
// dotnet.exe not found
Assert.NotNull(dir);
Environment.SetEnvironmentVariable("DOTNET_ROOT", dir);
}
}
protected AbstractInteractiveHostTests()
{
Host = new InteractiveHost(typeof(CSharpReplServiceProvider), ".", millisecondsTimeout: -1, joinOutputWritingThreadsOnDisposal: true);
Host.InteractiveHostProcessCreationFailed += (exception, exitCode) =>
Assert.False(true, (exception?.Message ?? "Host process terminated unexpectedly.") + $" Exit code: {exitCode?.ToString() ?? "<unknown>"}");
RedirectOutput();
}
internal abstract InteractiveHostPlatform DefaultPlatform { get; }
internal abstract bool UseDefaultInitializationFile { get; }
public async Task InitializeAsync()
{
var initializationFileName = UseDefaultInitializationFile ? "CSharpInteractive.rsp" : null;
await Host.ResetAsync(InteractiveHostOptions.CreateFromDirectory(TestUtils.HostRootPath, initializationFileName, CultureInfo.InvariantCulture, DefaultPlatform));
// assert and remove logo:
var output = SplitLines(await ReadOutputToEnd());
var errorOutput = await ReadErrorOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences("", errorOutput);
var expectedOutput = new List<string>();
expectedOutput.Add(string.Format(CSharpScriptingResources.LogoLine1, CommonCompiler.GetProductVersion(typeof(CSharpReplServiceProvider))));
if (UseDefaultInitializationFile)
{
expectedOutput.Add(string.Format(InteractiveHostResources.Loading_context_from_0, initializationFileName));
}
expectedOutput.Add(InteractiveHostResources.Type_Sharphelp_for_more_information);
AssertEx.Equal(expectedOutput, output);
// remove logo:
ClearOutput();
}
public async Task DisposeAsync()
{
var service = await Host.TryGetServiceAsync();
Assert.NotNull(service);
var process = service!.Process;
Host.Dispose();
// the process should be terminated
if (process != null && !process.HasExited)
{
process.WaitForExit();
}
}
public void RedirectOutput()
{
_synchronizedOutput = new SynchronizedStringWriter();
_synchronizedErrorOutput = new SynchronizedStringWriter();
ClearOutput();
Host.SetOutputs(_synchronizedOutput, _synchronizedErrorOutput);
}
public static ImmutableArray<string> SplitLines(string text)
{
return ImmutableArray.Create(text.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
}
public async Task<bool> LoadReference(string reference)
{
return await Execute($"#r \"{reference}\"");
}
public async Task<bool> Execute(string code)
{
var task = await Host.ExecuteAsync(code);
return task.Success;
}
public Task<string> ReadErrorOutputToEnd()
{
return ReadOutputToEnd(isError: true);
}
public void ClearOutput()
{
_outputReadPosition = new int[] { 0, 0 };
_synchronizedOutput.Clear();
_synchronizedErrorOutput.Clear();
}
public async Task RestartHost()
{
ClearOutput();
await Host.ResetAsync(InteractiveHostOptions.CreateFromDirectory(TestUtils.HostRootPath, initializationFileName: null, CultureInfo.InvariantCulture, InteractiveHostPlatform.Desktop64));
}
public async Task<string> ReadOutputToEnd(bool isError = false)
{
// writes mark to the STDOUT/STDERR pipe in the remote process:
var remoteService = await Host.TryGetServiceAsync().ConfigureAwait(false);
if (remoteService == null)
{
Assert.True(false, @$"
Remote service unavailable
STDERR: {_synchronizedErrorOutput}
STDOUT: {_synchronizedOutput}
");
}
var writer = isError ? _synchronizedErrorOutput : _synchronizedOutput;
var markPrefix = '\uFFFF';
var mark = markPrefix + Guid.NewGuid().ToString();
await remoteService!.JsonRpc.InvokeAsync(nameof(InteractiveHost.Service.RemoteConsoleWriteAsync), Encoding.UTF8.GetBytes(mark), isError).ConfigureAwait(false);
while (true)
{
var data = writer.Prefix(mark, ref _outputReadPosition[isError ? 0 : 1]);
if (data != null)
{
return data;
}
await Task.Delay(10);
}
}
public static (string Path, ImmutableArray<byte> Image) CompileLibrary(
TempDirectory dir, string fileName, string assemblyName, string source, params MetadataReference[] references)
{
var file = dir.CreateFile(fileName);
var compilation = CreateEmptyCompilation(
new[] { source },
assemblyName: assemblyName,
references: TargetFrameworkUtil.GetReferences(TargetFramework.NetStandard20, references),
options: fileName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) ? TestOptions.ReleaseExe : TestOptions.ReleaseDll);
var image = compilation.EmitToArray();
file.WriteAllBytes(image);
return (file.Path, image);
}
public static string PrintSearchPaths(params string[] paths)
=> paths.Length == 0 ? "SearchPaths { }" : $"SearchPaths {{ {string.Join(", ", paths.Select(p => "\"" + p.Replace("\\", "\\\\") + "\""))} }}";
// Forces xUnit to load dependent assemblies before we launch InteractiveHost.exe process.
private static readonly Type[] s_testDependencies = new[]
public async Task<string> GetHostRuntimeDirectoryAsync()
{
typeof(InteractiveHost),
typeof(CSharpCompilation)
};
var remoteService = await Host.TryGetServiceAsync().ConfigureAwait(false);
Assert.NotNull(remoteService);
return await remoteService!.JsonRpc.InvokeAsync<string>(nameof(InteractiveHost.Service.GetRuntimeDirectoryAsync)).ConfigureAwait(false);
}
}
}
......@@ -4,55 +4,63 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<RootNamespace>Roslyn.InteractiveHost.UnitTests</RootNamespace>
<TargetFramework>net472</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\..\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj" />
<ProjectReference Include="..\..\Compilers\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.csproj" />
<ProjectReference Include="..\..\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj" />
<ProjectReference Include="..\..\Compilers\Test\Resources\Core\Microsoft.CodeAnalysis.Compiler.Test.Resources.csproj" />
<ProjectReference Include="..\..\Compilers\Test\Utilities\CSharp\Microsoft.CodeAnalysis.CSharp.Test.Utilities.csproj" />
<ProjectReference Include="..\..\Features\LanguageServer\Protocol\Microsoft.CodeAnalysis.LanguageServer.Protocol.csproj" />
<ProjectReference Include="..\..\Scripting\Core\Microsoft.CodeAnalysis.Scripting.csproj" />
<ProjectReference Include="..\..\Test\Utilities\Portable\Roslyn.Test.Utilities.csproj" />
<ProjectReference Include="..\..\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj" />
<ProjectReference Include="..\..\EditorFeatures\CSharp\Microsoft.CodeAnalysis.CSharp.EditorFeatures.csproj" />
<ProjectReference Include="..\..\EditorFeatures\CSharp.Wpf\Microsoft.CodeAnalysis.CSharp.EditorFeatures.Wpf.csproj" />
<ProjectReference Include="..\..\Features\Core\Portable\Microsoft.CodeAnalysis.Features.csproj" />
<ProjectReference Include="..\Host\Microsoft.CodeAnalysis.InteractiveHost.csproj">
<Aliases>InteractiveHost</Aliases>
</ProjectReference>
<ProjectReference Include="..\..\EditorFeatures\TestUtilities\Roslyn.Services.Test.Utilities.csproj" />
<ProjectReference Include="..\..\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj" />
<ProjectReference Include="..\..\EditorFeatures\VisualBasic\Microsoft.CodeAnalysis.VisualBasic.EditorFeatures.vbproj" />
<ProjectReference Include="..\..\Features\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.Features.vbproj" />
<ProjectReference Include="..\..\Scripting\VisualBasic\Microsoft.CodeAnalysis.VisualBasic.Scripting.vbproj" />
<ProjectReference Include="..\..\Workspaces\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.Workspaces.vbproj" />
<ProjectReference Include="..\..\Features\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Features.csproj" />
<ProjectReference Include="..\..\Scripting\CSharp\Microsoft.CodeAnalysis.CSharp.Scripting.csproj" />
<ProjectReference Include="..\..\Workspaces\CSharp\Portable\Microsoft.CodeAnalysis.CSharp.Workspaces.csproj" />
<ProjectReference Include="..\..\EditorFeatures\Core\Microsoft.CodeAnalysis.EditorFeatures.csproj" />
<ProjectReference Include="..\..\EditorFeatures\Core.Wpf\Microsoft.CodeAnalysis.EditorFeatures.Wpf.csproj" />
<ProjectReference Include="..\..\Test\PdbUtilities\Roslyn.Test.PdbUtilities.csproj" />
<ProjectReference Include="..\..\Workspaces\Remote\Core\Microsoft.CodeAnalysis.Remote.Workspaces.csproj" />
<ProjectReference Include="..\..\Workspaces\Remote\ServiceHub\Microsoft.CodeAnalysis.Remote.ServiceHub.csproj" />
<ProjectReference Include="..\..\EditorFeatures\Text\Microsoft.CodeAnalysis.EditorFeatures.Text.csproj" />
<ProjectReference Include="..\..\Workspaces\CoreTestUtilities\Roslyn.Services.UnitTests.Utilities.csproj" />
<ProjectReference Include="..\DesktopHost\InteractiveHost32.csproj" />
<ProjectReference Include="..\DesktopHost\InteractiveHost64.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Runtime.Remoting" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<PackageReference Include="Microsoft.ServiceHub.Client" Version="$(MicrosoftServiceHubClientVersion)" />
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="$(MicrosoftVisualStudioThreadingVersion)" />
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
<!--
Not using ProjectReference since it does not execute the specified targets when building in VS.
See https://github.com/microsoft/msbuild/issues/5434.
-->
<CopyPublishedOutputProjectReference Include="..\HostProcess\InteractiveHost32.csproj">
<SetTargetFramework>TargetFramework=net472</SetTargetFramework>
<OutputItemType>InteractiveHostFiles_Desktop32</OutputItemType>
</CopyPublishedOutputProjectReference>
<CopyPublishedOutputProjectReference Include="..\HostProcess\InteractiveHost64.csproj">
<SetTargetFramework>TargetFramework=net472</SetTargetFramework>
<OutputItemType>InteractiveHostFiles_Desktop64</OutputItemType>
</CopyPublishedOutputProjectReference>
<CopyPublishedOutputProjectReference Include="..\HostProcess\InteractiveHost64.csproj">
<SetTargetFramework>TargetFramework=netcoreapp3.1</SetTargetFramework>
<OutputItemType>InteractiveHostFiles_Core</OutputItemType>
</CopyPublishedOutputProjectReference>
</ItemGroup>
<!--
Creates the same directory structure containing flavors of InteractiveHost under the output directory as is used in VSIX.
-->
<Target Name="_DeployInteractiveHosts" AfterTargets="ResolveProjectReferences" Condition="'$(DesignTimeBuild)' != 'true'">
<MSBuild
Projects="@(CopyPublishedOutputProjectReference)"
Targets="PublishProjectOutputGroup"
BuildInParallel="$(BuildInParallel)"
Properties="%(CopyPublishedOutputProjectReference.SetTargetFramework)">
<Output TaskParameter="TargetOutputs" ItemName="%(CopyPublishedOutputProjectReference.OutputItemType)" />
</MSBuild>
<ItemGroup>
<_SourceFiles Include="@(InteractiveHostFiles_Desktop64)" TargetDirectory="Host\Desktop\" />
<_SourceFiles Include="@(InteractiveHostFiles_Desktop32)" TargetDirectory="Host\Desktop\" />
<_SourceFiles Include="@(InteractiveHostFiles_Core)" TargetDirectory="Host\Core\" />
<Content Include="%(_SourceFiles.Identity)" Link="%(_SourceFiles.TargetDirectory)%(_SourceFiles.TargetPath)" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Target>
</Project>
\ No newline at end of file
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
extern alias InteractiveHost;
using System.IO;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests.Interactive
{
using InteractiveHost::Microsoft.CodeAnalysis.Interactive;
[Trait(Traits.Feature, Traits.Features.InteractiveHost)]
public sealed class InteractiveHostCoreInitTests : AbstractInteractiveHostTests
{
internal override InteractiveHostPlatform DefaultPlatform => InteractiveHostPlatform.Core;
internal override bool UseDefaultInitializationFile => true;
[Fact]
public async Task DefaultReferencesAndImports()
{
await Execute(@"
dynamic d = (""home"", Directory.GetCurrentDirectory(), await Task.FromResult(1));
WriteLine(d.ToString());
");
var dir = Path.GetDirectoryName(typeof(InteractiveHostCoreInitTests).Assembly.Location);
var output = await ReadOutputToEnd();
var error = await ReadErrorOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences("", error);
AssertEx.AssertEqualToleratingWhitespaceDifferences($"(home, {dir}, 1)", output);
}
[Fact]
public async Task InteractiveHostImplAssemblies()
{
var scriptingAssemblyName = typeof(CSharpScript).Assembly.GetName().Name;
await Execute($@"#r ""{scriptingAssemblyName}""");
var error = await ReadErrorOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(@$"
(1,1): error CS0006: {string.Format(CSharpResources.ERR_NoMetadataFile, scriptingAssemblyName)}", error);
}
[Fact]
public async Task SearchPaths1()
{
var dll = Temp.CreateFile(extension: ".dll").WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSInterfaces01);
var srcDir = Temp.CreateDirectory();
var dllDir = Path.GetDirectoryName(dll.Path)!;
srcDir.CreateFile("goo.csx").WriteAllText("ReferencePaths.Add(@\"" + dllDir + "\");");
// print default:
await Host.ExecuteAsync(@"ReferencePaths");
var output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(), output);
await Host.ExecuteAsync(@"SourcePaths");
output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(), output);
// add and test if added:
await Host.ExecuteAsync("SourcePaths.Add(@\"" + srcDir + "\");");
await Host.ExecuteAsync(@"SourcePaths");
output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(srcDir.Path), output);
// execute file (uses modified search paths), the file adds a reference path
await Host.ExecuteFileAsync("goo.csx");
await Host.ExecuteAsync(@"ReferencePaths");
output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(dllDir), output);
await Host.AddReferenceAsync(Path.GetFileName(dll.Path));
await Host.ExecuteAsync(@"typeof(Metadata.ICSProp)");
var error = await ReadErrorOutputToEnd();
output = await ReadOutputToEnd();
Assert.Equal("", error);
Assert.Equal("[Metadata.ICSProp]\r\n", output);
}
}
}
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
extern alias InteractiveHost;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests.Interactive
{
using InteractiveHost::Microsoft.CodeAnalysis.Interactive;
[Trait(Traits.Feature, Traits.Features.InteractiveHost)]
public sealed class InteractiveHostDesktopInitTests : AbstractInteractiveHostTests
{
internal override InteractiveHostPlatform DefaultPlatform => InteractiveHostPlatform.Desktop32;
internal override bool UseDefaultInitializationFile => true;
[Fact]
public async Task SearchPaths1()
{
var fxDir = await GetHostRuntimeDirectoryAsync();
var dll = Temp.CreateFile(extension: ".dll").WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSInterfaces01);
var srcDir = Temp.CreateDirectory();
var dllDir = Path.GetDirectoryName(dll.Path)!;
srcDir.CreateFile("goo.csx").WriteAllText("ReferencePaths.Add(@\"" + dllDir + "\");");
// print default:
await Host.ExecuteAsync(@"ReferencePaths");
var output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(fxDir), output);
await Host.ExecuteAsync(@"SourcePaths");
output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(), output);
// add and test if added:
await Host.ExecuteAsync("SourcePaths.Add(@\"" + srcDir + "\");");
await Host.ExecuteAsync(@"SourcePaths");
output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(srcDir.Path), output);
// execute file (uses modified search paths), the file adds a reference path
await Host.ExecuteFileAsync("goo.csx");
await Host.ExecuteAsync(@"ReferencePaths");
output = await ReadOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences(PrintSearchPaths(fxDir, dllDir), output);
await Host.AddReferenceAsync(Path.GetFileName(dll.Path));
await Host.ExecuteAsync(@"typeof(Metadata.ICSProp)");
var error = await ReadErrorOutputToEnd();
output = await ReadOutputToEnd();
Assert.Equal("", error);
Assert.Equal("[Metadata.ICSProp]\r\n", output);
}
[Fact]
public async Task AddReference_AssemblyAlreadyLoaded()
{
var result = await LoadReference("System.Core");
var output = await ReadOutputToEnd();
var error = await ReadErrorOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences("", error);
AssertEx.AssertEqualToleratingWhitespaceDifferences("", output);
Assert.True(result);
result = await LoadReference("System.Core.dll");
output = await ReadOutputToEnd();
error = await ReadErrorOutputToEnd();
AssertEx.AssertEqualToleratingWhitespaceDifferences("", error);
AssertEx.AssertEqualToleratingWhitespaceDifferences("", output);
Assert.True(result);
}
}
}
......@@ -7,18 +7,17 @@
extern alias InteractiveHost;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Globalization;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp.Scripting.Hosting;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests.Interactive
{
using System.Threading.Tasks;
using InteractiveHost::Microsoft.CodeAnalysis.Interactive;
public sealed class StressTests : AbstractInteractiveHostTests
public sealed class StressTests
{
[Fact]
public async Task TestKill()
......@@ -32,6 +31,7 @@ public async Task TestKill()
private async Task TestKillAfterAsync(int milliseconds)
{
using var host = new InteractiveHost(typeof(CSharpReplServiceProvider), ".", millisecondsTimeout: 1, joinOutputWritingThreadsOnDisposal: true);
var options = InteractiveHostOptions.CreateFromDirectory(TestUtils.HostRootPath, initializationFileName: null, CultureInfo.InvariantCulture, InteractiveHostPlatform.Desktop64);
host.InteractiveHostProcessCreated += new Action<Process>(proc =>
{
......@@ -49,7 +49,7 @@ private async Task TestKillAfterAsync(int milliseconds)
});
});
await host.ResetAsync(new InteractiveHostOptions(GetInteractiveHostDirectory())).ConfigureAwait(false);
await host.ResetAsync(options).ConfigureAwait(false);
for (int j = 0; j < 10; j++)
{
......
......@@ -21,7 +21,7 @@ public override void Write(char value)
}
}
public override void Write(string value)
public override void Write(string? value)
{
lock (SyncRoot)
{
......
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.IO;
namespace Microsoft.CodeAnalysis.UnitTests.Interactive
{
internal static class TestUtils
{
public readonly static string HostRootPath = Path.Combine(Path.GetDirectoryName(typeof(TestUtils).Assembly.Location)!, "Host");
}
}
......@@ -85,7 +85,7 @@
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.ExternalAccess.FSharp\$(Configuration)\net472\Microsoft.CodeAnalysis.ExternalAccess.FSharp.dll" TargetDir="" />
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.ExternalAccess.Razor\$(Configuration)\netstandard2.0\Microsoft.CodeAnalysis.ExternalAccess.Razor.dll" TargetDir="" />
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.Features\$(Configuration)\netstandard2.0\Microsoft.CodeAnalysis.Features.dll" TargetDir="" />
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.InteractiveHost\$(Configuration)\net472\Microsoft.CodeAnalysis.InteractiveHost.dll" TargetDir="" />
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.InteractiveHost\$(Configuration)\netstandard2.0\Microsoft.CodeAnalysis.InteractiveHost.dll" TargetDir="" />
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.LanguageServer.Protocol\$(Configuration)\net472\Microsoft.CodeAnalysis.LanguageServer.Protocol.dll" TargetDir="" />
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.Remote.Razor.ServiceHub\$(Configuration)\net472\Microsoft.CodeAnalysis.Remote.Razor.ServiceHub.dll" TargetDir="" />
<_File Include="$(ArtifactsBinDir)Microsoft.CodeAnalysis.Remote.ServiceHub\$(Configuration)\net472\Microsoft.CodeAnalysis.Remote.ServiceHub.dll" TargetDir="" />
......
......@@ -172,11 +172,9 @@ private static ScriptOptions GetScriptOptions(CommandLineArguments arguments, st
internal static MetadataReferenceResolver GetMetadataReferenceResolver(CommandLineArguments arguments, TouchedFileLogger loggerOpt)
{
return new RuntimeMetadataReferenceResolver(
pathResolver: new RelativePathResolver(arguments.ReferencePaths, arguments.BaseDirectory),
packageResolver: null,
gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
useCoreResolver: !GacFileResolver.IsAvailable,
return RuntimeMetadataReferenceResolver.CreateCurrentPlatformResolver(
arguments.ReferencePaths,
arguments.BaseDirectory,
fileReferenceProvider: (path, properties) =>
{
loggerOpt?.AddRead(path);
......
......@@ -53,6 +53,7 @@
<InternalsVisibleTo Include="csi" />
<InternalsVisibleTo Include="vbi" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.InteractiveHost" />
<InternalsVisibleTo Include="Microsoft.VisualStudio.LanguageServices" WorkItem="https://github.com/dotnet/roslyn/issues/5661" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.EditorFeatures" WorkItem="https://github.com/dotnet/roslyn/issues/5661" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.EditorFeatures.Wpf" WorkItem="https://github.com/dotnet/roslyn/issues/5661" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.CSharp.EditorFeatures" WorkItem="https://github.com/dotnet/roslyn/issues/5661" />
......@@ -65,6 +66,7 @@
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.CSharp.Scripting.Desktop.UnitTests" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.VisualBasic.Scripting.UnitTests" />
<InternalsVisibleTo Include="Microsoft.CodeAnalysis.VisualBasic.Scripting.Desktop.UnitTests" />
<InternalsVisibleTo Include="Roslyn.Services.Test.Utilities" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="ScriptingResources.resx" GenerateSource="true" />
......
......@@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
#pragma warning disable 436 // The type 'RelativePathResolver' conflicts with imported type
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
......@@ -14,16 +17,17 @@ namespace Microsoft.CodeAnalysis.Scripting
public sealed class ScriptMetadataResolver : MetadataReferenceResolver, IEquatable<ScriptMetadataResolver>
{
public static ScriptMetadataResolver Default { get; } = new ScriptMetadataResolver(ImmutableArray<string>.Empty, null);
public static ScriptMetadataResolver Default { get; } = new ScriptMetadataResolver(
RuntimeMetadataReferenceResolver.CreateCurrentPlatformResolver(ImmutableArray<string>.Empty, baseDirectory: null));
private readonly RuntimeMetadataReferenceResolver _resolver;
public ImmutableArray<string> SearchPaths => _resolver.PathResolver.SearchPaths;
public string BaseDirectory => _resolver.PathResolver.BaseDirectory;
private ScriptMetadataResolver(ImmutableArray<string> searchPaths, string baseDirectoryOpt)
internal ScriptMetadataResolver(RuntimeMetadataReferenceResolver resolver)
{
_resolver = new RuntimeMetadataReferenceResolver(searchPaths, baseDirectoryOpt);
_resolver = resolver;
}
public ScriptMetadataResolver WithSearchPaths(params string[] searchPaths)
......@@ -39,10 +43,11 @@ public ScriptMetadataResolver WithSearchPaths(ImmutableArray<string> searchPaths
return this;
}
return new ScriptMetadataResolver(ToImmutableArrayChecked(searchPaths, nameof(searchPaths)), BaseDirectory);
return new ScriptMetadataResolver(_resolver.WithRelativePathResolver(
_resolver.PathResolver.WithSearchPaths(ToImmutableArrayChecked(searchPaths, nameof(searchPaths)))));
}
public ScriptMetadataResolver WithBaseDirectory(string baseDirectory)
public ScriptMetadataResolver WithBaseDirectory(string? baseDirectory)
{
if (BaseDirectory == baseDirectory)
{
......@@ -54,19 +59,20 @@ public ScriptMetadataResolver WithBaseDirectory(string baseDirectory)
CompilerPathUtilities.RequireAbsolutePath(baseDirectory, nameof(baseDirectory));
}
return new ScriptMetadataResolver(SearchPaths, baseDirectory);
return new ScriptMetadataResolver(_resolver.WithRelativePathResolver(
_resolver.PathResolver.WithBaseDirectory(baseDirectory)));
}
public override bool ResolveMissingAssemblies => _resolver.ResolveMissingAssemblies;
public override PortableExecutableReference ResolveMissingAssembly(MetadataReference definition, AssemblyIdentity referenceIdentity)
public override PortableExecutableReference? ResolveMissingAssembly(MetadataReference definition, AssemblyIdentity referenceIdentity)
=> _resolver.ResolveMissingAssembly(definition, referenceIdentity);
public override ImmutableArray<PortableExecutableReference> ResolveReference(string reference, string baseFilePath, MetadataReferenceProperties properties)
public override ImmutableArray<PortableExecutableReference> ResolveReference(string reference, string? baseFilePath, MetadataReferenceProperties properties)
=> _resolver.ResolveReference(reference, baseFilePath, properties);
public bool Equals(ScriptMetadataResolver other) => _resolver.Equals(other);
public override bool Equals(object other) => Equals(other as ScriptMetadataResolver);
public bool Equals(ScriptMetadataResolver? other) => _resolver.Equals(other);
public override bool Equals(object? other) => Equals(other as ScriptMetadataResolver);
public override int GetHashCode() => _resolver.GetHashCode();
}
}
......@@ -25,7 +25,7 @@ public sealed class ScriptOptions
filePath: string.Empty,
references: GetDefaultMetadataReferences(),
namespaces: ImmutableArray<string>.Empty,
metadataResolver: RuntimeMetadataReferenceResolver.Default,
metadataResolver: ScriptMetadataResolver.Default,
sourceResolver: SourceFileResolver.Default,
emitDebugInformation: false,
fileEncoding: null,
......
......@@ -26,10 +26,10 @@ public void Resolve()
// With NuGetPackageResolver.
var resolver = new RuntimeMetadataReferenceResolver(
new RelativePathResolver(ImmutableArray.Create(directory.Path), baseDirectory: directory.Path),
new PackageResolver(ImmutableDictionary<string, ImmutableArray<string>>.Empty.Add("nuget:N/1.0", ImmutableArray.Create(assembly1.Path, assembly2.Path))),
new RelativePathResolver(ImmutableArray.Create(directory.Path), directory.Path),
packageResolver: new PackageResolver(ImmutableDictionary<string, ImmutableArray<string>>.Empty.Add("nuget:N/1.0", ImmutableArray.Create(assembly1.Path, assembly2.Path))),
gacFileResolver: null,
useCoreResolver: false);
trustedPlatformAssemblies: ImmutableDictionary<string, string>.Empty);
// Recognized NuGet reference.
var actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly);
......@@ -46,10 +46,8 @@ public void Resolve()
// Without NuGetPackageResolver.
resolver = new RuntimeMetadataReferenceResolver(
new RelativePathResolver(ImmutableArray.Create(directory.Path), baseDirectory: directory.Path),
packageResolver: null,
gacFileResolver: null,
useCoreResolver: false);
searchPaths: ImmutableArray.Create(directory.Path),
baseDirectory: directory.Path);
// Unrecognized NuGet reference.
actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册