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

Misc #61

Merged
merged 3 commits into from
Apr 12, 2023
Merged

Misc #61

Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Collection of Internet Computer Protocol (ICP) libraries for .NET/Blazor

- [Internet Identity (Experimental)](src/InternetIdentity/README.md) - Internet Identity authenticater (experimental and not secure)

## See each individual project README for more in depth guides


# 🎮 Unity Integration
Expand Down
58 changes: 4 additions & 54 deletions samples/Sample.CLI/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using EdjCase.ICP.Candid.Models;
using System;
using System.Threading.Tasks;
using EdjCase.ICP.InternetIdentity;
using EdjCase.ICP.Agent.Identities;
using CommandLine;
using Sample.Shared.Governance;
Expand All @@ -12,57 +11,10 @@

public class Program
{
public class Options
{

[Option('a', "anchor", Required = true, HelpText = "Anchor identifier to authenticate with")]
public ulong Anchor { get; set; }

[Option('n', "hostname", Required = true, HelpText = "Client hostname to give access to")]
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
public string Hostname { get; set; }
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.

}

public static async Task Main(string[] args)
{
#if DEBUG
if (args.Length == 0)
{
await ParseAndRunAsync(new string[] { "--help" }); // Prints the help if there are no args
args = Console.ReadLine()!.Split(' ', StringSplitOptions.RemoveEmptyEntries);
}
#endif
await ParseAndRunAsync(args);
}

private static async Task<bool> ParseAndRunAsync(string[] args)
{
ParserResult<Options> result = await Parser.Default.ParseArguments<Options>(args)
.WithParsedAsync<Options>(async o =>
{
await Run(o.Anchor, o.Hostname);
});
return result.Tag == ParserResultType.Parsed;
}

public static async Task Run(ulong anchor, string hostname)
public static async Task Main()
{
bool login = true; // TODO
IIdentity? identity;
if (login)
{
LoginResult result = await Authenticator
.WithHttpAgent()
.LoginAsync(anchor, hostname);
identity = result.GetIdentityOrThrow();
Console.WriteLine("Login success!");
}
else
{
identity = null;
}
IIdentity? identity = null;
var agent = new HttpAgent(identity);
Principal canisterId = Principal.FromText("rrkah-fqaaa-aaaaa-aaaaq-cai");
var client = new GovernanceApiClient(agent, canisterId);
Expand All @@ -71,9 +23,7 @@ public static async Task Run(ulong anchor, string hostname)
OptionalValue<Sample.Shared.Governance.Models.ProposalInfo> proposalInfo = await client.GetProposalInfo(proposalId);
CandidTypedValue rawCandid = CandidTypedValue.FromObject(proposalInfo);
Console.WriteLine("ProposalInfo:\n" + rawCandid.Value.ToString());

var paths = new List<StatePath> {
};
await agent.ReadStateAsync(canisterId, paths);
Console.WriteLine("Press ENTER to exit");
Console.ReadLine();
}
}
2 changes: 0 additions & 2 deletions samples/Sample.CLI/Sample.CLI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@


<ItemGroup>
<ProjectReference Include="..\..\src\InternetIdentity\EdjCase.ICP.InternetIdentity.csproj" />
<ProjectReference Include="..\Sample.Shared\Sample.Shared.csproj" />
<ProjectReference Include="..\..\src\ClientGenerator\EdjCase.ICP.ClientGenerator.csproj" />
</ItemGroup>


Expand Down
1 change: 0 additions & 1 deletion samples/Sample.Shared/Sample.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@

<ItemGroup>
<ProjectReference Include="..\..\src\Agent\EdjCase.ICP.Agent.csproj" />
<ProjectReference Include="..\..\src\Candid\EdjCase.ICP.Candid.csproj" />
</ItemGroup>
</Project>
14 changes: 7 additions & 7 deletions src/ClientGenerator/ClientCodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,37 +75,37 @@ ClientGenerationOptions options

// Mapping of A => Type
// where candid is: type A = Type;
Dictionary<ValueName, SourceCodeType> declaredTypes = service.DeclaredTypes
Dictionary<string, SourceCodeType> declaredTypes = service.DeclaredTypes
.Where(t => t.Value is not CandidServiceType) // avoid duplication service of type
.ToDictionary(
t => ValueName.Default(t.Key.ToString(), false),
t => t.Key.ToString(),
t => ResolveSourceCodeType(t.Value, options.KeepCandidCase)
);

string modelNamespace = options.NoFolders
? options.Namespace
: options.Namespace + ".Models";
HashSet<ValueName> aliases = declaredTypes
HashSet<string> aliases = declaredTypes
.Where(t => t.Value is CompiledTypeSourceCodeType || t.Value is ReferenceSourceCodeType)
.Select(t => t.Key)
.ToHashSet();

var typeResolver = new RoslynTypeResolver(modelNamespace, aliases, options.FeatureNullable, options.KeepCandidCase);
Dictionary<ValueName, ResolvedType> resolvedTypes = declaredTypes
Dictionary<string, ResolvedType> resolvedTypes = declaredTypes
.ToDictionary(
t => t.Key,
t => typeResolver.ResolveTypeDeclaration(t.Key, t.Value)
);

var typeFiles = new List<(string FileName, CompilationUnitSyntax Source)>();
Dictionary<ValueName, TypeName> aliasTypes = aliases
Dictionary<string, TypeName> aliasTypes = aliases
.ToDictionary(t => t, t => resolvedTypes[t].Name);
foreach ((ValueName id, ResolvedType typeInfo) in resolvedTypes)
foreach ((string id, ResolvedType typeInfo) in resolvedTypes)
{
CompilationUnitSyntax? sourceCode = RoslynSourceGenerator.GenerateTypeSourceCode(typeInfo, typeResolver.ModelNamespace, aliasTypes);
if (sourceCode != null)
{
typeFiles.Add((id.PropertyName, sourceCode));
typeFiles.Add((id, sourceCode));
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/ClientGenerator/RoslynSourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public static CompilationUnitSyntax GenerateClientSourceCode(
string modelNamespace,
ServiceSourceCodeType service,
RoslynTypeResolver typeResolver,
Dictionary<ValueName, TypeName> aliases
Dictionary<string, TypeName> aliases
)
{
// Generate client class
Expand All @@ -48,7 +48,7 @@ Dictionary<ValueName, TypeName> aliases
public static CompilationUnitSyntax? GenerateTypeSourceCode(
ResolvedType type,
string modelNamespace,
Dictionary<ValueName, TypeName> aliases
Dictionary<string, TypeName> aliases
)
{
// Generate client class
Expand All @@ -63,7 +63,7 @@ Dictionary<ValueName, TypeName> aliases

private static CompilationUnitSyntax PostProcessSourceCode(
string modelNamespace,
Dictionary<ValueName, TypeName> aliases,
Dictionary<string, TypeName> aliases,
params MemberDeclarationSyntax[] members)
{
// Generate namespace with class in it
Expand All @@ -88,7 +88,7 @@ private static CompilationUnitSyntax PostProcessSourceCode(
// Add alias using statements
.AddUsings(aliases
.Select(a => SyntaxFactory.UsingDirective(
alias: SyntaxFactory.NameEquals(a.Key.PropertyName),
alias: SyntaxFactory.NameEquals(a.Key),
name: SyntaxFactory.IdentifierName(a.Value.GetNamespacedName())
))
.ToArray()
Expand Down
18 changes: 8 additions & 10 deletions src/ClientGenerator/RoslynTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ internal class RoslynTypeResolver
private readonly Dictionary<string, ResolvedType> _resolvedTypes = new();

public string ModelNamespace { get; }
public HashSet<ValueName> Aliases { get; }
public HashSet<string> Aliases { get; }
public bool FeatureNullable { get; }
public bool KeepCandidCase { get; }

public RoslynTypeResolver(
string modelNamespace,
HashSet<ValueName> aliases,
HashSet<string> aliases,
bool featureNullable,
bool keepCandidCase)
{
Expand All @@ -39,7 +39,7 @@ public RoslynTypeResolver(
}

public ResolvedType ResolveTypeDeclaration(
ValueName typeName,
string typeName,
SourceCodeType type
)
{
Expand All @@ -49,14 +49,13 @@ SourceCodeType type
// type X = blob;
// type F = A<X>;

string typeNameStr = typeName.PropertyName;

if (this._resolvedTypes.TryGetValue(typeNameStr, out ResolvedType? existing))
if (this._resolvedTypes.TryGetValue(typeName, out ResolvedType? existing))
{
return existing;
}
ResolvedType res = this.ResolveTypeInner(type, typeNameStr, parentType: null);
this._resolvedTypes[typeNameStr] = res;
ResolvedType res = this.ResolveTypeInner(type, typeName, parentType: null);
this._resolvedTypes[typeName] = res;
return res;
}

Expand Down Expand Up @@ -110,12 +109,11 @@ private ResolvedType ResolveTypeInner(
}
case ReferenceSourceCodeType re:
{
ValueName correctedRefId = ValueName.Default(re.Id.Value, false);
bool isAlias = this.Aliases.Contains(correctedRefId);
bool isAlias = this.Aliases.Contains(re.Id.Value);

string? @namespace = isAlias ? null : this.ModelNamespace;
return new ResolvedType(new TypeName(
correctedRefId.PropertyName,
re.Id.Value,
@namespace,
prefix: null
));
Expand Down
6 changes: 3 additions & 3 deletions src/ClientGenerator/Tool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,13 @@ private async static Task<int> Generate(GenerateOptions options)
source = await ClientCodeGenerator.GenerateClientFromCanisterAsync(canisterId, clientOptions, boundryNodeUrl);
break;
default:
throw new InvalidOperationException($"Invalid client type '{type}'");
throw new InvalidOperationException($"Failed to parse the `candid-client.toml` config. Invalid client type '{type}'");
}
WriteClient(source, clientOutputDirectory, clientNoFolders);
}
return 0;
}
catch (InvalidOperationException ex)
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return 1;
Expand All @@ -180,7 +180,7 @@ private static T GetRequired<T>(TomlTable table, string key, string? prefix = nu
{
key = prefix + "." + key;
}
throw new InvalidOperationException($"Missing key '{key}'");
throw new InvalidOperationException("Failed to parse the `candid-client.toml` config. Missing required field: '{key}'");
}

private static T? GetOptional<T>(TomlTable table, string key)
Expand Down
Loading