Skip to content

Commit

Permalink
Validate manifest after compilation (#658)
Browse files Browse the repository at this point in the history
* Validate manifest after compilation

* update nuget

* Change UT

* Fix

* Improve message

* Reduce checks

* Remove manifest checks too

* Remove const

* Rename

* Check method name conflict

* Improve exception message

* Fix method key

https://github.com/neo-project/neo/blob/02cae386af6da48d46d02a373e2cf0116e3a8622/src/neo/SmartContract/Manifest/ContractAbi.cs#L77

Co-authored-by: Erik Zhang <[email protected]>
  • Loading branch information
shargon and erikzhang authored Nov 12, 2021
1 parent 145b329 commit 697c4a2
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 2 deletions.
13 changes: 11 additions & 2 deletions src/Neo.Compiler.CSharp/CompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,10 @@ private void ProcessEvent(IEventSymbol symbol)
INamedTypeSymbol type = (INamedTypeSymbol)symbol.Type;
if (!type.DelegateInvokeMethod!.ReturnsVoid)
throw new CompilationException(symbol, DiagnosticId.EventReturns, $"Event return value is not supported.");
eventsExported.Add(new AbiEvent(symbol));
AbiEvent ev = new(symbol);
if (eventsExported.Any(u => u.Name == ev.Name))
throw new CompilationException(symbol, DiagnosticId.EventNameConflict, $"Duplicate event name: {ev.Name}.");
eventsExported.Add(ev);
}

private void ProcessMethod(SemanticModel model, IMethodSymbol symbol, bool export)
Expand All @@ -453,7 +456,13 @@ private void ProcessMethod(SemanticModel model, IMethodSymbol symbol, bool expor
if (symbol.MethodKind != MethodKind.Ordinary && symbol.MethodKind != MethodKind.PropertyGet && symbol.MethodKind != MethodKind.PropertySet)
return;
}
if (export) methodsExported.Add(new AbiMethod(symbol));
if (export)
{
AbiMethod method = new(symbol);
if (methodsExported.Any(u => u.Name == method.Name && u.Parameters.Length == method.Parameters.Length))
throw new CompilationException(symbol, DiagnosticId.MethodNameConflict, $"Duplicate method key: {method.Name},{method.Parameters.Length}.");
methodsExported.Add(method);
}
MethodConvert convert = ConvertMethod(model, symbol);
if (export && !symbol.IsStatic)
{
Expand Down
2 changes: 2 additions & 0 deletions src/Neo.Compiler.CSharp/DiagnosticId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ static class DiagnosticId
public const string FormatClause = "NC2013";
public const string InvalidInitialValueType = "NC3001";
public const string InvalidMethodName = "NC3002";
public const string MethodNameConflict = "NC3003";
public const string EventNameConflict = "NC3004";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Numerics;
using System.ComponentModel;

namespace Neo.Compiler.CSharp.UnitTests.TestClasses
{
public class Contract_DuplicateNames : SmartContract.Framework.SmartContract
{
[DisplayName("Notify")]
public static event Action<BigInteger> Notice;

[DisplayName("Notify")]
public static event Action<BigInteger> AA;
}
}
9 changes: 9 additions & 0 deletions tests/Neo.Compiler.CSharp.UnitTests/UnitTest1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@ public void Test_InvalidNameMethodContracts()
Assert.IsTrue(context.Diagnostics.Any(u => u.Id == DiagnosticId.InvalidMethodName));
}

[TestMethod]
public void Test_DuplicateDisplayNames()
{
var testengine = new TestEngine();
var context = testengine.AddEntryScript("./TestClasses/Contract_DuplicateNames.cs");
Assert.IsFalse(context.Success);
Assert.IsTrue(context.Diagnostics.Any(u => u.Id == DiagnosticId.EventNameConflict));
}

[TestMethod]
public void Test_PrivateMethod()
{
Expand Down

0 comments on commit 697c4a2

Please sign in to comment.