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

[Framework Add] predefine manifest #903

Merged
merged 7 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
22 changes: 15 additions & 7 deletions src/Neo.Compiler.CSharp/CompilationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
shargon marked this conversation as resolved.
Show resolved Hide resolved
{
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)
Expand Down
12 changes: 12 additions & 0 deletions src/Neo.SmartContract.Framework/Attributes/AuthorAttribute.cs
Original file line number Diff line number Diff line change
@@ -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)
{
}
}
}
12 changes: 12 additions & 0 deletions src/Neo.SmartContract.Framework/Attributes/DescriptionAttribute.cs
Original file line number Diff line number Diff line change
@@ -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)
{
}
}
}
12 changes: 12 additions & 0 deletions src/Neo.SmartContract.Framework/Attributes/EmailAttribute.cs
Original file line number Diff line number Diff line change
@@ -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)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// 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
{
shargon marked this conversation as resolved.
Show resolved Hide resolved
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
Expand All @@ -18,5 +18,13 @@ public class ManifestExtraAttribute : Attribute
public ManifestExtraAttribute(string key, string value)
{
}

internal static readonly Dictionary<string, string> AttributeType = new Dictionary<string, string>
{
{ nameof(AuthorAttribute), "Author" },
{ nameof(EmailAttribute), "E-mail" },
{ nameof(DescriptionAttribute), "Description" },
{ nameof(VersionAttribute), "Version" },
};
}
}
12 changes: 12 additions & 0 deletions src/Neo.SmartContract.Framework/Attributes/VersionAttribute.cs
Original file line number Diff line number Diff line change
@@ -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)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Neo.SmartContract.Framework.Attributes;

namespace Neo.SmartContract.Framework.UnitTests.TestClasses
{
[Author("core-dev")]
[Email("[email protected]")]
[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);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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("[email protected]")]
// [Version("v3.6.3")]
// [Description("This is a test contract.")]
// [ManifestExtra("ExtraKey", "ExtraValue")]
Assert.AreEqual("core-dev", extra["Author"]!.GetString());
Assert.AreEqual("[email protected]", 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());
}
}