Skip to content

Commit

Permalink
test: collection numeric indexing adds one codegen
Browse files Browse the repository at this point in the history
  • Loading branch information
R-unic committed Jul 14, 2024
1 parent a155f56 commit 07c6131
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 17 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Roblox CSharp to Lua compiler

# To-do
- Test `DebugTransformer`
- Imports
- Inheritance chains 🤮
- Append ` = null` to generated nullable properties
Expand Down
9 changes: 9 additions & 0 deletions RobloxCS.Tests/CodeGenerator_GenerateLuaShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ public void CollectionInitializer_GeneratesTable()
Assert.Equal("local nums = {1, 2, 3}", cleanedLua);
}

[Theory]
[InlineData("int[] nums = [1, 2, 3]; nums[0]", "nums[1]", 1)]
[InlineData("int[] nums = [1, 2, 3]; int i = 4; nums[i]", "nums[i + 1]", 2)]
public void CollectionIndexing_AddsOneToNumericalIndices(string input, string expected, int removeLines = 0)
{
var cleanedLua = GetCleanLua(input, removeLines);
Assert.Equal(expected, cleanedLua);
}

private static void AssertEqualLines(List<string> lines, List<string> expectedLines)
{
foreach (var line in lines)
Expand Down
23 changes: 9 additions & 14 deletions RobloxCS/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,8 @@ public override void VisitBracketedArgumentList(BracketedArgumentListSyntax node
{
Visit(argument);

var argumentSymbol = _semanticModel.GetSymbolInfo(argument.Expression).Symbol;
var definitionSymbol = argumentSymbol?.OriginalDefinition;
var indexSymbol = definitionSymbol ?? argumentSymbol;
var isNumericalIndex = indexSymbol is ITypeSymbol typeSymbol && Constants.INTEGER_TYPES.Contains(typeSymbol.Name);
var typeSymbol = _semanticModel.GetTypeInfo(argument.Expression).Type;
var isNumericalIndex = typeSymbol != null && Constants.INTEGER_TYPES.Contains(typeSymbol.Name);
if (isNumericalIndex)
{
Write(" + 1");
Expand Down Expand Up @@ -306,17 +304,15 @@ public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node
public override void VisitBinaryExpression(BinaryExpressionSyntax node)
{
var operatorText = node.OperatorToken.Text;
var leftSymbolInfo = _semanticModel.GetSymbolInfo(node.Left);
var rightSymbolInfo = _semanticModel.GetSymbolInfo(node.Right);
var leftSymbol = leftSymbolInfo.Symbol?.OriginalDefinition ?? leftSymbolInfo.Symbol ?? _semanticModel.GetTypeInfo(node.Left).Type;
var rightSymbol = rightSymbolInfo.Symbol?.OriginalDefinition ?? rightSymbolInfo.Symbol ?? _semanticModel.GetTypeInfo(node.Right).Type;
var leftType = _semanticModel.GetTypeInfo(node.Left).Type;
var rightType = _semanticModel.GetTypeInfo(node.Right).Type;
var perTypeOperators = Constants.PER_TYPE_BINARY_OPERATOR_MAP;
if (
(leftSymbol != null && perTypeOperators.Any(pair => pair.Key.Contains(leftSymbol.Name)))
|| (rightSymbol != null && perTypeOperators.Any(pair => pair.Key.Contains(rightSymbol.Name)))
(leftType != null && perTypeOperators.Any(pair => pair.Key.Contains(leftType.Name)))
|| (rightType != null && perTypeOperators.Any(pair => pair.Key.Contains(rightType.Name)))
)
{
var typeList = perTypeOperators.FirstOrDefault(pair => pair.Key.Contains(leftSymbol!.Name) || pair.Key.Contains(rightSymbol!.Name)).Key;
var typeList = perTypeOperators.FirstOrDefault(pair => pair.Key.Contains(leftType!.Name) || pair.Key.Contains(rightType!.Name)).Key;
var operatorMap = perTypeOperators[typeList];
if (operatorText == operatorMap.Item1)
{
Expand Down Expand Up @@ -447,9 +443,8 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node)
case "Write":
case "WriteLine":
{
var objectSymbolInfo = _semanticModel.GetSymbolInfo(memberAccess.Expression);
var objectDefinitionSymbol = (ITypeSymbol)objectSymbolInfo.Symbol!;
if (objectDefinitionSymbol.Name != "Console") break;
var objectType = _semanticModel.GetTypeInfo(memberAccess.Expression).Type;
if (objectType == null || objectType.Name != "Console") break;

Write("print");
Visit(node.ArgumentList);
Expand Down
12 changes: 11 additions & 1 deletion RobloxCS/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,17 @@ internal static class Constants
"int",
"uint",
"long",
"ulong"
"ulong",
"SByte",
"Byte",
"Int16",
"Int32",
"Int64",
"Int128",
"UInt16",
"UInt32",
"UInt64",
"UInt128",
};
}
}
4 changes: 3 additions & 1 deletion TestProject/dist/client/Main.client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ CS.class("Game", function(namespace)
class.__index = class

function class.Main()
print("[TestProject/Client/Main.client.cs:5:9]:", 420)
local nums = {1, 2, 3}
local i = 4
print("[TestProject/Client/Main.client.cs:9:9]:", nums[i + 1])
end

if namespace == nil then
Expand Down
4 changes: 3 additions & 1 deletion TestProject/src/client/Main.client.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public static class Game
{
public static void Main()
{
warn("hello baby");
int[] nums = [1, 2, 3];
int i = 4;
Console.WriteLine(nums[i]);
}
}

0 comments on commit 07c6131

Please sign in to comment.