diff --git a/CSharp.lua/CSharp.lua.csproj b/CSharp.lua/CSharp.lua.csproj
index bbf8e12e..23c53910 100644
--- a/CSharp.lua/CSharp.lua.csproj
+++ b/CSharp.lua/CSharp.lua.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/CSharp.lua/CoreSystem.Lua/CoreSystem/Array.lua b/CSharp.lua/CoreSystem.Lua/CoreSystem/Array.lua
index 26805f59..ee856011 100644
--- a/CSharp.lua/CoreSystem.Lua/CoreSystem/Array.lua
+++ b/CSharp.lua/CoreSystem.Lua/CoreSystem/Array.lua
@@ -1661,7 +1661,7 @@ local MultiArray = {
Clone = function (this)
local array = { __rank__ = this.__rank__ }
tmove(this, 1, #this, 1, array)
- return arrayFromTable(array, this.__genericT__)
+ return setmetatable(array, Array(this.__genericT__, #this.__rank__))
end
}
diff --git a/CSharp.lua/CoreSystem.Lua/CoreSystem/Collections/Linq.lua b/CSharp.lua/CoreSystem.Lua/CoreSystem/Collections/Linq.lua
index 6e170a4c..7f115bbb 100644
--- a/CSharp.lua/CoreSystem.Lua/CoreSystem/Collections/Linq.lua
+++ b/CSharp.lua/CoreSystem.Lua/CoreSystem/Collections/Linq.lua
@@ -895,6 +895,11 @@ function Enumerable.Cast(source, T)
end)
end
+function Enumerable.AsEnumerable(source)
+ if source == nil then throw(ArgumentNullException("source")) end
+ return source
+end
+
local function first(source, ...)
if source == nil then throw(ArgumentNullException("source")) end
local len = select("#", ...)
diff --git a/CSharp.lua/LuaAst/LuaIfStatementSyntax.cs b/CSharp.lua/LuaAst/LuaIfStatementSyntax.cs
index 840808d3..3c6f7be8 100644
--- a/CSharp.lua/LuaAst/LuaIfStatementSyntax.cs
+++ b/CSharp.lua/LuaAst/LuaIfStatementSyntax.cs
@@ -63,29 +63,26 @@ internal override void Render(LuaRenderer renderer) {
public sealed class LuaSwitchAdapterStatementSyntax : LuaStatementSyntax {
public readonly LuaRepeatStatementSyntax RepeatStatement = new(LuaIdentifierNameSyntax.One);
- public LuaIdentifierNameSyntax Temp { get; }
+ public LuaBlockSyntax Body => RepeatStatement.Body;
+
+ public LuaIdentifierNameSyntax Temp { get; set; }
private LuaBlockSyntax defaultBlock_;
private readonly LuaLocalVariablesSyntax caseLabelVariables_ = new();
public LuaIdentifierNameSyntax DefaultLabel { get; set; }
public readonly Dictionary CaseLabels = new();
private LuaIfStatementSyntax headIfStatement_;
- public LuaSwitchAdapterStatementSyntax(LuaIdentifierNameSyntax temp) {
- Temp = temp;
+ public LuaSwitchAdapterStatementSyntax() {
}
- public void Fill(LuaExpressionSyntax expression, IEnumerable sections) {
- if (expression == null) {
- throw new ArgumentNullException(nameof(expression));
- }
+ public void Fill(IEnumerable sections) {
if (sections == null) {
throw new ArgumentNullException(nameof(sections));
}
- var body = RepeatStatement.Body;
+ var body = Body;
body.Statements.Add(caseLabelVariables_);
- body.Statements.Add(new LuaLocalVariableDeclaratorSyntax(Temp, expression));
-
+
LuaIfStatementSyntax ifStatement = null;
foreach (var section in sections) {
if (section is LuaIfStatementSyntax statement) {
@@ -122,10 +119,10 @@ private void CheckHasDefaultLabel() {
Contract.Assert(defaultBlock_ != null);
caseLabelVariables_.Variables.Add(DefaultLabel);
LuaLabeledStatement labeledStatement = new LuaLabeledStatement(DefaultLabel);
- RepeatStatement.Body.Statements.Add(labeledStatement);
+ Body.Statements.Add(labeledStatement);
LuaIfStatementSyntax ifStatement = new LuaIfStatementSyntax(DefaultLabel);
ifStatement.Body.Statements.AddRange(defaultBlock_.Statements);
- RepeatStatement.Body.Statements.Add(ifStatement);
+ Body.Statements.Add(ifStatement);
}
}
@@ -143,10 +140,10 @@ private void CheckHasCaseLabel() {
caseLabelVariables_.Variables.AddRange(CaseLabels.Values);
foreach (var (index, labelIdentifier) in CaseLabels) {
var caseLabelStatement = FindMatchIfStatement(index);
- RepeatStatement.Body.Statements.Add(new LuaLabeledStatement(labelIdentifier));
+ Body.Statements.Add(new LuaLabeledStatement(labelIdentifier));
LuaIfStatementSyntax ifStatement = new LuaIfStatementSyntax(labelIdentifier);
ifStatement.Body.Statements.AddRange(caseLabelStatement.Statements);
- RepeatStatement.Body.Statements.Add(ifStatement);
+ Body.Statements.Add(ifStatement);
}
}
}
diff --git a/CSharp.lua/LuaSyntaxNodeTransform.Object.cs b/CSharp.lua/LuaSyntaxNodeTransform.Object.cs
index a8137fec..f6b5017b 100644
--- a/CSharp.lua/LuaSyntaxNodeTransform.Object.cs
+++ b/CSharp.lua/LuaSyntaxNodeTransform.Object.cs
@@ -796,7 +796,10 @@ public override LuaSyntaxNode VisitTryStatement(TryStatementSyntax node) {
}
private LuaStatementSyntax BuildUsingStatement(List variableIdentifiers, List variableExpressions, Action writeStatements) {
- var usingAdapterExpress = new LuaUsingAdapterExpressionSyntax();
+ return BuildUsingStatement(new LuaUsingAdapterExpressionSyntax(), variableIdentifiers, variableExpressions, writeStatements);
+ }
+
+ private LuaStatementSyntax BuildUsingStatement(LuaUsingAdapterExpressionSyntax usingAdapterExpress, List variableIdentifiers, List variableExpressions, Action writeStatements) {
usingAdapterExpress.ParameterList.Parameters.AddRange(variableIdentifiers);
PushFunction(usingAdapterExpress);
var block = new LuaBlockSyntax();
@@ -854,7 +857,10 @@ private void ApplyUsingDeclarations(LuaBlockSyntax block, List indexes, Blo
int lastIndex = indexes.Last();
var statements = block.Statements.Skip(lastIndex + 1);
- var usingStatement = BuildUsingStatement(variableIdentifiers, variableExpressions, body => body.Statements.AddRange(statements));
+ var usingAdapterExpress = new LuaUsingAdapterExpressionSyntax() {
+ HasReturn = node.Statements.Any(i => i.IsKind((SyntaxKind.ReturnStatement))),
+ };
+ var usingStatement = BuildUsingStatement(usingAdapterExpress, variableIdentifiers, variableExpressions, body => body.Statements.AddRange(statements));
block.Statements.RemoveRange(indexes[position]);
block.AddStatement(usingStatement);
indexes.RemoveRange(position);
@@ -1434,7 +1440,7 @@ private LuaExpressionSyntax BuildPatternExpression(LuaExpressionSyntax targetExp
case SyntaxKind.RecursivePattern: {
var recursivePattern = (RecursivePatternSyntax)notPattern.Pattern;
var governingIdentifier = GetIdentifierNameFromExpression(targetExpression);
- var expression = BuildRecursivePatternExpression(recursivePattern, governingIdentifier, null, targetNode);
+ var expression = BuildRecursivePatternExpression(recursivePattern, governingIdentifier, targetNode);
return expression.Parenthesized().Not();
}
case SyntaxKind.ConstantPattern: {
@@ -1480,7 +1486,7 @@ private LuaExpressionSyntax BuildPatternExpression(LuaExpressionSyntax targetExp
} else {
name = GetIdentifierNameFromExpression(targetExpression);
}
- return BuildRecursivePatternExpression(recursivePattern, name, null, targetNode);
+ return BuildRecursivePatternExpression(recursivePattern, name, targetNode);
}
}
}
diff --git a/CSharp.lua/LuaSyntaxNodeTransform.cs b/CSharp.lua/LuaSyntaxNodeTransform.cs
index 8b565efd..c797a38a 100644
--- a/CSharp.lua/LuaSyntaxNodeTransform.cs
+++ b/CSharp.lua/LuaSyntaxNodeTransform.cs
@@ -1239,7 +1239,9 @@ public override LuaSyntaxNode VisitIndexerDeclaration(IndexerDeclarationSyntax n
var indexName = GetMemberName(symbol);
var parameterList = node.ParameterList.Accept(this);
- void Fill(Action action) {
+ void Fill(IMethodSymbol accessorSymbol, Action action) {
+ var methodInfo = new MethodInfo(accessorSymbol);
+ methodInfos_.Push(methodInfo);
var function = new LuaFunctionExpressionSyntax();
function.AddParameter(LuaIdentifierNameSyntax.This);
function.ParameterList.Parameters.AddRange(parameterList.Parameters);
@@ -1247,12 +1249,14 @@ void Fill(Action {
+ var accessorSymbol = semanticModel_.GetDeclaredSymbol(accessor);
+ Fill(accessorSymbol, (function, name) => {
bool isGet = accessor.IsKind(SyntaxKind.GetAccessorDeclaration);
if (accessor.Body != null) {
var block = accessor.Body.Accept(this);
@@ -1272,7 +1276,7 @@ void Fill(Action {
+ Fill(symbol.GetMethod, (function, name) => {
var bodyExpression = node.ExpressionBody.AcceptExpression(this);
function.AddStatement(new LuaReturnStatementSyntax(bodyExpression));
});
@@ -3675,11 +3679,19 @@ public override LuaSyntaxNode VisitElseClause(ElseClauseSyntax node) {
}
public override LuaSyntaxNode VisitSwitchStatement(SwitchStatementSyntax node) {
- var temp = GetTempIdentifier();
- var switchStatement = new LuaSwitchAdapterStatementSyntax(temp);
+ var switchStatement = new LuaSwitchAdapterStatementSyntax();
switches_.Push(switchStatement);
+ PushBlock(switchStatement.Body);
var expression = node.Expression.AcceptExpression(this);
- switchStatement.Fill(expression, node.Sections.Select(i => i.Accept(this)));
+ if (expression is LuaIdentifierNameSyntax name) {
+ switchStatement.Temp = name;
+ } else {
+ var temp = GetTempIdentifier();
+ switchStatement.Temp = temp;
+ switchStatement.Body.Statements.Add(new LuaLocalVariableDeclaratorSyntax(temp, expression));
+ }
+ switchStatement.Fill(node.Sections.Select(i => i.Accept(this)));
+ PopBlock();
switches_.Pop();
return switchStatement;
}
@@ -3713,8 +3725,14 @@ public override LuaSyntaxNode VisitSwitchSection(SwitchSectionSyntax node) {
public override LuaSyntaxNode VisitCaseSwitchLabel(CaseSwitchLabelSyntax node) {
var left = switches_.Peek().Temp;
- var right = node.Value.AcceptExpression(this);
- return left.EqualsEquals(right);
+ var symbol = semanticModel_.GetSymbolInfo(node.Value).Symbol;
+ if (symbol?.Kind == SymbolKind.NamedType) {
+ var switchStatement = (SwitchStatementSyntax)FindParent(node, SyntaxKind.SwitchStatement);
+ return BuildTypePattern(node.Value, left, switchStatement.Expression, null);
+ } else {
+ var right = node.Value.AcceptExpression(this);
+ return left.EqualsEquals(right);
+ }
}
private LuaExpressionSyntax BuildSwitchLabelWhenClause(LuaExpressionSyntax expression, WhenClauseSyntax whenClause) {
@@ -3735,14 +3753,19 @@ private LuaExpressionSyntax BuildDeclarationPattern(DeclarationPatternSyntax dec
if (!declarationPattern.Designation.IsKind(SyntaxKind.DiscardDesignation)) {
AddLocalVariableMapping(left, declarationPattern.Designation);
}
- var isExpression = BuildIsPatternExpression(expressionType, declarationPattern.Type, left);
+
+ return BuildTypePattern(declarationPattern.Type, left, expressionType, whenClause);
+ }
+
+ private LuaExpressionSyntax BuildTypePattern(ExpressionSyntax typePattern, LuaIdentifierNameSyntax left, ExpressionSyntax expressionType, WhenClauseSyntax whenClause) {
+ var isExpression = BuildIsPatternExpression(expressionType, typePattern, left);
if (isExpression == LuaIdentifierLiteralExpressionSyntax.True) {
return whenClause != null ? whenClause.AcceptExpression(this) : LuaIdentifierLiteralExpressionSyntax.True;
}
return BuildSwitchLabelWhenClause(isExpression, whenClause);
- }
-
+ }
+
public override LuaSyntaxNode VisitCasePatternSwitchLabel(CasePatternSwitchLabelSyntax node) {
var left = switches_.Peek().Temp;
switch (node.Pattern.Kind()) {
@@ -3759,7 +3782,11 @@ public override LuaSyntaxNode VisitCasePatternSwitchLabel(CasePatternSwitchLabel
case SyntaxKind.RecursivePattern: {
var recursivePattern = (RecursivePatternSyntax)node.Pattern;
var switchStatement = (SwitchStatementSyntax)FindParent(node, SyntaxKind.SwitchStatement);
- var expression = BuildRecursivePatternExpression(recursivePattern, left, null, switchStatement.Expression);
+ LuaLocalVariablesSyntax deconstruct = null;
+ var expression = BuildRecursivePatternExpression(recursivePattern, left, ref deconstruct, switchStatement.Expression);
+ if (deconstruct != null) {
+ CurBlock.AddStatement(deconstruct);
+ }
return BuildSwitchLabelWhenClause(expression, node.WhenClause);
}
case SyntaxKind.AndPattern:
@@ -3768,6 +3795,11 @@ public override LuaSyntaxNode VisitCasePatternSwitchLabel(CasePatternSwitchLabel
var expression = BuildPatternExpression(left, node.Pattern, switchStatement.Expression);
return BuildSwitchLabelWhenClause(expression, node.WhenClause);
}
+ case SyntaxKind.TypePattern: {
+ var switchStatement = (SwitchStatementSyntax)FindParent(node, SyntaxKind.SwitchStatement);
+ var typePattern = (TypePatternSyntax)node.Pattern;
+ return BuildTypePattern(typePattern.Type, left, switchStatement.Expression, node.WhenClause);
+ }
default: {
var patternExpression = node.Pattern.AcceptExpression(this);
var expression = left.EqualsEquals(patternExpression);
@@ -3840,7 +3872,12 @@ public override LuaSyntaxNode VisitRelationalPattern(RelationalPatternSyntax nod
return node.Expression.AcceptExpression(this);
}
- private LuaExpressionSyntax BuildRecursivePatternExpression(RecursivePatternSyntax recursivePattern, LuaIdentifierNameSyntax governingIdentifier, LuaLocalVariablesSyntax deconstruct, ExpressionSyntax governingExpression) {
+ private LuaExpressionSyntax BuildRecursivePatternExpression(RecursivePatternSyntax recursivePattern, LuaIdentifierNameSyntax governingIdentifier, ExpressionSyntax governingExpression) {
+ LuaLocalVariablesSyntax deconstruct = null;
+ return BuildRecursivePatternExpression(recursivePattern, governingIdentifier, ref deconstruct, governingExpression);
+ }
+
+ private LuaExpressionSyntax BuildRecursivePatternExpression(RecursivePatternSyntax recursivePattern, LuaIdentifierNameSyntax governingIdentifier, ref LuaLocalVariablesSyntax deconstruct, ExpressionSyntax governingExpression) {
var subpatterns = recursivePattern.PropertyPatternClause?.Subpatterns ?? recursivePattern.PositionalPatternClause.Subpatterns;
var subpatternExpressions = new List();
int subpatternIndex = 0;
@@ -3868,8 +3905,8 @@ private LuaExpressionSyntax BuildRecursivePatternExpression(RecursivePatternSynt
var variable = deconstruct.Variables[subpatternIndex];
subpatternExpressions.Add(variable.EqualsEquals(expression));
}
+ ++subpatternIndex;
}
- ++subpatternIndex;
var condition = subpatternExpressions.Count > 0
? subpatternExpressions.Aggregate((x, y) => x.And(y))
: governingIdentifier.NotEquals(LuaIdentifierNameSyntax.Nil);
@@ -3919,7 +3956,7 @@ public override LuaSyntaxNode VisitSwitchExpression(SwitchExpressionSyntax node)
if (recursivePattern.Designation != null) {
AddLocalVariableMapping(governingIdentifier, recursivePattern.Designation);
}
- var condition = BuildRecursivePatternExpression(recursivePattern, governingIdentifier, deconstruct, node.GoverningExpression);
+ var condition = BuildRecursivePatternExpression(recursivePattern, governingIdentifier, ref deconstruct, node.GoverningExpression);
FillSwitchPatternSyntax(ref ifStatement, condition, arm.WhenClause, result, arm.Expression);
break;
}
diff --git a/CSharp.lua/System.xml b/CSharp.lua/System.xml
index ecf0e12b..46d82436 100644
--- a/CSharp.lua/System.xml
+++ b/CSharp.lua/System.xml
@@ -731,6 +731,7 @@ limitations under the License.
+