From 0865963f6c6c9e1ecf617fe63f9557e6a74c4547 Mon Sep 17 00:00:00 2001 From: Jim8y Date: Thu, 15 Feb 2024 19:57:31 +0800 Subject: [PATCH 1/7] predefine manifest --- src/Neo.Compiler.CSharp/CompilationContext.cs | 22 +++++--- .../Attributes/ManifestExtraAttribute.cs | 53 +++++++++++++++++-- .../Contract_ManifestAttribute.cs | 22 ++++++++ .../ManifestAttributeTest.cs | 29 ++++++++++ 4 files changed, 114 insertions(+), 12 deletions(-) create mode 100644 tests/Neo.SmartContract.Framework.TestContracts/Contract_ManifestAttribute.cs create mode 100644 tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs diff --git a/src/Neo.Compiler.CSharp/CompilationContext.cs b/src/Neo.Compiler.CSharp/CompilationContext.cs index e745ad480..7c9155ffe 100644 --- a/src/Neo.Compiler.CSharp/CompilationContext.cs +++ b/src/Neo.Compiler.CSharp/CompilationContext.cs @@ -426,31 +426,39 @@ private void ProcessClass(SemanticModel model, INamedTypeSymbol symbol) bool isSmartContract = isPublic && !isAbstract && isContractType; if (isSmartContract) { - if (scTypeFound) throw new CompilationException(DiagnosticId.MultiplyContracts, $"Only one smart contract is allowed."); + if (scTypeFound) throw new CompilationException(DiagnosticId.MultiplyContracts, "Only one smart contract is allowed."); scTypeFound = true; - foreach (var attribute in symbol.GetAttributesWithInherited()) + var a = symbol.GetAttributes(); + var b = symbol.GetAttributesWithInherited(); + foreach (var attribute in b) { + if (attribute.AttributeClass!.IsSubclassOf(nameof(ManifestExtraAttribute))) + { + manifestExtra[ManifestExtraAttribute.AttributeType[attribute.AttributeClass!.Name]] = (string)attribute.ConstructorArguments[0].Value!; + continue; + } + switch (attribute.AttributeClass!.Name) { case nameof(DisplayNameAttribute): displayName = (string)attribute.ConstructorArguments[0].Value!; break; - case nameof(scfx.Neo.SmartContract.Framework.Attributes.ContractSourceCodeAttribute): + case nameof(ContractSourceCodeAttribute): Source = (string)attribute.ConstructorArguments[0].Value!; break; - case nameof(scfx.Neo.SmartContract.Framework.Attributes.ManifestExtraAttribute): + case nameof(ManifestExtraAttribute): manifestExtra[(string)attribute.ConstructorArguments[0].Value!] = (string)attribute.ConstructorArguments[1].Value!; break; - case nameof(scfx.Neo.SmartContract.Framework.Attributes.ContractPermissionAttribute): + case nameof(ContractPermissionAttribute): permissions.Add((string)attribute.ConstructorArguments[0].Value!, attribute.ConstructorArguments[1].Values.Select(p => (string)p.Value!).ToArray()); break; - case nameof(scfx.Neo.SmartContract.Framework.Attributes.ContractTrustAttribute): + case nameof(ContractTrustAttribute): string trust = (string)attribute.ConstructorArguments[0].Value!; if (!ValidateContractTrust(trust)) throw new ArgumentException($"The value {trust} is not a valid one for ContractTrust"); trusts.Add(trust); break; - case nameof(scfx.Neo.SmartContract.Framework.Attributes.SupportedStandardsAttribute): + case nameof(SupportedStandardsAttribute): supportedStandards.UnionWith( attribute.ConstructorArguments[0].Values .Select(p => p.Value) diff --git a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs index 0ce97cf59..43d458665 100644 --- a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs +++ b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs @@ -1,22 +1,65 @@ // Copyright (C) 2015-2023 The Neo Project. -// -// The Neo.SmartContract.Framework 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 +// +// The Neo.SmartContract.Framework 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 System; +using System.Collections.Generic; + namespace Neo.SmartContract.Framework.Attributes { + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class ManifestExtraAttribute : Attribute { public ManifestExtraAttribute(string key, string value) { } + + internal static readonly Dictionary AttributeType = new Dictionary + { + { nameof(AuthorAttribute), "Author" }, + { nameof(EmailAttribute), "E-mail" }, + { nameof(DescriptionAttribute), "Description" }, + { nameof(VersionAttribute), "Version" }, + }; + } + + [AttributeUsage(AttributeTargets.Class)] + public class AuthorAttribute : ManifestExtraAttribute + { + public AuthorAttribute(string value) : base(AttributeType[nameof(AuthorAttribute)], value) + { + } + } + + [AttributeUsage(AttributeTargets.Class)] + public class EmailAttribute : ManifestExtraAttribute + { + public EmailAttribute(string value) : base(AttributeType[nameof(EmailAttribute)], value) + { + } + } + + [AttributeUsage(AttributeTargets.Class)] + public class DescriptionAttribute : ManifestExtraAttribute + { + public DescriptionAttribute(string value) : base(AttributeType[nameof(DescriptionAttribute)], value) + { + } + } + + [AttributeUsage(AttributeTargets.Class)] + public class VersionAttribute : ManifestExtraAttribute + { + public VersionAttribute(string value) : base(AttributeType[nameof(VersionAttribute)], value) + { + } } } diff --git a/tests/Neo.SmartContract.Framework.TestContracts/Contract_ManifestAttribute.cs b/tests/Neo.SmartContract.Framework.TestContracts/Contract_ManifestAttribute.cs new file mode 100644 index 000000000..9e7aff6ea --- /dev/null +++ b/tests/Neo.SmartContract.Framework.TestContracts/Contract_ManifestAttribute.cs @@ -0,0 +1,22 @@ +using Neo.SmartContract.Framework.Attributes; + +namespace Neo.SmartContract.Framework.UnitTests.TestClasses +{ + [Author("core-dev")] + [Email("core@neo.org")] + [Version("v3.6.3")] + [Description("This is a test contract.")] + [ManifestExtra("ExtraKey", "ExtraValue")] + public class Contract_ManifestAttribute : SmartContract + { + [NoReentrant] + public void reentrantTest(int value) + { + if (value == 0) return; + if (value == 123) + { + reentrantTest(0); + } + } + } +} diff --git a/tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs new file mode 100644 index 000000000..7f0d7f435 --- /dev/null +++ b/tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs @@ -0,0 +1,29 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Neo.SmartContract.Framework.UnitTests; + +[TestClass] +public class ManifestAttributeTest +{ + + [TestMethod] + public void TestManifestAttribute() + { + var testEngine = new TestEngine.TestEngine(); + testEngine.AddEntryScript(Utils.Extensions.TestContractRoot + "Contract_ManifestAttribute.cs"); + + var extra = testEngine.Manifest!.Extra; + + Assert.AreEqual(5, extra.Count); + // [Author("core-dev")] + // [Email("core@neo.org")] + // [Version("v3.6.3")] + // [Description("This is a test contract.")] + // [ManifestExtra("ExtraKey", "ExtraValue")] + Assert.AreEqual("core-dev", extra["Author"]!.GetString()); + Assert.AreEqual("core@neo.org", extra["E-mail"]!.GetString()); + Assert.AreEqual("v3.6.3", extra["Version"]!.GetString()); + Assert.AreEqual("This is a test contract.", extra["Description"]!.GetString()); + Assert.AreEqual("ExtraValue", extra["ExtraKey"]!.GetString()); + } +} From 15f5bb6f68597477de5a339a7b302b3d29cab7df Mon Sep 17 00:00:00 2001 From: Jim8y Date: Thu, 15 Feb 2024 20:46:38 +0800 Subject: [PATCH 2/7] one attribute per file --- .../Attributes/AuthorAttribute.cs | 12 +++++++ .../Attributes/DescriptionAttribute.cs | 12 +++++++ .../Attributes/EmailAttribute.cs | 12 +++++++ .../Attributes/ManifestExtraAttribute.cs | 32 ------------------- .../Attributes/VersionAttribute.cs | 12 +++++++ 5 files changed, 48 insertions(+), 32 deletions(-) create mode 100644 src/Neo.SmartContract.Framework/Attributes/AuthorAttribute.cs create mode 100644 src/Neo.SmartContract.Framework/Attributes/DescriptionAttribute.cs create mode 100644 src/Neo.SmartContract.Framework/Attributes/EmailAttribute.cs create mode 100644 src/Neo.SmartContract.Framework/Attributes/VersionAttribute.cs diff --git a/src/Neo.SmartContract.Framework/Attributes/AuthorAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/AuthorAttribute.cs new file mode 100644 index 000000000..bab7fb99d --- /dev/null +++ b/src/Neo.SmartContract.Framework/Attributes/AuthorAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Neo.SmartContract.Framework.Attributes +{ + [AttributeUsage(AttributeTargets.Class)] + public class AuthorAttribute : ManifestExtraAttribute + { + public AuthorAttribute(string value) : base(AttributeType[nameof(AuthorAttribute)], value) + { + } + } +} diff --git a/src/Neo.SmartContract.Framework/Attributes/DescriptionAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/DescriptionAttribute.cs new file mode 100644 index 000000000..ab1812bee --- /dev/null +++ b/src/Neo.SmartContract.Framework/Attributes/DescriptionAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Neo.SmartContract.Framework.Attributes +{ + [AttributeUsage(AttributeTargets.Class)] + public class DescriptionAttribute : ManifestExtraAttribute + { + public DescriptionAttribute(string value) : base(AttributeType[nameof(DescriptionAttribute)], value) + { + } + } +} diff --git a/src/Neo.SmartContract.Framework/Attributes/EmailAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/EmailAttribute.cs new file mode 100644 index 000000000..22c16a28d --- /dev/null +++ b/src/Neo.SmartContract.Framework/Attributes/EmailAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Neo.SmartContract.Framework.Attributes +{ + [AttributeUsage(AttributeTargets.Class)] + public class EmailAttribute : ManifestExtraAttribute + { + public EmailAttribute(string value) : base(AttributeType[nameof(EmailAttribute)], value) + { + } + } +} diff --git a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs index 43d458665..e3e1f5d34 100644 --- a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs +++ b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs @@ -30,36 +30,4 @@ public ManifestExtraAttribute(string key, string value) { nameof(VersionAttribute), "Version" }, }; } - - [AttributeUsage(AttributeTargets.Class)] - public class AuthorAttribute : ManifestExtraAttribute - { - public AuthorAttribute(string value) : base(AttributeType[nameof(AuthorAttribute)], value) - { - } - } - - [AttributeUsage(AttributeTargets.Class)] - public class EmailAttribute : ManifestExtraAttribute - { - public EmailAttribute(string value) : base(AttributeType[nameof(EmailAttribute)], value) - { - } - } - - [AttributeUsage(AttributeTargets.Class)] - public class DescriptionAttribute : ManifestExtraAttribute - { - public DescriptionAttribute(string value) : base(AttributeType[nameof(DescriptionAttribute)], value) - { - } - } - - [AttributeUsage(AttributeTargets.Class)] - public class VersionAttribute : ManifestExtraAttribute - { - public VersionAttribute(string value) : base(AttributeType[nameof(VersionAttribute)], value) - { - } - } } diff --git a/src/Neo.SmartContract.Framework/Attributes/VersionAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/VersionAttribute.cs new file mode 100644 index 000000000..eb62fa3bf --- /dev/null +++ b/src/Neo.SmartContract.Framework/Attributes/VersionAttribute.cs @@ -0,0 +1,12 @@ +using System; + +namespace Neo.SmartContract.Framework.Attributes +{ + [AttributeUsage(AttributeTargets.Class)] + public class VersionAttribute : ManifestExtraAttribute + { + public VersionAttribute(string value) : base(AttributeType[nameof(VersionAttribute)], value) + { + } + } +} From 8d896a1aa020d03d3b57b12d4ab7550751912ad2 Mon Sep 17 00:00:00 2001 From: Jim8y Date: Thu, 15 Feb 2024 20:47:25 +0800 Subject: [PATCH 3/7] remove empty line --- .../Attributes/ManifestExtraAttribute.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs index e3e1f5d34..a02bec7ac 100644 --- a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs +++ b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs @@ -14,7 +14,6 @@ namespace Neo.SmartContract.Framework.Attributes { - [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class ManifestExtraAttribute : Attribute { From 27eec54de3a3b80c10b9729a12915967b8384db0 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 15 Feb 2024 05:27:00 -0800 Subject: [PATCH 4/7] Update tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs --- .../ManifestAttributeTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs index 7f0d7f435..d7d23bd26 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/ManifestAttributeTest.cs @@ -5,7 +5,6 @@ namespace Neo.SmartContract.Framework.UnitTests; [TestClass] public class ManifestAttributeTest { - [TestMethod] public void TestManifestAttribute() { From ed6e8b2164eae96007286c7df63ea3422c136942 Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 15 Feb 2024 05:27:43 -0800 Subject: [PATCH 5/7] Update src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs --- .../Attributes/ManifestExtraAttribute.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs index a02bec7ac..c736aec05 100644 --- a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs +++ b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs @@ -10,8 +10,6 @@ using System; using System.Collections.Generic; - - namespace Neo.SmartContract.Framework.Attributes { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] From 80d20ed478807b9586bba4307a2dbe6971ecdf3f Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 15 Feb 2024 05:28:11 -0800 Subject: [PATCH 6/7] Update src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs --- .../Attributes/ManifestExtraAttribute.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs index c736aec05..cf4ac1a66 100644 --- a/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs +++ b/src/Neo.SmartContract.Framework/Attributes/ManifestExtraAttribute.cs @@ -10,6 +10,7 @@ using System; using System.Collections.Generic; + namespace Neo.SmartContract.Framework.Attributes { [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] From 913a7632bebedd98c7d05fabf29944df5bcdd83e Mon Sep 17 00:00:00 2001 From: Shargon Date: Thu, 15 Feb 2024 05:30:59 -0800 Subject: [PATCH 7/7] Update src/Neo.Compiler.CSharp/CompilationContext.cs --- src/Neo.Compiler.CSharp/CompilationContext.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Neo.Compiler.CSharp/CompilationContext.cs b/src/Neo.Compiler.CSharp/CompilationContext.cs index 7c9155ffe..57b3a7653 100644 --- a/src/Neo.Compiler.CSharp/CompilationContext.cs +++ b/src/Neo.Compiler.CSharp/CompilationContext.cs @@ -428,9 +428,7 @@ private void ProcessClass(SemanticModel model, INamedTypeSymbol symbol) { if (scTypeFound) throw new CompilationException(DiagnosticId.MultiplyContracts, "Only one smart contract is allowed."); scTypeFound = true; - var a = symbol.GetAttributes(); - var b = symbol.GetAttributesWithInherited(); - foreach (var attribute in b) + foreach (var attribute in symbol.GetAttributesWithInherited()) { if (attribute.AttributeClass!.IsSubclassOf(nameof(ManifestExtraAttribute))) {