Skip to content

Commit

Permalink
Updated variadic params to use Span
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchiecarroll committed Nov 26, 2024
1 parent b579222 commit 487f358
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 121 deletions.
5 changes: 3 additions & 2 deletions src/Tests/Behavioral/SpreadOperator/SpreadOperator.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
namespace go;

using fmt = fmt_package;
using ꓸꓸꓸnint = System.Span<nint>;

public static partial class main_package {

private static nint sum(params nint[] numsʗp) {
private static nint sum(params ꓸꓸꓸnint numsʗp) {
var nums = numsʗp.slice();

nint total = 0;
Expand All @@ -16,7 +17,7 @@ private static nint sum(params nint[] numsʗp) {

private static void Main() {
var values = new nint[]{1, 2, 3}.slice();
fmt.Println(sum(values.ToArray()));
fmt.Println(sum(values.ꓸꓸꓸ));
fmt.Println(sum(1, 2, 3));
}

Expand Down
6 changes: 3 additions & 3 deletions src/go2cs2/convExprList.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ func (v *Visitor) convExprList(exprs []ast.Expr, prevEndPos token.Pos, callConte

result.WriteString(v.convExpr(expr, contexts))

// If the last expression has a spread operator, convert it to a `ToArray()` call,
// this way elements of source are passed as arguments instead of a slice or array
// If the last expression has a spread operator, use elipsis property as source
// this way elements are passed as arguments instead of a slice or array
if hasSpreadOperator && i == len(exprs)-1 {
result.WriteString(".ToArray()")
result.WriteString("." + ElipsisOperator)
}

if exprOnNewLine {
Expand Down
2 changes: 1 addition & 1 deletion src/go2cs2/convFunType.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func (v *Visitor) convFuncType(funcType *ast.FuncType) (resultsSignature, parameterSignature string) {
signature := v.getSignature(funcType)
resultsSignature = generateResultSignature(signature)
parameterSignature = generateParametersSignature(signature, false)
parameterSignature = v.generateParametersSignature(signature, false)
return
}

Expand Down
1 change: 1 addition & 0 deletions src/go2cs2/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const ShadowVarMarker = "Δ" // Variants: Δ Ʌ ꞥ
const CapturedVarMarker = "ʗ" // Variants: ʗ ɔ ᴄ
const TempVarMarker = "ᴛ" // Variants: ᴛ Ŧ ᵀ
const TrueMarker = "ᐧ" // Variants: ᐧ true
const ElipsisOperator = "ꓸꓸꓸ"

// TODO: Consider adding removing items that are also reserved by Go to reduce search space
var keywords = NewHashSet[string]([]string{
Expand Down
41 changes: 29 additions & 12 deletions src/go2cs2/visitFuncDecl.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (v *Visitor) visitFuncDecl(funcDecl *ast.FuncDecl) {

signatureOnly := funcDecl.Body == nil
useFuncExecutionContext := v.hasDefer || v.hasRecover
parameterSignature := generateParametersSignature(signature, true)
parameterSignature := v.generateParametersSignature(signature, true)
blockPrefix := ""

if !signatureOnly {
Expand Down Expand Up @@ -174,16 +174,31 @@ func (v *Visitor) visitFuncDecl(funcDecl *ast.FuncDecl) {

if i == parameters.Len()-1 && signature.Variadic() {
updatedSignature.WriteString("params ")
}

updatedSignature.WriteString(getCSTypeName(param.Type()))
updatedSignature.WriteRune(' ')
// If parameter is a slice, convert it to a Span
if sliceType, ok := param.Type().(*types.Slice); ok {
typeName := getCSTypeName(sliceType.Elem())

updatedSignature.WriteString(ElipsisOperator + typeName)
v.requiredUsings.Add(fmt.Sprintf("%s%s = System.Span<%s>", ElipsisOperator, typeName, typeName))
} else {
updatedSignature.WriteString("object[]")
}

if _, ok := param.Type().(*types.Pointer); ok {
updatedSignature.WriteString(AddressPrefix)
updatedSignature.WriteString(param.Name())
// Variadic parameters are passed as C# param arrays, so we use a temporary
// parameter name that will be later converted to a Go slice<T>
updatedSignature.WriteRune(' ')
updatedSignature.WriteString(getVariadicParamName(param))
} else {
updatedSignature.WriteString(getSanitizedIdentifier(param.Name()))
updatedSignature.WriteString(getCSTypeName(param.Type()))
updatedSignature.WriteRune(' ')

if _, ok := param.Type().(*types.Pointer); ok {
updatedSignature.WriteString(AddressPrefix)
updatedSignature.WriteString(param.Name())
} else {
updatedSignature.WriteString(getSanitizedIdentifier(param.Name()))
}
}
}

Expand Down Expand Up @@ -260,7 +275,7 @@ func getParameters(signature *types.Signature, addRecv bool) *types.Tuple {
return parameters
}

func generateParametersSignature(signature *types.Signature, addRecv bool) string {
func (v *Visitor) generateParametersSignature(signature *types.Signature, addRecv bool) string {
parameters := getParameters(signature, addRecv)

if parameters == nil {
Expand All @@ -283,10 +298,12 @@ func generateParametersSignature(signature *types.Signature, addRecv bool) strin
if i == parameters.Len()-1 && signature.Variadic() {
result.WriteString("params ")

// If parameter is a slice, convert it to an array
// If parameter is a slice, convert it to a Span
if sliceType, ok := param.Type().(*types.Slice); ok {
result.WriteString(getCSTypeName(sliceType.Elem()))
result.WriteString("[]")
typeName := getCSTypeName(sliceType.Elem())

result.WriteString(ElipsisOperator + typeName)
v.requiredUsings.Add(fmt.Sprintf("%s%s = System.Span<%s>", ElipsisOperator, typeName, typeName))
} else {
result.WriteString("object[]")
}
Expand Down
2 changes: 1 addition & 1 deletion src/go2cs2/visitInterfaceType.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (v *Visitor) visitInterfaceType(interfaceType *ast.InterfaceType, name stri

signature := methodType.Signature()
resultSignature := generateResultSignature(signature)
parameterSignature := generateParametersSignature(signature, false)
parameterSignature := v.generateParametersSignature(signature, false)

typeLenDeviation += token.Pos(len(parameterSignature) - getSourceParameterSignatureLen(signature))
typeLenDeviation += token.Pos(len(resultSignature) - getSourceResultSignatureLen(signature))
Expand Down
57 changes: 10 additions & 47 deletions src/gocore/golib/array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public array(ReadOnlyMemory<T> source)

public T[] Source => m_array;

public Span<T> ꓸꓸꓸ => new(m_array);

public nint Length => m_array.Length;

// Returning by-ref value allows array to be a struct instead of a class and still allow read and write
Expand Down Expand Up @@ -305,32 +307,17 @@ object ICloneable.Clone()
return m_array.Clone();
}

Array IArray.Source
{
get
{
return m_array;
}
}
Array IArray.Source => m_array;

object? IArray.this[nint index]
{
get
{
return this[index];
}
set
{
this[index] = (T)value!;
}
get => this[index];
set => this[index] = (T)value!;
}

T IList<T>.this[int index]
{
get
{
return this[index];
}
get => this[index];
set
{
if (index < 0 || index >= Length)
Expand All @@ -355,37 +342,13 @@ void IList<T>.RemoveAt(int index)
throw new NotSupportedException();
}

int IReadOnlyCollection<T>.Count
{
get
{
return (int)Length;
}
}
int IReadOnlyCollection<T>.Count => (int)Length;

T IReadOnlyList<T>.this[int index]
{
get
{
return this[index];
}
}
T IReadOnlyList<T>.this[int index] => this[index];

bool ICollection<T>.IsReadOnly
{
get
{
return false;
}
}
bool ICollection<T>.IsReadOnly => false;

int ICollection<T>.Count
{
get
{
return (int)Length;
}
}
int ICollection<T>.Count => (int)Length;

void ICollection<T>.Add(T item)
{
Expand Down
67 changes: 12 additions & 55 deletions src/gocore/golib/slice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ public slice(array<T> array) : this((T[])array) { }

public T[] Source => m_array;

public Span<T> ꓸꓸꓸ => new(m_array, (int)m_low, (int)m_length);

public slice(T[]? array, nint low = 0, nint high = -1)
{
if (array is null)
Expand Down Expand Up @@ -347,7 +349,7 @@ public static implicit operator array<T>(slice<T> value)
// slice<T> to nil comparisons
public static bool operator ==(slice<T> slice, NilType _)
{
return slice.Length == 0 && slice.Capacity == 0;
return slice is { Length: 0, Capacity: 0 };
}

public static bool operator !=(slice<T> slice, NilType nil)
Expand Down Expand Up @@ -389,32 +391,17 @@ ISlice<T> ISlice<T>.Append(params T[] elems)
return Append(elems);
}

Array IArray.Source
{
get
{
return m_array;
}
}
Array IArray.Source => m_array;

object? IArray.this[nint index]
{
get
{
return this[index];
}
set
{
this[index] = (T)value!;
}
get => this[index];
set => this[index] = (T)value!;
}

T IList<T>.this[int index]
{
get
{
return this[index];
}
get => this[index];
set
{
if (index < 0 || index >= m_length)
Expand All @@ -439,37 +426,13 @@ void IList<T>.RemoveAt(int index)
throw new NotSupportedException();
}

int IReadOnlyCollection<T>.Count
{
get
{
return (int)m_length;
}
}
int IReadOnlyCollection<T>.Count => (int)m_length;

T IReadOnlyList<T>.this[int index]
{
get
{
return this[m_low + index];
}
}
T IReadOnlyList<T>.this[int index] => this[m_low + index];

bool ICollection<T>.IsReadOnly
{
get
{
return false;
}
}
bool ICollection<T>.IsReadOnly => false;

int ICollection<T>.Count
{
get
{
return (int)m_length;
}
}
int ICollection<T>.Count => (int)m_length;

void ICollection<T>.Add(T item)
{
Expand Down Expand Up @@ -543,13 +506,7 @@ public T Current
}
}

object? IEnumerator.Current
{
get
{
return Current;
}
}
object? IEnumerator.Current => Current;

void IEnumerator.Reset()
{
Expand Down

0 comments on commit 487f358

Please sign in to comment.