Exemplo n.º 1
0
 private static VBSyntax.ExpressionSyntax GetInitializerToConvert(VariableDeclaratorSyntax declarator)
 {
     return(declarator.AsClause?.TypeSwitch(
                (VBSyntax.SimpleAsClauseSyntax _) => declarator.Initializer?.Value,
                (VBSyntax.AsNewClauseSyntax c) => c.NewExpression
                ) ?? declarator.Initializer?.Value);
 }
Exemplo n.º 2
0
    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);
    }
Exemplo n.º 3
0
    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);
    }