private static VBSyntax.ExpressionSyntax GetInitializerToConvert(VariableDeclaratorSyntax declarator) { return(declarator.AsClause?.TypeSwitch( (VBSyntax.SimpleAsClauseSyntax _) => declarator.Initializer?.Value, (VBSyntax.AsNewClauseSyntax c) => c.NewExpression ) ?? declarator.Initializer?.Value); }
public async Task <(IReadOnlyCollection <(CSSyntax.VariableDeclarationSyntax Decl, ITypeSymbol Type)> Variables, IReadOnlyCollection <CSharpSyntaxNode> Methods)> SplitVariableDeclarationsAsync( VariableDeclaratorSyntax declarator, HashSet <ILocalSymbol> symbolsToSkip = null, bool preferExplicitType = false) { var vbInitValue = GetInitializerToConvert(declarator); var initializerOrMethodDecl = await vbInitValue.AcceptAsync <CSharpSyntaxNode>(TriviaConvertingExpressionVisitor); var vbInitializerTypeInfo = vbInitValue != null?SemanticModel.GetTypeInfo(vbInitValue) : default(TypeInfo?); var vbInitializerType = vbInitValue != null ? vbInitializerTypeInfo.Value.Type : default(ITypeSymbol); bool requireExplicitTypeForAll = declarator.Names.Count > 1; IMethodSymbol initSymbol = null; if (vbInitValue != null) { TypeInfo expType = vbInitializerTypeInfo.Value; preferExplicitType |= ShouldPreferExplicitType(vbInitValue, expType.ConvertedType, out bool vbInitIsNothingLiteral); initSymbol = SemanticModel.GetSymbolInfo(vbInitValue).Symbol as IMethodSymbol; bool isAnonymousFunction = initSymbol?.IsAnonymousFunction() == true; requireExplicitTypeForAll |= vbInitIsNothingLiteral || isAnonymousFunction; } var csVars = new Dictionary <string, (CSSyntax.VariableDeclarationSyntax Decl, ITypeSymbol Type)>(); var csMethods = new List <CSharpSyntaxNode>(); foreach (var name in declarator.Names) { var declaredSymbol = SemanticModel.GetDeclaredSymbol(name); if (symbolsToSkip?.Contains(declaredSymbol, SymbolEqualityComparer.IncludeNullability) == true) { continue; } var declaredSymbolType = declaredSymbol.GetSymbolType(); var equalsValueClauseSyntax = await ConvertEqualsValueClauseSyntaxAsync(declarator, name, vbInitValue, declaredSymbolType, declaredSymbol, initializerOrMethodDecl); var v = SyntaxFactory.VariableDeclarator(ConvertIdentifier(name.Identifier), null, equalsValueClauseSyntax); string k = declaredSymbolType?.GetFullMetadataName() ?? name.ToString();//Use likely unique key if the type symbol isn't available if (csVars.TryGetValue(k, out var decl)) { csVars[k] = (decl.Decl.AddVariables(v), decl.Type); continue; } if (initializerOrMethodDecl == null || initializerOrMethodDecl is ExpressionSyntax) { var variableDeclaration = CreateVariableDeclaration(preferExplicitType, requireExplicitTypeForAll, vbInitializerType, declaredSymbolType, equalsValueClauseSyntax, initSymbol, v); csVars[k] = (variableDeclaration, declaredSymbolType); } else { csMethods.Add(initializerOrMethodDecl); } } return(csVars.Values, csMethods); }
private async Task <CSSyntax.EqualsValueClauseSyntax> ConvertEqualsValueClauseSyntaxAsync( VariableDeclaratorSyntax vbDeclarator, VBSyntax.ModifiedIdentifierSyntax vbName, VBSyntax.ExpressionSyntax vbInitValue, ITypeSymbol declaredSymbolType, ISymbol declaredSymbol, CSharpSyntaxNode initializerOrMethodDecl) { var csTypeSyntax = GetTypeSyntax(declaredSymbolType); bool isField = vbDeclarator.Parent.IsKind(SyntaxKind.FieldDeclaration); bool declaredConst = declaredSymbol is IFieldSymbol fieldSymbol && fieldSymbol.IsConst || declaredSymbol is ILocalSymbol localSymbol && localSymbol.IsConst; CSSyntax.EqualsValueClauseSyntax equalsValueClauseSyntax; if (await GetInitializerFromNameAndTypeAsync(declaredSymbolType, vbName, initializerOrMethodDecl) is ExpressionSyntax adjustedInitializerExpr) { var convertedInitializer = vbInitValue != null ? TypeConversionAnalyzer.AddExplicitConversion(vbInitValue, adjustedInitializerExpr, isConst : declaredConst) : adjustedInitializerExpr; if (isField && !declaredSymbol.IsStatic && !SemanticModel.IsDefinitelyStatic(vbName, vbInitValue)) { if (!_typeContext.Initializers.HasInstanceConstructorsOutsideThisPart) { var lhs = SyntaxFactory.IdentifierName(ConvertIdentifier(vbName.Identifier, sourceTriviaMapKind: SourceTriviaMapKind.None)); _typeContext.Initializers.AdditionalInstanceInitializers.Add(new Assignment(lhs, CSSyntaxKind.SimpleAssignmentExpression, adjustedInitializerExpr)); equalsValueClauseSyntax = null; } else { var returnBlock = SyntaxFactory.Block(SyntaxFactory.ReturnStatement(adjustedInitializerExpr)); _typeContext.PerScopeState.Hoist(new HoistedParameterlessFunction(GetInitialValueFunctionName(vbName), csTypeSyntax, returnBlock)); equalsValueClauseSyntax = null; } } else { equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(convertedInitializer); } } else if (isField || declaredSymbol != null && SemanticModel.IsDefinitelyAssignedBeforeRead(declaredSymbol, vbName)) { equalsValueClauseSyntax = null; } else { // VB initializes variables to their default equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(SyntaxFactory.DefaultExpression(csTypeSyntax)); } return(equalsValueClauseSyntax); }