|
21 | 21 | using System.IO; |
22 | 22 | using System.Linq; |
23 | 23 | using System.Xml.Linq; |
24 | | -using Akka.Util.Internal; |
25 | 24 | using BigInteger = System.Numerics.BigInteger; |
26 | 25 |
|
27 | 26 | namespace Neo.Compiler |
@@ -60,13 +59,44 @@ public List<CompilationContext> Compile(IEnumerable<string> sourceFiles, IEnumer |
60 | 59 | return CompileProjectContracts(Compilation); |
61 | 60 | } |
62 | 61 |
|
63 | | - public List<CompilationContext> CompileSources(string[] sourceFiles) |
| 62 | + public List<CompilationContext> CompileSources(params string[] sourceFiles) |
64 | 63 | { |
65 | | - List<MetadataReference> references = new(CommonReferences) |
66 | | - { |
67 | | - MetadataReference.CreateFromFile(typeof(scfx.Neo.SmartContract.Framework.SmartContract).Assembly.Location) |
68 | | - }; |
69 | | - return Compile(sourceFiles, references); |
| 64 | + // Generate a dummy csproj |
| 65 | + |
| 66 | + var version = typeof(scfx.Neo.SmartContract.Framework.SmartContract).Assembly.GetName().Version!.ToString(); |
| 67 | + var csproj = $@" |
| 68 | +<Project Sdk=""Microsoft.NET.Sdk""> |
| 69 | +
|
| 70 | + <PropertyGroup> |
| 71 | + <TargetFramework>{AppContext.TargetFrameworkName!}</TargetFramework> |
| 72 | + <ImplicitUsings>enable</ImplicitUsings> |
| 73 | + <Nullable>enable</Nullable> |
| 74 | + </PropertyGroup> |
| 75 | +
|
| 76 | + <!-- Remove all Compile items from compilation --> |
| 77 | + <ItemGroup> |
| 78 | + <Compile Remove=""*.cs"" /> |
| 79 | + </ItemGroup> |
| 80 | +
|
| 81 | + <!-- Add specific files for compilation --> |
| 82 | + <ItemGroup> |
| 83 | + {string.Join(Environment.NewLine, sourceFiles.Select(u => $"<Compile Include=\"{Path.GetFullPath(u)}\" />"))} |
| 84 | + </ItemGroup> |
| 85 | +
|
| 86 | + <ItemGroup> |
| 87 | + <PackageReference Include=""Neo.SmartContract.Framework"" Version=""{version}"" /> |
| 88 | + </ItemGroup> |
| 89 | +
|
| 90 | +</Project>"; |
| 91 | + |
| 92 | + // Write and compile |
| 93 | + |
| 94 | + var path = Path.GetTempFileName(); |
| 95 | + File.WriteAllText(path, csproj); |
| 96 | + |
| 97 | + try { return CompileProject(path); } |
| 98 | + catch { throw; } |
| 99 | + finally { File.Delete(path); } |
70 | 100 | } |
71 | 101 |
|
72 | 102 | public List<CompilationContext> CompileProject(string csproj) |
@@ -176,26 +206,34 @@ static bool IsDerivedFromSmartContract(INamedTypeSymbol classSymbol, string smar |
176 | 206 |
|
177 | 207 | public Compilation GetCompilation(string csproj) |
178 | 208 | { |
| 209 | + // Restore project |
| 210 | + |
179 | 211 | string folder = Path.GetDirectoryName(csproj)!; |
180 | | - string obj = Path.Combine(folder, "obj"); |
181 | | - string binSc = Path.Combine(Path.Combine(folder, "bin"), "sc"); |
182 | | - HashSet<string> sourceFiles = Directory.EnumerateFiles(folder, "*.cs", SearchOption.AllDirectories) |
183 | | - .Where(p => !p.StartsWith(obj) && !p.StartsWith(binSc)) |
184 | | - .GroupBy(Path.GetFileName) |
185 | | - .Select(g => g.First()) |
186 | | - .ToHashSet(StringComparer.OrdinalIgnoreCase); |
187 | | - List<MetadataReference> references = new(CommonReferences); |
188 | | - CSharpCompilationOptions compilationOptions = new(OutputKind.DynamicallyLinkedLibrary, deterministic: true, nullableContextOptions: Options.Nullable); |
189 | | - XDocument document = XDocument.Load(csproj); |
190 | | - sourceFiles.UnionWith(document.Root!.Elements("ItemGroup").Elements("Compile").Attributes("Include").Select(p => Path.GetFullPath(p.Value, folder))); |
191 | 212 | Process.Start(new ProcessStartInfo |
192 | 213 | { |
193 | 214 | FileName = "dotnet", |
194 | 215 | Arguments = $"restore \"{csproj}\"", |
195 | 216 | WorkingDirectory = folder |
196 | 217 | })!.WaitForExit(); |
197 | | - string assetsPath = Path.Combine(folder, "obj", "project.assets.json"); |
198 | | - JObject assets = (JObject)JToken.Parse(File.ReadAllBytes(assetsPath))!; |
| 218 | + |
| 219 | + // Get sources |
| 220 | + |
| 221 | + XDocument document = XDocument.Load(csproj); |
| 222 | + var remove = document.Root!.Elements("ItemGroup").Elements("Compile").Attributes("Remove").Select(p => p.Value).ToArray(); |
| 223 | + var obj = Path.Combine(folder, "obj"); |
| 224 | + var binSc = Path.Combine(Path.Combine(folder, "bin"), "sc"); |
| 225 | + var sourceFiles = |
| 226 | + remove.Contains("*.cs") ? new HashSet<string>(StringComparer.OrdinalIgnoreCase) : |
| 227 | + Directory.EnumerateFiles(folder, "*.cs", SearchOption.AllDirectories) |
| 228 | + .Where(p => !p.StartsWith(obj) && !p.StartsWith(binSc)) |
| 229 | + .GroupBy(Path.GetFileName) |
| 230 | + .Select(g => g.First()) |
| 231 | + .ToHashSet(StringComparer.OrdinalIgnoreCase); |
| 232 | + sourceFiles.UnionWith(document.Root!.Elements("ItemGroup").Elements("Compile").Attributes("Include").Select(p => Path.GetFullPath(p.Value, folder))); |
| 233 | + var assetsPath = Path.Combine(folder, "obj", "project.assets.json"); |
| 234 | + var assets = (JObject)JToken.Parse(File.ReadAllBytes(assetsPath))!; |
| 235 | + List<MetadataReference> references = new(CommonReferences); |
| 236 | + CSharpCompilationOptions compilationOptions = new(OutputKind.DynamicallyLinkedLibrary, deterministic: true, nullableContextOptions: Options.Nullable); |
199 | 237 | foreach (var (name, package) in ((JObject)assets["targets"]![0]!).Properties) |
200 | 238 | { |
201 | 239 | MetadataReference? reference = GetReference(name, (JObject)package!, assets, folder, Options, compilationOptions); |
|
0 commit comments