Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestEngine: Template testing optimization #956

Merged
merged 32 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0e31b51
Ensure compilation
shargon Feb 26, 2024
d2b89e5
Merge branch 'master' into core-avoid-msbuild-compile
shargon Feb 26, 2024
637aa44
Update src/Neo.SmartContract.Testing/Coverage/Formats/ConsoleFormat.cs
shargon Feb 26, 2024
8ebaea8
TODO
shargon Feb 26, 2024
a2142bd
Move namespace
shargon Feb 26, 2024
10f54a9
LF
shargon Feb 26, 2024
505b7e2
LF
shargon Feb 26, 2024
1334f9f
LF
shargon Feb 26, 2024
05c9d4e
Merge branch 'master' into core-avoid-msbuild-compile
shargon Feb 26, 2024
619eaa9
Fix remove
shargon Feb 26, 2024
8560cac
indent comment
shargon Feb 26, 2024
c5f584c
Change artifact name
shargon Feb 26, 2024
f9546aa
Split options
shargon Feb 26, 2024
6c6f0eb
Fix Context result
shargon Feb 26, 2024
5eb6656
Clean debugInfo from artifacts
shargon Feb 26, 2024
a37fb3d
Merge branch 'master' into core-avoid-msbuild-compile
Jim8y Feb 26, 2024
d39813b
Fix compilation
shargon Feb 26, 2024
1a11b86
Merge branch 'core-avoid-msbuild-compile' of https://github.com/neo-p…
shargon Feb 26, 2024
ba7b375
Cleanup
shargon Feb 26, 2024
2f510bc
format
shargon Feb 26, 2024
9dd861a
remove artifacts
shargon Feb 26, 2024
e6c87ee
fix nep17 template
shargon Feb 26, 2024
5db5882
Fix type
shargon Feb 26, 2024
bf564dd
Rename artifacts
shargon Feb 26, 2024
02fc864
some fixes
shargon Feb 26, 2024
50a4f1d
Merge remote-tracking branch 'origin/master' into core-avoid-msbuild-…
shargon Feb 26, 2024
63b881d
Update .github/workflows/main.yml
shargon Feb 26, 2024
5b923eb
Clean
shargon Feb 26, 2024
116746e
Allow old code
shargon Feb 26, 2024
3204169
Fix old ECPoint
shargon Feb 26, 2024
6e8e257
Jimmy's feedback
shargon Feb 26, 2024
95a4ca0
Fix
shargon Feb 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
dotnet format --no-restore --verify-no-changes --verbosity diagnostic
- name: Build Neo.Compiler.CSharp
run: dotnet build ./src/Neo.Compiler.CSharp/Neo.Compiler.CSharp.csproj
- name: Build Neo.SmartContract.Template and generate artifacts
- name: Build Neo.SmartContract.Template and test templates
run: |
dotnet pack ./src/Neo.SmartContract.Template/Neo.SmartContract.Template.csproj
dotnet new install ./src/Neo.SmartContract.Template/bin/Debug/Neo.SmartContract.Template.*.nupkg
Expand All @@ -41,9 +41,9 @@ jobs:
dotnet add ./src/Neo.SmartContract.Template/bin/Debug/ownable/Ownable.csproj reference ./src/Neo.SmartContract.Framework/Neo.SmartContract.Framework.csproj
dotnet remove ./src/Neo.SmartContract.Template/bin/Debug/oracle/OracleRequest.csproj package Neo.SmartContract.Framework
dotnet add ./src/Neo.SmartContract.Template/bin/Debug/oracle/OracleRequest.csproj reference ./src/Neo.SmartContract.Framework/Neo.SmartContract.Framework.csproj
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/nep17/Nep17Contract.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Artifacts/ --generate-artifacts source --debug
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/ownable/Ownable.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractowner/Artifacts/ --generate-artifacts source --debug
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/oracle/OracleRequest.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractoracle/Artifacts/ --generate-artifacts source --debug
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/nep17/Nep17Contract.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Artifacts/
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/ownable/Ownable.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractowner/Artifacts/
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/oracle/OracleRequest.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractoracle/Artifacts/
- name: Build Solution
run: dotnet build ./neo-devpack-dotnet.sln
- name: Add package coverlet.msbuild
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.Compiler.CSharp/CompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class CompilationContext
{
private readonly CompilationEngine _engine;
readonly INamedTypeSymbol _targetContract;
internal Options Options => _engine.Options;
internal CompilationOptions Options => _engine.Options;
private string? _displayName, _className;
private readonly List<Diagnostic> _diagnostics = new();
private readonly HashSet<string> _supportedStandards = new();
Expand Down
79 changes: 50 additions & 29 deletions src/Neo.Compiler.CSharp/CompilationEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ namespace Neo.Compiler
public class CompilationEngine
{
internal Compilation? Compilation;
internal Options Options { get; private set; }
internal CompilationOptions Options { get; private set; }
private static readonly MetadataReference[] CommonReferences;
private static readonly Dictionary<string, MetadataReference> MetaReferences = new();
internal readonly Dictionary<INamedTypeSymbol, CompilationContext> Contexts = new(SymbolEqualityComparer.Default);
Expand All @@ -46,7 +46,7 @@ static CompilationEngine()
};
}

public CompilationEngine(Options options)
public CompilationEngine(CompilationOptions options)
{
Options = options;
}
Expand All @@ -59,11 +59,24 @@ public List<CompilationContext> Compile(IEnumerable<string> sourceFiles, IEnumer
return CompileProjectContracts(Compilation);
}

public List<CompilationContext> CompileSources(params string[] sourceFiles)
public List<CompilationContext> CompileSources(params string[] sourceFiles) => CompileSources(null, sourceFiles);

public List<CompilationContext> CompileSources((string packageName, string packageVersion) package, params string[] sourceFiles)
{
return CompileSources(new[] { package }, sourceFiles);
}

public List<CompilationContext> CompileSources(IEnumerable<(string packageName, string packageVersion)>? packages = null, params string[] sourceFiles)
{
// Generate a dummy csproj

var version = typeof(scfx.Neo.SmartContract.Framework.SmartContract).Assembly.GetName().Version!.ToString();
var packageGroup = packages is null ? "" :
$@"
<ItemGroup>
{(packages is null ? "" : string.Join(Environment.NewLine, packages.Select(u => $" <PackageReference Include =\"{u.packageName}\" Version=\"{u.packageVersion}\" />")))}
</ItemGroup>
";

var csproj = $@"
<Project Sdk=""Microsoft.NET.Sdk"">

Expand All @@ -83,9 +96,7 @@ public List<CompilationContext> CompileSources(params string[] sourceFiles)
{string.Join(Environment.NewLine, sourceFiles.Select(u => $"<Compile Include=\"{Path.GetFullPath(u)}\" />"))}
</ItemGroup>

<ItemGroup>
<PackageReference Include=""Neo.SmartContract.Framework"" Version=""{version}"" />
</ItemGroup>
{packageGroup}

</Project>";

Expand All @@ -94,7 +105,10 @@ public List<CompilationContext> CompileSources(params string[] sourceFiles)
var path = Path.GetTempFileName();
File.WriteAllText(path, csproj);

try { return CompileProject(path); }
try
{
return CompileProject(path);
}
catch { throw; }
finally { File.Delete(path); }
}
Expand Down Expand Up @@ -138,14 +152,13 @@ private List<CompilationContext> CompileProjectContracts(Compilation compilation
if (classDependencies.Count == 0) throw new FormatException("No valid neo SmartContract found. Please make sure your contract is subclass of SmartContract and is not abstract.");
// Check contract dependencies, make sure there is no cycle in the dependency graph
var sortedClasses = TopologicalSort(classDependencies);

sortedClasses.ForEach(c =>
{
var context = new CompilationContext(this, c);
context.Compile();
// Process the target contract add this compilation context
this.Contexts.Add(c, context);
});
{
var context = new CompilationContext(this, c);
context.Compile();
// Process the target contract add this compilation context
Contexts.Add(c, context);
});

return Contexts.Select(p => p.Value).ToList();
}
Expand Down Expand Up @@ -216,38 +229,46 @@ public Compilation GetCompilation(string csproj)
Process.Start(new ProcessStartInfo
{
FileName = "dotnet",
Arguments = $"restore \"{csproj}\"",
Arguments = $"restore \"{csproj}\" --source \"https://www.myget.org/F/neo/api/v3/index.json\"",
WorkingDirectory = folder
})!.WaitForExit();

// Get sources
// Parse csproj

XDocument document = XDocument.Load(csproj);
var remove = document.Root!.Elements("ItemGroup").Elements("Compile").Attributes("Remove").Select(p => p.Value).ToArray();
var obj = Path.Combine(folder, "obj");
var binSc = Path.Combine(Path.Combine(folder, "bin"), "sc");
var sourceFiles =
remove.Contains("*.cs") ? new HashSet<string>(StringComparer.OrdinalIgnoreCase) :
Directory.EnumerateFiles(folder, "*.cs", SearchOption.AllDirectories)
.Where(p => !p.StartsWith(obj) && !p.StartsWith(binSc))
.GroupBy(Path.GetFileName)
.Select(g => g.First())
.ToHashSet(StringComparer.OrdinalIgnoreCase);
var remove = document.Root!.Elements("ItemGroup").Elements("Compile").Attributes("Remove")
.Select(p => p.Value.Contains("*") ? p.Value : Path.GetFullPath(p.Value)).ToArray();
var sourceFiles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

if (!remove.Contains("*.cs"))
{
var obj = Path.Combine(folder, "obj");
var binSc = Path.Combine(Path.Combine(folder, "bin"), "sc");
foreach (var entry in Directory.EnumerateFiles(folder, "*.cs", SearchOption.AllDirectories)
.Where(p => !p.StartsWith(obj) && !p.StartsWith(binSc))
.Select(u => u))
//.GroupBy(Path.GetFileName)
//.Select(g => g.First()))
{
if (!remove.Contains(entry)) sourceFiles.Add(entry);
}
}

sourceFiles.UnionWith(document.Root!.Elements("ItemGroup").Elements("Compile").Attributes("Include").Select(p => Path.GetFullPath(p.Value, folder)));
var assetsPath = Path.Combine(folder, "obj", "project.assets.json");
var assets = (JObject)JToken.Parse(File.ReadAllBytes(assetsPath))!;
List<MetadataReference> references = new(CommonReferences);
CSharpCompilationOptions compilationOptions = new(OutputKind.DynamicallyLinkedLibrary, deterministic: true, nullableContextOptions: Options.Nullable);
foreach (var (name, package) in ((JObject)assets["targets"]![0]!).Properties)
{
MetadataReference? reference = GetReference(name, (JObject)package!, assets, folder, Options, compilationOptions);
MetadataReference? reference = GetReference(name, (JObject)package!, assets, folder, compilationOptions);
if (reference is not null) references.Add(reference);
}
IEnumerable<SyntaxTree> syntaxTrees = sourceFiles.OrderBy(p => p).Select(p => CSharpSyntaxTree.ParseText(File.ReadAllText(p), options: Options.GetParseOptions(), path: p));
return CSharpCompilation.Create(assets["project"]!["restore"]!["projectName"]!.GetString(), syntaxTrees, references, compilationOptions);
}

private MetadataReference? GetReference(string name, JObject package, JObject assets, string folder, Options options, CSharpCompilationOptions compilationOptions)
private MetadataReference? GetReference(string name, JObject package, JObject assets, string folder, CSharpCompilationOptions compilationOptions)
{
string assemblyName = Path.GetDirectoryName(name)!;
if (!MetaReferences.TryGetValue(assemblyName, out var reference))
Expand Down
39 changes: 39 additions & 0 deletions src/Neo.Compiler.CSharp/CompilationOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (C) 2015-2023 The Neo Project.
//
// The Neo.Compiler.CSharp is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Generic;

namespace Neo.Compiler
{
public class CompilationOptions
{
public NullableContextOptions Nullable { get; set; }
public bool Debug { get; set; }
public bool NoOptimize { get; set; }
public bool Checked { get; set; }
public bool NoInline { get; set; }
public byte AddressVersion { get; set; }
public string? BaseName { get; set; }

private CSharpParseOptions? parseOptions = null;
public CSharpParseOptions GetParseOptions()
{
if (parseOptions is null)
{
List<string> preprocessorSymbols = new();
if (Debug) preprocessorSymbols.Add("DEBUG");
parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols);
}
return parseOptions;
}
}
}
9 changes: 6 additions & 3 deletions src/Neo.Compiler.CSharp/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ public static ContractParameterType GetContractParameterType(this ITypeSymbol ty
case "string": return ContractParameterType.String;
case "byte[]": return ContractParameterType.ByteArray;
case "object": return ContractParameterType.Any;
case "Neo.Cryptography.ECC.ECPoint": return ContractParameterType.PublicKey;
case "Neo.Cryptography.ECC.ECPoint": // Old Neo.SmartContract.Framework
case "Neo.SmartContract.Framework.ECPoint": return ContractParameterType.PublicKey;
case "Neo.SmartContract.Framework.ByteString": return ContractParameterType.ByteArray;
case "Neo.UInt160": return ContractParameterType.Hash160;
case "Neo.UInt256": return ContractParameterType.Hash256;
case "Neo.UInt160": // Old Neo.SmartContract.Framework
case "Neo.SmartContract.Framework.UInt160": return ContractParameterType.Hash160;
case "Neo.UInt256": // Old Neo.SmartContract.Framework
case "Neo.SmartContract.Framework.UInt256": return ContractParameterType.Hash256;
case "System.Numerics.BigInteger": return ContractParameterType.Integer;
}
if (type.Name == "Map") return ContractParameterType.Map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ private void ConvertObjectToString(SemanticModel model, ExpressionSyntax express
Call(NativeContract.StdLib.Hash, "itoa", 1, true);
break;
case "string":
case "Neo.Cryptography.ECC.ECPoint":
case "Neo.SmartContract.Framework.ECPoint":
case "Neo.SmartContract.Framework.ByteString":
case "Neo.SmartContract.Framework.UInt160":
case "Neo.SmartContract.Framework.UInt256":
Expand Down
27 changes: 2 additions & 25 deletions src/Neo.Compiler.CSharp/Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,9 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Collections.Generic;

namespace Neo.Compiler
{
public class Options
public class Options : CompilationOptions
{
public enum GenerateArtifactsKind
{
Expand All @@ -25,26 +21,7 @@ public enum GenerateArtifactsKind
}

public string? Output { get; set; }
public string? BaseName { get; set; }
public NullableContextOptions Nullable { get; set; }
public bool Checked { get; set; }
public bool Debug { get; set; }
public bool Assembly { get; set; }
public GenerateArtifactsKind GenerateArtifacts { get; set; } = GenerateArtifactsKind.Source;
public bool NoOptimize { get; set; }
public bool NoInline { get; set; }
public byte AddressVersion { get; set; }

private CSharpParseOptions? parseOptions = null;
public CSharpParseOptions GetParseOptions()
{
if (parseOptions is null)
{
List<string> preprocessorSymbols = new();
if (Debug) preprocessorSymbols.Add("DEBUG");
parseOptions = new CSharpParseOptions(preprocessorSymbols: preprocessorSymbols);
}
return parseOptions;
}
public GenerateArtifactsKind GenerateArtifacts { get; set; } = GenerateArtifactsKind.None;
}
}
4 changes: 2 additions & 2 deletions src/Neo.Compiler.CSharp/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ private static int ProcessCsproj(Options options, string path)

private static int ProcessSources(Options options, string folder, string[] sourceFiles)
{
return ProcessOutputs(options, folder, new CompilationEngine(options).CompileSources(sourceFiles));
return ProcessOutputs(options, folder, new CompilationEngine(options).CompileSources(null, sourceFiles));
}

private static int ProcessOutputs(Options options, string folder, List<CompilationContext> contexts)
Expand Down Expand Up @@ -212,7 +212,7 @@ private static int ProcessOutput(Options options, string folder, CompilationCont

if (options.GenerateArtifacts != Options.GenerateArtifactsKind.None)
{
var artifact = manifest.GetArtifactsSource(baseName, nef, debugInfo);
var artifact = manifest.GetArtifactsSource(baseName, nef);

if (options.GenerateArtifacts == Options.GenerateArtifactsKind.All || options.GenerateArtifacts == Options.GenerateArtifactsKind.Source)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.SmartContract.Framework/ContractParameterType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

namespace Neo.SmartContract
namespace Neo.SmartContract.Framework
{
public enum ContractParameterType : byte
{
Expand Down
3 changes: 1 addition & 2 deletions src/Neo.SmartContract.Framework/ECPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Attributes;

namespace Neo.Cryptography.ECC
namespace Neo.SmartContract.Framework
{
public abstract class ECPoint : ByteString
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Cryptography.ECC;

namespace Neo.SmartContract.Framework.Native
{
public class CalledByGroupCondition : WitnessCondition
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.SmartContract.Framework/Native/CryptoLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ public static partial class CryptoLib

public static extern ByteString Murmur32(ByteString value, uint seed);

public static extern bool VerifyWithECDsa(ByteString message, Cryptography.ECC.ECPoint pubkey, ByteString signature, NamedCurve curve);
public static extern bool VerifyWithECDsa(ByteString message, ECPoint pubkey, ByteString signature, NamedCurve curve);
}
}
2 changes: 0 additions & 2 deletions src/Neo.SmartContract.Framework/Native/GroupCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Cryptography.ECC;

namespace Neo.SmartContract.Framework.Native
{
public class GroupCondition : WitnessCondition
Expand Down
1 change: 0 additions & 1 deletion src/Neo.SmartContract.Framework/Native/NEO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

#pragma warning disable CS0626

using Neo.Cryptography.ECC;
using Neo.SmartContract.Framework.Attributes;
using Neo.SmartContract.Framework.Services;
using System.Numerics;
Expand Down
1 change: 0 additions & 1 deletion src/Neo.SmartContract.Framework/Native/NeoAccountState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Cryptography.ECC;
using System.Numerics;

namespace Neo.SmartContract.Framework.Native
Expand Down
2 changes: 1 addition & 1 deletion src/Neo.SmartContract.Framework/Native/RoleManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ public class RoleManagement
{
[ContractHash]
public static extern UInt160 Hash { get; }
public static extern Cryptography.ECC.ECPoint[] GetDesignatedByRole(Role role, uint index);
public static extern ECPoint[] GetDesignatedByRole(Role role, uint index);
}
}
2 changes: 0 additions & 2 deletions src/Neo.SmartContract.Framework/Native/Signer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.Cryptography.ECC;

namespace Neo.SmartContract.Framework.Native
{
public class Signer
Expand Down
4 changes: 2 additions & 2 deletions src/Neo.SmartContract.Framework/Services/Contract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ public class Contract
public static extern CallFlags GetCallFlags();

[Syscall("System.Contract.CreateStandardAccount")]
public static extern UInt160 CreateStandardAccount(Cryptography.ECC.ECPoint pubKey);
public static extern UInt160 CreateStandardAccount(ECPoint pubKey);

[Syscall("System.Contract.CreateMultisigAccount")]
public static extern UInt160 CreateMultisigAccount(int m, params Cryptography.ECC.ECPoint[] pubKey);
public static extern UInt160 CreateMultisigAccount(int m, params ECPoint[] pubKey);
}
}
Loading
Loading