1313using VBasic = Microsoft . CodeAnalysis . VisualBasic ;
1414using VBSyntax = Microsoft . CodeAnalysis . VisualBasic . Syntax ;
1515using Microsoft . CodeAnalysis . Text ;
16+ using ICSharpCode . CodeConverter . Util . FromRoslyn ;
1617
1718namespace ICSharpCode . CodeConverter . CSharp
1819{
@@ -474,12 +475,12 @@ public override async Task<SyntaxList<StatementSyntax>> VisitForBlock(VBSyntax.F
474475 id = ( ExpressionSyntax ) await stmt . ControlVariable . AcceptAsync ( _expressionVisitor ) ;
475476
476477 // If missing semantic info, the compiler just guesses object. In this branch there was no explicit type, so let's try to improve on that guess:
477- var bestType = controlVarType . Yield ( )
478+ controlVarType = controlVarType . Yield ( )
478479 . Concat ( new [ ] { stmt . FromValue , stmt . ToValue , stmt . StepClause ? . StepValue } . Select ( exp => _semanticModel . GetTypeInfo ( exp ) . Type ) )
479480 . FirstOrDefault ( t => t != null && t . SpecialType != SpecialType . System_Object ) ;
480481
481482 if ( controlVarSymbol != null && controlVarSymbol . DeclaringSyntaxReferences . Any ( r => r . Span . OverlapsWith ( stmt . ControlVariable . Span ) ) ) {
482- declaration = CommonConversions . CreateVariableDeclarationAndAssignment ( controlVarSymbol . Name , startValue , CommonConversions . GetTypeSyntax ( bestType ) ) ;
483+ declaration = CommonConversions . CreateVariableDeclarationAndAssignment ( controlVarSymbol . Name , startValue , CommonConversions . GetTypeSyntax ( controlVarType ) ) ;
483484 } else {
484485 startValue = SyntaxFactory . AssignmentExpression ( SyntaxKind . SimpleAssignmentExpression , id , startValue ) ;
485486 initializers . Add ( startValue ) ;
@@ -498,6 +499,7 @@ public override async Task<SyntaxList<StatementSyntax>> VisitForBlock(VBSyntax.F
498499 var loopToAssignment = CommonConversions . CreateVariableDeclarator ( loopToVariableName , csToValue ) ;
499500 declaration = declaration . AddVariables ( loopToAssignment ) ;
500501 } else {
502+ csToValue = CommonConversions . TypeConversionAnalyzer . AddExplicitConversion ( stmt . ToValue , csToValue , forceTargetType : controlVarType ) ;
501503 var loopEndDeclaration = SyntaxFactory . LocalDeclarationStatement (
502504 CommonConversions . CreateVariableDeclarationAndAssignment ( loopToVariableName , csToValue ) ) ;
503505 // Does not do anything about porting newline trivia upwards to maintain spacing above the loop
@@ -507,8 +509,7 @@ public override async Task<SyntaxList<StatementSyntax>> VisitForBlock(VBSyntax.F
507509 csToValue = toVariableId ;
508510 } ;
509511
510-
511- var ( csCondition , csStep ) = await ConvertConditionAndStepClause ( stmt , id , csToValue ) ;
512+ var ( csCondition , csStep ) = await ConvertConditionAndStepClause ( stmt , id , csToValue , controlVarType ) ;
512513
513514 var block = SyntaxFactory . Block ( await ConvertStatements ( node . Statements ) ) ;
514515 var forStatementSyntax = SyntaxFactory . ForStatement (
@@ -525,11 +526,15 @@ public override async Task<SyntaxList<StatementSyntax>> VisitForBlock(VBSyntax.F
525526 return await CommonConversions . SplitVariableDeclarations ( v , _localsToInlineInLoop , preferExplicitType ) ;
526527 }
527528
528- private async Task < ( ExpressionSyntax , ExpressionSyntax ) > ConvertConditionAndStepClause ( VBSyntax . ForStatementSyntax stmt , ExpressionSyntax id , ExpressionSyntax csToValue )
529+ private async Task < ( ExpressionSyntax , ExpressionSyntax ) > ConvertConditionAndStepClause ( VBSyntax . ForStatementSyntax stmt , ExpressionSyntax id , ExpressionSyntax csToValue , ITypeSymbol controlVarType )
529530 {
530531 var vbStepValue = stmt . StepClause ? . StepValue ;
531532 var csStepValue = ( ExpressionSyntax ) await ( stmt . StepClause ? . StepValue ) . AcceptAsync ( _expressionVisitor ) ;
532- csStepValue = csStepValue ? . SkipParens ( ) ;
533+ // For an enum, you need to add on an integer for example:
534+ var forceStepType = controlVarType is INamedTypeSymbol nt && nt . IsEnumType ( ) ? nt . EnumUnderlyingType : controlVarType ;
535+ csStepValue = CommonConversions . TypeConversionAnalyzer . AddExplicitConversion ( vbStepValue , csStepValue ? . SkipParens ( ) , forceTargetType : forceStepType ) ;
536+ csToValue = CommonConversions . TypeConversionAnalyzer . AddExplicitConversion ( stmt . ToValue , csToValue ? . SkipParens ( ) , forceTargetType : controlVarType ) ;
537+
533538 var nonNegativeCondition = SyntaxFactory . BinaryExpression ( SyntaxKind . LessThanOrEqualExpression , id , csToValue ) ;
534539 var negativeCondition = SyntaxFactory . BinaryExpression ( SyntaxKind . GreaterThanOrEqualExpression , id , csToValue ) ;
535540 if ( csStepValue == null ) {
0 commit comments