Esempio n. 1
0
        public CompilationContext CompileProject(
            CompilationProjectContext projectContext,
            IEnumerable<IMetadataReference> incomingReferences,
            IEnumerable<ISourceReference> incomingSourceReferences,
            Func<IList<ResourceDescriptor>> resourcesResolver,
            string configuration)
        {
            var path = projectContext.ProjectDirectory;
            var name = projectContext.Target.Name;

            var isMainAspect = string.IsNullOrEmpty(projectContext.Target.Aspect);
            var isPreprocessAspect = string.Equals(projectContext.Target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase);

            if (!string.IsNullOrEmpty(projectContext.Target.Aspect))
            {
                name += "!" + projectContext.Target.Aspect;
            }

            if (_cacheContextAccessor.Current != null)
            {
                _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath));

                if (isMainAspect)
                {
                    // Monitor the trigger {projectName}_BuildOutputs
                    var buildOutputsName = projectContext.Target.Name + "_BuildOutputs";

                    _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
                }

                _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(projectContext.Target.Name + "_Dependencies"));
            }

            var exportedReferences = incomingReferences
                .Select(reference => reference.ConvertMetadataReference(_assemblyMetadataFactory));

            Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name);
            var sw = Stopwatch.StartNew();

            var compilationSettings = projectContext.CompilerOptions.ToCompilationSettings(
                projectContext.Target.TargetFramework, projectContext.ProjectDirectory);

            var sourceFiles = Enumerable.Empty<string>();
            if (isMainAspect)
            {
                sourceFiles = projectContext.Files.SourceFiles;
            }
            else if (isPreprocessAspect)
            {
                sourceFiles = projectContext.Files.PreprocessSourceFiles;
            }

            var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion,
                                                      preprocessorSymbols: compilationSettings.Defines);

            var trees = GetSyntaxTrees(
                projectContext,
                sourceFiles,
                incomingSourceReferences,
                parseOptions,
                isMainAspect);

            var references = new List<MetadataReference>();
            references.AddRange(exportedReferences);

            if (isPreprocessAspect)
            {
                compilationSettings.CompilationOptions =
                    compilationSettings.CompilationOptions
                        .WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
                        .WithCryptoKeyFile(null)
                        .WithCryptoPublicKey(ImmutableArray<byte>.Empty)
                        .WithDelaySign(false);
            }

            var compilation = CSharpCompilation.Create(
                name,
                trees,
                references,
                compilationSettings.CompilationOptions);

            compilation = ApplyProjectInfo(compilation, projectContext, parseOptions);

            var compilationContext = new CompilationContext(
                compilation,
                projectContext,
                incomingReferences,
                resourcesResolver);

            ValidateSigningOptions(compilationContext);
            AddStrongNameProvider(compilationContext);

            if (isMainAspect && projectContext.Files.PreprocessSourceFiles.Any())
            {
                try
                {
                    var modules = GetCompileModules(projectContext.Target, configuration).Modules;

                    foreach (var m in modules)
                    {
                        compilationContext.Modules.Add(m);
                    }
                }
                catch (Exception ex) when (ex.InnerException is RoslynCompilationException)
                {
                    var compilationException = ex.InnerException as RoslynCompilationException;

                    // Add diagnostics from the precompile step
                    foreach (var diag in compilationException.Diagnostics)
                    {
                        compilationContext.Diagnostics.Add(diag);
                    }
                }
            }

            if (compilationContext.Modules.Count > 0)
            {
                var precompSw = Stopwatch.StartNew();
                foreach (var module in compilationContext.Modules)
                {
                    module.BeforeCompile(compilationContext.BeforeCompileContext);
                }

                precompSw.Stop();
                Logger.TraceInformation("[{0}]: Compile modules ran in in {1}ms", GetType().Name, precompSw.ElapsedMilliseconds);
            }

            sw.Stop();
            Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds);

            return compilationContext;
        }
Esempio n. 2
0
        private void ValidateSigningOptions(CompilationContext compilationContext)
        {
            var compilerOptions = compilationContext.Project.CompilerOptions;
            if (compilerOptions.UseOssSigning == false)
            {
#if DNX451
                if (!RuntimeEnvironmentHelper.IsMono)
                {
                    return;
                }
#endif
                compilationContext.Diagnostics.Add(
                    Diagnostic.Create(RoslynDiagnostics.RealSigningSupportedOnlyOnDesktopClr, null));
            }
        }
Esempio n. 3
0
        private void AddStrongNameProvider(CompilationContext compilationContext)
        {
            if (!string.IsNullOrEmpty(compilationContext.Compilation.Options.CryptoKeyFile))
            {
                var strongNameProvider =
                    new DesktopStrongNameProvider(ImmutableArray.Create(compilationContext.Project.ProjectDirectory));

                compilationContext.Compilation =
                    compilationContext.Compilation.WithOptions(
                        compilationContext.Compilation.Options.WithStrongNameProvider(strongNameProvider));
            }
        }
Esempio n. 4
0
 public RoslynProjectReference(CompilationContext compilationContext)
 {
     CompilationContext = compilationContext;
     MetadataReference = compilationContext.Compilation.ToMetadataReference(embedInteropTypes: compilationContext.Project.EmbedInteropTypes);
     Name = compilationContext.Project.Target.Name;
 }
Esempio n. 5
0
        private void ValidateSigningOptions(CompilationContext compilationContext)
        {
            var compilerOptions = compilationContext.Project.CompilerOptions;
            if (compilerOptions.UseOssSigning == false)
            {
#if DNX451
                if (!RuntimeEnvironmentHelper.IsMono)
                {
                    return;
                }
#endif
                // Workaround for https://github.com/dotnet/roslyn/issues/6326
                compilationContext.Diagnostics.Add(
                    Diagnostic.Create(id: "DNX1001",
                        title: "Strong name generation with a private and public key pair is not supported on this platform",
                        message: "Strong name generation with a private and public key pair is supported only on desktop CLR. Falling back to OSS signing.",
                        category: "StrongNaming",
                        defaultSeverity: DiagnosticSeverity.Warning,
                        severity: DiagnosticSeverity.Warning,
                        warningLevel: 1,
                        isEnabledByDefault: true));
            }
        }
Esempio n. 6
0
        public CompilationContext CompileProject(
            CompilationProjectContext projectContext,
            IEnumerable<IMetadataReference> incomingReferences,
            IEnumerable<ISourceReference> incomingSourceReferences,
            Func<IList<ResourceDescriptor>> resourcesResolver)
        {
            var path = projectContext.ProjectDirectory;
            var name = projectContext.Target.Name.TrimStart('/');

            var isMainAspect = string.IsNullOrEmpty(projectContext.Target.Aspect);
            var isPreprocessAspect = string.Equals(projectContext.Target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase);

            if (!string.IsNullOrEmpty(projectContext.Target.Aspect)) {
                name += "!" + projectContext.Target.Aspect;
            }

            _watcher.WatchProject(path);

            _watcher.WatchFile(projectContext.ProjectFilePath);

            if (_cacheContextAccessor.Current != null) {
                _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath));

                if (isMainAspect) {
                    // Monitor the trigger {projectName}_BuildOutputs
                    var buildOutputsName = projectContext.Target.Name + "_BuildOutputs";

                    _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
                }

                _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(projectContext.Target.Name + "_Dependencies"));
            }

            var exportedReferences = incomingReferences.Select(ConvertMetadataReference);

            Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name);
            var sw = Stopwatch.StartNew();

            var compilationSettings = projectContext.CompilerOptions.ToCompilationSettings(
                projectContext.Target.TargetFramework);

            var sourceFiles = Enumerable.Empty<String>();
            if (isMainAspect) {
                sourceFiles = projectContext.Files.SourceFiles;
            }
            else if (isPreprocessAspect) {
                sourceFiles = projectContext.Files.PreprocessSourceFiles;
            }

            var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion,
                                                      preprocessorSymbols: compilationSettings.Defines);

            IList<SyntaxTree> trees = GetSyntaxTrees(
                projectContext,
                sourceFiles,
                incomingSourceReferences,
                parseOptions,
                isMainAspect);

            var embeddedReferences = incomingReferences.OfType<IMetadataEmbeddedReference>()
                                                       .ToDictionary(a => a.Name, ConvertMetadataReference);

            var references = new List<MetadataReference>();
            references.AddRange(exportedReferences);

            var compilation = CSharpCompilation.Create(
                name,
                trees,
                references,
                compilationSettings.CompilationOptions);

            compilation = ApplyVersionInfo(compilation, projectContext, parseOptions);

            var compilationContext = new CompilationContext(
                compilation,
                projectContext,
                incomingReferences,
                () => resourcesResolver()
                    .Select(res => new ResourceDescription(
                        res.Name,
                        res.StreamFactory,
                        isPublic: true))
                    .ToList());

            // Apply strong-name settings
            ApplyStrongNameSettings(compilationContext);

            if (isMainAspect && projectContext.Files.PreprocessSourceFiles.Any()) {
                try {
                    var modules = GetCompileModules(projectContext.Target).Modules;

                    foreach (var m in modules) {
                        compilationContext.Modules.Add(m);
                    }
                }
                catch (Exception ex) {
                    var compilationException = ex.InnerException as RoslynCompilationException;

                    if (compilationException != null) {
                        // Add diagnostics from the precompile step
                        foreach (var diag in compilationException.Diagnostics) {
                            compilationContext.Diagnostics.Add(diag);
                        }

                        Logger.TraceError("[{0}]: Failed loading meta assembly '{1}'", GetType().Name, name);
                    }
                    else {
                        Logger.TraceError("[{0}]: Failed loading meta assembly '{1}':\n {2}", GetType().Name, name, ex);
                    }
                }
            }

            if (compilationContext.Modules.Count > 0) {
                var precompSw = Stopwatch.StartNew();
                foreach (var module in compilationContext.Modules) {
                    module.BeforeCompile(compilationContext.BeforeCompileContext);
                }

                precompSw.Stop();
                Logger.TraceInformation("[{0}]: Compile modules ran in in {1}ms", GetType().Name, precompSw.ElapsedMilliseconds);
            }

            sw.Stop();
            Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds);

            return compilationContext;
        }
Esempio n. 7
0
        private void ApplyStrongNameSettings(CompilationContext compilationContext)
        {
            var keyFile =
                System.Environment.GetEnvironmentVariable(EnvironmentNames.BuildKeyFile) ??
                compilationContext.Compilation.Options.CryptoKeyFile;

            if (!string.IsNullOrEmpty(keyFile) && !RuntimeEnvironmentHelper.IsMono) {
            #if DNX451
                var delaySignString = System.Environment.GetEnvironmentVariable(EnvironmentNames.BuildDelaySign);
                var delaySign =
                    delaySignString == null
                        ? compilationContext.Compilation.Options.DelaySign
                        : string.Equals(delaySignString, "true", StringComparison.OrdinalIgnoreCase) ||
                          string.Equals(delaySignString, "1", StringComparison.OrdinalIgnoreCase);

                var strongNameProvider = new DesktopStrongNameProvider(
                    ImmutableArray.Create(compilationContext.Project.ProjectDirectory));
                var newOptions = compilationContext.Compilation.Options
                    .WithStrongNameProvider(strongNameProvider)
                    .WithCryptoKeyFile(keyFile)
                    .WithDelaySign(delaySign);
                compilationContext.Compilation = compilationContext.Compilation.WithOptions(newOptions);
            #else
                var diag = Diagnostic.Create(
                    RoslynDiagnostics.StrongNamingNotSupported,
                    null);
                compilationContext.Diagnostics.Add(diag);
            #endif
            }

            // If both CryptoPublicKey and CryptoKeyFile compilation will fail so we don't need a check
            if (compilationContext.Compilation.Options.CryptoPublicKey != null) {
                var options = compilationContext.Compilation.Options
                    .WithCryptoPublicKey(compilationContext.Compilation.Options.CryptoPublicKey);
                compilationContext.Compilation = compilationContext.Compilation.WithOptions(options);
            }
        }
Esempio n. 8
0
        public CompilationContext CompileProject(
            CompilationProjectContext projectContext,
            IEnumerable <IMetadataReference> incomingReferences,
            IEnumerable <ISourceReference> incomingSourceReferences,
            Func <IList <ResourceDescriptor> > resourcesResolver,
            string configuration)
        {
            var path = projectContext.ProjectDirectory;
            var name = projectContext.Target.Name;

            var isMainAspect       = string.IsNullOrEmpty(projectContext.Target.Aspect);
            var isPreprocessAspect = string.Equals(projectContext.Target.Aspect, "preprocess", StringComparison.OrdinalIgnoreCase);

            if (!string.IsNullOrEmpty(projectContext.Target.Aspect))
            {
                name += "!" + projectContext.Target.Aspect;
            }

            if (_cacheContextAccessor.Current != null)
            {
                _cacheContextAccessor.Current.Monitor(new FileWriteTimeCacheDependency(projectContext.ProjectFilePath));

                if (isMainAspect)
                {
                    // Monitor the trigger {projectName}_BuildOutputs
                    var buildOutputsName = projectContext.Target.Name + "_BuildOutputs";

                    _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(buildOutputsName));
                }

                _cacheContextAccessor.Current.Monitor(_namedDependencyProvider.GetNamedDependency(projectContext.Target.Name + "_Dependencies"));
            }

            var exportedReferences = incomingReferences
                                     .Select(reference => reference.ConvertMetadataReference(_assemblyMetadataFactory));

            Logger.TraceInformation("[{0}]: Compiling '{1}'", GetType().Name, name);
            var sw = Stopwatch.StartNew();

            var compilationSettings = projectContext.CompilerOptions.ToCompilationSettings(
                projectContext.Target.TargetFramework, projectContext.ProjectDirectory);

            var sourceFiles = Enumerable.Empty <string>();

            if (isMainAspect)
            {
                sourceFiles = projectContext.Files.SourceFiles;
            }
            else if (isPreprocessAspect)
            {
                sourceFiles = projectContext.Files.PreprocessSourceFiles;
            }

            var parseOptions = new CSharpParseOptions(languageVersion: compilationSettings.LanguageVersion,
                                                      preprocessorSymbols: compilationSettings.Defines);

            var trees = GetSyntaxTrees(
                projectContext,
                sourceFiles,
                incomingSourceReferences,
                parseOptions,
                isMainAspect);

            var references = new List <MetadataReference>();

            references.AddRange(exportedReferences);

            if (isPreprocessAspect)
            {
                compilationSettings.CompilationOptions =
                    compilationSettings.CompilationOptions
                    .WithOutputKind(OutputKind.DynamicallyLinkedLibrary)
                    .WithCryptoKeyFile(null)
                    .WithCryptoPublicKey(ImmutableArray <byte> .Empty)
                    .WithDelaySign(false);
            }

            var compilation = CSharpCompilation.Create(
                name,
                trees,
                references,
                compilationSettings.CompilationOptions);

            compilation = ApplyProjectInfo(compilation, projectContext, parseOptions);

            var compilationContext = new CompilationContext(
                compilation,
                projectContext,
                incomingReferences,
                resourcesResolver);

            ValidateSigningOptions(compilationContext);
            AddStrongNameProvider(compilationContext);

            if (isMainAspect && projectContext.Files.PreprocessSourceFiles.Any())
            {
                try
                {
                    var modules = GetCompileModules(projectContext.Target, configuration).Modules;

                    foreach (var m in modules)
                    {
                        compilationContext.Modules.Add(m);
                    }
                }
                catch (Exception ex) when(ex.InnerException is RoslynCompilationException)
                {
                    var compilationException = ex.InnerException as RoslynCompilationException;

                    // Add diagnostics from the precompile step
                    foreach (var diag in compilationException.Diagnostics)
                    {
                        compilationContext.Diagnostics.Add(diag);
                    }
                }
            }

            if (compilationContext.Modules.Count > 0)
            {
                var precompSw = Stopwatch.StartNew();
                foreach (var module in compilationContext.Modules)
                {
                    module.BeforeCompile(compilationContext.BeforeCompileContext);
                }

                precompSw.Stop();
                Logger.TraceInformation("[{0}]: Compile modules ran in in {1}ms", GetType().Name, precompSw.ElapsedMilliseconds);
            }

            sw.Stop();
            Logger.TraceInformation("[{0}]: Compiled '{1}' in {2}ms", GetType().Name, name, sw.ElapsedMilliseconds);

            return(compilationContext);
        }