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