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

Added Nullable Returns and Params #7

Merged
merged 2 commits into from
May 23, 2023
Merged
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
37 changes: 6 additions & 31 deletions src/NexNet.Generator/NexNetHubGenerator.Parser.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.CodeAnalysis;
using System.Collections.Concurrent;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Immutable;
using System.Diagnostics;
Expand Down Expand Up @@ -361,20 +362,10 @@ public MethodParameterMeta(IParameterSymbol symbol)
{
this.Symbol = symbol;
this.Name = symbol.Name;
IsArrayType = symbol.Type.TypeKind == TypeKind.Array;
if (IsArrayType)
{
var type = ((IArrayTypeSymbol)symbol.Type);
var arrayType = type.ElementType;
this.ParamType = arrayType.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + "." + arrayType.Name + "[]";
}
else
{
this.ParamType = symbol.Type.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + "." + symbol.Type.Name;
}

this.IsArrayType = symbol.Type.TypeKind == TypeKind.Array;
this.ParamType = SymbolUtilities.GetFullSymbolType(symbol.Type, false);
this.IsParamsArray = symbol.IsParams;
IsCancellationToken = symbol.Type.Name == "CancellationToken";
this.IsCancellationToken = symbol.Type.Name == "CancellationToken";
}
}

Expand Down Expand Up @@ -418,24 +409,8 @@ public MethodMeta(IMethodSymbol symbol)
this.IsReturnVoid = returnSymbol.Name == "Void";
this.NexNetMethodAttribute = new NexNetMethodAttributeMeta(symbol);



if (ReturnArity > 0)
{
var firstReturnType = returnSymbol.TypeArguments[0];

if (firstReturnType.TypeKind == TypeKind.Array)
{
var type = ((IArrayTypeSymbol)firstReturnType);
var arrayType = type.ElementType;
this.ReturnType = arrayType.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + "." + arrayType.Name + "[]";
}
else
{
var returnType = (INamedTypeSymbol)firstReturnType;
this.ReturnType = returnType.ContainingNamespace.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + "." + returnType.Name;
}
}
this.ReturnType = SymbolUtilities.GetFullSymbolType(returnSymbol, true);
}


Expand Down
63 changes: 63 additions & 0 deletions src/NexNet.Generator/SymbolUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using Microsoft.CodeAnalysis;

namespace NexNet.Generator;

internal class SymbolUtilities
{
private static readonly ConcurrentBag<StringBuilder> _sbCache = new ConcurrentBag<StringBuilder>();

public static StringBuilder GetStringBuilder()
{
if (!_sbCache.TryTake(out var sb))
sb = new StringBuilder();

return sb;
}

public static void ReturnStringBuilder(StringBuilder sb)
{
sb.Clear();
_sbCache.Add(sb);
}

private static readonly SymbolDisplayFormat _symbolDisplayFormat = new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers
| SymbolDisplayMiscellaneousOptions.UseErrorTypeSymbolName);

public static string GetFullSymbolType(ITypeSymbol typeSymbol, bool extractValueTask)
{
if (extractValueTask)
{
if (typeSymbol is INamedTypeSymbol namedTypeSymbol)
{
if (namedTypeSymbol.Arity == 1
&& namedTypeSymbol.ConstructedFrom.MetadataName == "ValueTask`1")
{
typeSymbol = namedTypeSymbol.TypeArguments[0];
}

}
}

var sb = GetStringBuilder();
sb.Append(typeSymbol.ToDisplayString(NullableFlowState.NotNull, _symbolDisplayFormat));

if (typeSymbol.TypeKind == TypeKind.Array
&& typeSymbol.NullableAnnotation == NullableAnnotation.Annotated)
sb.Append("?");

if (sb.Length == 0)
return "UNKNOWN TYPE " + typeSymbol.ToString();

var result = sb.ToString();
ReturnStringBuilder(sb);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Runtime.CompilerServices;
using MemoryPack;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
Expand All @@ -24,7 +25,8 @@ public static void InitializeCompilation()
});

var references = systemAssemblies
.Append(typeof(NexNetHubAttribute<,>).Assembly.Location) // System Assemblies + MemoryPack.Core.dll
.Append(typeof(NexNetHubAttribute<,>).Assembly.Location) // System Assemblies
.Append(typeof(MemoryPackableAttribute).Assembly.Location) // System Assemblies
.Select(x => MetadataReference.CreateFromFile(x))
.ToArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,25 @@ public void Update() { }
partial class ServerHub : IServerHub
{
public void Update(string arg) { }
}
""");
Assert.IsEmpty(diagnostic);
}

[Test]
public void CompilesSimpleServerAndClientWithNullableReturn()
{
var diagnostic = CSharpGeneratorRunner.RunGenerator("""
using NexNet;
using System.Threading.Tasks;
namespace NexNetDemo;
partial interface IClientHub { ValueTask<string?> Update(string[]? val); }
partial interface IServerHub { }

[NexNetHub<IServerHub, IClientHub>(NexNetHubType.Server)]
partial class ServerHub : IServerHub
{

}
""");
Assert.IsEmpty(diagnostic);
Expand Down