public static void VerifyReferenceInfo( TestMetadataReferenceInfo[] references, TargetFramework targetFramework, BlobReader metadataReferenceReader ) { var frameworkReferences = TargetFrameworkUtil.GetReferences(targetFramework); var count = 0; while (metadataReferenceReader.RemainingBytes > 0) { var info = ParseMetadataReferenceInfo(ref metadataReferenceReader); if (frameworkReferences.Any(x => x.GetModuleVersionId() == info.Mvid)) { count++; continue; } var testReference = references.Single( x => x.MetadataReferenceInfo.Mvid == info.Mvid ); testReference.MetadataReferenceInfo.AssertEqual(info); count++; } Assert.Equal(references.Length + frameworkReferences.Length, count); }
private CSharpCompilation CreateCompilation(string code) => CreateCSharpCompilation( code, referencedAssemblies: TargetFrameworkUtil.GetReferences( TargetFramework.NetStandard20 ) );
private static Solution AddDefaultTestSolution( TestWorkspace workspace, string[] markedSources ) { var solution = workspace.CurrentSolution; var project = solution .AddProject("proj", "proj", LanguageNames.CSharp) .WithMetadataReferences( TargetFrameworkUtil.GetReferences(TargetFramework.Standard) ); solution = project.Solution; for (var i = 0; i < markedSources.Length; i++) { var name = $"test{i + 1}.cs"; var text = SourceText.From( ActiveStatementsDescription.ClearTags(markedSources[i]), Encoding.UTF8 ); var id = DocumentId.CreateNewId(project.Id, name); solution = solution.AddDocument( id, name, text, filePath: Path.Combine(TempRoot.Root, name) ); } workspace.ChangeSolution(solution); return solution; }
public async Task TryGetCompileTimeDocumentAsync() { var workspace = new TestWorkspace(composition: FeaturesTestCompositions.Features); var projectId = ProjectId.CreateNewId(); var projectFilePath = Path.Combine(TempRoot.Root, "a.csproj"); var additionalFilePath = Path.Combine(TempRoot.Root, "a", "X.razor"); var designTimeFilePath = Path.Combine(TempRoot.Root, "a", "X.razor.g.cs"); var generatedHintName = @"_a_X_razor.cs"; var generator = new TestSourceGenerator() { ExecuteImpl = context => context.AddSource(generatedHintName, "") }; var sourceGeneratedPathPrefix = Path.Combine(typeof(TestSourceGenerator).Assembly.GetName().Name, typeof(TestSourceGenerator).FullName); var analyzerConfigId = DocumentId.CreateNewId(projectId); var documentId = DocumentId.CreateNewId(projectId); var additionalDocumentId = DocumentId.CreateNewId(projectId); var designTimeDocumentId = DocumentId.CreateNewId(projectId); var designTimeSolution = workspace.CurrentSolution. AddProject(ProjectInfo.Create(projectId, VersionStamp.Default, "proj", "proj", LanguageNames.CSharp, filePath: projectFilePath)). WithProjectMetadataReferences(projectId, TargetFrameworkUtil.GetReferences(TargetFramework.NetStandard20)). AddAnalyzerReference(projectId, new TestGeneratorReference(generator)). AddAdditionalDocument(additionalDocumentId, "additional", SourceText.From(""), filePath: additionalFilePath). AddAnalyzerConfigDocument(analyzerConfigId, "config", SourceText.From(""), filePath: "RazorSourceGenerator.razorencconfig"). AddDocument(documentId, "a.cs", ""). AddDocument(DocumentInfo.Create( designTimeDocumentId, name: "a", folders: Array.Empty <string>(), sourceCodeKind: SourceCodeKind.Regular, loader: null, filePath: designTimeFilePath, isGenerated: true, designTimeOnly: true, documentServiceProvider: null)); var designTimeDocument = designTimeSolution.GetRequiredDocument(designTimeDocumentId); var provider = workspace.Services.GetRequiredService <ICompileTimeSolutionProvider>(); var compileTimeSolution = provider.GetCompileTimeSolution(designTimeSolution); Assert.False(compileTimeSolution.ContainsAnalyzerConfigDocument(analyzerConfigId)); Assert.False(compileTimeSolution.ContainsDocument(designTimeDocumentId)); Assert.True(compileTimeSolution.ContainsDocument(documentId)); var sourceGeneratedDoc = (await compileTimeSolution.Projects.Single().GetSourceGeneratedDocumentsAsync()).Single(); var compileTimeDocument = await CompileTimeSolutionProvider.TryGetCompileTimeDocumentAsync(designTimeDocument, compileTimeSolution, CancellationToken.None, sourceGeneratedPathPrefix); Assert.Same(sourceGeneratedDoc, compileTimeDocument); var actualDesignTimeDocumentIds = await CompileTimeSolutionProvider.GetDesignTimeDocumentsAsync( compileTimeSolution, ImmutableArray.Create(documentId, sourceGeneratedDoc.Id), designTimeSolution, CancellationToken.None, sourceGeneratedPathPrefix); AssertEx.Equal(new[] { documentId, designTimeDocumentId }, actualDesignTimeDocumentIds); }
public static PortableExecutableReference CreateWindowsRuntimeMetadataReference() { var source = @" namespace System.Runtime.InteropServices.WindowsRuntime { public struct EventRegistrationToken { } public sealed class EventRegistrationTokenTable<T> where T : class { public T InvocationList { get; set; } public static EventRegistrationTokenTable<T> GetOrCreateEventRegistrationTokenTable(ref EventRegistrationTokenTable<T> refEventTable) { throw null; } public void RemoveEventHandler(EventRegistrationToken token) { } public void RemoveEventHandler(T handler) { } } public static class WindowsRuntimeMarshal { public static void AddEventHandler<T>(Func<T, EventRegistrationToken> addMethod, Action<EventRegistrationToken> removeMethod, T handler) { } public static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod) { } public static void RemoveEventHandler<T>(Action<EventRegistrationToken> removeMethod, T handler) { } } } "; // The actual System.Runtime.InteropServices.WindowsRuntime DLL has a public key of // b03f5f7f11d50a3a and version 4.0.4.0. The compiler just looks at these via // WellKnownTypes and WellKnownMembers so it can be safely skipped here. var compilation = CSharpCompilation.Create( "System.Runtime.InteropServices.WindowsRuntime", new[] { CSharpSyntaxTree.ParseText(source) }, references: TargetFrameworkUtil.GetReferences(TargetFramework.NetCoreApp), options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); compilation.VerifyEmitDiagnostics(); return(compilation.EmitToPortableExecutableReference()); }
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 async Task Proxy(TestHost testHost) { var localComposition = EditorTestCompositions.EditorFeatures.WithTestHostParts(testHost); if (testHost == TestHost.InProcess) { localComposition = localComposition.AddParts(typeof(MockEncServiceFactory)); } using var localWorkspace = new TestWorkspace(composition: localComposition); MockEditAndContinueWorkspaceService mockEncService; var clientProvider = (InProcRemoteHostClientProvider?)localWorkspace.Services.GetService <IRemoteHostClientProvider>(); if (testHost == TestHost.InProcess) { Assert.Null(clientProvider); mockEncService = (MockEditAndContinueWorkspaceService)localWorkspace.Services.GetRequiredService <IEditAndContinueWorkspaceService>(); } else { Assert.NotNull(clientProvider); clientProvider !.AdditionalRemoteParts = new[] { typeof(MockEncServiceFactory) }; var client = await InProcRemoteHostClient.GetTestClientAsync(localWorkspace).ConfigureAwait(false); var remoteWorkspace = client.TestData.WorkspaceManager.GetWorkspace(); mockEncService = (MockEditAndContinueWorkspaceService)remoteWorkspace.Services.GetRequiredService <IEditAndContinueWorkspaceService>(); } localWorkspace.ChangeSolution(localWorkspace.CurrentSolution. AddProject("proj", "proj", LanguageNames.CSharp). AddMetadataReferences(TargetFrameworkUtil.GetReferences(TargetFramework.Mscorlib40)). AddDocument("test.cs", SourceText.From("class C { }", Encoding.UTF8), filePath: "test.cs").Project.Solution); var solution = localWorkspace.CurrentSolution; var project = solution.Projects.Single(); var document = project.Documents.Single(); var mockDiagnosticService = new MockDiagnosticAnalyzerService(); void VerifyReanalyzeInvocation(ImmutableArray <DocumentId> documentIds) { AssertEx.Equal(documentIds, mockDiagnosticService.DocumentsToReanalyze); mockDiagnosticService.DocumentsToReanalyze.Clear(); } var diagnosticUpdateSource = new EditAndContinueDiagnosticUpdateSource(); var emitDiagnosticsUpdated = new List <DiagnosticsUpdatedArgs>(); var emitDiagnosticsClearedCount = 0; diagnosticUpdateSource.DiagnosticsUpdated += (object sender, DiagnosticsUpdatedArgs args) => emitDiagnosticsUpdated.Add(args); diagnosticUpdateSource.DiagnosticsCleared += (object sender, EventArgs args) => emitDiagnosticsClearedCount++; var span1 = new LinePositionSpan(new LinePosition(1, 2), new LinePosition(1, 5)); var moduleId1 = new Guid("{44444444-1111-1111-1111-111111111111}"); var methodId1 = new ManagedMethodId(moduleId1, token: 0x06000003, version: 2); var instructionId1 = new ManagedInstructionId(methodId1, ilOffset: 10); var as1 = new ManagedActiveStatementDebugInfo( instructionId1, documentName: "test.cs", span1.ToSourceSpan(), flags: ActiveStatementFlags.IsLeafFrame | ActiveStatementFlags.PartiallyExecuted); var methodId2 = new ManagedModuleMethodId(token: 0x06000002, version: 1); var exceptionRegionUpdate1 = new ManagedExceptionRegionUpdate( methodId2, delta: 1, newSpan: new SourceSpan(1, 2, 1, 5)); var document1 = localWorkspace.CurrentSolution.Projects.Single().Documents.Single(); var activeSpans1 = ImmutableArray.Create( new ActiveStatementSpan(0, new LinePositionSpan(new LinePosition(1, 2), new LinePosition(3, 4)), ActiveStatementFlags.IsNonLeafFrame, document.Id)); var activeStatementSpanProvider = new ActiveStatementSpanProvider((documentId, path, cancellationToken) => { Assert.Equal(document1.Id, documentId); Assert.Equal("test.cs", path); return(new(activeSpans1)); }); var proxy = new RemoteEditAndContinueServiceProxy(localWorkspace); // StartDebuggingSession IManagedEditAndContinueDebuggerService?remoteDebuggeeModuleMetadataProvider = null; var debuggingSession = mockEncService.StartDebuggingSessionImpl = (solution, debuggerService, captureMatchingDocuments, captureAllMatchingDocuments, reportDiagnostics) => { Assert.Equal("proj", solution.Projects.Single().Name); AssertEx.Equal(new[] { document1.Id }, captureMatchingDocuments); Assert.False(captureAllMatchingDocuments); Assert.True(reportDiagnostics); remoteDebuggeeModuleMetadataProvider = debuggerService; return(new DebuggingSessionId(1)); }; var sessionProxy = await proxy.StartDebuggingSessionAsync( localWorkspace.CurrentSolution, debuggerService : new MockManagedEditAndContinueDebuggerService() { IsEditAndContinueAvailable = _ => new ManagedEditAndContinueAvailability(ManagedEditAndContinueAvailabilityStatus.NotAllowedForModule, "can't do enc"), GetActiveStatementsImpl = () => ImmutableArray.Create(as1) }, captureMatchingDocuments : ImmutableArray.Create(document1.Id), captureAllMatchingDocuments : false, reportDiagnostics : true, CancellationToken.None).ConfigureAwait(false); Contract.ThrowIfNull(sessionProxy); // BreakStateEntered mockEncService.BreakStateEnteredImpl = (out ImmutableArray <DocumentId> documentsToReanalyze) => { documentsToReanalyze = ImmutableArray.Create(document.Id); }; await sessionProxy.BreakStateEnteredAsync(mockDiagnosticService, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document.Id)); var activeStatement = (await remoteDebuggeeModuleMetadataProvider !.GetActiveStatementsAsync(CancellationToken.None).ConfigureAwait(false)).Single(); Assert.Equal(as1.ActiveInstruction, activeStatement.ActiveInstruction); Assert.Equal(as1.SourceSpan, activeStatement.SourceSpan); Assert.Equal(as1.Flags, activeStatement.Flags); var availability = await remoteDebuggeeModuleMetadataProvider !.GetAvailabilityAsync(moduleId1, CancellationToken.None).ConfigureAwait(false); Assert.Equal(new ManagedEditAndContinueAvailability(ManagedEditAndContinueAvailabilityStatus.NotAllowedForModule, "can't do enc"), availability); // HasChanges mockEncService.HasChangesImpl = (solution, activeStatementSpanProvider, sourceFilePath) => { Assert.Equal("proj", solution.Projects.Single().Name); Assert.Equal("test.cs", sourceFilePath); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document1.Id, "test.cs", CancellationToken.None).AsTask().Result); return(true); }; Assert.True(await sessionProxy.HasChangesAsync(localWorkspace.CurrentSolution, activeStatementSpanProvider, "test.cs", CancellationToken.None).ConfigureAwait(false)); // EmitSolutionUpdate var diagnosticDescriptor1 = EditAndContinueDiagnosticDescriptors.GetDescriptor(EditAndContinueErrorCode.ErrorReadingFile); mockEncService.EmitSolutionUpdateImpl = (solution, activeStatementSpanProvider) => { var project = solution.Projects.Single(); Assert.Equal("proj", project.Name); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document1.Id, "test.cs", CancellationToken.None).AsTask().Result); var deltas = ImmutableArray.Create(new ManagedModuleUpdate( module: moduleId1, ilDelta: ImmutableArray.Create <byte>(1, 2), metadataDelta: ImmutableArray.Create <byte>(3, 4), pdbDelta: ImmutableArray.Create <byte>(5, 6), updatedMethods: ImmutableArray.Create(0x06000001), updatedTypes: ImmutableArray.Create(0x02000001), sequencePoints: ImmutableArray.Create(new SequencePointUpdates("file.cs", ImmutableArray.Create(new SourceLineUpdate(1, 2)))), activeStatements: ImmutableArray.Create(new ManagedActiveStatementUpdate(instructionId1.Method.Method, instructionId1.ILOffset, span1.ToSourceSpan())), exceptionRegions: ImmutableArray.Create(exceptionRegionUpdate1))); var syntaxTree = project.Documents.Single().GetSyntaxTreeSynchronously(CancellationToken.None) !; var documentDiagnostic = Diagnostic.Create(diagnosticDescriptor1, Location.Create(syntaxTree, TextSpan.FromBounds(1, 2)), new[] { "doc", "some error" }); var projectDiagnostic = Diagnostic.Create(diagnosticDescriptor1, Location.None, new[] { "proj", "some error" }); var updates = new ManagedModuleUpdates(ManagedModuleUpdateStatus.Ready, deltas); var diagnostics = ImmutableArray.Create((project.Id, ImmutableArray.Create(documentDiagnostic, projectDiagnostic))); var documentsWithRudeEdits = ImmutableArray.Create((document1.Id, ImmutableArray <RudeEditDiagnostic> .Empty)); return(new(updates, diagnostics, documentsWithRudeEdits)); }; var(updates, _, _) = await sessionProxy.EmitSolutionUpdateAsync(localWorkspace.CurrentSolution, activeStatementSpanProvider, mockDiagnosticService, diagnosticUpdateSource, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document1.Id)); Assert.Equal(ManagedModuleUpdateStatus.Ready, updates.Status); Assert.Equal(1, emitDiagnosticsClearedCount); emitDiagnosticsClearedCount = 0; AssertEx.Equal(new[] { $"[{project.Id}] Error ENC1001: test.cs(0, 1, 0, 2): {string.Format(FeaturesResources.ErrorReadingFile, "doc", "some error")}", $"[{project.Id}] Error ENC1001: {string.Format(FeaturesResources.ErrorReadingFile, "proj", "some error")}" }, emitDiagnosticsUpdated.Select(update => { var d = update.GetPushDiagnostics(localWorkspace, InternalDiagnosticsOptions.NormalDiagnosticMode).Single(); return($"[{d.ProjectId}] {d.Severity} {d.Id}:" + (d.DataLocation != null ? $" {d.DataLocation.OriginalFilePath}({d.DataLocation.OriginalStartLine}, {d.DataLocation.OriginalStartColumn}, {d.DataLocation.OriginalEndLine}, {d.DataLocation.OriginalEndColumn}):" : "") + $" {d.Message}"); })); emitDiagnosticsUpdated.Clear(); var delta = updates.Updates.Single(); Assert.Equal(moduleId1, delta.Module); AssertEx.Equal(new byte[] { 1, 2 }, delta.ILDelta); AssertEx.Equal(new byte[] { 3, 4 }, delta.MetadataDelta); AssertEx.Equal(new byte[] { 5, 6 }, delta.PdbDelta); AssertEx.Equal(new[] { 0x06000001 }, delta.UpdatedMethods); AssertEx.Equal(new[] { 0x02000001 }, delta.UpdatedTypes); var lineEdit = delta.SequencePoints.Single(); Assert.Equal("file.cs", lineEdit.FileName); AssertEx.Equal(new[] { new SourceLineUpdate(1, 2) }, lineEdit.LineUpdates); Assert.Equal(exceptionRegionUpdate1, delta.ExceptionRegions.Single()); var activeStatements = delta.ActiveStatements.Single(); Assert.Equal(instructionId1.Method.Method, activeStatements.Method); Assert.Equal(instructionId1.ILOffset, activeStatements.ILOffset); Assert.Equal(span1, activeStatements.NewSpan.ToLinePositionSpan()); // CommitSolutionUpdate mockEncService.CommitSolutionUpdateImpl = (out ImmutableArray <DocumentId> documentsToReanalyze) => { documentsToReanalyze = ImmutableArray.Create(document.Id); }; await sessionProxy.CommitSolutionUpdateAsync(mockDiagnosticService, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document.Id)); // DiscardSolutionUpdate var called = false; mockEncService.DiscardSolutionUpdateImpl = () => called = true; await sessionProxy.DiscardSolutionUpdateAsync(CancellationToken.None).ConfigureAwait(false); Assert.True(called); // GetCurrentActiveStatementPosition mockEncService.GetCurrentActiveStatementPositionImpl = (solution, activeStatementSpanProvider, instructionId) => { Assert.Equal("proj", solution.Projects.Single().Name); Assert.Equal(instructionId1, instructionId); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document1.Id, "test.cs", CancellationToken.None).AsTask().Result); return(new LinePositionSpan(new LinePosition(1, 2), new LinePosition(1, 5))); }; Assert.Equal(span1, await sessionProxy.GetCurrentActiveStatementPositionAsync( localWorkspace.CurrentSolution, activeStatementSpanProvider, instructionId1, CancellationToken.None).ConfigureAwait(false)); // IsActiveStatementInExceptionRegion mockEncService.IsActiveStatementInExceptionRegionImpl = (solution, instructionId) => { Assert.Equal(instructionId1, instructionId); return(true); }; Assert.True(await sessionProxy.IsActiveStatementInExceptionRegionAsync(localWorkspace.CurrentSolution, instructionId1, CancellationToken.None).ConfigureAwait(false)); // GetBaseActiveStatementSpans var activeStatementSpan1 = new ActiveStatementSpan(0, span1, ActiveStatementFlags.IsNonLeafFrame | ActiveStatementFlags.PartiallyExecuted, unmappedDocumentId: document1.Id); mockEncService.GetBaseActiveStatementSpansImpl = (solution, documentIds) => { AssertEx.Equal(new[] { document1.Id }, documentIds); return(ImmutableArray.Create(ImmutableArray.Create(activeStatementSpan1))); }; var baseActiveSpans = await sessionProxy.GetBaseActiveStatementSpansAsync(localWorkspace.CurrentSolution, ImmutableArray.Create(document1.Id), CancellationToken.None).ConfigureAwait(false); Assert.Equal(activeStatementSpan1, baseActiveSpans.Single().Single()); // GetDocumentActiveStatementSpans mockEncService.GetAdjustedActiveStatementSpansImpl = (document, activeStatementSpanProvider) => { Assert.Equal("test.cs", document.Name); AssertEx.Equal(activeSpans1, activeStatementSpanProvider(document.Id, "test.cs", CancellationToken.None).AsTask().Result); return(ImmutableArray.Create(activeStatementSpan1)); }; var documentActiveSpans = await sessionProxy.GetAdjustedActiveStatementSpansAsync(document1, activeStatementSpanProvider, CancellationToken.None).ConfigureAwait(false); Assert.Equal(activeStatementSpan1, documentActiveSpans.Single()); // GetDocumentActiveStatementSpans (default array) mockEncService.GetAdjustedActiveStatementSpansImpl = (document, _) => default; documentActiveSpans = await sessionProxy.GetAdjustedActiveStatementSpansAsync(document1, activeStatementSpanProvider, CancellationToken.None).ConfigureAwait(false); Assert.True(documentActiveSpans.IsDefault); // OnSourceFileUpdatedAsync called = false; mockEncService.OnSourceFileUpdatedImpl = updatedDocument => { Assert.Equal(document.Id, updatedDocument.Id); called = true; }; await proxy.OnSourceFileUpdatedAsync(document, CancellationToken.None).ConfigureAwait(false); Assert.True(called); // EndDebuggingSession mockEncService.EndDebuggingSessionImpl = (out ImmutableArray <DocumentId> documentsToReanalyze) => { documentsToReanalyze = ImmutableArray.Create(document.Id); }; await sessionProxy.EndDebuggingSessionAsync(solution, diagnosticUpdateSource, mockDiagnosticService, CancellationToken.None).ConfigureAwait(false); VerifyReanalyzeInvocation(ImmutableArray.Create(document.Id)); Assert.Equal(1, emitDiagnosticsClearedCount); emitDiagnosticsClearedCount = 0; Assert.Empty(emitDiagnosticsUpdated); }
public void TestGeneratorsCantTargetNetFramework() { var directory = Temp.CreateDirectory(); // core var errors = buildAndLoadGeneratorAndReturnAnyErrors(".NETCoreApp,Version=v5.0"); Assert.Empty(errors); // netstandard errors = buildAndLoadGeneratorAndReturnAnyErrors(".NETStandard,Version=v2.0"); Assert.Empty(errors); // no target errors = buildAndLoadGeneratorAndReturnAnyErrors(targetFramework: null); Assert.Empty(errors); // framework errors = buildAndLoadGeneratorAndReturnAnyErrors(".NETFramework,Version=v4.7.2"); Assert.Equal(2, errors.Count); Assert.Equal(AnalyzerLoadFailureEventArgs.FailureErrorCode.ReferencesFramework, errors.First().ErrorCode); List <AnalyzerLoadFailureEventArgs> buildAndLoadGeneratorAndReturnAnyErrors(string?targetFramework) { string targetFrameworkAttributeText = targetFramework is object ?$"[assembly: System.Runtime.Versioning.TargetFramework(\"{targetFramework}\")]" : string.Empty; string generatorSource = $@" using Microsoft.CodeAnalysis; {targetFrameworkAttributeText} [Generator] public class Generator : ISourceGenerator {{ public void Execute(GeneratorExecutionContext context) {{ }} public void Initialize(GeneratorInitializationContext context) {{ }} }}"; var directory = Temp.CreateDirectory(); var generatorPath = Path.Combine(directory.Path, $"generator_{targetFramework}.dll"); var compilation = CSharpCompilation.Create($"generator_{targetFramework}", new[] { CSharpSyntaxTree.ParseText(generatorSource) }, TargetFrameworkUtil.GetReferences(TargetFramework.Standard, new[] { MetadataReference.CreateFromAssemblyInternal(typeof(ISourceGenerator).Assembly) }), new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); compilation.VerifyDiagnostics(); var result = compilation.Emit(generatorPath); Assert.True(result.Success); AnalyzerFileReference reference = CreateAnalyzerFileReference(generatorPath); List <AnalyzerLoadFailureEventArgs> errors = new List <AnalyzerLoadFailureEventArgs>(); void errorHandler(object?o, AnalyzerLoadFailureEventArgs e) => errors.Add(e); reference.AnalyzerLoadFailed += errorHandler; var builder = ImmutableArray.CreateBuilder <ISourceGenerator>(); reference.AddGenerators(builder, LanguageNames.CSharp); reference.AnalyzerLoadFailed -= errorHandler; if (errors.Count > 0) { Assert.Empty(builder); } else { Assert.Single(builder); } return(errors); } }
public async Task GetHotReloadDiagnostics() { using var workspace = new TestWorkspace(composition: FeaturesTestCompositions.Features); var sourcePath = Path.Combine(TempRoot.Root, "x", "a.cs"); var razorPath = Path.Combine(TempRoot.Root, "a.razor"); var document = workspace.CurrentSolution. AddProject("proj", "proj", LanguageNames.CSharp). WithMetadataReferences(TargetFrameworkUtil.GetReferences(TargetFramework.Standard)). AddDocument(sourcePath, SourceText.From("class C {}", Encoding.UTF8), filePath: Path.Combine(TempRoot.Root, sourcePath)); var solution = document.Project.Solution; var diagnosticData = ImmutableArray.Create( new DiagnosticData( id: "CS0001", category: "Test", message: "warning", enuMessageForBingSearch: "test2 message format", severity: DiagnosticSeverity.Warning, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 0, customTags: ImmutableArray.Create("Test2"), properties: ImmutableDictionary <string, string?> .Empty, document.Project.Id, new DiagnosticDataLocation(document.Id, new TextSpan(1, 2), "a.cs", 0, 0, 0, 5, "a.razor", 10, 10, 10, 15), language: "C#", title: "title", description: "description", helpLink: "http://link"), new DiagnosticData( id: "CS0012", category: "Test", message: "error", enuMessageForBingSearch: "test2 message format", severity: DiagnosticSeverity.Error, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, warningLevel: 0, customTags: ImmutableArray.Create("Test2"), properties: ImmutableDictionary <string, string?> .Empty, document.Project.Id, new DiagnosticDataLocation(document.Id, new TextSpan(1, 2), originalFilePath: sourcePath, 0, 0, 0, 5, mappedFilePath: @"..\a.razor", 10, 10, 10, 15), language: "C#", title: "title", description: "description", helpLink: "http://link")); var rudeEdits = ImmutableArray.Create( (document.Id, ImmutableArray.Create(new RudeEditDiagnostic(RudeEditKind.Insert, TextSpan.FromBounds(1, 10), 123, new[] { "a" }))), (document.Id, ImmutableArray.Create(new RudeEditDiagnostic(RudeEditKind.Delete, TextSpan.FromBounds(1, 10), 123, new[] { "b" })))); var actual = await EmitSolutionUpdateResults.GetHotReloadDiagnosticsAsync(solution, diagnosticData, rudeEdits, CancellationToken.None); AssertEx.Equal(new[] { $@"Error CS0012: {razorPath} (10,10)-(10,15): error", $@"Error ENC0021: {sourcePath} (0,1)-(0,10): {string.Format(FeaturesResources.Adding_0_will_prevent_the_debug_session_from_continuing, "a")}", $@"Error ENC0033: {sourcePath} (0,1)-(0,10): {string.Format(FeaturesResources.Deleting_0_will_prevent_the_debug_session_from_continuing, "b")}" }, actual.Select(d => $"{d.Severity} {d.Id}: {d.FilePath} {d.Span.GetDebuggerDisplay()}: {d.Message}")); }
//generate the code from the parsed BrowserDefinitionTree //compile it, and install it in the gac internal void GenerateCode(AssemblyBuilder assemblyBuilder) { ProcessBrowserFiles(true /*useVirtualPath*/, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString); ProcessCustomBrowserFiles(true /*useVirtualPath*/, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString); CodeCompileUnit ccu = new CodeCompileUnit(); Debug.Assert(BrowserTree != null); ArrayList customTreeRoots = new ArrayList(); for (int i = 0; i < CustomTreeNames.Count; i++) { customTreeRoots.Add((BrowserDefinition)(((BrowserTree)CustomTreeList[i])[CustomTreeNames[i]])); } // namespace ASP CodeNamespace cnamespace = new CodeNamespace(BaseCodeDomTreeGenerator.defaultNamespace); //GEN: using System; cnamespace.Imports.Add(new CodeNamespaceImport("System")); //GEN: using System.Web; cnamespace.Imports.Add(new CodeNamespaceImport("System.Web")); //GEN: using System.Web.Configuration; cnamespace.Imports.Add(new CodeNamespaceImport("System.Web.Configuration")); //GEN: using System.Reflection; cnamespace.Imports.Add(new CodeNamespaceImport("System.Reflection")); //GEN: class BrowserCapabilitiesFactory ccu.Namespaces.Add(cnamespace); Type baseType = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType(); CodeTypeDeclaration factoryType = new CodeTypeDeclaration(); factoryType.Attributes = MemberAttributes.Private; factoryType.IsClass = true; factoryType.Name = TypeName; factoryType.BaseTypes.Add(new CodeTypeReference(baseType)); cnamespace.Types.Add(factoryType); BindingFlags flags = BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.NonPublic; BrowserDefinition bd = null; //GEN: protected override object ConfigureBrowserCapabilities(NameValueCollection headers, HttpBrowserCapabilities browserCaps) CodeMemberMethod method = new CodeMemberMethod(); method.Attributes = MemberAttributes.Override | MemberAttributes.Public; method.ReturnType = new CodeTypeReference(typeof(void)); method.Name = "ConfigureCustomCapabilities"; CodeParameterDeclarationExpression cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers"); method.Parameters.Add(cpde); cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps"); method.Parameters.Add(cpde); factoryType.Members.Add(method); for (int i = 0; i < customTreeRoots.Count; i++) { GenerateSingleProcessCall((BrowserDefinition)customTreeRoots[i], method); } foreach (DictionaryEntry entry in _browserOverrides) { object key = entry.Key; BrowserDefinition firstBrowserDefinition = (BrowserDefinition)BrowserTree[GetFirstItemFromKey(_browserOverrides, key)]; string parentName = firstBrowserDefinition.ParentName; // if ((!TargetFrameworkUtil.HasMethod(baseType, parentName + "ProcessBrowsers", flags)) || (!TargetFrameworkUtil.HasMethod(baseType, parentName + "ProcessGateways", flags))) { String parentID = firstBrowserDefinition.ParentID; if (firstBrowserDefinition != null) { throw new ConfigurationErrorsException(SR.GetString(SR.Browser_parentID_Not_Found, parentID), firstBrowserDefinition.XmlNode); } else { throw new ConfigurationErrorsException(SR.GetString(SR.Browser_parentID_Not_Found, parentID)); } } bool isBrowserDefinition = true; if (firstBrowserDefinition is GatewayDefinition) { isBrowserDefinition = false; } //GenerateMethodsToOverrideBrowsers //Gen: protected override void Xxx_ProcessChildBrowsers(bool ignoreApplicationBrowsers, MNameValueCollection headers, HttpBrowserCapabilities browserCaps) ; string methodName = parentName + (isBrowserDefinition ? "ProcessBrowsers" : "ProcessGateways"); CodeMemberMethod cmm = new CodeMemberMethod(); cmm.Name = methodName; cmm.ReturnType = new CodeTypeReference(typeof(void)); cmm.Attributes = MemberAttributes.Family | MemberAttributes.Override; if (isBrowserDefinition) { cpde = new CodeParameterDeclarationExpression(typeof(bool), BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName); cmm.Parameters.Add(cpde); } cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers"); cmm.Parameters.Add(cpde); cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), browserCapsVariable); cmm.Parameters.Add(cpde); factoryType.Members.Add(cmm); ArrayList overrides = (ArrayList)_browserOverrides[key]; CodeStatementCollection statements = cmm.Statements; bool ignoreApplicationBrowsersVarRefGenerated = false; foreach (string browserID in overrides) { bd = (BrowserDefinition)BrowserTree[browserID]; if (bd is GatewayDefinition || bd.IsRefID) { GenerateSingleProcessCall(bd, cmm); } else { if (!ignoreApplicationBrowsersVarRefGenerated) { Debug.Assert(isBrowserDefinition); // Gen: if (ignoreApplicationBrowsers) { // } // else { // ... // } CodeConditionStatement istatement = new CodeConditionStatement(); istatement.Condition = new CodeVariableReferenceExpression(BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName); cmm.Statements.Add(istatement); statements = istatement.FalseStatements; ignoreApplicationBrowsersVarRefGenerated = true; } statements = GenerateTrackedSingleProcessCall(statements, bd, cmm); if (_baseInstance == null) { // If we are targeting 4.0 or using the ASP.BrowserCapsFactory assembly generated by // aspnet_regbrowsers.exe, we can simply just instantiate the type. // If not, then we need to use the type BrowserCapabilitiesFactory35 that contains code // from the 2.0 version of BrowserCapabilitiesFactory. This is because "baseType" is the 4.0 type // that contains the new 4.0 definitions. // (Dev10 bug 795509) if (MultiTargetingUtil.IsTargetFramework40OrAbove || baseType.Assembly == BrowserCapabilitiesCompiler.AspBrowserCapsFactoryAssembly) { _baseInstance = (BrowserCapabilitiesFactoryBase)Activator.CreateInstance(baseType); } else { _baseInstance = new BrowserCapabilitiesFactory35(); } } int parentDepth = (int)((Triplet)_baseInstance.InternalGetBrowserElements()[parentName]).Third; AddBrowserToCollectionRecursive(bd, parentDepth + 1); } } } foreach (DictionaryEntry entry in _defaultBrowserOverrides) { object key = entry.Key; BrowserDefinition firstDefaultBrowserDefinition = (BrowserDefinition)DefaultTree[GetFirstItemFromKey(_defaultBrowserOverrides, key)]; string parentName = firstDefaultBrowserDefinition.ParentName; if (baseType.GetMethod("Default" + parentName + "ProcessBrowsers", flags) == null) { String parentID = firstDefaultBrowserDefinition.ParentID; if (firstDefaultBrowserDefinition != null) { throw new ConfigurationErrorsException(SR.GetString(SR.DefaultBrowser_parentID_Not_Found, parentID), firstDefaultBrowserDefinition.XmlNode); } } string methodName = "Default" + parentName + "ProcessBrowsers"; CodeMemberMethod cmm = new CodeMemberMethod(); cmm.Name = methodName; cmm.ReturnType = new CodeTypeReference(typeof(void)); cmm.Attributes = MemberAttributes.Family | MemberAttributes.Override; cpde = new CodeParameterDeclarationExpression(typeof(bool), BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName); cmm.Parameters.Add(cpde); cpde = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers"); cmm.Parameters.Add(cpde); cpde = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), browserCapsVariable); cmm.Parameters.Add(cpde); factoryType.Members.Add(cmm); ArrayList overrides = (ArrayList)_defaultBrowserOverrides[key]; CodeConditionStatement istatement = new CodeConditionStatement(); istatement.Condition = new CodeVariableReferenceExpression(BrowserCapabilitiesCodeGenerator.IgnoreApplicationBrowserVariableName); cmm.Statements.Add(istatement); CodeStatementCollection statements = istatement.FalseStatements; foreach (string browserID in overrides) { bd = (BrowserDefinition)DefaultTree[browserID]; Debug.Assert(!(bd is GatewayDefinition)); if (bd.IsRefID) { GenerateSingleProcessCall(bd, cmm, "Default"); } else { statements = GenerateTrackedSingleProcessCall(statements, bd, cmm, "Default"); } } } // Generate process method for the browser elements foreach (DictionaryEntry entry in BrowserTree) { bd = entry.Value as BrowserDefinition; Debug.Assert(bd != null); GenerateProcessMethod(bd, factoryType); } for (int i = 0; i < customTreeRoots.Count; i++) { foreach (DictionaryEntry entry in (BrowserTree)CustomTreeList[i]) { bd = entry.Value as BrowserDefinition; Debug.Assert(bd != null); GenerateProcessMethod(bd, factoryType); } } // Generate process method for the default browser elements foreach (DictionaryEntry entry in DefaultTree) { bd = entry.Value as BrowserDefinition; Debug.Assert(bd != null); GenerateProcessMethod(bd, factoryType, "Default"); } GenerateOverrideMatchedHeaders(factoryType); GenerateOverrideBrowserElements(factoryType); Assembly assembly = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType().Assembly; assemblyBuilder.AddAssemblyReference(assembly, ccu); assemblyBuilder.AddCodeCompileUnit(_buildProvider, ccu); }
internal void GenerateCode(AssemblyBuilder assemblyBuilder) { base.ProcessBrowserFiles(true, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString); base.ProcessCustomBrowserFiles(true, BrowserCapabilitiesCompiler.AppBrowsersVirtualDir.VirtualPathString); CodeCompileUnit ccu = new CodeCompileUnit(); ArrayList list = new ArrayList(); for (int i = 0; i < base.CustomTreeNames.Count; i++) { list.Add((BrowserDefinition)((BrowserTree)base.CustomTreeList[i])[base.CustomTreeNames[i]]); } CodeNamespace namespace2 = new CodeNamespace("ASP"); namespace2.Imports.Add(new CodeNamespaceImport("System")); namespace2.Imports.Add(new CodeNamespaceImport("System.Web")); namespace2.Imports.Add(new CodeNamespaceImport("System.Web.Configuration")); namespace2.Imports.Add(new CodeNamespaceImport("System.Reflection")); ccu.Namespaces.Add(namespace2); Type browserCapabilitiesFactoryBaseType = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType(); CodeTypeDeclaration declaration = new CodeTypeDeclaration { Attributes = MemberAttributes.Private, IsClass = true, Name = this.TypeName }; declaration.BaseTypes.Add(new CodeTypeReference(browserCapabilitiesFactoryBaseType)); namespace2.Types.Add(declaration); BindingFlags bindingAttr = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase; BrowserDefinition bd = null; CodeMemberMethod method = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Override, ReturnType = new CodeTypeReference(typeof(void)), Name = "ConfigureCustomCapabilities" }; CodeParameterDeclarationExpression expression = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers"); method.Parameters.Add(expression); expression = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps"); method.Parameters.Add(expression); declaration.Members.Add(method); for (int j = 0; j < list.Count; j++) { base.GenerateSingleProcessCall((BrowserDefinition)list[j], method); } foreach (DictionaryEntry entry in this._browserOverrides) { object key = entry.Key; BrowserDefinition definition2 = (BrowserDefinition)base.BrowserTree[GetFirstItemFromKey(this._browserOverrides, key)]; string parentName = definition2.ParentName; if (!TargetFrameworkUtil.HasMethod(browserCapabilitiesFactoryBaseType, parentName + "ProcessBrowsers", bindingAttr) || !TargetFrameworkUtil.HasMethod(browserCapabilitiesFactoryBaseType, parentName + "ProcessGateways", bindingAttr)) { string parentID = definition2.ParentID; if (definition2 != null) { throw new ConfigurationErrorsException(System.Web.SR.GetString("Browser_parentID_Not_Found", new object[] { parentID }), definition2.XmlNode); } throw new ConfigurationErrorsException(System.Web.SR.GetString("Browser_parentID_Not_Found", new object[] { parentID })); } bool flag = true; if (definition2 is GatewayDefinition) { flag = false; } string str3 = parentName + (flag ? "ProcessBrowsers" : "ProcessGateways"); CodeMemberMethod method2 = new CodeMemberMethod { Name = str3, ReturnType = new CodeTypeReference(typeof(void)), Attributes = MemberAttributes.Family | MemberAttributes.Override }; if (flag) { expression = new CodeParameterDeclarationExpression(typeof(bool), "ignoreApplicationBrowsers"); method2.Parameters.Add(expression); } expression = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers"); method2.Parameters.Add(expression); expression = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps"); method2.Parameters.Add(expression); declaration.Members.Add(method2); ArrayList list2 = (ArrayList)this._browserOverrides[key]; CodeStatementCollection stmts = method2.Statements; bool flag2 = false; foreach (string str4 in list2) { bd = (BrowserDefinition)base.BrowserTree[str4]; if ((bd is GatewayDefinition) || bd.IsRefID) { base.GenerateSingleProcessCall(bd, method2); } else { if (!flag2) { CodeConditionStatement statement = new CodeConditionStatement { Condition = new CodeVariableReferenceExpression("ignoreApplicationBrowsers") }; method2.Statements.Add(statement); stmts = statement.FalseStatements; flag2 = true; } stmts = base.GenerateTrackedSingleProcessCall(stmts, bd, method2); if (this._baseInstance == null) { if (MultiTargetingUtil.IsTargetFramework40OrAbove || (browserCapabilitiesFactoryBaseType.Assembly == BrowserCapabilitiesCompiler.AspBrowserCapsFactoryAssembly)) { this._baseInstance = (BrowserCapabilitiesFactoryBase)Activator.CreateInstance(browserCapabilitiesFactoryBaseType); } else { this._baseInstance = new BrowserCapabilitiesFactory35(); } } int third = (int)((Triplet)this._baseInstance.InternalGetBrowserElements()[parentName]).Third; base.AddBrowserToCollectionRecursive(bd, third + 1); } } } foreach (DictionaryEntry entry2 in this._defaultBrowserOverrides) { object obj3 = entry2.Key; BrowserDefinition definition3 = (BrowserDefinition)base.DefaultTree[GetFirstItemFromKey(this._defaultBrowserOverrides, obj3)]; string str5 = definition3.ParentName; if (browserCapabilitiesFactoryBaseType.GetMethod("Default" + str5 + "ProcessBrowsers", bindingAttr) == null) { string str6 = definition3.ParentID; if (definition3 != null) { throw new ConfigurationErrorsException(System.Web.SR.GetString("DefaultBrowser_parentID_Not_Found", new object[] { str6 }), definition3.XmlNode); } } string str7 = "Default" + str5 + "ProcessBrowsers"; CodeMemberMethod method3 = new CodeMemberMethod { Name = str7, ReturnType = new CodeTypeReference(typeof(void)), Attributes = MemberAttributes.Family | MemberAttributes.Override }; expression = new CodeParameterDeclarationExpression(typeof(bool), "ignoreApplicationBrowsers"); method3.Parameters.Add(expression); expression = new CodeParameterDeclarationExpression(typeof(NameValueCollection), "headers"); method3.Parameters.Add(expression); expression = new CodeParameterDeclarationExpression(typeof(HttpBrowserCapabilities), "browserCaps"); method3.Parameters.Add(expression); declaration.Members.Add(method3); ArrayList list3 = (ArrayList)this._defaultBrowserOverrides[obj3]; CodeConditionStatement statement2 = new CodeConditionStatement { Condition = new CodeVariableReferenceExpression("ignoreApplicationBrowsers") }; method3.Statements.Add(statement2); CodeStatementCollection falseStatements = statement2.FalseStatements; foreach (string str8 in list3) { bd = (BrowserDefinition)base.DefaultTree[str8]; if (bd.IsRefID) { base.GenerateSingleProcessCall(bd, method3, "Default"); } else { falseStatements = base.GenerateTrackedSingleProcessCall(falseStatements, bd, method3, "Default"); } } } foreach (DictionaryEntry entry3 in base.BrowserTree) { bd = entry3.Value as BrowserDefinition; base.GenerateProcessMethod(bd, declaration); } for (int k = 0; k < list.Count; k++) { foreach (DictionaryEntry entry4 in (BrowserTree)base.CustomTreeList[k]) { bd = entry4.Value as BrowserDefinition; base.GenerateProcessMethod(bd, declaration); } } foreach (DictionaryEntry entry5 in base.DefaultTree) { bd = entry5.Value as BrowserDefinition; base.GenerateProcessMethod(bd, declaration, "Default"); } base.GenerateOverrideMatchedHeaders(declaration); base.GenerateOverrideBrowserElements(declaration); Assembly a = BrowserCapabilitiesCompiler.GetBrowserCapabilitiesFactoryBaseType().Assembly; assemblyBuilder.AddAssemblyReference(a, ccu); assemblyBuilder.AddCodeCompileUnit(this._buildProvider, ccu); }
public CSharpEditAndContinueTestHelpers(TargetFramework targetFramework, Action <SyntaxNode> faultInjector = null) { _fxReferences = TargetFrameworkUtil.GetReferences(targetFramework); _analyzer = new CSharpEditAndContinueAnalyzer(faultInjector); }
public CSharpEditAndContinueTestHelpers(TargetFramework targetFramework) { _fxReferences = TargetFrameworkUtil.GetReferences(targetFramework); }