private TypeSyntax ConvertDeclaratorType(VariableDeclaratorSyntax declarator, bool preferExplicitType) { var vbType = declarator.AsClause?.TypeSwitch( (SimpleAsClauseSyntax c) => c.Type, (AsNewClauseSyntax c) => c.NewExpression.Type(), _ => throw new NotImplementedException($"{_.GetType().FullName} not implemented!")); return((TypeSyntax)vbType?.Accept(_nodesVisitor) ?? GetTypeSyntax(declarator, preferExplicitType)); }
public async Task <(IReadOnlyCollection <VariableDeclarationSyntax> Variables, IReadOnlyCollection <CSharpSyntaxNode> Methods)> SplitVariableDeclarations( VariableDeclaratorSyntax declarator, bool preferExplicitType = false) { var vbInitValue = GetInitializerToConvert(declarator); var initializerOrMethodDecl = await vbInitValue.AcceptAsync(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, VariableDeclarationSyntax>(); var csMethods = new List <CSharpSyntaxNode>(); foreach (var name in declarator.Names) { var declaredSymbol = _semanticModel.GetDeclaredSymbol(name); var declaredSymbolType = declaredSymbol.GetSymbolType(); var equalsValueClauseSyntax = await ConvertEqualsValueClauseSyntax(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.AddVariables(v); continue; } if (initializerOrMethodDecl == null || initializerOrMethodDecl is ExpressionSyntax) { var variableDeclaration = CreateVariableDeclaration(declarator, preferExplicitType, requireExplicitTypeForAll, vbInitializerType, declaredSymbolType, equalsValueClauseSyntax, initSymbol, v); csVars[k] = variableDeclaration; } else { csMethods.Add(initializerOrMethodDecl); } } return(csVars.Values, csMethods); }
public Dictionary <string, VariableDeclarationSyntax> SplitVariableDeclarations( VariableDeclaratorSyntax declarator, bool preferExplicitType = false) { var rawType = ConvertDeclaratorType(declarator, preferExplicitType); var initializer = ConvertInitializer(declarator); var newDecls = new Dictionary <string, VariableDeclarationSyntax>(); var method = declarator.Ancestors().OfType <MethodBlockBaseSyntax>().SingleOrDefault(); DataFlowAnalysis dataFlow = null; if (method != null) { dataFlow = _semanticModel.AnalyzeDataFlow(method.Statements.First(), method.Statements.Last()); } foreach (var name in declarator.Names) { var(type, adjustedInitializer) = AdjustFromName(rawType, name, initializer); bool isField = declarator.Parent.IsKind(SyntaxKind.FieldDeclaration); EqualsValueClauseSyntax equalsValueClauseSyntax; if (adjustedInitializer != null) { equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(adjustedInitializer); } else { Func <ISymbol, bool> equalsId = s => s.Name.Equals(name.Identifier.ValueText, StringComparison.OrdinalIgnoreCase); bool alwaysAssigned = dataFlow != null && dataFlow.AlwaysAssigned.Any(equalsId); bool neverRead = dataFlow != null && !dataFlow.ReadInside.Any(equalsId) && !dataFlow.ReadOutside.Any(equalsId); if (isField || alwaysAssigned || neverRead) { equalsValueClauseSyntax = null; } else { equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(SyntaxFactory.DefaultExpression(type)); } } var v = SyntaxFactory.VariableDeclarator(ConvertIdentifier(name.Identifier), null, equalsValueClauseSyntax); string k = type.ToString(); if (newDecls.TryGetValue(k, out var decl)) { newDecls[k] = decl.AddVariables(v); } else { newDecls[k] = SyntaxFactory.VariableDeclaration(type, SyntaxFactory.SingletonSeparatedList(v)); } } return(newDecls); }
private async Task <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; 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.ShouldAddTypeWideInitToThisPart) { var lhs = SyntaxFactory.IdentifierName(ConvertIdentifier(vbName.Identifier, sourceTriviaMapKind: SourceTriviaMapKind.None)); _typeContext.Initializers.AdditionalInstanceInitializers.Add((lhs, CSSyntaxKind.SimpleAssignmentExpression, adjustedInitializerExpr)); equalsValueClauseSyntax = null; } else { var returnBlock = SyntaxFactory.Block(SyntaxFactory.ReturnStatement(adjustedInitializerExpr)); _typeContext.HoistedState.Hoist <HoistedParameterlessFunction>(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); }
private VariableDeclarationSyntax CreateVariableDeclaration(VariableDeclaratorSyntax vbDeclarator, bool preferExplicitType, bool requireExplicitTypeForAll, ITypeSymbol vbInitializerType, ITypeSymbol declaredSymbolType, EqualsValueClauseSyntax equalsValueClauseSyntax, IMethodSymbol initSymbol, CSSyntax.VariableDeclaratorSyntax v) { var requireExplicitType = requireExplicitTypeForAll || vbInitializerType != null && !Equals(declaredSymbolType, vbInitializerType); bool useVar = equalsValueClauseSyntax != null && !preferExplicitType && !requireExplicitType; var typeSyntax = initSymbol == null || !initSymbol.IsAnonymousFunction() ? GetTypeSyntax(declaredSymbolType, useVar) : GetFuncTypeSyntax(initSymbol); return(SyntaxFactory.VariableDeclaration(typeSyntax, SyntaxFactory.SingletonSeparatedList(v))); }
private TypeSyntax GetTypeSyntax(VariableDeclaratorSyntax declarator, bool preferExplicitType) { if (!preferExplicitType) { return(CreateVarTypeName()); } var typeInf = _semanticModel.GetTypeInfo(declarator.Initializer.Value); if (typeInf.ConvertedType == null) { return(CreateVarTypeName()); } return(ToCsTypeSyntax(typeInf.ConvertedType, declarator)); }
public Dictionary <string, VariableDeclarationSyntax> SplitVariableDeclarations( VariableDeclaratorSyntax declarator, bool preferExplicitType = false) { var rawType = ConvertDeclaratorType(declarator, preferExplicitType); var initializer = ConvertInitializer(declarator); var newDecls = new Dictionary <string, VariableDeclarationSyntax>(); foreach (var name in declarator.Names) { var(type, adjustedInitializer) = AdjustFromName(rawType, name, initializer); bool isField = declarator.Parent.IsKind(SyntaxKind.FieldDeclaration); EqualsValueClauseSyntax equalsValueClauseSyntax; if (adjustedInitializer != null) { var vbInitializer = declarator.Initializer?.Value; // Explicit conversions are never needed for AsClause, since the type is inferred from the RHS var convertedInitializer = vbInitializer == null ? adjustedInitializer : TypeConversionAnalyzer.AddExplicitConversion(vbInitializer, adjustedInitializer); equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(convertedInitializer); } else if (isField || _semanticModel.IsDefinitelyAssignedBeforeRead(declarator, name)) { equalsValueClauseSyntax = null; } else { // VB initializes variables to their default equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(SyntaxFactory.DefaultExpression(type)); } var v = SyntaxFactory.VariableDeclarator(ConvertIdentifier(name.Identifier), null, equalsValueClauseSyntax); string k = type.ToString(); if (newDecls.TryGetValue(k, out var decl)) { newDecls[k] = decl.AddVariables(v); } else { newDecls[k] = SyntaxFactory.VariableDeclaration(type, SyntaxFactory.SingletonSeparatedList(v)); } } return(newDecls); }
public override SyntaxList <StatementSyntax> VisitForEachVariableStatement(CSS.ForEachVariableStatementSyntax node) { var loopVar = node.Variable.Accept(_nodesVisitor); var extraStatements = new List <StatementSyntax>(); if (node.Variable is CSS.DeclarationExpressionSyntax des && des.Designation is CSS.ParenthesizedVariableDesignationSyntax pv) { var tupleName = CommonConversions.GetTupleName(pv); extraStatements.AddRange(pv.Variables.Select((v, i) => { var initializer = SyntaxFactory.EqualsValue(SyntaxFactory.SimpleMemberAccessExpression( SyntaxFactory.IdentifierName(tupleName), SyntaxFactory.IdentifierName("Item" + (i + 1).ToString()))); VariableDeclaratorSyntax variableDeclaratorSyntax = SyntaxFactory.VariableDeclarator( SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(v.ToString()))) .WithInitializer(initializer); return(CommonConversions.CreateLocalDeclarationStatement(variableDeclaratorSyntax)); })); } return(CreateForEachStatement(loopVar, node.Expression, node.Statement, extraStatements.ToArray())); }
public async Task <(IReadOnlyCollection <VariableDeclarationSyntax> Variables, IReadOnlyCollection <CSharpSyntaxNode> Methods)> SplitVariableDeclarations( VariableDeclaratorSyntax declarator, bool preferExplicitType = false) { var vbInitValue = GetInitializerToConvert(declarator); var initializerOrMethodDecl = await vbInitValue.AcceptAsync(TriviaConvertingExpressionVisitor); var vbInitializerType = vbInitValue != null?_semanticModel.GetTypeInfo(vbInitValue).Type : null; bool requireExplicitTypeForAll = false; IMethodSymbol initSymbol = null; if (vbInitValue != null) { var vbInitConstantValue = _semanticModel.GetConstantValue(vbInitValue); var vbInitIsNothingLiteral = vbInitConstantValue.HasValue && vbInitConstantValue.Value == null; preferExplicitType |= vbInitializerType != null && vbInitializerType.HasCsKeyword(); initSymbol = _semanticModel.GetSymbolInfo(vbInitValue).Symbol as IMethodSymbol; bool isAnonymousFunction = initSymbol?.IsAnonymousFunction() == true; requireExplicitTypeForAll = vbInitIsNothingLiteral || isAnonymousFunction; } var csVars = new Dictionary <string, VariableDeclarationSyntax>(); var csMethods = new List <CSharpSyntaxNode>(); foreach (var name in declarator.Names) { var declaredSymbol = _semanticModel.GetDeclaredSymbol(name); var declaredSymbolType = declaredSymbol.GetSymbolType(); var requireExplicitType = requireExplicitTypeForAll || vbInitializerType != null && !Equals(declaredSymbolType, vbInitializerType); var csTypeSyntax = (TypeSyntax)GetTypeSyntax(declaredSymbolType); bool isField = declarator.Parent.IsKind(SyntaxKind.FieldDeclaration); EqualsValueClauseSyntax equalsValueClauseSyntax; if (await GetInitializerFromNameAndType(declaredSymbolType, name, initializerOrMethodDecl) is ExpressionSyntax adjustedInitializerExpr) { var convertedInitializer = vbInitValue != null?TypeConversionAnalyzer.AddExplicitConversion(vbInitValue, adjustedInitializerExpr) : adjustedInitializerExpr; equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(convertedInitializer); } else if (isField || _semanticModel.IsDefinitelyAssignedBeforeRead(declaredSymbol, name)) { equalsValueClauseSyntax = null; } else { // VB initializes variables to their default equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(SyntaxFactory.DefaultExpression(csTypeSyntax)); } var v = SyntaxFactory.VariableDeclarator(ConvertIdentifier(name.Identifier), null, equalsValueClauseSyntax); string k = declaredSymbolType.GetFullMetadataName(); if (csVars.TryGetValue(k, out var decl)) { csVars[k] = decl.AddVariables(v); } else { if (initializerOrMethodDecl == null || initializerOrMethodDecl is ExpressionSyntax) { bool useVar = equalsValueClauseSyntax != null && !preferExplicitType && !requireExplicitType; var typeSyntax = initSymbol == null || !initSymbol.IsAnonymousFunction() ? GetTypeSyntax(declaredSymbolType, useVar) : GetFuncTypeSyntax(initSymbol); csVars[k] = SyntaxFactory.VariableDeclaration(typeSyntax, SyntaxFactory.SingletonSeparatedList(v)); } else { csMethods.Add(initializerOrMethodDecl); } } } return(csVars.Values, csMethods); }
static Dictionary <string, VariableDeclarationSyntax> SplitVariableDeclarations(VBSyntax.VariableDeclaratorSyntax declarator, NodesVisitor nodesVisitor, SemanticModel semanticModel) { var rawType = (TypeSyntax)declarator.AsClause?.TypeSwitch( (VBSyntax.SimpleAsClauseSyntax c) => c.Type, (VBSyntax.AsNewClauseSyntax c) => VBasic.SyntaxExtensions.Type(c.NewExpression), _ => { throw new NotImplementedException($"{_.GetType().FullName} not implemented!"); } )?.Accept(nodesVisitor) ?? SyntaxFactory.ParseTypeName("var"); var initializer = (ExpressionSyntax)declarator.AsClause?.TypeSwitch( (VBSyntax.SimpleAsClauseSyntax _) => declarator.Initializer?.Value, (VBSyntax.AsNewClauseSyntax c) => c.NewExpression )?.Accept(nodesVisitor) ?? (ExpressionSyntax)declarator.Initializer?.Value.Accept(nodesVisitor); var newDecls = new Dictionary <string, VariableDeclarationSyntax>(); foreach (var name in declarator.Names) { var type = rawType; if (!name.Nullable.IsKind(VBasic.SyntaxKind.None)) { if (type is ArrayTypeSyntax) { type = ((ArrayTypeSyntax)type).WithElementType(SyntaxFactory.NullableType(((ArrayTypeSyntax)type).ElementType)); } else { type = SyntaxFactory.NullableType(type); } } if (name.ArrayRankSpecifiers.Count > 0) { type = SyntaxFactory.ArrayType(type, SyntaxFactory.List(name.ArrayRankSpecifiers.Select(a => (ArrayRankSpecifierSyntax)a.Accept(nodesVisitor)))); } VariableDeclarationSyntax decl; var v = SyntaxFactory.VariableDeclarator(ConvertIdentifier(name.Identifier, semanticModel), null, initializer == null ? null : SyntaxFactory.EqualsValueClause(initializer)); string k = type.ToString(); if (newDecls.TryGetValue(k, out decl)) { newDecls[k] = decl.AddVariables(v); } else { newDecls[k] = SyntaxFactory.VariableDeclaration(type, SyntaxFactory.SingletonSeparatedList(v)); } } return(newDecls); }