Skip to content

Commit 5b66493

Browse files
Improved application of sanitized shadowed identifiers
1 parent c97b1aa commit 5b66493

File tree

9 files changed

+51
-57
lines changed

9 files changed

+51
-57
lines changed

src/Tests/Behavioral/ArrayPassByValue/ArrayPassByValue.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ private static void Main() {
3131
private static void stest(ptr<@string> Ꮡp) {
3232
ref var p = ref Ꮡp.val;
3333

34-
// *p
34+
p = "hello"u8;
3535
}
3636

3737
// Arrays are passed by value (a full copy)

src/Tests/Behavioral/ExprSwitch/ExprSwitch.cs

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ public static partial class main_package {
88

99
private static nint x = 1;
1010

11-
private static nint getNext() {
12-
x++;
11+
private static nint getNext() { x++;
12+
1313
return x;
1414
}
1515

@@ -26,14 +26,11 @@ private static @string getStr3(@string format, params object[] a) {
2626
}
2727

2828
private static void Main() {
29-
3029
fmt.Println(getStr("test"u8));
3130
fmt.Println(getStr2("hello, ", "world"u8));
3231
fmt.Println(getStr3("hello, %s"u8, "world"));
33-
3432
// Here's a basic `switch`.
35-
36-
var i = 2;
33+
nint i = 2;
3734
fmt.Print("Write ", i, " as ");
3835
switch (i) {
3936
case 1:
@@ -42,8 +39,8 @@ private static void Main() {
4239
case 2:
4340
fmt.Println("two");
4441
break;
45-
case 3: {
46-
42+
case 3:
43+
{
4744
fmt.Println("three");
4845
}
4946

@@ -56,22 +53,14 @@ private static void Main() {
5653
break;
5754
}
5855

59-
60-
61-
var xꞥ1 = 5;
62-
fmt.Println(xꞥ1);
63-
{
64-
65-
66-
var xꞥ2 = 6;
67-
fmt.Println(xꞥ2);
56+
nint x = 5;
57+
fmt.Println(x);
58+
{
59+
nint xꞥ1 = 6;
60+
fmt.Println(xꞥ1);
6861
}
6962

70-
71-
fmt.Println(xꞥ1);
72-
73-
74-
63+
fmt.Println(x);
7564
// You can use commas to separate multiple expressions
7665
// in the same `case` statement. We use the optional
7766
// `default` case in this example as well.
@@ -88,30 +77,22 @@ private static void Main() {
8877
break;
8978
}
9079

91-
92-
93-
9480
// Case Mon comment
9581
// `switch` without an expression is an alternate way
9682
// to express if/else logic. Here we also show how the
9783
// `case` expressions can be non-constants.
98-
9984
var t = time.Now();
10085

101-
10286
// Before noon
10387
// After noon
10488
// "i" before should be saved
10589
fmt.Printf("i before = %d\n"u8, i);
106-
10790
// Here is a switch with simple statement and a redeclared identifier plus a fallthrough
10891
{
10992

110-
111-
var iꞥ1 = 1;
93+
nint iꞥ1 = 1;
11294
}
11395

114-
11596
// "i" after should be restored
11697
fmt.Printf("i after = %d\n"u8, i);
11798
}

src/Tests/Behavioral/SortArrayType/SortArrayType.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Pre-package Comments
22

33
// Package Comments
4-
54
namespace go;
65

76
// Pre-comment
@@ -152,18 +151,18 @@ public static (nint E2, @string p) Testing() {
152151

153152
fmt.Println(E2);
154153
E2 = 1;
155-
var B2 = 2;
154+
nint B2 = 2;
156155
fmt.Println(E2, B2);
157156
p = "Hello"u8;
158157
{
159-
var E2ꞥ1 = 99;
160-
var B2ꞥ1 = 199;
158+
nint E2ꞥ1 = 99;
159+
nint B2ꞥ1 = 199;
161160
fmt.Println(E2ꞥ1, B2ꞥ1);
162161
}
163162

164163
{
165164
E2 = 100;
166-
var B2ꞥ2 = 200;
165+
nint B2ꞥ2 = 200;
167166
fmt.Println(E2, B2ꞥ2);
168167
}
169168

src/go2cs2/.vscode/launch.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
//"-var=false",
1515
"-tree",
1616
//"H:\\Projects\\go2cs\\src\\Tests\\Behavioral\\SortArrayType\\SortArrayType.go",
17-
"H:\\Projects\\go2cs\\src\\Tests\\Behavioral\\ArrayPassByValue\\ArrayPassByValue.go",
18-
//"H:\\Projects\\go2cs\\src\\Tests\\Behavioral\\ExprSwitch\\ExprSwitch.go",
17+
//"H:\\Projects\\go2cs\\src\\Tests\\Behavioral\\ArrayPassByValue\\ArrayPassByValue.go",
18+
"H:\\Projects\\go2cs\\src\\Tests\\Behavioral\\ExprSwitch\\ExprSwitch.go",
1919
]
2020
}
2121
]

src/go2cs2/convUnaryExpr.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import (
88
)
99

1010
func (v *Visitor) convUnaryExpr(unaryExpr *ast.UnaryExpr) string {
11+
// Check if the unary expression is a pointer dereference
1112
if unaryExpr.Op == token.AND {
12-
// Check if the expression is an address of an indexed array or slice
13+
// Check if the unary expression is an address of an indexed array or slice
1314
if indexExpr, ok := unaryExpr.X.(*ast.IndexExpr); ok {
1415
typeName := v.getTypeName(indexExpr.X, true)
1516

1617
if strings.HasPrefix(typeName, "[") {
18+
// For an indexed reference into an array or slice, we use the "ptr.at<T>(index)" syntax
1719
csTypeName := convertToCSTypeName(typeName[strings.Index(typeName, "]")+1:])
1820
return fmt.Sprintf("%s.at<%s>(%s)", AddressPrefix+v.convExpr(indexExpr.X, nil), csTypeName, v.convExpr(indexExpr.Index, nil))
1921
}

src/go2cs2/main.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ func (v *Visitor) getStringLiteral(str string) (result string, isRawStr bool) {
389389
}
390390

391391
func getSanitizedIdentifier(identifier string) string {
392+
if strings.HasPrefix(identifier, "@") {
393+
return identifier // Already sanitized
394+
}
395+
392396
if keywords.Contains(identifier) ||
393397
strings.HasPrefix(identifier, AddressPrefix) ||
394398
strings.HasSuffix(identifier, ClassSuffix) ||
@@ -447,6 +451,8 @@ func getIdentifier(node ast.Node) *ast.Ident {
447451
if identExpr, ok := indexExpr.X.(*ast.Ident); ok {
448452
ident = identExpr
449453
}
454+
} else if starExpr, ok := node.(*ast.StarExpr); ok {
455+
ident = getIdentifier(starExpr.X)
450456
} else if identExpr, ok := node.(*ast.Ident); ok {
451457
ident = identExpr
452458
}

src/go2cs2/performVariableAnalysis.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func (v *Visitor) performVariableAnalysis(funcDecl *ast.FuncDecl, signature *typ
129129
}
130130

131131
varNames[varObj] = adjustedName
132-
v.identNames[ident] = getSanitizedIdentifier(adjustedName)
132+
v.identNames[ident] = adjustedName
133133
v.isReassigned[ident] = false
134134

135135
scope := v.scopeStack[len(v.scopeStack)-1]
@@ -323,7 +323,7 @@ func (v *Visitor) performVariableAnalysis(funcDecl *ast.FuncDecl, signature *typ
323323
if obj := v.info.Uses[node]; obj != nil {
324324
if varObj, ok := obj.(*types.Var); ok {
325325
if adjustedName, ok := varNames[varObj]; ok {
326-
v.identNames[node] = getSanitizedIdentifier(adjustedName)
326+
v.identNames[node] = adjustedName
327327
}
328328
}
329329
}

src/gocore/golib/array.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ public interface IArray : IEnumerable, ICloneable
3838
nint Length { get; }
3939

4040
object? this[nint index] { get; set; }
41+
42+
bool IndexIsValid(nint index)
43+
{
44+
return index >= 0 && index < Length;
45+
}
4146
}
4247

4348
public interface IArray<T> : IArray

src/gocore/golib/ptr.cs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
namespace go;
2929

30-
3130
/// <summary>
3231
/// Represents a heap allocated reference to an instance of type <typeparamref name="T"/>.
3332
/// </summary>
@@ -52,7 +51,7 @@ namespace go;
5251
/// </remarks>
5352
public class ptr<T>
5453
{
55-
private readonly (object, int)? m_srcIndex;
54+
private readonly (IArray, int)? m_arrayRefIndex;
5655
private T m_val;
5756

5857
/// <summary>
@@ -64,10 +63,10 @@ public ptr(in T value)
6463
m_val = value;
6564
}
6665

67-
// Creates a new indexed reference to an existing heap allocated reference.
68-
internal ptr(object src, int index)
66+
// Create a new indexed reference into an existing heap allocated array
67+
internal ptr(IArray arrayRef, int index)
6968
{
70-
m_srcIndex = (src, index);
69+
m_arrayRefIndex = (arrayRef, index);
7170
}
7271

7372
/// <summary>
@@ -89,32 +88,34 @@ public ref T val
8988
{
9089
get
9190
{
92-
if (m_srcIndex is null)
91+
if (m_arrayRefIndex is null)
9392
return ref m_val;
9493

95-
(object src, int index) = m_srcIndex.Value;
96-
97-
if (src is ptr<array<T>> array)
98-
return ref array.val[index];
94+
(IArray arrayRef, int index) = m_arrayRefIndex.Value;
9995

100-
if (src is ptr<slice<T>> slice)
101-
return ref slice.val[index];
96+
if (arrayRef is IArray<T> array)
97+
return ref array[index];
10298

10399
throw new InvalidOperationException("Cannot get reference to value, source is not a valid array or slice pointer.");
104100
}
105101
}
106102

107103
/// <summary>
108-
/// Gets a pointer to element at the specified index for a <see cref="array{T}"/> or <see cref="slice{T}"/> types.
104+
/// Gets a pointer to element at the specified index for <see cref="array{T}"/> or <see cref="slice{T}"/> types.
109105
/// </summary>
110106
/// <typeparam name="Telem">Element type of array or slice.</typeparam>
111107
/// <param name="index">Index of element to get pointer for.</param>
112108
/// <returns>Pointer to element at specified index.</returns>
113109
/// <exception cref="InvalidOperationException">Cannot get pointer element at index, type is not an array or slice.</exception>
114110
public ptr<Telem> at<Telem>(int index)
115111
{
116-
if (m_val is array<Telem> or slice<Telem>)
117-
return new ptr<Telem>(this, index);
112+
if (m_val is IArray<Telem> array)
113+
{
114+
if (!array.IndexIsValid(index))
115+
throw new IndexOutOfRangeException("Index is out of range for array or slice.");
116+
117+
return new ptr<Telem>(array, index);
118+
}
118119

119120
throw new InvalidOperationException("Cannot get pointer to element at index, type is not an array or slice.");
120121
}

0 commit comments

Comments
 (0)