private ExpressionSyntax CreateCast(ExpressionSyntax csNode, ITypeSymbol vbConvertedType) { var typeName = (TypeSyntax)_csSyntaxGenerator.TypeExpression(vbConvertedType); if (csNode is CastExpressionSyntax cast && cast.Type.IsEquivalentTo(typeName)) { return(csNode); } return(ValidSyntaxFactory.CastExpression(typeName, csNode)); }
public static CS.Syntax.ExpressionSyntax SkipOutOfParens(this CS.Syntax.ExpressionSyntax expression) { if (expression == null) { return(null); } while (expression is CS.Syntax.ParenthesizedExpressionSyntax pes) { expression = pes.Parent as CS.Syntax.ExpressionSyntax; } return(expression); }
public static ExpressionSyntax SkipParens(this ExpressionSyntax expression) { if (expression == null) { return(null); } while (expression != null && expression.IsKind(SyntaxKind.ParenthesizedExpression)) { expression = ((ParenthesizedExpressionSyntax)expression).Expression; } return(expression); }
private ExpressionSyntax AddTypeConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded, ITypeSymbol vbType, ITypeSymbol vbConvertedType) { switch (conversionKind) { case TypeConversionKind.FractionalNumberRoundThenCast: csNode = vbType.IsNullable() && vbConvertedType.IsNullable() ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetMathRoundMemberAccess(), GetTypeSyntax(vbConvertedType)) : AddRoundInvocation(vbType.IsNullable() ? csNode.NullableGetValueExpression() : csNode); return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType)); case TypeConversionKind.EnumConversionThenCast: vbConvertedType.IsNullable(out var convertedNullableType); var underlyingEnumType = ((INamedTypeSymbol)(convertedNullableType ?? vbConvertedType)).EnumUnderlyingType; csNode = vbType.IsNullable() && convertedNullableType != null ? _vbNullableExpressionsConverter.InvokeConversionWhenNotNull(csNode, GetConversionsMemberAccess(underlyingEnumType), GetTypeSyntax(vbConvertedType)) : AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, vbType, underlyingEnumType); return(AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, vbConvertedType)); case TypeConversionKind.EnumCastThenConversion: var enumUnderlyingType = ((INamedTypeSymbol)vbType).EnumUnderlyingType; csNode = AddTypeConversion(vbNode, csNode, TypeConversionKind.NonDestructiveCast, addParenthesisIfNeeded, vbType, enumUnderlyingType); return(AddTypeConversion(vbNode, csNode, TypeConversionKind.Conversion, addParenthesisIfNeeded, enumUnderlyingType, vbConvertedType)); case TypeConversionKind.Unknown: case TypeConversionKind.Identity: return(addParenthesisIfNeeded ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode) : csNode); case TypeConversionKind.DestructiveCast: case TypeConversionKind.NonDestructiveCast: return(CreateCast(csNode, vbConvertedType)); case TypeConversionKind.Conversion: return(AddExplicitConvertTo(vbNode, csNode, vbType, vbConvertedType)); case TypeConversionKind.NullableBool: return(SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, csNode, LiteralConversions.GetLiteralExpression(true))); case TypeConversionKind.StringToCharArray: var memberAccessExpressionSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, csNode, SyntaxFactory.IdentifierName(nameof(string.ToCharArray))); return(SyntaxFactory.InvocationExpression(memberAccessExpressionSyntax, SyntaxFactory.ArgumentList())); case TypeConversionKind.DelegateConstructor: return(SyntaxFactory.ObjectCreationExpression(GetCommonDelegateTypeOrNull(vbNode, vbConvertedType)).WithArgumentList(new[] { csNode }.CreateCsArgList())); default: throw new ArgumentOutOfRangeException(nameof(conversionKind), conversionKind, null); } }
public ExpressionSyntax AddExplicitConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool defaultToCast = false, bool isConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null) { if (csNode == null) { return(null); } var conversionKind = AnalyzeConversion(vbNode, defaultToCast, isConst, forceSourceType, forceTargetType); csNode = addParenthesisIfNeeded && conversionKind is TypeConversionKind.DestructiveCast or TypeConversionKind.NonDestructiveCast ? vbNode.ParenthesizeIfPrecedenceCouldChange(csNode) : csNode; return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, isConst, forceSourceType: forceSourceType, forceTargetType: forceTargetType).Expr); }
public static Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax SkipParens(this Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression) { if (expression == null) { return(null); } while (expression is Microsoft.CodeAnalysis.CSharp.Syntax.ParenthesizedExpressionSyntax pes) { expression = pes.Expression; } return(expression); }
public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false) { var vbConvertedType = ModelExtensions.GetTypeInfo(_semanticModel, vbNode).ConvertedType; switch (conversionKind) { case TypeConversionKind.Unknown: case TypeConversionKind.Identity: return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode); case TypeConversionKind.DestructiveCast: case TypeConversionKind.NonDestructiveCast: return(CreateCast(csNode, vbConvertedType)); case TypeConversionKind.Conversion: return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType)); default: throw new ArgumentOutOfRangeException(); } }
public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool alwaysExplicit = false) { var conversionKind = AnalyzeConversion(vbNode, alwaysExplicit); csNode = addParenthesisIfNeeded && (conversionKind == TypeConversionKind.DestructiveCast || conversionKind == TypeConversionKind.NonDestructiveCast) ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode; return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded)); }
public ExpressionSyntax AddExplicitConvertTo(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, ITypeSymbol type) { var displayType = type.ToMinimalDisplayString(_semanticModel, vbNode.SpanStart); if (csNode is InvocationExpressionSyntax invoke && invoke.Expression is MemberAccessExpressionSyntax expr && expr.Expression is IdentifierNameSyntax name && name.Identifier.ValueText == "Conversions" && expr.Name.Identifier.ValueText == $"To{displayType}") { return(csNode); } if (!ConversionsTypeFullNames.TryGetValue(type.GetFullMetadataName(), out var methodId)) { return(CreateCast(csNode, type)); } // Need to use Conversions rather than Convert to match what VB does, eg. True -> -1 _extraUsingDirectives.Add("Microsoft.VisualBasic.CompilerServices"); var memberAccess = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("Conversions"), SyntaxFactory.IdentifierName(methodId)); var arguments = SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(csNode))); return(SyntaxFactory.InvocationExpression(memberAccess, arguments)); }
public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false, ITypeSymbol forceTargetType = null) { var vbConvertedType = forceTargetType ?? ModelExtensions.GetTypeInfo(_semanticModel, vbNode).ConvertedType; switch (conversionKind) { case TypeConversionKind.Unknown: case TypeConversionKind.Identity: return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode); case TypeConversionKind.DestructiveCast: case TypeConversionKind.NonDestructiveCast: return(CreateCast(csNode, vbConvertedType)); case TypeConversionKind.Conversion: return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType)); case TypeConversionKind.ConstConversion: return(ConstantFold(vbNode, vbConvertedType)); case TypeConversionKind.NullableBool: return(SyntaxFactory.BinaryExpression(SyntaxKind.EqualsExpression, csNode, LiteralConversions.GetLiteralExpression(true))); case TypeConversionKind.StringToCharArray: var memberAccessExpressionSyntax = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, csNode, SyntaxFactory.IdentifierName(nameof(string.ToCharArray))); return(SyntaxFactory.InvocationExpression(memberAccessExpressionSyntax, SyntaxFactory.ArgumentList())); default: throw new ArgumentOutOfRangeException(); } }
public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, bool addParenthesisIfNeeded = true, bool defaultToCast = false, bool isConst = false, ITypeSymbol forceTargetType = null) { if (csNode == null) { return(null); } var conversionKind = AnalyzeConversion(vbNode, defaultToCast, isConst, forceTargetType); csNode = addParenthesisIfNeeded && (conversionKind == TypeConversionKind.DestructiveCast || conversionKind == TypeConversionKind.NonDestructiveCast) ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode; return(AddExplicitConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, forceTargetType: forceTargetType)); }
public (ExpressionSyntax Expr, bool IsConst) AddExplicitConversion(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false, bool requiresConst = false, ITypeSymbol forceSourceType = null, ITypeSymbol forceTargetType = null) { var(vbType, vbConvertedType) = GetTypeInfo(vbNode, forceSourceType, forceTargetType); bool resultConst = false; if (requiresConst) { var(constExpression, isCorrectType) = _expressionEvaluator.GetConstantOrNull(vbNode, vbConvertedType, conversionKind, csNode); if (isCorrectType) { return(constExpression, true); } if (constExpression != null) { csNode = constExpression ?? csNode; resultConst = true; } } var typeConvertedResult = AddTypeConversion(vbNode, csNode, conversionKind, addParenthesisIfNeeded, vbType, vbConvertedType); return(typeConvertedResult, resultConst); }
static void CompileExpression(CompileContext context, Neo.ASML.Node.ASMFunction func, Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionSyntax expression, string comment = null) { if (expression is Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax) { var lit = expression as Microsoft.CodeAnalysis.CSharp.Syntax.LiteralExpressionSyntax; var v = lit.Token.ValueText; func.nodes.Add(new Neo.ASML.Node.ASMInstruction() { opcode = Neo.ASML.Node.ASMOpCode.CreatePush(), valuetext = v, commentRight = comment }); return; } else if (expression is Microsoft.CodeAnalysis.CSharp.Syntax.BinaryExpressionSyntax) { var binary = expression as Microsoft.CodeAnalysis.CSharp.Syntax.BinaryExpressionSyntax; if (comment != null) { func.nodes.Add(new Neo.ASML.Node.ASMComment() { text = comment }); } CompileExpression(context, func, binary.Left); CompileExpression(context, func, binary.Right); Neo.VM.OpCode opcode = Neo.VM.OpCode.NOP; if (binary.OperatorToken.ValueText == "+") { opcode = Neo.VM.OpCode.ADD; } else if (binary.OperatorToken.ValueText == "-") { opcode = Neo.VM.OpCode.DEC; } if (binary.OperatorToken.ValueText == "*") { opcode = Neo.VM.OpCode.MUL; } if (binary.OperatorToken.ValueText == "/") { opcode = Neo.VM.OpCode.DIV; } func.nodes.Add(new Neo.ASML.Node.ASMInstruction() { opcode = Neo.ASML.Node.ASMOpCode.Create(opcode) }); } else if (expression is Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax) { var id = expression as Microsoft.CodeAnalysis.CSharp.Syntax.IdentifierNameSyntax; var varname = id.Identifier.ValueText; var varindex = context.variables.IndexOf(varname); if (varindex >= 0) { //this is a LDLoc op func.nodes.Add(new Neo.ASML.Node.ASMComment() { text = "//" + varname }); //push setitem func.nodes.Add(new Neo.ASML.Node.ASMInstruction() { opcode = Neo.ASML.Node.ASMOpCode.Create(Neo.VM.OpCode.DUPFROMALTSTACK), commentRight = "//variables array" }); func.nodes.Add(new Neo.ASML.Node.ASMInstruction() { opcode = Neo.ASML.Node.ASMOpCode.CreatePush(), valuetext = varindex.ToString(), commentRight = "//index" }); func.nodes.Add(new Neo.ASML.Node.ASMInstruction() { opcode = Neo.ASML.Node.ASMOpCode.Create(Neo.VM.OpCode.PICKITEM) }); } } else { var type = expression.GetType().ToString(); throw new Exception("not support type:" + type); } }
public ExpressionSyntax AddExplicitConversion(Microsoft.CodeAnalysis.VisualBasic.Syntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeConversionKind conversionKind, bool addParenthesisIfNeeded = false) { var vbConvertedType = ModelExtensions.GetTypeInfo(_semanticModel, vbNode).ConvertedType; switch (conversionKind) { case TypeConversionKind.Unknown: case TypeConversionKind.Identity: return(addParenthesisIfNeeded ? VbSyntaxNodeExtensions.ParenthesizeIfPrecedenceCouldChange(vbNode, csNode) : csNode); case TypeConversionKind.DestructiveCast: case TypeConversionKind.NonDestructiveCast: var typeName = (TypeSyntax)_csSyntaxGenerator.TypeExpression(vbConvertedType); if (csNode is CastExpressionSyntax cast && cast.Type.IsEquivalentTo(typeName)) { return(csNode); } return(ValidSyntaxFactory.CastExpression(typeName, csNode)); case TypeConversionKind.Conversion: return(AddExplicitConvertTo(vbNode, csNode, vbConvertedType)); default: throw new ArgumentOutOfRangeException(); } }