diff --git a/src/Neo.Compiler.CSharp/CompilationEngine.cs b/src/Neo.Compiler.CSharp/CompilationEngine.cs index aba277639..9d46344a6 100644 --- a/src/Neo.Compiler.CSharp/CompilationEngine.cs +++ b/src/Neo.Compiler.CSharp/CompilationEngine.cs @@ -21,6 +21,7 @@ using System.IO; using System.Linq; using System.Xml.Linq; +using Akka.Util.Internal; using BigInteger = System.Numerics.BigInteger; namespace Neo.Compiler @@ -54,7 +55,6 @@ public CompilationEngine(Options options) public List Compile(IEnumerable sourceFiles, IEnumerable references) { IEnumerable syntaxTrees = sourceFiles.OrderBy(p => p).Select(p => CSharpSyntaxTree.ParseText(File.ReadAllText(p), options: Options.GetParseOptions(), path: p)); - if (IsSingleAbstractClass(syntaxTrees)) throw new FormatException("The given class is abstract, no valid neo SmartContract found."); CSharpCompilationOptions compilationOptions = new(OutputKind.DynamicallyLinkedLibrary, deterministic: true, nullableContextOptions: Options.Nullable); Compilation = CSharpCompilation.Create(null, syntaxTrees, references, compilationOptions); return CompileProjectContracts(Compilation); @@ -104,6 +104,9 @@ private List CompileProjectContracts(Compilation compilation } } + // Verify if there is any valid smart contract class + 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); foreach (var classSymbol in sortedClasses) { @@ -125,13 +128,11 @@ void Visit(INamedTypeSymbol classSymbol) { return; } - if (visiting.Contains(classSymbol)) + if (!visiting.Add(classSymbol)) { throw new InvalidOperationException("Cyclic dependency detected"); } - visiting.Add(classSymbol); - if (dependencies.TryGetValue(classSymbol, out var dependency)) { foreach (var dep in dependency) @@ -244,15 +245,5 @@ public Compilation GetCompilation(string csproj) } return reference; } - - private static bool IsSingleAbstractClass(IEnumerable syntaxTrees) - { - if (syntaxTrees.Count() != 1) return false; - - var tree = syntaxTrees.First(); - var classDeclarations = tree.GetCompilationUnitRoot().DescendantNodes().OfType().ToList(); - - return classDeclarations.Count == 1 && classDeclarations[0].Modifiers.Any(SyntaxKind.AbstractKeyword); - } } }