public void Local_Array() { var source = @"class C { static void M() { dynamic[] d = new dynamic[1]; } static dynamic ForceDynamicAttribute() { return null; } }"; var comp = CreateCompilationWithMscorlib(source, new[] { SystemCoreRef, CSharpRef }, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(comp); var context = CreateMethodContext(runtime, "C.M"); var testData = new CompilationTestData(); var locals = ArrayBuilder<LocalAndMethod>.GetInstance(); string typeName; var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData); Assert.Equal(1, locals.Count); var method = testData.Methods.Single().Value.Method; AssertHasDynamicAttribute(method); Assert.Equal(TypeKind.Dynamic, ((ArrayTypeSymbol)method.ReturnType).ElementType.TypeKind); VerifyLocal(testData, typeName, locals[0], "<>m0", "d", expectedILOpt: @"{ // Code size 2 (0x2) .maxstack 1 .locals init (dynamic[] V_0) //d IL_0000: ldloc.0 IL_0001: ret }"); }
internal abstract ReadOnlyCollection<byte> CompileGetLocals( ArrayBuilder<LocalAndMethod> locals, bool argumentsOnly, ImmutableArray<Alias> aliases, DiagnosticBag diagnostics, out string typeName, CompilationTestData testData);
public void AddressOfParameter() { var source = @"class C { void M(string s) { } }"; var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(comp); var context = CreateMethodContext( runtime, methodName: "C.M"); var testData = new CompilationTestData(); string error; context.CompileExpression("&s", out error, testData); Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); AssertIsIntPtrPointer(methodData.Method.ReturnType); methodData.VerifyIL(@" { // Code size 4 (0x4) .maxstack 1 IL_0000: ldarga.s V_1 IL_0002: conv.u IL_0003: ret } "); }
internal abstract CompileResult CompileExpression( string expr, DkmEvaluationFlags compilationFlags, ImmutableArray<Alias> aliases, DiagnosticBag diagnostics, out ResultProperties resultProperties, CompilationTestData testData);
internal abstract CompileResult CompileAssignment( string target, string expr, ImmutableArray<Alias> aliases, DiagnosticBag diagnostics, out ResultProperties resultProperties, CompilationTestData testData);
public void DebugOnly() { var source = @"class C { static System.IDisposable F() { return null; } static void M() { lock (F()) { } using (F()) { } } }"; var debug = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var release = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseDll); CompilationTestData testData; ImmutableArray<string> names; testData = new CompilationTestData(); debug.EmitToArray(testData: testData); names = GetLocalNames(testData.GetMethodData("C.M")); AssertEx.Equal(new string[] { "CS$2$0000", "CS$520$0001", "CS$3$0002" }, names); testData = new CompilationTestData(); release.EmitToArray(testData: testData); names = GetLocalNames(testData.GetMethodData("C.M")); AssertEx.Equal(new string[] { null, null }, names); }
public EEAssemblyBuilder( SourceAssemblySymbol sourceAssembly, EmitOptions emitOptions, ImmutableArray<MethodSymbol> methods, ModulePropertiesForSerialization serializationProperties, ImmutableArray<NamedTypeSymbol> additionalTypes, NamedTypeSymbol dynamicOperationContextType, CompilationTestData testData) : base( sourceAssembly, emitOptions, outputKind: OutputKind.DynamicallyLinkedLibrary, serializationProperties: serializationProperties, manifestResources: SpecializedCollections.EmptyEnumerable<ResourceDescription>(), additionalTypes: additionalTypes) { Methods = ImmutableHashSet.CreateRange(methods); _dynamicOperationContextType = dynamicOperationContextType; if (testData != null) { this.SetMethodTestData(testData.Methods); testData.Module = this; } }
internal static ImmutableArray<byte> EmitToArray( this Compilation compilation, bool metadataOnly = false, CompilationTestData testData = null, DiagnosticDescription[] expectedWarnings = null) { var stream = new MemoryStream(); var emitResult = compilation.Emit( peStream: stream, outputName: null, pdbFilePath: null, pdbStream: null, xmlDocumentationStream: null, cancellationToken: default(CancellationToken), win32Resources: null, manifestResources: null, metadataOnly: metadataOnly, testData: testData); Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n, ", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return stream.ToImmutable(); }
internal static CompileResult CompileAssignment( this EvaluationContextBase context, string target, string expr, out string error, CompilationTestData testData = null, DiagnosticFormatter formatter = null) { ResultProperties resultProperties; ImmutableArray<AssemblyIdentity> missingAssemblyIdentities; var result = context.CompileAssignment( DefaultInspectionContext.Instance, target, expr, formatter ?? DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); // This is a crude way to test the language, but it's convenient to share this test helper. var isCSharp = context.GetType().Namespace.IndexOf("csharp", StringComparison.OrdinalIgnoreCase) >= 0; var expectedFlags = error != null ? DkmClrCompilationResultFlags.None : isCSharp ? DkmClrCompilationResultFlags.PotentialSideEffect : DkmClrCompilationResultFlags.PotentialSideEffect | DkmClrCompilationResultFlags.ReadOnlyResult; Assert.Equal(expectedFlags, resultProperties.Flags); Assert.Equal(default(DkmEvaluationResultCategory), resultProperties.Category); Assert.Equal(default(DkmEvaluationResultAccessType), resultProperties.AccessType); Assert.Equal(default(DkmEvaluationResultStorageType), resultProperties.StorageType); Assert.Equal(default(DkmEvaluationResultTypeModifierFlags), resultProperties.ModifierFlags); return result; }
public void AddressOfLocal() { var source = @"class C { void M() { string s = ""hello""; } }"; var comp = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); WithRuntimeInstance(comp, runtime => { var context = CreateMethodContext(runtime, "C.M"); var testData = new CompilationTestData(); string error; context.CompileExpression("&s", out error, testData); Assert.Null(error); var methodData = testData.GetMethodData("<>x.<>m0"); AssertIsIntPtrPointer(methodData.Method.ReturnType); methodData.VerifyIL(@" { // Code size 4 (0x4) .maxstack 1 .locals init (string V_0) //s IL_0000: ldloca.s V_0 IL_0002: conv.u IL_0003: ret } "); }); }
internal abstract CompileResult CompileAssignment( InspectionContext inspectionContext, string target, string expr, DiagnosticBag diagnostics, out ResultProperties resultProperties, CompilationTestData testData);
internal abstract CompileResult CompileExpression( InspectionContext inspectionContext, string expr, DkmEvaluationFlags compilationFlags, DiagnosticBag diagnostics, out ResultProperties resultProperties, CompilationTestData testData);
/// <summary> /// Compile C# expression and emit assembly with evaluation method. /// </summary> /// <returns> /// Result containing generated assembly, type and method names, and any format specifiers. /// </returns> internal CompileResult CompileExpression( InspectionContext inspectionContext, string expr, DkmEvaluationFlags compilationFlags, DiagnosticFormatter formatter, out ResultProperties resultProperties, out string error, out ImmutableArray<AssemblyIdentity> missingAssemblyIdentities, CultureInfo preferredUICulture, CompilationTestData testData) { var diagnostics = DiagnosticBag.GetInstance(); var result = this.CompileExpression(inspectionContext, expr, compilationFlags, diagnostics, out resultProperties, testData); if (diagnostics.HasAnyErrors()) { bool useReferencedModulesOnly; error = GetErrorMessageAndMissingAssemblyIdentities(diagnostics, formatter, preferredUICulture, out useReferencedModulesOnly, out missingAssemblyIdentities); } else { error = null; missingAssemblyIdentities = ImmutableArray<AssemblyIdentity>.Empty; } diagnostics.Free(); return result; }
internal static ImmutableArray<byte> EmitToArray( this Compilation compilation, EmitOptions options = null, CompilationTestData testData = null, DiagnosticDescription[] expectedWarnings = null) { var stream = new MemoryStream(); MemoryStream pdbStream = (compilation.Options.OptimizationLevel == OptimizationLevel.Debug) && !CLRHelpers.IsRunningOnMono() ? new MemoryStream() : null; var emitResult = compilation.Emit( peStream: stream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: null, options: options, testData: testData, getHostDiagnostics: null, cancellationToken: default(CancellationToken)); Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return stream.ToImmutable(); }
internal static CompileResult CompileExpression( this EvaluationContextBase context, string expr, out string error, CompilationTestData testData = null, DiagnosticFormatter formatter = null) { ResultProperties resultProperties; return CompileExpression(context, expr, out resultProperties, out error, testData, formatter); }
internal abstract CompileResult CompileAssignment( InspectionContext inspectionContext, string target, string expr, DiagnosticFormatter formatter, out ResultProperties resultProperties, out string error, out ImmutableArray<AssemblyIdentity> missingAssemblyIdentities, CultureInfo preferredUICulture, CompilationTestData testData);
public CompilationDifference( ImmutableArray<byte> metadata, ImmutableArray<byte> il, Stream pdbStream, EmitBaseline nextGeneration, CompilationTestData testData, EmitResult result) { this.MetadataBlob = metadata; this.ILBlob = il; this.Pdb = pdbStream; this.NextGeneration = nextGeneration; this.TestData = testData; this.Result = result; }
public CompilationDifference( ImmutableArray<byte> metadata, ImmutableArray<byte> il, Stream pdbStream, CompilationTestData testData, EmitDifferenceResult result, ImmutableArray<MethodDefinitionHandle> methodHandles) { this.MetadataDelta = metadata; this.ILDelta = il; this.PdbDelta = pdbStream; this.TestData = testData; this.EmitResult = result; this.UpdatedMethods = methodHandles; }
internal static ImmutableArray<byte> EmitToArray( this Compilation compilation, EmitOptions options = null, CompilationTestData testData = null, DiagnosticDescription[] expectedWarnings = null, Stream pdbStream = null, IMethodSymbol debugEntryPoint = null, Stream sourceLinkStream = null, IEnumerable<EmbeddedText> embeddedTexts = null) { var peStream = new MemoryStream(); if (pdbStream == null && compilation.Options.OptimizationLevel == OptimizationLevel.Debug && options?.DebugInformationFormat != DebugInformationFormat.Embedded) { if (MonoHelpers.IsRunningOnMono()) { options = (options ?? EmitOptions.Default).WithDebugInformationFormat(DebugInformationFormat.PortablePdb); } pdbStream = new MemoryStream(); } var emitResult = compilation.Emit( peStream: peStream, pdbStream: pdbStream, xmlDocumentationStream: null, win32Resources: null, manifestResources: null, options: options, debugEntryPoint: debugEntryPoint, sourceLinkStream: sourceLinkStream, embeddedTexts: embeddedTexts, testData: testData, cancellationToken: default(CancellationToken)); Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return peStream.ToImmutable(); }
public void Win8RuntimeAssemblies() { var source = @"class C { static void M(Windows.Storage.StorageFolder f, Windows.Foundation.Collections.PropertySet p) { } }"; var compilation0 = CreateCompilationWithMscorlib( source, options: TestOptions.DebugDll, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName(), references: WinRtRefs); var runtimeAssemblies = ExpressionCompilerTestHelpers.GetRuntimeWinMds("Windows.Storage", "Windows.Foundation.Collections"); Assert.True(runtimeAssemblies.Length >= 2); byte[] exeBytes; byte[] pdbBytes; ImmutableArray<MetadataReference> references; compilation0.EmitAndGetReferences(out exeBytes, out pdbBytes, out references); var runtime = CreateRuntimeInstance( ExpressionCompilerUtilities.GenerateUniqueName(), ImmutableArray.Create(MscorlibRef).Concat(runtimeAssemblies), // no reference to Windows.winmd exeBytes, new SymReader(pdbBytes)); var context = CreateMethodContext(runtime, "C.M"); ResultProperties resultProperties; string error; var testData = new CompilationTestData(); context.CompileExpression("(p == null) ? f : null", out resultProperties, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 7 (0x7) .maxstack 1 IL_0000: ldarg.1 IL_0001: brfalse.s IL_0005 IL_0003: ldnull IL_0004: ret IL_0005: ldarg.0 IL_0006: ret }"); }
public void ExplicitEmbeddedType() { var source = @"using System.Runtime.InteropServices; [TypeIdentifier] [Guid(""863D5BC0-46A1-49AD-97AA-A5F0D441A9D8"")] public interface I { object F(); } class C { void M() { var o = (I)null; } static void Main() { (new C()).M(); } }"; var compilation0 = CSharpTestBase.CreateCompilationWithMscorlib( source, options: TestOptions.DebugExe, assemblyName: ExpressionCompilerUtilities.GenerateUniqueName()); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext(runtime, "C.M"); ResultProperties resultProperties; string error; var testData = new CompilationTestData(); var result = context.CompileExpression("this", out resultProperties, out error, testData); Assert.Null(error); testData.GetMethodData("<>x.<>m0").VerifyIL( @"{ // Code size 2 (0x2) .maxstack 1 .locals init (I V_0) //o IL_0000: ldarg.0 IL_0001: ret }"); }
internal static CompilationDifference EmitDifference( this Compilation compilation, EmitBaseline baseline, ImmutableArray<SemanticEdit> edits, IEnumerable<ISymbol> allAddedSymbols = null, CompilationTestData testData = null) { testData = testData ?? new CompilationTestData(); var isAddedSymbol = new Func<ISymbol, bool>(s => allAddedSymbols?.Contains(s) ?? false); var pdbName = Path.ChangeExtension(compilation.SourceModule.Name, "pdb"); // keep the stream open, it's passed to CompilationDifference var pdbStream = new MemoryStream(); using (MemoryStream mdStream = new MemoryStream(), ilStream = new MemoryStream()) { var updatedMethods = new List<MethodDefinitionHandle>(); var result = compilation.EmitDifference( baseline, edits, isAddedSymbol, mdStream, ilStream, pdbStream, updatedMethods, testData, default(CancellationToken)); pdbStream.Seek(0, SeekOrigin.Begin); return new CompilationDifference( mdStream.ToImmutable(), ilStream.ToImmutable(), pdbStream, testData, result, updatedMethods.ToImmutableArray()); } }
public void Literal() { var source = @"class C { static void M() { (int, int) o; } }"; var comp = CreateCompilationWithMscorlib(source, new[] { ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll); WithRuntimeInstance(comp, new[] { ValueTupleRef, SystemRuntimeFacadeRef, MscorlibRef }, runtime => { var context = CreateMethodContext(runtime, "C.M"); var testData = new CompilationTestData(); string error; var result = context.CompileExpression("(A: 1, B: 2)", out error, testData); Assert.Null(error); ReadOnlyCollection<byte> customTypeInfo; var customTypeInfoId = result.GetCustomTypeInfo(out customTypeInfo); ReadOnlyCollection<byte> dynamicFlags; ReadOnlyCollection<string> tupleElementNames; CustomTypeInfo.Decode(customTypeInfoId, customTypeInfo, out dynamicFlags, out tupleElementNames); Assert.Equal(new[] { "A", "B" }, tupleElementNames); var methodData = testData.GetMethodData("<>x.<>m0"); var method = methodData.Method; Assert.True(method.ReturnType.IsTupleType); Assert.NotNull(GetTupleElementNamesAttributeIfAny(method)); methodData.VerifyIL( @"{ // Code size 8 (0x8) .maxstack 2 .locals init ((int, int) V_0) //o IL_0000: ldc.i4.1 IL_0001: ldc.i4.2 IL_0002: newobj ""System.ValueTuple<int, int>..ctor(int, int)"" IL_0007: ret }"); }); }
public void NoLocals() { var source = @"class C { static void M() { } }"; var compilation0 = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(compilation0); var context = CreateMethodContext( runtime, methodName: "C.M"); var testData = new CompilationTestData(); var locals = ArrayBuilder<LocalAndMethod>.GetInstance(); string typeName; var assembly = context.CompileGetLocals(locals, argumentsOnly: false, typeName: out typeName, testData: testData); Assert.NotNull(assembly); Assert.Equal(assembly.Count, 0); Assert.Equal(locals.Count, 0); }
internal static CompileResult CompileExpression( this EvaluationContextBase context, string expr, out ResultProperties resultProperties, out string error, CompilationTestData testData = null, DiagnosticFormatter formatter = null) { ImmutableArray<AssemblyIdentity> missingAssemblyIdentities; var result = context.CompileExpression( DefaultInspectionContext.Instance, expr, DkmEvaluationFlags.TreatAsExpression, formatter ?? DiagnosticFormatter.Instance, out resultProperties, out error, out missingAssemblyIdentities, EnsureEnglishUICulture.PreferredOrNull, testData); Assert.Empty(missingAssemblyIdentities); return result; }
internal static CompilationDifference EmitDifference( this Compilation compilation, EmitBaseline baseline, ImmutableArray<SemanticEdit> edits, CompilationTestData testData = null) { testData = testData ?? new CompilationTestData(); var pdbName = Path.ChangeExtension(compilation.SourceModule.Name, "pdb"); // keep the stream open, it's passed to CompilationDifference var pdbStream = new MemoryStream(); using (MemoryStream mdStream = new MemoryStream(), ilStream = new MemoryStream()) { var updatedMethodTokens = new List<uint>(); var result = compilation.EmitDifference( baseline, edits, mdStream, ilStream, pdbStream, updatedMethodTokens, testData, default(CancellationToken)); pdbStream.Seek(0, SeekOrigin.Begin); return new CompilationDifference( mdStream.ToImmutable(), ilStream.ToImmutable(), pdbStream, result.Baseline, testData, result, updatedMethodTokens.ToImmutableArray()); } }
internal static ImmutableArray<byte> EmitToArray( this Compilation compilation, bool metadataOnly = false, bool debug = false, CompilationTestData testData = null, Guid mvid = default(Guid), DiagnosticDescription[] expectedWarnings = null) { var stream = new MemoryStream(); if (mvid == default(Guid)) { mvid = Guid.NewGuid(); } var emitResult = compilation.Emit( executableStream: stream, outputName: null, pdbFilePath: debug ? "Compilation.pdb" : null, pdbStream: debug ? new MemoryStream() : null, xmlDocStream: null, cancellationToken: default(CancellationToken), win32Resources: null, manifestResources: null, moduleVersionId: mvid, metadataOnly: metadataOnly, testData: testData); Assert.True(emitResult.Success, "Diagnostics: " + string.Join(", ", emitResult.Diagnostics.Select(d => d.ToString()))); if (expectedWarnings != null) { emitResult.Diagnostics.Verify(expectedWarnings); } return stream.ToImmutable(); }
public static EmitResult EmitWithMdb(this Compilation compilation, Stream peStream, Stream pdbStream = null, Stream xmlDocumentationStream = null, Stream win32Resources = null, IEnumerable<ResourceDescription> manifestResources = null, EmitOptions options = null, IMethodSymbol debugEntryPoint = null, CancellationToken cancellationToken = default(CancellationToken)) { if (peStream == null) { throw new ArgumentNullException(nameof(peStream)); } if (!peStream.CanWrite) { throw new ArgumentException(CodeAnalysisResources.StreamMustSupportWrite, nameof(peStream)); } if (pdbStream != null && !pdbStream.CanWrite) { throw new ArgumentException(CodeAnalysisResources.StreamMustSupportWrite, nameof(pdbStream)); } var testData = new CompilationTestData { SymWriterFactory = () => new MdbWriter() }; return compilation.Emit( peStream, pdbStream, xmlDocumentationStream, win32Resources, manifestResources, options, debugEntryPoint, testData, null, cancellationToken); }
private string VisualizeIL(CompilationTestData.MethodData methodData, bool realIL, string sequencePoints, bool useRefEmitter) { Dictionary<int, string> markers = null; if (sequencePoints != null) { var actualPdbXml = PdbToXmlConverter.ToXml( pdbStream: new MemoryStream(EmittedAssemblyPdb.ToArray()), peStream: new MemoryStream(EmittedAssemblyData.ToArray()), options: PdbToXmlOptions.ResolveTokens | PdbToXmlOptions.ThrowOnError | PdbToXmlOptions.ExcludeDocuments | PdbToXmlOptions.ExcludeCustomDebugInformation | PdbToXmlOptions.ExcludeScopes, methodName: sequencePoints); markers = PdbValidation.GetMarkers(actualPdbXml); } if (!realIL) { return ILBuilderVisualizer.ILBuilderToString(methodData.ILBuilder, markers: markers); } if (_lazyModuleSymbol == null) { _lazyModuleSymbol = GetModuleSymbolForEmittedImage(EmittedAssemblyData, MetadataImportOptions.All); } return _lazyModuleSymbol != null ? _test.VisualizeRealIL(_lazyModuleSymbol, methodData, markers) : null; }
private string Emit(HostedRuntimeEnvironment testEnvironment, IEnumerable<ResourceDescription> manifestResources) { testEnvironment.Emit(_compilation, manifestResources); _diagnostics = testEnvironment.GetDiagnostics(); EmittedAssemblyData = testEnvironment.GetMainImage(); EmittedAssemblyPdb = testEnvironment.GetMainPdb(); _testData = testEnvironment.GetCompilationTestData(); return _compilation.Assembly.Identity.GetDisplayName(); }