Skip to content

Commit 3610493

Browse files
committed
fix PropertyPatternClause
1 parent e2f8cdd commit 3610493

7 files changed

Lines changed: 126 additions & 53 deletions

File tree

‎CSharp.lua.Launcher/Program.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Program {
2727
private const string kHelpCmdString = @"Usage: CSharp.lua [-s srcfolder] [-d dstfolder]
2828
Arguments
2929
-s : can be a directory where all cs files will be compiled, or a list of files, using ';' or ',' to separate
30-
-d : destination directory, will put the out lua files
30+
-d : destination directory, will put the out lua files
3131
3232
Options
3333
-h : show the help message and exit

‎CSharp.lua/CoreSystem.Lua/CoreSystem/Delegate.lua‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ if debugsetmetatable then
183183
else
184184
System.DelegateCombine = combine
185185
System.DelegateRemove = remove
186+
187+
function System.event(name)
188+
local function a(this, v)
189+
this[name] = combine(this[name], v)
190+
end
191+
local function r(this, v)
192+
this[name] = remove(this[name], v)
193+
end
194+
return a, r
195+
end
186196
end
187197

188198
multicast = setmetatable({

‎CSharp.lua/CoreSystem.Lua/CoreSystem/Exception.lua‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,4 +306,12 @@ define("System.AggregateException", {
306306
getInnerExceptions = function (this)
307307
return this.innerExceptions
308308
end
309-
})
309+
})
310+
311+
System.SwitchExpressionException = define("System.Runtime.CompilerServices", {
312+
__tostring = toString,
313+
__inherits__ = { InvalidOperationException },
314+
__ctor__ = function(this, message, innerException)
315+
ctorOfException(this, message or "Non-exhaustive switch expression failed to match its input.", innerException)
316+
end
317+
})

‎CSharp.lua/LuaSyntaxNodeTransform.Object.cs‎

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,11 +1232,15 @@ public override LuaSyntaxNode VisitSingleVariableDesignation(SingleVariableDesig
12321232
return name;
12331233
}
12341234

1235-
private LuaExpressionSyntax BuildIsExpression(ExpressionSyntax leftTypeExpression, ExpressionSyntax rightTypeExpression, LuaIdentifierNameSyntax leftName) {
1235+
private LuaExpressionSyntax BuildIsPatternExpression(ExpressionSyntax leftTypeExpression, ExpressionSyntax rightTypeExpression, LuaIdentifierNameSyntax leftName) {
12361236
var leftType = semanticModel_.GetTypeInfo(leftTypeExpression).Type;
12371237
var rightType = semanticModel_.GetTypeInfo(rightTypeExpression).Type;
12381238
if (leftType.Is(rightType)) {
1239-
return LuaIdentifierLiteralExpressionSyntax.True;
1239+
if (leftType.IsValueType) {
1240+
return LuaIdentifierLiteralExpressionSyntax.True;
1241+
} else {
1242+
return leftName.NotEquals(LuaIdentifierNameSyntax.Nil);
1243+
}
12401244
} else {
12411245
var type = rightTypeExpression.AcceptExpression(this);
12421246
return new LuaInvocationExpressionSyntax(LuaIdentifierNameSyntax.Is, leftName, type);
@@ -1249,11 +1253,14 @@ private LuaExpressionSyntax BuildIsConstantExpression(CSharpSyntaxNode left, CSh
12491253
}
12501254

12511255
private LuaExpressionSyntax BuildIsConstantExpression(CSharpSyntaxNode left, CSharpSyntaxNode right, Optional<object> constValue) {
1256+
const string kIsNaNMethodName = "System.Double.IsNaN";
1257+
12521258
Contract.Assert(constValue.HasValue);
12531259
var leftExpression = left.AcceptExpression(this);
12541260
if (constValue.Value is double.NaN) {
1255-
return new LuaInvocationExpressionSyntax("System.Double.IsNaN", leftExpression);
1261+
return new LuaInvocationExpressionSyntax(kIsNaNMethodName, leftExpression);
12561262
}
1263+
12571264
var rightExpression = right.AcceptExpression(this);
12581265
return leftExpression.EqualsEquals(rightExpression);
12591266
}
@@ -1274,11 +1281,26 @@ public override LuaSyntaxNode VisitIsPatternExpression(IsPatternExpressionSyntax
12741281
return BuildIsConstantExpression(node.Expression, pattern.Expression);
12751282
}
12761283
default: {
1277-
var expression = node.Expression.AcceptExpression(this);
1278-
var declarationPattern = (DeclarationPatternSyntax)node.Pattern;
1279-
var name = declarationPattern.Designation.Accept<LuaIdentifierNameSyntax>(this);
1280-
CurBlock.AddStatement(new LuaLocalVariableDeclaratorSyntax(name, expression));
1281-
return BuildIsExpression(node.Expression, declarationPattern.Type, name);
1284+
var targetExpression = node.Expression.AcceptExpression(this);
1285+
if (node.Pattern.IsKind(SyntaxKind.DeclarationPattern)) {
1286+
var declarationPattern = (DeclarationPatternSyntax)node.Pattern;
1287+
var name = declarationPattern.Designation.Accept<LuaIdentifierNameSyntax>(this);
1288+
CurBlock.AddStatement(new LuaLocalVariableDeclaratorSyntax(name, targetExpression));
1289+
return BuildIsPatternExpression(node.Expression, declarationPattern.Type, name);
1290+
} else {
1291+
var recursivePattern = (RecursivePatternSyntax)node.Pattern;
1292+
LuaIdentifierNameSyntax name;
1293+
if (recursivePattern.Designation != null) {
1294+
name = recursivePattern.Designation.Accept<LuaIdentifierNameSyntax>(this);
1295+
CurBlock.AddStatement(new LuaLocalVariableDeclaratorSyntax(name, targetExpression));
1296+
} else if (targetExpression is LuaIdentifierNameSyntax identifierName) {
1297+
name = identifierName;
1298+
} else {
1299+
name = GetTempIdentifier();
1300+
CurBlock.AddStatement(new LuaLocalVariableDeclaratorSyntax(name, targetExpression));
1301+
}
1302+
return BuildRecursivePatternExpression(recursivePattern, name, null, node.Expression);
1303+
}
12821304
}
12831305
}
12841306
}

‎CSharp.lua/LuaSyntaxNodeTransform.cs‎

Lines changed: 74 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3470,7 +3470,7 @@ private LuaExpressionSyntax BuildDeclarationPattern(DeclarationPatternSyntax dec
34703470
if (!declarationPattern.Designation.IsKind(SyntaxKind.DiscardDesignation)) {
34713471
AddLocalVariableMapping(left, declarationPattern.Designation);
34723472
}
3473-
var isExpression = BuildIsExpression(expressionType, declarationPattern.Type, left);
3473+
var isExpression = BuildIsPatternExpression(expressionType, declarationPattern.Type, left);
34743474
if (isExpression == LuaIdentifierLiteralExpressionSyntax.True) {
34753475
return whenClause != null ? whenClause.AcceptExpression(this) : LuaIdentifierLiteralExpressionSyntax.True;
34763476
} else {
@@ -3542,7 +3542,65 @@ private void CheckSwitchDeconstruct(ref LuaLocalVariablesStatementSyntax deconst
35423542
}
35433543
}
35443544

3545+
public LuaExpressionSyntax BuildPropertyPatternNameExpression(LuaIdentifierNameSyntax governingIdentifier, IdentifierNameSyntax nameIdentifier) {
3546+
var symbol = semanticModel_.GetSymbolInfo(nameIdentifier).Symbol;
3547+
if (symbol.Kind == SymbolKind.Field) {
3548+
var name = GetMemberName(symbol);
3549+
return governingIdentifier.MemberAccess(name);
3550+
} else {
3551+
var propertySymbol = (IPropertySymbol)symbol;
3552+
var codeTemplate = XmlMetaProvider.GetProertyCodeTemplate(propertySymbol, true);
3553+
if (codeTemplate != null) {
3554+
return InternalBuildCodeTemplateExpression(codeTemplate, null, null, null, governingIdentifier);
3555+
}
3556+
3557+
var name = nameIdentifier.AcceptExpression(this);
3558+
return governingIdentifier.MemberAccess(name, name is LuaPropertyAdapterExpressionSyntax);
3559+
}
3560+
}
3561+
3562+
private LuaExpressionSyntax BuildRecursivePatternExpression(RecursivePatternSyntax recursivePattern, LuaIdentifierNameSyntax governingIdentifier, LuaLocalVariablesStatementSyntax deconstruct, ExpressionSyntax governingExpression) {
3563+
var subpatterns = recursivePattern.PropertyPatternClause?.Subpatterns ?? recursivePattern.PositionalPatternClause.Subpatterns;
3564+
var subpatternExpressions = new List<LuaExpressionSyntax>();
3565+
int subpatternIndex = 0;
3566+
foreach (var subpattern in subpatterns) {
3567+
var expression = subpattern.Pattern.AcceptExpression(this);
3568+
if (subpattern.NameColon != null) {
3569+
LuaExpressionSyntax left;
3570+
if (governingIdentifier != null) {
3571+
left = BuildPropertyPatternNameExpression(governingIdentifier, subpattern.NameColon.Name);
3572+
} else {
3573+
var fieldSymbol = (IFieldSymbol)semanticModel_.GetSymbolInfo(subpattern.NameColon.Name).Symbol;
3574+
Contract.Assert(fieldSymbol.ContainingType.IsTupleType);
3575+
int elementIndex = fieldSymbol.GetTupleElementIndex();
3576+
left = deconstruct.Variables[subpatternIndex];
3577+
}
3578+
subpatternExpressions.Add(left.EqualsEquals(expression));
3579+
} else if (!subpattern.Pattern.IsKind(SyntaxKind.DiscardPattern)) {
3580+
CheckSwitchDeconstruct(ref deconstruct, governingIdentifier, recursivePattern.Type ?? governingExpression, subpatterns.Count);
3581+
var variable = deconstruct.Variables[subpatternIndex];
3582+
subpatternExpressions.Add(variable.EqualsEquals(expression));
3583+
}
3584+
}
3585+
++subpatternIndex;
3586+
LuaExpressionSyntax condition;
3587+
if (subpatternExpressions.Count > 0) {
3588+
condition = subpatternExpressions.Aggregate((x, y) => x.And(y));
3589+
} else {
3590+
condition = governingIdentifier.NotEquals(LuaIdentifierNameSyntax.Nil);
3591+
}
3592+
if (recursivePattern.Type != null) {
3593+
var isExpression = BuildIsPatternExpression(governingExpression, recursivePattern.Type, governingIdentifier);
3594+
if (isExpression != LuaIdentifierLiteralExpressionSyntax.True) {
3595+
condition = isExpression.And(condition);
3596+
}
3597+
}
3598+
return condition;
3599+
}
3600+
35453601
public override LuaSyntaxNode VisitSwitchExpression(SwitchExpressionSyntax node) {
3602+
const string kNewSwitchExpressionException = "System.SwitchExpressionException()";
3603+
35463604
var result = GetTempIdentifier();
35473605
CurBlock.AddStatement(new LuaLocalVariableDeclaratorSyntax(result));
35483606

@@ -3574,46 +3632,10 @@ public override LuaSyntaxNode VisitSwitchExpression(SwitchExpressionSyntax node)
35743632
}
35753633
case SyntaxKind.RecursivePattern: {
35763634
var recursivePattern = (RecursivePatternSyntax)arm.Pattern;
3577-
var subpatterns = recursivePattern.PropertyPatternClause?.Subpatterns ?? recursivePattern.PositionalPatternClause.Subpatterns;
3578-
var subpatternExpressions = new List<LuaExpressionSyntax>();
3579-
int subpatternIndex = 0;
3580-
foreach (var subpattern in subpatterns) {
3581-
var expression = subpattern.Pattern.AcceptExpression(this);
3582-
if (subpattern.NameColon != null) {
3583-
LuaExpressionSyntax left;
3584-
if (governingIdentifier != null) {
3585-
var name = subpattern.NameColon.Name.AcceptExpression(this);
3586-
left = governingIdentifier.MemberAccess(name);
3587-
} else {
3588-
var fieldSymbol = (IFieldSymbol)semanticModel_.GetSymbolInfo(subpattern.NameColon.Name).Symbol;
3589-
Contract.Assert(fieldSymbol.ContainingType.IsTupleType);
3590-
int elementIndex = fieldSymbol.GetTupleElementIndex();
3591-
left = deconstruct.Variables[subpatternIndex];
3592-
}
3593-
subpatternExpressions.Add(left.EqualsEquals(expression));
3594-
} else if (!subpattern.Pattern.IsKind(SyntaxKind.DiscardPattern)) {
3595-
CheckSwitchDeconstruct(ref deconstruct, governingIdentifier, recursivePattern.Type ?? node.GoverningExpression, subpatterns.Count);
3596-
var variable = deconstruct.Variables[subpatternIndex];
3597-
subpatternExpressions.Add(variable.EqualsEquals(expression));
3598-
}
3599-
}
3600-
++subpatternIndex;
3601-
LuaExpressionSyntax condition;
3602-
if (subpatternExpressions.Count > 0) {
3603-
condition = subpatternExpressions.Aggregate((x, y) => x.And(y));
3604-
} else {
3605-
condition = LuaIdentifierLiteralExpressionSyntax.True;
3606-
}
3607-
if (recursivePattern.Type != null) {
3608-
var isExpression = BuildIsExpression(node.GoverningExpression, recursivePattern.Type, governingIdentifier);
3609-
if (isExpression != LuaIdentifierLiteralExpressionSyntax.True) {
3610-
if (condition != LuaIdentifierLiteralExpressionSyntax.True) {
3611-
condition = isExpression;
3612-
} else {
3613-
condition = isExpression.And(condition);
3614-
}
3615-
}
3635+
if (recursivePattern.Designation != null) {
3636+
AddLocalVariableMapping(governingIdentifier, recursivePattern.Designation);
36163637
}
3638+
var condition = BuildRecursivePatternExpression(recursivePattern, governingIdentifier, deconstruct, node.GoverningExpression);
36173639
FillSwitchPatternSyntax(ref ifStatement, condition, arm.WhenClause, result, arm.Expression);
36183640
break;
36193641
}
@@ -3653,9 +3675,16 @@ public override LuaSyntaxNode VisitSwitchExpression(SwitchExpressionSyntax node)
36533675
}
36543676
}
36553677

3678+
if (ifStatement.Else == null) {
3679+
var elseClause = new LuaElseClauseSyntax();
3680+
elseClause.Body.AddStatement(LuaIdentifierNameSyntax.Throw.Invocation(kNewSwitchExpressionException));
3681+
ifStatement.Else = elseClause;
3682+
}
3683+
36563684
if (deconstruct != null) {
36573685
CurBlock.AddStatement(deconstruct);
36583686
}
3687+
36593688
CurBlock.AddStatement(ifStatement);
36603689
return result;
36613690
}
@@ -4083,7 +4112,11 @@ public override LuaSyntaxNode VisitBinaryExpression(BinaryExpressionSyntax node)
40834112

40844113
var leftType = semanticModel_.GetTypeInfo(node.Left).Type;
40854114
if (leftType.Is(rightType)) {
4086-
return LuaIdentifierLiteralExpressionSyntax.True;
4115+
if (leftType.IsValueType) {
4116+
return LuaIdentifierLiteralExpressionSyntax.True;
4117+
} else {
4118+
return node.Left.AcceptExpression(this).NotEquals(LuaIdentifierNameSyntax.Nil);
4119+
}
40874120
}
40884121

40894122
var constValue = semanticModel_.GetConstantValue(node.Right);

‎CSharp.lua/System.xml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,6 @@ limitations under the License.
760760
<method name="op_Implicit" Name="ToComplex" />
761761
</class>
762762
</namespace>
763-
763+
<namespace name="System.Runtime.CompilerServices" Name="System" />
764764
</assembly>
765765
</meta>

‎README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ D:\>dotnet CSharp.Lua.Launcher.dll -h
5555
Usage: CSharp.lua [-s srcfolder] [-d dstfolder]
5656
Arguments
5757
-s : can be a directory where all cs files will be compiled, or a list of files, using ';' or ',' to separate
58-
-d : destination directory, will put the out lua files
58+
-d : destination directory, will put the out lua files
5959
6060
Options
6161
-h : show the help message and exit

0 commit comments

Comments
 (0)