/// <summary>
        /// Returns syntax for initializing a new instance of the provided type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>Syntax for initializing a new instance of the provided type.</returns>
        private static ExpressionSyntax GetObjectCreationExpressionSyntax(Type type)
        {
            ExpressionSyntax result;
            var typeInfo = type.GetTypeInfo();

            if (typeInfo.IsValueType)
            {
                // Use the default value.
                result = SF.DefaultExpression(typeInfo.AsType().GetTypeSyntax());
            }
            else if (GetEmptyConstructor(typeInfo) != null)
            {
                // Use the default constructor.
                result = SF.ObjectCreationExpression(typeInfo.AsType().GetTypeSyntax()).AddArgumentListArguments();
            }
            else
            {
                // Create an unformatted object.
                Expression <Func <object> > getUninitializedObject =
                    () => FormatterServices.GetUninitializedObject(default(Type));

                result = SF.CastExpression(
                    type.GetTypeSyntax(),
                    getUninitializedObject.Invoke()
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(typeInfo.AsType().GetTypeSyntax()))));
            }

            return(result);
        }
Beispiel #2
0
        /// <summary>
        /// Returns syntax for initializing a new instance of the provided type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>Syntax for initializing a new instance of the provided type.</returns>
        private static ExpressionSyntax GetObjectCreationExpressionSyntax(Type type)
        {
            ExpressionSyntax result;
            var typeInfo = type.GetTypeInfo();

            if (typeInfo.IsValueType)
            {
                // Use the default value.
                result = SF.DefaultExpression(typeInfo.GetTypeSyntax());
            }
            else if (type.GetConstructor(Type.EmptyTypes) != null)
            {
                // Use the default constructor.
                result = SF.ObjectCreationExpression(typeInfo.GetTypeSyntax()).AddArgumentListArguments();
            }
            else
            {
                // Create an unformatted object.
                Expression <Func <object> > getUninitializedObject =
#if NETSTANDARD
                    () => SerializationManager.GetUninitializedObjectWithFormatterServices(default(Type));
#else
                    () => FormatterServices.GetUninitializedObject(default(Type));
#endif
                result = SF.CastExpression(
                    type.GetTypeSyntax(),
                    getUninitializedObject.Invoke()
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(typeInfo.GetTypeSyntax()))));
            }

            return(result);
        }
        private async Task <EqualsValueClauseSyntax> ConvertEqualsValueClauseSyntax(
            VariableDeclaratorSyntax vbDeclarator, ModifiedIdentifierSyntax vbName,
            VBSyntax.ExpressionSyntax vbInitValue,
            ITypeSymbol declaredSymbolType,
            ISymbol declaredSymbol, CSharpSyntaxNode initializerOrMethodDecl)
        {
            var csTypeSyntax = GetTypeSyntax(declaredSymbolType);

            bool isField = vbDeclarator.Parent.IsKind(SyntaxKind.FieldDeclaration);
            bool isConst = declaredSymbol is IFieldSymbol fieldSymbol && fieldSymbol.IsConst ||
                           declaredSymbol is ILocalSymbol localSymbol && localSymbol.IsConst;

            EqualsValueClauseSyntax equalsValueClauseSyntax;

            if (await GetInitializerFromNameAndType(declaredSymbolType, vbName, initializerOrMethodDecl) is ExpressionSyntax
                adjustedInitializerExpr)
            {
                var convertedInitializer = vbInitValue != null
                    ? TypeConversionAnalyzer.AddExplicitConversion(vbInitValue, adjustedInitializerExpr, isConst : isConst)
                    : adjustedInitializerExpr;

                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);
        }
        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);
        }
Beispiel #5
0
        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);
        }
        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> VisitExitStatement(VBSyntax.ExitStatementSyntax node)
            {
                switch (VBasic.VisualBasicExtensions.Kind(node.BlockKeyword))
                {
                case VBasic.SyntaxKind.SubKeyword:
                    return(SingleStatement(SyntaxFactory.ReturnStatement()));

                case VBasic.SyntaxKind.FunctionKeyword:
                    VBasic.VisualBasicSyntaxNode typeContainer = (VBasic.VisualBasicSyntaxNode)node.Ancestors().OfType <VBSyntax.LambdaExpressionSyntax>().FirstOrDefault()
                                                                 ?? node.Ancestors().OfType <VBSyntax.MethodBlockSyntax>().FirstOrDefault();
                    var info = typeContainer.TypeSwitch(
                        (VBSyntax.LambdaExpressionSyntax e) => _semanticModel.GetTypeInfo(e).Type.GetReturnType(),
                        (VBSyntax.MethodBlockSyntax e) => {
                        var type = (TypeSyntax)e.SubOrFunctionStatement.AsClause?.Type.Accept(_nodesVisitor) ?? SyntaxFactory.ParseTypeName("object");
                        return(_semanticModel.GetSymbolInfo(type).Symbol?.GetReturnType());
                    }
                        );
                    ExpressionSyntax expr;
                    if (HasReturnVariable)
                    {
                        expr = ReturnVariable;
                    }
                    else if (info == null)
                    {
                        expr = null;
                    }
                    else if (info.IsReferenceType)
                    {
                        expr = SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression);
                    }
                    else if (info.CanBeReferencedByName)
                    {
                        expr = SyntaxFactory.DefaultExpression(SyntaxFactory.ParseTypeName(info.ToMinimalCSharpDisplayString(_semanticModel, node.SpanStart)));
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                    return(SingleStatement(SyntaxFactory.ReturnStatement(expr)));

                default:
                    return(SingleStatement(SyntaxFactory.BreakStatement()));
                }
            }
        /// <summary>
        /// Generates a method.
        /// </summary>
        /// <param name="methodDescription">
        /// The method description.
        /// </param>
        /// <returns>
        /// The generated method.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// The return type of the provided method is not supported.
        /// </exception>
        private static MethodDeclarationSyntax GenerateMethod(ActorMethodDescription methodDescription)
        {
            // Types
            var method = methodDescription.MethodInfo;

            Type asyncReturnType;

            if (!method.ReturnType.IsGenericType && (method.ReturnType == typeof(Task)))
            {
                asyncReturnType = typeof(void);
            }
            else if (method.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))
            {
                asyncReturnType = method.ReturnType.GenericTypeArguments[0];
            }
            else
            {
                throw new ArgumentException("Method return type is not Task or Task<T>.");
            }

            // Body statements
            var parameterReferences =
                method.GetParameters()
                .Select(
                    p => SF.Argument(SF.CastExpression(typeof(object).GetTypeSyntax(), SF.IdentifierName(p.Name))))
                .ToArray();
            var writeEventMethod = SF.ThisExpression().Member((EventProducerBase <object> _) => _.WriteEvent(default(string), default(object), default(object)));
            var writeEvent       =
                SF.ExpressionStatement(
                    SF.AwaitExpression(
                        SF.InvocationExpression(writeEventMethod)
                        .AddArgumentListArguments(SF.Argument(methodDescription.Name.GetLiteralExpression()))
                        .AddArgumentListArguments(parameterReferences)));

            var returnValue = asyncReturnType == typeof(void) ? null : SF.DefaultExpression(asyncReturnType.GetTypeSyntax());

            // Build and return the method.
            return
                (SF.MethodDeclaration(method.ReturnType.GetTypeSyntax(), methodDescription.MethodInfo.Name)
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.AsyncKeyword))
                 .AddParameterListParameters(method.GetParameterListSyntax())
                 .AddBodyStatements(writeEvent, SF.ReturnStatement(returnValue)));
        }
Beispiel #9
0
        /// <summary>
        /// Returns syntax for initializing a new instance of the provided type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>Syntax for initializing a new instance of the provided type.</returns>
        private static ExpressionSyntax GetObjectCreationExpressionSyntax(Type type)
        {
            ExpressionSyntax result;
            var typeInfo = type.GetTypeInfo();

            if (typeInfo.IsValueType)
            {
                // Use the default value.
                result = SF.DefaultExpression(typeInfo.GetTypeSyntax());
            }
            else if (type.GetConstructor(Type.EmptyTypes) != null)
            {
                // Use the default constructor.
                result = SF.ObjectCreationExpression(typeInfo.GetTypeSyntax()).AddArgumentListArguments();
            }
            else
            {
                // Create an unformatted object.
#if DNXCORE50
                var bindingFlags = SyntaxFactoryExtensions.GetBindingFlagsParenthesizedExpressionSyntax(
                    SyntaxKind.BitwiseOrExpression,
                    BindingFlags.Instance,
                    BindingFlags.NonPublic,
                    BindingFlags.Public);
                var            nullLiteralExpressionArgument = SF.Argument(SF.LiteralExpression(SyntaxKind.NullLiteralExpression));
                var            typeArg         = SF.Argument(SF.TypeOfExpression(typeInfo.GetTypeSyntax()));
                var            bindingFlagsArg = SF.Argument(bindingFlags);
                var            binderArg       = nullLiteralExpressionArgument;
                ArgumentSyntax ctorArgumentsArg;
                var            cons = typeInfo.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                                      .OrderBy(p => p.GetParameters().Count()).FirstOrDefault();
                var consParameters = cons != null?cons.GetParameters().Select(p => p.ParameterType).ToArray() : null;

                if (consParameters != null && consParameters.Length > 0)
                {
                    var separatedSyntaxList = new SeparatedSyntaxList <ExpressionSyntax>();
                    separatedSyntaxList = consParameters
                                          .Aggregate(separatedSyntaxList, (current, t) => current.Add(SF.DefaultExpression(t.GetTypeInfo().GetTypeSyntax())));
                    ctorArgumentsArg = SF.Argument(separatedSyntaxList.GetArrayCreationWithInitializerSyntax(
                                                       SF.PredefinedType(SF.Token(SyntaxKind.ObjectKeyword))));
                }
                else
                {
                    ctorArgumentsArg = nullLiteralExpressionArgument;
                }

                var cultureInfoArg = SF.Argument(
                    SF.IdentifierName("System").Member("Globalization").Member("CultureInfo").Member("InvariantCulture"));
                var createInstanceArguments = new []
                {
                    typeArg,
                    bindingFlagsArg,
                    binderArg,
                    ctorArgumentsArg,
                    cultureInfoArg
                };

                Expression <Func <object> > getUninitializedObject = () => Activator.CreateInstance(
                    default(Type),
                    BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public,
                    null,
                    null,
                    System.Globalization.CultureInfo.InvariantCulture);
                result = SF.CastExpression(
                    type.GetTypeSyntax(),
                    getUninitializedObject.Invoke()
                    .AddArgumentListArguments(createInstanceArguments));
#else
                Expression <Func <object> > getUninitializedObject =
                    () => FormatterServices.GetUninitializedObject(default(Type));
                result = SF.CastExpression(
                    type.GetTypeSyntax(),
                    getUninitializedObject.Invoke()
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(typeInfo.GetTypeSyntax()))));
#endif
            }

            return(result);
        }
Beispiel #10
0
        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);
        }
Beispiel #11
0
 //*
 public static ParameterSyntax Optional(ParameterSyntax parameter)
 {
     return(parameter
            .WithType(OptionalOf(parameter.Type))
            .WithDefault(SF.EqualsValueClause(SF.DefaultExpression(OptionalOf(parameter.Type)))));
 }