Skip to content

Commit

Permalink
Improved escape analysis operations
Browse files Browse the repository at this point in the history
  • Loading branch information
ritchiecarroll committed Jan 21, 2025
1 parent 1c6c621 commit 276cb95
Show file tree
Hide file tree
Showing 30 changed files with 511 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/Tests/Behavioral/ArrayPassByValue/ArrayPassByValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace go;
partial class main_package {

private static void Main() {
array<@string> a = default!;
ref var a = ref heap(new array<@string>(2), out var Ꮡa);
a[0] = "Hello"u8;
a[1] = "World"u8;
var p = Ꮡa.at<@string>(0);
Expand Down
11 changes: 7 additions & 4 deletions src/Tests/Behavioral/BehavioralTests/BehavioralTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="MSTest.TestAdapter" Version="3.7.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.7.1" />
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<!-- Define Go type aliases -->
Expand Down
2 changes: 1 addition & 1 deletion src/Tests/Behavioral/BehavioralTests/CompileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace BehavioralTests;

[TestClass]
public class CompileTests : BehavioralTestBase
public class B2_CompileTests : BehavioralTestBase
{
[ClassInitialize]
public static void Initialize(TestContext context) => Init(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
namespace BehavioralTests;

[TestClass]
public class TargetComparisonTests : BehavioralTestBase
public class C3_TargetComparisonTests : BehavioralTestBase
{
[ClassInitialize]
public static void Initialize(TestContext context) => Init(context);
Expand Down
2 changes: 1 addition & 1 deletion src/Tests/Behavioral/BehavioralTests/TranspileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
namespace BehavioralTests;

[TestClass]
public class TranspileTests : BehavioralTestBase
public class A1_TranspileTests : BehavioralTestBase
{
[ClassInitialize]
public static void Initialize(TestContext context) => Init(context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ private static void Main() {
for (nint i = 0; i < 10; i++) {
var cʗ1 = c;
goǃ(() => {
ref var j = ref heap<nint>(out var Ꮡj);
for (j = 0; j < 10; j++) {
for (nint j = 0; j < 10; j++) {
cʗ1.ᐸꟷ(j);
}
close(cʗ1);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//---------------------------------------------------------
// <auto-generated>
// This code was generated by a tool. Changes to this
// file may cause incorrect behavior and will be lost
// if the code is regenerated.
// </auto-generated>
//---------------------------------------------------------

using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Collections;
using System;

#nullable enable

namespace go;

public static partial class main_package
{
[GeneratedCode("go2cs-gen", "0.1.4")]
public partial struct Counter
{
// Value of the Counter struct
private readonly nint m_value;

public override bool Equals(object? obj) => obj is Counter other && m_value == other.m_value;

public override int GetHashCode() => m_value.GetHashCode();

public static bool operator ==(Counter left, Counter right) => left.m_value == right.m_value;

public static bool operator !=(Counter left, Counter right) => !(left == right);

public static bool operator <(Counter left, Counter right) => left.m_value < right.m_value;

public static bool operator <=(Counter left, Counter right) => left.m_value <= right.m_value;

public static bool operator >(Counter left, Counter right) => left.m_value > right.m_value;

public static bool operator >=(Counter left, Counter right) => left.m_value >= right.m_value;

public static Counter operator +(Counter left, Counter right) => new(left.m_value + right.m_value);

public static Counter operator -(Counter left, Counter right) => new(left.m_value - right.m_value);

public static Counter operator -(Counter value) => new(-value.m_value);

public static Counter operator *(Counter left, Counter right) => new(left.m_value * right.m_value);

public static Counter operator /(Counter left, Counter right) => new(left.m_value / right.m_value);

public static Counter operator %(Counter left, Counter right) => new(left.m_value % right.m_value);

public override string ToString() => m_value.ToString();

public Counter(nint value) => m_value = value;

// Enable implicit conversions between nint and Counter struct
public static implicit operator Counter(nint value) => new Counter(value);

public static implicit operator nint(Counter value) => value.m_value;

// Enable comparisons between nil and Counter struct
public static bool operator ==(Counter value, NilType nil) => value.Equals(default(Counter));

public static bool operator !=(Counter value, NilType nil) => !(value == nil);

public static bool operator ==(NilType nil, Counter value) => value == nil;

public static bool operator !=(NilType nil, Counter value) => value != nil;

public static implicit operator Counter(NilType nil) => default(Counter);
}
}
19 changes: 19 additions & 0 deletions src/Tests/Behavioral/MethodSelector/MethodSelector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace go;

using fmt = fmt_package;

partial class main_package {

[GoType("num:nint")] partial struct Counter {}

public static @string String(this Counter c) {
return fmt.Sprint(((nint)c));
}

private static void Main() {
Counter c = 5;
var f = () => c.String();
fmt.Println(f());
}

} // end main_package
101 changes: 101 additions & 0 deletions src/Tests/Behavioral/MethodSelector/MethodSelector.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net9.0;net8.0</TargetFrameworks>
<RootNamespace>go</RootNamespace>
<AssemblyName>MethodSelector</AssemblyName>
<Product>go2cs</Product>
<Version>0.1.4</Version>
<Description>$(AssemblyName) ($(TargetFramework) - $(Configuration))</Description>
<AssemblyTitle>$(Description)</AssemblyTitle>
<Copyright>Copyright © 2025</Copyright>
<Authors>$(Product) Authors</Authors>
<Company>Grid Protection Alliance</Company>
<RepositoryUrl>https://github.com/GridProtectionAlliance/go2cs</RepositoryUrl>
<ApplicationIcon>go2cs.ico</ApplicationIcon>
<Nullable>enable</Nullable>
<NoWarn>CS0660;CS0661;CS8981;IDE0060;IDE1006</NoWarn>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(OutDir)'==''">
<OutDir>bin\$(Configuration)\$(TargetFramework)\</OutDir>
</PropertyGroup>

<!-- Enable native compiled output optimizations -->
<PropertyGroup>
<PublishReadyToRun>true</PublishReadyToRun>
<PublishTrimmed>True</PublishTrimmed>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
</PropertyGroup>

<!-- Setup packaging options for library projects -->
<PropertyGroup Condition="'$(OutputType)'=='Library'">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageId>go.$(AssemblyName)</PackageId>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageDescription>$(Description) -- C# project converted from Go source</PackageDescription>
<PackageProjectUrl>https://github.com/GridProtectionAlliance/go2cs</PackageProjectUrl>
<PackageIcon>go2cs.png</PackageIcon>
<PackageTags>$(AssemblyName);go2cs;Golang;go</PackageTags>
</PropertyGroup>

<ItemGroup Condition="'$(OutputType)'=='Library'">
<None Include="go2cs.png" Pack="true" PackagePath="" Visible="false" />
<None Include="go2cs.ico" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>

<!-- Expose output of source generators as local files -->
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>Generated</CompilerGeneratedFilesOutputPath>
</PropertyGroup>

<ItemGroup>
<Compile Remove="$(CompilerGeneratedFilesOutputPath)/**/*.cs" />
<ProjectReference Include="..\..\..\go2cs-gen\go2cs-gen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" PrivateAssets="All" />
</ItemGroup>

<!-- Define Go type aliases -->
<ItemGroup>
<Using Include="go.builtin" Static="True" />
<Using Include="System" />
<Using Include="System.Byte" Alias="uint8" />
<Using Include="System.UInt16" Alias="uint16" />
<Using Include="System.UInt32" Alias="uint32" />
<Using Include="System.UInt64" Alias="uint64" />
<Using Include="System.SByte" Alias="int8" />
<Using Include="System.Int16" Alias="int16" />
<Using Include="System.Int32" Alias="int32" />
<Using Include="System.Int64" Alias="int64" />
<Using Include="System.Single" Alias="float32" />
<Using Include="System.Double" Alias="float64" />
<Using Include="System.Numerics.Complex" Alias="complex128" />
<Using Include="System.Int32" Alias="rune" />
<Using Include="System.UIntPtr" Alias="uintptr" />
<Using Include="System.Numerics.BigInteger" Alias="GoUntyped" />
<Using Include="System.ComponentModel.DescriptionAttribute" Alias="GoTag" />
<Using Include="System.Runtime.CompilerServices.ModuleInitializerAttribute" Alias="GoInit" />
</ItemGroup>

<ItemGroup>
<!-- Remove all .cs files, including those in sub-folders -->
<Compile Remove="**/*.cs" />
<!-- Include only .cs files from current folder -->
<Compile Include="*.cs" />
<!-- Remove test files from current folder -->
<Compile Remove="*._test.cs" />
</ItemGroup>

<ItemGroup>
<!-- TODO: Add references to required projects -->
<ProjectReference Include="..\..\..\gocore\golib\golib.csproj" />
<ProjectReference Include="..\..\..\gocore\fmt\fmt.csproj" />
<ProjectReference Include="..\..\..\gocore\math\math.csproj" />
<ProjectReference Include="..\..\..\gocore\sort\sort.csproj" />
<ProjectReference Include="..\..\..\gocore\time\time.csproj" />
</ItemGroup>

</Project>
15 changes: 15 additions & 0 deletions src/Tests/Behavioral/MethodSelector/MethodSelector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

import "fmt"

type Counter int

func (c Counter) String() string {
return fmt.Sprint(int(c))
}

func main() {
var c Counter = 5
f := c.String
fmt.Println(f())
}
Binary file added src/Tests/Behavioral/MethodSelector/go2cs.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion src/Tests/Behavioral/PointerToPointer/PointerToPointer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ [GoType] partial struct Buffer {
private const int8 opRead = -1;
private const int8 opInvalid = 0;
private static void Main() {
nint a = default!;
ref var a = ref heap(new nint(), out var Ꮡa);
ptr<nint> ptr = default!;
ptr<ptr<nint>> pptr = default!;
ptr<ptr<ptr<nint>>> ppptr = default!;
Expand Down
9 changes: 3 additions & 6 deletions src/Tests/Behavioral/SelectStatement/SelectStatement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,12 @@ private static void sieve() {
var chʗ1 = ch;
goǃ(_ => generate(chʗ1));
while () {
ref var prime = ref heap<nint>(out var Ꮡprime);
prime = ᐸꟷ(ch);
nint prime = ᐸꟷ(ch);
fmt.Print(prime, "\n");
var ch1 = new channel<nint>(1);
var chʗ2 = ch;
var ch1ʗ1 = ch1;
var primeʗ1 = prime;
goǃ(_ => filter(chʗ2, ch1ʗ1, primeʗ1));
goǃ(_ => filter(chʗ2, ch1ʗ1, prime));
ch = ch1;
if (prime > 40) {
break;
Expand Down Expand Up @@ -164,8 +162,7 @@ private static void Main() {
var fʗ1 = fΔ1;
var quitʗ1 = quit;
goǃ(() => {
ref var i = ref heap<nint>(out var Ꮡi);
for (i = 0; i < 10; i++) {
for (nint i = 0; i < 10; i++) {
fmt.Println(ᐸꟷ(fʗ1));
}
quitʗ1.ᐸꟷ(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace go;
partial class main_package {

private static void Main() {
@string a = default!;
ref var a = ref heap(new @string(), out var Ꮡa);
a = "Hello World"u8;
test(a);
fmt.Println(a);
Expand Down
2 changes: 1 addition & 1 deletion src/Tests/Behavioral/TypeConversion/TypeConversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ [GoType] partial struct Person {
}

ptr<struct{Name string "json:\"name\""; Address *struct{Street string "json:\"street\""; City string "json:\"city\""} "json:\"address\""}> data = default!;
Person mine = default!;
ref var mine = ref heap(new Person(), out var Ꮡmine);
ptr<Person> person = (Person.val)(data);
person = Ꮡmine;
fmt.Println(mine == person.val);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
// </auto-generated>
//---------------------------------------------------------

using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Collections;
using System;

#nullable enable

Expand Down
51 changes: 51 additions & 0 deletions src/Tests/Behavioral/package_info.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// go2cs code converter defines `global using` statements here for imported type
// aliases as package references are encountered via `import' statements. Exported
// type aliases that need a `global using` declaration will be loaded from the
// referenced package by parsing its 'package_info.cs' source file and reading its
// defined `GoTypeAlias` attributes.

// Package name separator "dot" used in imported type aliases is extended Unicode
// character '\uA4F8' which is a valid character in a C# identifier name. This is
// used to simulate Go's package level type aliases since C# does not yet support
// importing type aliases at a namespace level.

// <ImportedTypeAliases>
// Example: global using mypkgꓸTable = go.map<go.@string, nint>;
// </ImportedTypeAliases>

using go;
using static go.main_package;

// For encountered type alias declarations, e.g., `type Table = map[string]int`,
// go2cs code converter will generate a `global using` statement for the alias in
// the converted source, e.g.: `global using Table = go.map<go.@string, nint>;`.
// Although scope of `global using` is available to all files in the project, all
// converted Go code for the project targets the same package, so `global using`
// statements will effectively have package level scope.

// Additionally, `GoTypeAlias` attributes will be generated here for exported type
// aliases. This allows the type alias to be imported and used from other packages
// when referenced.

// <ExportedTypeAliases>
// Example: [assembly: GoTypeAlias("Table", "go.map<go.@string, nint>")]
// </ExportedTypeAliases>

// As types are cast to interfaces in Go source code, the go2cs code converter
// will generate an assembly level `GoImpl` attribute for each unique cast. This
// allows the interface to be implemented in the C# source code using source
// code generation (see go2cs-gen). An alternate interface implementation exists
// that can resolve duck-typed interfaces at run-time, but handling interface
// implementations at compile-time results in faster startup times, avoiding
// reflection-based interface resolution.

// <InterfaceImplementations>
[assembly: GoImpl<T, I>]
// </InterfaceImplementations>

namespace go;

[GoPackage("main")]
public static partial class main_package
{
}
Loading

0 comments on commit 276cb95

Please sign in to comment.