public void TestRemoteWorkspaceCircularReferences() { using (var tempRoot = new Microsoft.CodeAnalysis.Test.Utilities.TempRoot()) { var file = tempRoot.CreateDirectory().CreateFile("p1.dll"); file.CopyContentFrom(typeof(object).Assembly.Location); var p1 = ProjectId.CreateNewId(); var p2 = ProjectId.CreateNewId(); var solutionInfo = SolutionInfo.Create( SolutionId.CreateNewId(), VersionStamp.Create(), "", new[] { ProjectInfo.Create( p1, VersionStamp.Create(), "p1", "p1", LanguageNames.CSharp, outputFilePath: file.Path, projectReferences: new [] { new ProjectReference(p2) }), ProjectInfo.Create( p2, VersionStamp.Create(), "p2", "p2", LanguageNames.CSharp, metadataReferences: new [] { MetadataReference.CreateFromFile(file.Path) }) }); var remoteWorkspace = new RemoteWorkspace(workspaceKind: "test"); // this shouldn't throw exception remoteWorkspace.TryAddSolutionIfPossible(solutionInfo, workspaceVersion: 1, out var solution); Assert.NotNull(solution); } }
/// <summary> /// Compiles some source code and returns the bytes that were contained in the compiled DLL file. /// /// Each time that this function is called, it will be compiled in a different directory. /// /// The default flags are "/shared /deterministic+ /nologo /t:library". /// </summary> /// <param name="source"> The source code for the program that will be compiled </param> /// <param name="additionalFlags"> A string containing any additional compiler flags </param> /// <returns> An array of bytes that were read from the compiled DLL</returns> private byte[] CompileAndGetBytes(string source, string additionalFlags, out string finalFlags) { var tempRoot = new TempRoot(); // Setup var tempDir = tempRoot.CreateDirectory(); var srcFile = tempDir.CreateFile("test.cs").WriteAllText(source).Path; var outFile = srcFile.Replace("test.cs", "test.dll"); finalFlags = $"{ _flags } { additionalFlags } /pathmap:{tempDir.Path}=/"; try { var errorsFile = srcFile + ".errors"; // Compile var result = ProcessUtilities.Run("cmd", $"/C {CompilerServerUnitTests.s_csharpCompilerExecutableSrc} { finalFlags } { srcFile } /out:{ outFile } > { errorsFile }"); if (result.ExitCode != 0) { var errors = File.ReadAllText(errorsFile); AssertEx.Fail($"Deterministic compile failed \n stderr: { result.Errors } \n stdout: { errors }"); } var bytes = File.ReadAllBytes(outFile); AssertEx.NotNull(bytes); return bytes; } finally { File.Delete(srcFile); File.Delete(outFile); } }
public void RejectEmptyTempPath() { using (var temp = new TempRoot()) { var host = new TestableCompilerServerHost(); var request = new RunRequest(LanguageNames.CSharp, currentDirectory: temp.CreateDirectory().Path, tempDirectory: null, libDirectory: null, arguments: Array.Empty<string>()); var response = host.RunCompilation(request, CancellationToken.None); Assert.Equal(ResponseType.Rejected, response.Type); } }
public void TempPECompilationWithInvalidReferenceDoesNotCrash() { var tempPEService = new TempPECompilerService(new TrivialMetadataService()); using (var tempRoot = new TempRoot()) { var directory = tempRoot.CreateDirectory(); // This should not crash. Visual inspection of the Dev12 codebase implied we might return // S_FALSE in this case, but it wasn't very clear. In any case, it's not expected to throw,m // so S_FALSE seems fine. var hr = tempPEService.CompileTempPE( pszOutputFileName: Path.Combine(directory.Path, "Output.dll"), sourceCount: 0, fileNames: Array.Empty<string>(), fileContents: Array.Empty<string>(), optionCount: 1, optionNames: new[] { "r" }, optionValues: new[] { Path.Combine(directory.Path, "MissingReference.dll") }); Assert.Equal(VSConstants.S_FALSE, hr); } }
// Set up directory for multiple simultaneous compilers. private TempDirectory SetupDirectory(TempRoot root, int i) { TempDirectory dir = root.CreateDirectory(); var helloFileCs = dir.CreateFile(string.Format("hello{0}.cs", i)); helloFileCs.WriteAllText(string.Format( @"using System; class Hello {{ public static void Main() {{ Console.WriteLine(""CS Hello number {0}""); }} }}", i)); var helloFileVb = dir.CreateFile(string.Format("hello{0}.vb", i)); helloFileVb.WriteAllText(string.Format( @"Imports System Module Hello Sub Main() Console.WriteLine(""VB Hello number {0}"") End Sub End Module", i)); return dir; }
public CompilerServerUnitTests() { root = new TempRoot(); tempDirectory = root.CreateDirectory(); }
public AssemblyLoadTestFixture() { _temp = new TempRoot(); _directory = _temp.CreateDirectory(); const string Delta1Source = @" using System.Text; [assembly: System.Reflection.AssemblyTitle(""Delta"")] [assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] namespace Delta { public class D { public void Write(StringBuilder sb, string s) { sb.AppendLine(""Delta: "" + s); } } } "; Delta1 = GenerateDll("Delta", _directory, Delta1Source); var delta1Reference = MetadataReference.CreateFromFile(Delta1.Path); DeltaPublicSigned1 = GenerateDll("DeltaPublicSigned", _directory.CreateDirectory("Delta1PublicSigned"), Delta1Source, publicSign: true); const string GammaSource = @" using System.Text; using Delta; namespace Gamma { public class G { public void Write(StringBuilder sb, string s) { D d = new D(); d.Write(sb, ""Gamma: "" + s); } } } "; Gamma = GenerateDll("Gamma", _directory, GammaSource, delta1Reference); GammaReferencingPublicSigned = GenerateDll("GammaReferencingPublicSigned", _directory.CreateDirectory("GammaReferencingPublicSigned"), GammaSource, MetadataReference.CreateFromFile(DeltaPublicSigned1.Path)); var gammaReference = MetadataReference.CreateFromFile(Gamma.Path); Beta = GenerateDll("Beta", _directory, @" using System.Text; using Gamma; namespace Beta { public class B { public void Write(StringBuilder sb, string s) { G g = new G(); g.Write(sb, ""Beta: "" + s); } } } ", gammaReference); Alpha = GenerateDll("Alpha", _directory, @" using System.Text; using Gamma; namespace Alpha { public class A { public void Write(StringBuilder sb, string s) { G g = new G(); g.Write(sb, ""Alpha: "" + s); } } } ", gammaReference); const string Delta2Source = @" using System.Text; [assembly: System.Reflection.AssemblyTitle(""Delta"")] [assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] namespace Delta { public class D { public void Write(StringBuilder sb, string s) { sb.AppendLine(""Delta.2: "" + s); } } } "; var v2Directory = _directory.CreateDirectory("Version2"); Delta2 = GenerateDll("Delta", v2Directory, Delta2Source); var v2PublicSignedDirectory = _directory.CreateDirectory("Version2PublicSigned"); DeltaPublicSigned2 = GenerateDll("DeltaPublicSigned", v2PublicSignedDirectory, Delta2Source, publicSign: true); var delta2Reference = MetadataReference.CreateFromFile(Delta2.Path); const string EpsilonSource = @" using System.Text; using Delta; namespace Epsilon { public class E { public void Write(StringBuilder sb, string s) { D d = new D(); d.Write(sb, ""Epsilon: "" + s); } } } "; Epsilon = GenerateDll("Epsilon", v2Directory, EpsilonSource, delta2Reference); EpsilonReferencingPublicSigned = GenerateDll("EpsilonReferencingPublicSigned", v2PublicSignedDirectory, EpsilonSource, MetadataReference.CreateFromFile(DeltaPublicSigned2.Path)); var v2BDirectory = _directory.CreateDirectory("Version2B"); Delta2B = GenerateDll("Delta", v2BDirectory, @" using System.Text; [assembly: System.Reflection.AssemblyTitle(""Delta"")] [assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] namespace Delta { public class D { public void Write(StringBuilder sb, string s) { sb.AppendLine(""Delta.2B: "" + s); } } } "); var v3Directory = _directory.CreateDirectory("Version3"); Delta3 = GenerateDll("Delta", v3Directory, @" using System.Text; [assembly: System.Reflection.AssemblyTitle(""Delta"")] [assembly: System.Reflection.AssemblyVersion(""3.0.0.0"")] namespace Delta { public class D { public void Write(StringBuilder sb, string s) { sb.AppendLine(""Delta.3: "" + s); } } } "); var sciUserDirectory = _directory.CreateDirectory("SCIUser"); var compilerReference = MetadataReference.CreateFromFile(typeof(Microsoft.CodeAnalysis.SyntaxNode).Assembly.Location); UserSystemCollectionsImmutable = GenerateDll("System.Collections.Immutable", sciUserDirectory, @" namespace System.Collections.Immutable { public static class ImmutableArray { public static ImmutableArray<T> Create<T>(T t) => new(); } public struct ImmutableArray<T> { public int Length => 42; public static int MyMethod() => 42; } } ", compilerReference); var userSystemCollectionsImmutableReference = MetadataReference.CreateFromFile(UserSystemCollectionsImmutable.Path); AnalyzerReferencesSystemCollectionsImmutable1 = GenerateDll("AnalyzerUsesSystemCollectionsImmutable1", sciUserDirectory, @" using System.Text; using System.Collections.Immutable; public class Analyzer { public void Method(StringBuilder sb) { sb.Append(ImmutableArray<object>.MyMethod()); } } ", userSystemCollectionsImmutableReference, compilerReference); AnalyzerReferencesSystemCollectionsImmutable2 = GenerateDll("AnalyzerUsesSystemCollectionsImmutable2", sciUserDirectory, @" using System.Text; using System.Collections.Immutable; public class Analyzer { public void Method(StringBuilder sb) { sb.Append(ImmutableArray.Create(""a"").Length); } } ", userSystemCollectionsImmutableReference, compilerReference); var analyzerReferencesDelta1Directory = _directory.CreateDirectory("AnalyzerReferencesDelta1"); var delta1InAnalyzerReferencesDelta1 = analyzerReferencesDelta1Directory.CopyFile(Delta1.Path); AnalyzerReferencesDelta1 = GenerateDll("AnalyzerReferencesDelta1", _directory, @" using System.Text; using Delta; public class Analyzer { public void Method(StringBuilder sb) { var d = new D(); d.Write(sb, ""Hello""); } } ", MetadataReference.CreateFromFile(delta1InAnalyzerReferencesDelta1.Path), compilerReference); var faultyAnalyzerDirectory = _directory.CreateDirectory("FaultyAnalyzer"); FaultyAnalyzer = GenerateDll("FaultyAnalyzer", faultyAnalyzerDirectory, @" using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] public abstract class TestAnalyzer : DiagnosticAnalyzer { } ", compilerReference); var realSciReference = MetadataReference.CreateFromFile(typeof(ImmutableArray).Assembly.Location); var analyzerWithDependencyDirectory = _directory.CreateDirectory("AnalyzerWithDependency"); AnalyzerDependency = GenerateDll("AnalyzerDependency", analyzerWithDependencyDirectory, @" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; public abstract class AbstractTestAnalyzer : DiagnosticAnalyzer { protected static string SomeString = nameof(SomeString); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { throw new NotImplementedException(); } } public override void Initialize(AnalysisContext context) { throw new NotImplementedException(); } } ", realSciReference, compilerReference); AnalyzerWithDependency = GenerateDll("Analyzer", analyzerWithDependencyDirectory, @" using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; [DiagnosticAnalyzer(LanguageNames.CSharp)] public sealed class TestAnalyzer : AbstractTestAnalyzer { private static string SomeString2 = AbstractTestAnalyzer.SomeString; }", realSciReference, compilerReference, MetadataReference.CreateFromFile(AnalyzerDependency.Path)); AnalyzerWithNativeDependency = GenerateDll("AnalyzerWithNativeDependency", _directory, @" using System; using System.Runtime.InteropServices; public class Class1 { [DllImport(""kernel32.dll"", CharSet = CharSet.Unicode, SetLastError = true)] private static extern int GetFileAttributesW(string lpFileName); public int GetFileAttributes(string path) { return GetFileAttributesW(path); } } "); }