1- using System ;
1+ using System ;
22using System . Collections . Generic ;
33using System . IO ;
44using System . Text ;
5- using System . Linq ;
65using Semmle . Util ;
76using Semmle . Util . Logging ;
87
98namespace Semmle . Extraction . CSharp . DependencyFetching
109{
11- internal class Razor
10+ internal abstract class DotnetSourceGeneratorWrapper
1211 {
13- private readonly DotNetVersion sdk ;
14- private readonly ILogger logger ;
15- private readonly IDotNet dotNet ;
16- private readonly string sourceGeneratorFolder ;
17- private readonly string cscPath ;
12+ protected readonly ILogger logger ;
13+ private readonly Sdk sdk ;
14+ protected readonly IDotNet dotnet ;
1815
19- public Razor ( DotNetVersion sdk , IDotNet dotNet , ILogger logger )
16+ protected abstract string SourceGeneratorFolder { get ; init ; }
17+ protected abstract string FileType { get ; }
18+
19+ public DotnetSourceGeneratorWrapper (
20+ Sdk sdk ,
21+ IDotNet dotnet ,
22+ ILogger logger )
2023 {
21- this . sdk = sdk ;
2224 this . logger = logger ;
23- this . dotNet = dotNet ;
24-
25- sourceGeneratorFolder = Path . Combine ( this . sdk . FullPath , "Sdks" , "Microsoft.NET.Sdk.Razor" , "source-generators" ) ;
26- this . logger . LogInfo ( $ "Razor source generator folder: { sourceGeneratorFolder } ") ;
27- if ( ! Directory . Exists ( sourceGeneratorFolder ) )
28- {
29- this . logger . LogInfo ( $ "Razor source generator folder { sourceGeneratorFolder } does not exist.") ;
30- throw new Exception ( $ "Razor source generator folder { sourceGeneratorFolder } does not exist.") ;
31- }
32-
33- cscPath = Path . Combine ( this . sdk . FullPath , "Roslyn" , "bincore" , "csc.dll" ) ;
34- this . logger . LogInfo ( $ "Razor source generator CSC: { cscPath } ") ;
35- if ( ! File . Exists ( cscPath ) )
36- {
37- this . logger . LogInfo ( $ "Csc.exe not found at { cscPath } .") ;
38- throw new Exception ( $ "csc.dll { cscPath } does not exist.") ;
39- }
25+ this . sdk = sdk ;
26+ this . dotnet = dotnet ;
4027 }
4128
42- private static void GenerateAnalyzerConfig ( IEnumerable < string > cshtmls , string analyzerConfigPath )
43- {
44- using var sw = new StreamWriter ( analyzerConfigPath ) ;
45- sw . WriteLine ( "is_global = true" ) ;
29+ protected abstract void GenerateAnalyzerConfig ( IEnumerable < string > additionalFiles , string analyzerConfigPath ) ;
4630
47- foreach ( var f in cshtmls . Select ( f => f . Replace ( '\\ ' , '/' ) ) )
31+ public IEnumerable < string > RunSourceGenerator ( IEnumerable < string > additionalFiles , IEnumerable < string > references , string targetDir )
32+ {
33+ if ( sdk . CscPath is null )
4834 {
49- sw . WriteLine ( $ "\n [{ f } ]") ;
50- var base64 = Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( f ) ) ; // TODO: this should be the relative path of the file.
51- sw . WriteLine ( $ "build_metadata.AdditionalFiles.TargetPath = { base64 } ") ;
35+ logger . LogWarning ( "Not running source generator because csc path is not available." ) ;
36+ return [ ] ;
5237 }
53- }
5438
55- public IEnumerable < string > GenerateFiles ( IEnumerable < string > cshtmls , IEnumerable < string > references , string workingDirectory )
56- {
5739 var name = Guid . NewGuid ( ) . ToString ( "N" ) . ToUpper ( ) ;
5840 var tempPath = FileUtils . GetTemporaryWorkingDirectory ( out var shouldCleanUp ) ;
5941 var analyzerConfig = Path . Combine ( tempPath , $ "{ name } .txt") ;
6042 var dllPath = Path . Combine ( tempPath , $ "{ name } .dll") ;
6143 var cscArgsPath = Path . Combine ( tempPath , $ "{ name } .rsp") ;
62- var outputFolder = Path . Combine ( workingDirectory , name ) ;
44+ var outputFolder = Path . Combine ( targetDir , name ) ;
6345 Directory . CreateDirectory ( outputFolder ) ;
6446
6547 try
6648 {
6749 logger . LogInfo ( "Produce analyzer config content." ) ;
68- GenerateAnalyzerConfig ( cshtmls , analyzerConfig ) ;
50+ GenerateAnalyzerConfig ( additionalFiles , analyzerConfig ) ;
6951
7052 logger . LogDebug ( $ "Analyzer config content: { File . ReadAllText ( analyzerConfig ) } ") ;
7153
7254 var args = new StringBuilder ( ) ;
7355 args . Append ( $ "/target:exe /generatedfilesout:\" { outputFolder } \" /out:\" { dllPath } \" /analyzerconfig:\" { analyzerConfig } \" ") ;
7456
75- foreach ( var f in Directory . GetFiles ( sourceGeneratorFolder , "*.dll" , new EnumerationOptions { RecurseSubdirectories = false , MatchCasing = MatchCasing . CaseInsensitive } ) )
57+ foreach ( var f in Directory . GetFiles ( SourceGeneratorFolder , "*.dll" , new EnumerationOptions { RecurseSubdirectories = false , MatchCasing = MatchCasing . CaseInsensitive } ) )
7658 {
7759 args . Append ( $ "/analyzer:\" { f } \" ") ;
7860 }
7961
80- foreach ( var f in cshtmls )
62+ foreach ( var f in additionalFiles )
8163 {
8264 args . Append ( $ "/additionalfile:\" { f } \" ") ;
8365 }
@@ -89,19 +71,19 @@ public IEnumerable<string> GenerateFiles(IEnumerable<string> cshtmls, IEnumerabl
8971
9072 var argsString = args . ToString ( ) ;
9173
92- logger . LogInfo ( $ "Running CSC to generate Razor source files.") ;
93- logger . LogDebug ( $ "Running CSC to generate Razor source files with arguments: { argsString } .") ;
74+ logger . LogInfo ( $ "Running CSC to generate source files from { FileType } files.") ;
75+ logger . LogDebug ( $ "Running CSC to generate source files from { FileType } files with arguments: { argsString } .") ;
9476
9577 using ( var sw = new StreamWriter ( cscArgsPath ) )
9678 {
9779 sw . Write ( argsString ) ;
9880 }
9981
100- dotNet . Exec ( $ "\" { cscPath } \" /noconfig @\" { cscArgsPath } \" ") ;
82+ dotnet . Exec ( $ "\" { sdk . CscPath } \" /noconfig @\" { cscArgsPath } \" ") ;
10183
10284 var files = Directory . GetFiles ( outputFolder , "*.*" , new EnumerationOptions { RecurseSubdirectories = true } ) ;
10385
104- logger . LogInfo ( $ "Generated { files . Length } source files from cshtml files.") ;
86+ logger . LogInfo ( $ "Generated { files . Length } source files from { FileType } files.") ;
10587
10688 return files ;
10789 }
0 commit comments