示例#1
0
        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");
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        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>());
        }
示例#5
0
        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()
            });
        }
示例#6
0
        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;
 }
示例#9
0
        // 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);
        }
示例#10
0
        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));
            }
        }
示例#11
0
            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();
            }
示例#12
0
 public DocumentationUtil(Microsoft.CodeAnalysis.Compilation compilation)
 {
     this.compilation = compilation;
 }
示例#13
0
 /// <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);
 }
示例#14
0
 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));
            }
示例#16
0
 /// <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)));
 }
示例#17
0
 private static bool Equals(Compilation compilation, string name1, string name2)
 {
     return(Equals(compilation.IsCaseSensitive, name1, name2));
 }
示例#18
0
            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);
            }
示例#19
0
            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;
                }
            }
示例#20
0
 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);
 }
示例#22
0
 public static SymbolKeyResolution ResolveString(
     string symbolKey, Compilation compilation,
     bool ignoreAssemblyKey = false, CancellationToken cancellationToken = default)
 {
     return(ResolveString(symbolKey, compilation, ignoreAssemblyKey, out _, cancellationToken));
 }
示例#23
0
 /// <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)));
            }
示例#25
0
 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));
 }
示例#27
0
 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));
 }
示例#30
0
        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));
        }