diff --git a/src/Neo.Compiler.CSharp/CompilationEngine/CompilationEngine.cs b/src/Neo.Compiler.CSharp/CompilationEngine/CompilationEngine.cs index d64edbe56..1122615a9 100644 --- a/src/Neo.Compiler.CSharp/CompilationEngine/CompilationEngine.cs +++ b/src/Neo.Compiler.CSharp/CompilationEngine/CompilationEngine.cs @@ -289,6 +289,7 @@ private List CompileProjectContracts(Compilation compilation var classDependencies = new Dictionary>(SymbolEqualityComparer.Default); var allSmartContracts = new HashSet(SymbolEqualityComparer.Default); var allClassSymbols = new List(); + var classSymbols = new List(); foreach (var tree in compilation.SyntaxTrees) { var semanticModel = compilation.GetSemanticModel(tree); @@ -298,22 +299,37 @@ private List CompileProjectContracts(Compilation compilation { var classSymbol = semanticModel.GetDeclaredSymbol(classNode); allClassSymbols.Add(classSymbol); + if (classSymbol is null) continue; + + classSymbols.Add(classSymbol); if (classSymbol is { IsAbstract: false, DeclaredAccessibility: Accessibility.Public } && IsDerivedFromSmartContract(classSymbol)) { allSmartContracts.Add(classSymbol); classDependencies[classSymbol] = []; - foreach (var member in classSymbol.GetMembers()) - { - var memberTypeSymbol = (member as IFieldSymbol)?.Type ?? (member as IPropertySymbol)?.Type; - if (memberTypeSymbol is INamedTypeSymbol namedTypeSymbol && allSmartContracts.Contains(namedTypeSymbol) && !namedTypeSymbol.IsAbstract) - { - classDependencies[classSymbol].Add(namedTypeSymbol); - } - } } } } + foreach (var classSymbol in classSymbols) + { + if (!allSmartContracts.Contains(classSymbol)) + continue; + + foreach (var member in classSymbol.GetMembers()) + { + var memberTypeSymbol = (member as IFieldSymbol)?.Type ?? (member as IPropertySymbol)?.Type; + if (memberTypeSymbol is not INamedTypeSymbol namedTypeSymbol) + continue; + if (namedTypeSymbol.IsAbstract) + continue; + if (!allSmartContracts.Contains(namedTypeSymbol)) + continue; + if (classDependencies[classSymbol].Any(p => SymbolEqualityComparer.Default.Equals(p, namedTypeSymbol))) + continue; + classDependencies[classSymbol].Add(namedTypeSymbol); + } + } + // 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