public Assembly CraeteAssembly(Microsoft.CodeAnalysis.Compilation compilation, params SyntaxNode[] units) { var trees = units.Select(unit => unit.SyntaxTree).ToArray(); var innerCompilation = compilation.AddSyntaxTrees(trees); var stream = new MemoryStream(); var emitResult = innerCompilation.Emit(stream); var diagnostics = emitResult.Diagnostics.Select(diagnostic => diagnostic.ToString()).ToArray(); var errors = string.Join("\n", diagnostics); if (!string.IsNullOrWhiteSpace(errors)) { throw new Exception(errors); } if (emitResult.Success) { stream.Seek(0, SeekOrigin.Begin); var assembly = Assembly.Load(stream.ToArray()); return(assembly); } throw new Exception("Error"); }
private int ReviewDiagnosticMessages(Microsoft.CodeAnalysis.Compilation compiler) { var results = compiler.GetDiagnostics(); // Console.WriteLine(results.Count()); foreach (var item in results) { // Console.WriteLine(item.Location.SourceTree.GetRoot().ToFullString()); Console.WriteLine(item.GetMessage() + item.Location); } return(results.Length); }
/// <summary> /// Emits compiled assembly to temporary file /// </summary> /// <param name="compilation"></param> /// <param name="result"></param> /// <param name="filename"></param> /// <returns></returns> public AssemblyWrapper EmitCompiledAssembly(Microsoft.CodeAnalysis.Compilation compilation, out EmitResult result, string filename) { var fi = new FileInfo(filename); fi.Directory?.Create(); using (var fs = new FileStream(fi.FullName, FileMode.Create)) { result = compilation.Emit(fs); if (!result.Success) { return(null); } } var assembly = LoadByFullFilename(fi.FullName); return(assembly); }
private static IEnumerable <T> Visit <T>(SyntaxTree syntaxTreeAsync, Microsoft.CodeAnalysis.Compilation compile, ICompilationInfo compilationInfo, ICompilationDocument document) { CheckClassVisitor visitor; if (!CompilationDocumentResult.TryGetValue(document.FullName, out visitor)) { var semanticModel = compile.GetSemanticModel(syntaxTreeAsync); visitor = new CheckClassVisitor(document, semanticModel, compilationInfo); visitor.Visit(syntaxTreeAsync.GetRoot()); CompilationDocumentResult.Add(document.FullName, visitor); } return(visitor.Get <T>()); }
private CompilationResult EmitCompilation( string path, string assemblyName, string filePath, Microsoft.CodeAnalysis.Compilation compilation) { var result = compilation.Emit(path, manifestResources: _embeddedResourceCreator.GetManifestResources(assemblyName, filePath)); return(new CompilationResult { IsSuccess = result.Success, Errors = result.Diagnostics .Where(d => d.Severity == DiagnosticSeverity.Error) .Select(d => new CompilationError { Message = d.GetMessage(), Location = d.Location.ToString() }) .ToList() }); }
public Assembly Compile(Microsoft.CodeAnalysis.Compilation compilation, string outputPath) { var pdbPath = Path.ChangeExtension(outputPath, "pdb"); var xmlDocPath = Path.ChangeExtension(outputPath, "xml"); using (MemoryStream dllStream = new MemoryStream(), pdbStream = new MemoryStream(), xmlStream = new MemoryStream()) { using (var win32ResStream = compilation.CreateDefaultWin32Resources( versionResource: true, // Important! noManifest: false, manifestContents: null, iconInIcoFormat: null)) { var result = compilation.Emit( peStream: dllStream, pdbStream: pdbStream, xmlDocumentationStream: xmlStream, win32Resources: win32ResStream); if (!result.Success) { var failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); foreach (var diagnostic in failures) { Logger.Error(diagnostic); } return(null); } _fileSystem.WriteAllBytes(outputPath, dllStream.ToArray()); _fileSystem.WriteAllBytes(pdbPath, pdbStream.ToArray()); _fileSystem.WriteAllBytes(xmlDocPath, xmlStream.ToArray()); return(_assemblyLoader.LoadFrom(outputPath)); } } }
public static CompilationResult GetAssemblyFromCompilation( ICodeGenAssemblyLoadContext loader, Microsoft.CodeAnalysis.Compilation compilation) { using (var ms = new MemoryStream()) { var result = compilation.Emit(ms, pdbStream: null); if (!result.Success) { var formatter = new DiagnosticFormatter(); var errorMessages = result.Diagnostics .Where(IsError) .Select(d => formatter.Format(d)); return(CompilationResult.FromErrorMessages(errorMessages)); } ms.Seek(0, SeekOrigin.Begin); try { return(CompilationResult.FromAssembly(loader.LoadStream(ms, symbols: null))); } catch (Exception ex) { var v = ex; while (v.InnerException != null) { v = v.InnerException; } return(CompilationResult.FromErrorMessages(ex.GetAllErrorMessages())); } } }
public DeferredDocumentationProvider(Compilation compilation) { this.compilation = compilation; }
// Hand out the same compilation reference for everyone who asks. Use // WeakReference<Compilation> so that if no-one is using the MetadataReference, // it can be collected. internal static Compilation GetCompilationForMetadataReference(ProjectState projectState, Compilation compilation) { var weakReference = s_compilationReferenceMap.GetValue(projectState, s_createValue); Compilation reference; lock (s_guard) { if (!weakReference.TryGetTarget(out reference)) { reference = compilation.Clone(); // drop all existing symbols weakReference.SetTarget(reference); } } return(reference); }
private static void ShouldHaveNoCompilerDiagnosticsWarningOrAbove(ITestOutputHelper output, Microsoft.CodeAnalysis.Compilation compilation, IEnumerable <Diagnostic> diagnostics) { var compilationErrors = diagnostics.Where(x => x.Severity >= DiagnosticSeverity.Warning).Select(x => $"// {x.Location.SourceTree?.FilePath} ({x.Location.GetLineSpan().StartLinePosition}): {x.GetMessage()}{Environment.NewLine}").ToList(); var outputSources = string.Join(Environment.NewLine, compilation.SyntaxTrees.Select(x => $"// {x.FilePath}:{Environment.NewLine}{x}").Where(x => !x.Contains("The impementation should have been generated."))); if (compilationErrors.Count > 0) { output.WriteLine(outputSources); throw new InvalidOperationException(string.Join(Environment.NewLine, compilationErrors)); } }
private void GetPartialCompilationState( SolutionState solution, DocumentId id, out ProjectState inProgressProject, out Compilation inProgressCompilation, CancellationToken cancellationToken) { var state = ReadState(); var compilation = state.Compilation?.GetValueOrNull(cancellationToken); // check whether we can bail out quickly for typing case var inProgressState = state as InProgressState; // all changes left for this document is modifying the given document. // we can use current state as it is since we will replace the document with latest document anyway. if (inProgressState != null && compilation != null && inProgressState.IntermediateProjects.All(t => IsTouchDocumentActionForDocument(t.action, id))) { inProgressProject = ProjectState; inProgressCompilation = compilation; SolutionLogger.UseExistingPartialProjectState(); return; } inProgressProject = inProgressState != null?inProgressState.IntermediateProjects.First().state : this.ProjectState; // if we already have a final compilation we are done. if (compilation != null && state is FinalState) { inProgressCompilation = compilation; SolutionLogger.UseExistingFullProjectState(); return; } // 1) if we have an in-progress compilation use it. // 2) If we don't, then create a simple empty compilation/project. // 3) then, make sure that all it's p2p refs and whatnot are correct. if (compilation == null) { inProgressProject = inProgressProject.RemoveAllDocuments(); inProgressCompilation = CreateEmptyCompilation(); } else { inProgressCompilation = compilation; } // first remove all project from the project and compilation. inProgressProject = inProgressProject.WithProjectReferences(ImmutableArray.Create <ProjectReference>()); // Now add in back a consistent set of project references. For project references // try to get either a CompilationReference or a SkeletonReference. This ensures // that the in-progress project only reports a reference to another project if it // could actually get a reference to that project's metadata. var metadataReferences = new List <MetadataReference>(); var newProjectReferences = new List <ProjectReference>(); metadataReferences.AddRange(this.ProjectState.MetadataReferences); var metadataReferenceToProjectId = new Dictionary <MetadataReference, ProjectId>(); foreach (var projectReference in this.ProjectState.ProjectReferences) { var referencedProject = solution.GetProjectState(projectReference.ProjectId); if (referencedProject != null) { if (referencedProject.IsSubmission) { var previousScriptCompilation = solution.GetCompilationAsync(projectReference.ProjectId, cancellationToken).WaitAndGetResult(cancellationToken); // previous submission project must support compilation: RoslynDebug.Assert(previousScriptCompilation != null); inProgressCompilation = inProgressCompilation.WithScriptCompilationInfo(inProgressCompilation.ScriptCompilationInfo !.WithPreviousScriptCompilation(previousScriptCompilation)); } else { // get the latest metadata for the partial compilation of the referenced project. var metadata = solution.GetPartialMetadataReference(projectReference, this.ProjectState); if (metadata == null) { // if we failed to get the metadata, check to see if we previously had existing metadata and reuse it instead. var inProgressCompilationNotRef = inProgressCompilation; metadata = inProgressCompilationNotRef.ExternalReferences.FirstOrDefault( r => solution.GetProjectState(inProgressCompilationNotRef.GetAssemblyOrModuleSymbol(r) as IAssemblySymbol)?.Id == projectReference.ProjectId); } if (metadata != null) { newProjectReferences.Add(projectReference); metadataReferences.Add(metadata); metadataReferenceToProjectId.Add(metadata, projectReference.ProjectId); } } } } inProgressProject = inProgressProject.AddProjectReferences(newProjectReferences); inProgressCompilation = UpdateCompilationWithNewReferencesAndRecordAssemblySymbols(inProgressCompilation, metadataReferences, metadataReferenceToProjectId); SolutionLogger.CreatePartialProjectState(); }
public DocumentationUtil(Microsoft.CodeAnalysis.Compilation compilation) { this.compilation = compilation; }
/// <summary> /// Executes the source generators. /// </summary> /// <param name="compilation">The target compilation.</param> /// <param name="diagnostics">The resulting diagnostics.</param> /// <param name="generators">The generators to include in the compilation.</param> /// <returns>The new compilation after the generators have executed.</returns> private static Microsoft.CodeAnalysis.Compilation RunGenerators(Microsoft.CodeAnalysis.Compilation compilation, out ImmutableArray <Diagnostic> diagnostics, params ISourceGenerator[] generators) { CreateDriver(compilation, generators).RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out diagnostics); return(outputCompilation); }
public abstract SymbolKeyResolution Resolve(Compilation compilation, bool ignoreAssemblyKey = false, CancellationToken cancellationToken = default(CancellationToken));
public override SymbolKeyResolution Resolve(Compilation compilation, bool ignoreAssemblyKey, CancellationToken cancellationToken) { var types = ResolveErrorTypes(compilation, ignoreAssemblyKey); return(CreateSymbolInfo(types)); }
/// <summary> /// <para> /// This entry point should only be called from the actual Symbol classes. It should not be /// used internally inside this type. Instead, any time we need to get the <see cref="SymbolKey"/> for a /// related symbol (i.e. the containing namespace of a namespace) we should call /// <see cref="GetOrCreate"/>. The benefit of this is twofold. First of all, it keeps the size of the /// <see cref="SymbolKey"/> small by allowing up to reuse parts we've already created. For example, if we /// have the <see cref="SymbolKey"/> for <c>Foo(int, int)</c>, then we will reuse the <see cref="SymbolKey"/>s for both <c>int</c>s. /// Second, this allows us to deal with the recursive nature of MethodSymbols and /// TypeParameterSymbols. Specifically, a MethodSymbol is defined by its signature. However, /// it's signature may refer to type parameters of that method. Unfortunately, the type /// parameters depend on their containing method. /// </para> /// <para> /// For example, if there is <c><![CDATA[Foo<T>(T t)]]></c>, then we must avoid the situation where we: /// <list type="number"> /// <item>try to get the symbol ID for the type parameter <c>T</c>, which in turn</item> /// <item>tries to get the symbol ID for the method <c>T</c>, which in turn</item> /// <item>tries to get the symbol IDs for the parameter types, which in turn</item> /// <item>tries to get the symbol ID for the type parameter <c>T</c>, which leads back to 1 and infinitely loops.</item> /// </list> /// </para> /// <para> /// In order to break this circularity we do not create the SymbolIDs for a method's type /// parameters directly in the visitor. Instead, we create the SymbolID for the method /// itself. When the MethodSymbolId is created it will directly instantiate the SymbolIDs /// for the type parameters, and directly assign the type parameter's method ID to itself. /// It will also then directly store the mapping from the type parameter to its SymbolID in /// the visitor cache. Then when we try to create the symbol IDs for the parameter types, /// any reference to the type parameters can be found in the cache. /// </para> /// <para> /// It is for this reason that it is essential that all calls to get related symbol IDs goes /// through GetOrCreate and not Create. /// </para> /// </summary> internal static SymbolKey Create(ISymbol symbol, Compilation compilation = null, CancellationToken cancellationToken = default(CancellationToken)) { return(GetOrCreate(symbol, new Visitor(compilation, cancellationToken))); }
private static bool Equals(Compilation compilation, string name1, string name2) { return(Equals(compilation.IsCaseSensitive, name1, name2)); }
private Compilation UpdateCompilationWithNewReferencesAndRecordAssemblySymbols(Compilation compilation, List <MetadataReference> newReferences, Dictionary <MetadataReference, ProjectId> metadataReferenceToProjectId) { if (!Enumerable.SequenceEqual(compilation.ExternalReferences, newReferences)) { compilation = compilation.WithReferences(newReferences); } // TODO: Record source assembly to project mapping // RecordSourceOfAssemblySymbol(compilation.Assembly, this.ProjectState.Id); foreach (var kvp in metadataReferenceToProjectId) { var metadataReference = kvp.Key; var projectId = kvp.Value; var symbol = compilation.GetAssemblyOrModuleSymbol(metadataReference); RecordSourceOfAssemblySymbol(symbol, projectId); } return(compilation); }
private async Task <CompilationInfo> FinalizeCompilationAsync( SolutionState solution, Compilation compilation, CancellationToken cancellationToken) { try { // if HasAllInformation is false, then this project is always not completed. var hasSuccessfullyLoaded = this.ProjectState.HasAllInformation; var newReferences = new List <MetadataReference>(); var metadataReferenceToProjectId = new Dictionary <MetadataReference, ProjectId>(); newReferences.AddRange(this.ProjectState.MetadataReferences); foreach (var projectReference in this.ProjectState.ProjectReferences) { var referencedProject = solution.GetProjectState(projectReference.ProjectId); // Even though we're creating a final compilation (vs. an in progress compilation), // it's possible that the target project has been removed. if (referencedProject != null) { // If both projects are submissions, we'll count this as a previous submission link // instead of a regular metadata reference if (referencedProject.IsSubmission) { // if the referenced project is a submission project must be a submission as well: Debug.Assert(this.ProjectState.IsSubmission); var previousSubmissionCompilation = await solution.GetCompilationAsync(projectReference.ProjectId, cancellationToken).ConfigureAwait(false); compilation = compilation.WithScriptCompilationInfo( compilation.ScriptCompilationInfo !.WithPreviousScriptCompilation(previousSubmissionCompilation !)); } else { var metadataReference = await solution.GetMetadataReferenceAsync( projectReference, this.ProjectState, cancellationToken).ConfigureAwait(false); // A reference can fail to be created if a skeleton assembly could not be constructed. if (metadataReference != null) { newReferences.Add(metadataReference); metadataReferenceToProjectId.Add(metadataReference, projectReference.ProjectId); } else { hasSuccessfullyLoaded = false; } } } } compilation = UpdateCompilationWithNewReferencesAndRecordAssemblySymbols(compilation, newReferences, metadataReferenceToProjectId); this.WriteState(new FinalState(State.CreateValueSource(compilation, solution.Services), compilation, hasSuccessfullyLoaded), solution); return(new CompilationInfo(compilation, hasSuccessfullyLoaded)); } catch (Exception e) when(FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
public CompilationInfo(Compilation compilation, bool hasSuccessfullyLoaded) { this.Compilation = compilation; this.HasSuccessfullyLoaded = hasSuccessfullyLoaded; }
public static Compilation GetCompilation(Solution solutionWithOptions, ProjectId projectId) { // Compilation is representation of single invocation of compiler Microsoft.CodeAnalysis.Compilation compilation = solutionWithOptions.GetProject(projectId).GetCompilationAsync().Result; return(compilation); }
public static SymbolKeyResolution ResolveString( string symbolKey, Compilation compilation, bool ignoreAssemblyKey = false, CancellationToken cancellationToken = default) { return(ResolveString(symbolKey, compilation, ignoreAssemblyKey, out _, cancellationToken)); }
/// <summary> /// Tries to get the cached <see cref="Compilation"/> for this project if it has already been created and is still cached. In almost all /// cases you should call <see cref="GetCompilationAsync"/> which will either return the cached <see cref="Compilation"/> /// or create a new one otherwise. /// </summary> public bool TryGetCompilation(out Compilation compilation) { return(_solution.State.TryGetCompilation(this.Id, out compilation)); }
private IEnumerable <INamedTypeSymbol> ResolveErrorTypeWithContainer(Compilation compilation, bool ignoreAssemblyKey) { var containerInfo = _containerKey.Resolve(compilation, ignoreAssemblyKey); return(GetAllSymbols <INamespaceOrTypeSymbol>(containerInfo).Select(s => Resolve(compilation, s))); }
public static SymbolKeyResolution ResolveString( string symbolKey, Compilation compilation, out string?failureReason, CancellationToken cancellationToken) { return(ResolveString(symbolKey, compilation, ignoreAssemblyKey: false, out failureReason, cancellationToken)); }
private INamedTypeSymbol Resolve(Compilation compilation, INamespaceOrTypeSymbol container) { return(CreateErrorTypeSymbol(compilation, container, _name, _arity)); }
private static GeneratorDriver CreateDriver(Microsoft.CodeAnalysis.Compilation compilation, params ISourceGenerator[] generators) => CSharpGeneratorDriver.Create( generators: ImmutableArray.Create(generators), additionalTexts: ImmutableArray <AdditionalText> .Empty, parseOptions: (CSharpParseOptions)compilation.SyntaxTrees.First().Options, optionsProvider: null);
private INamedTypeSymbol CreateErrorTypeSymbol( Compilation compilation, INamespaceOrTypeSymbol container, string name, int arity) { return(compilation.CreateErrorTypeSymbol(container, name, arity)); }
private IEnumerable <INamedTypeSymbol> ResolveErrorTypesWorker(Compilation compilation, bool ignoreAssemblyKey) { return(_containerKey == null ? SpecializedCollections.EmptyEnumerable <INamedTypeSymbol>() : ResolveErrorTypeWithContainer(compilation, ignoreAssemblyKey)); }
internal static bool TryGetCompilationForMetadataReference(ProjectState projectState, out Compilation referenceCompilation) { referenceCompilation = null; WeakReference <Compilation> weakReference; return(s_compilationReferenceMap.TryGetValue(projectState, out weakReference) && weakReference.TryGetTarget(out referenceCompilation)); }