@@ -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 ) ;
0 commit comments