public void GenerateInto(Scope scope) { Debug.Assert(operands.Count >= 2, "Not enough operands for binary expression"); var ops = new Queue <ExpressionSyntax>(); foreach (var op in operands) { ops.Enqueue(op); } var left = ops.Dequeue(); ScriptDataType?topType = this.OwnDataType; while (ops.Any()) { var right = ops.Dequeue(); var binExp = SyntaxFactory.BinaryExpression(operatorSyntaxKind, left, right); if (numericPromotionOperators.Contains(this.operatorSyntaxKind) && SyntaxUtil.TryGetTypeOfExpression(left, out var leftType) && SyntaxUtil.TryGetTypeOfExpression(right, out var rightType)) { var promoted = SyntaxUtil.BinaryNumericPromotion(leftType, rightType); binExp = binExp.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(promoted)); topType = promoted; } left = binExp; } if (topType.HasValue && topType.Value != scope.Type) { left = SyntaxUtil.CreateCast(topType.Value, scope.Type, SyntaxFactory.ParenthesizedExpression(left)); } scope.Context.AddExpression(left); }
public void GenerateInto(Scope scope) { var invocationExpression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName("Engine"), SyntaxFactory.IdentifierName(this.MethodName)); ExpressionSyntax invocation = SyntaxFactory.InvocationExpression(invocationExpression) .WithArgumentList(SyntaxFactory.ArgumentList( SyntaxFactory.SeparatedList(this.arguments))) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType)); var tempArgs = new List <Type>(); foreach (var t in argumentTypes) { if (t.HasValue && SyntaxUtil.TryGetTypeFromScriptType(t.Value, out var T)) { tempArgs.Add(T); } else { break; } } if (tempArgs.Count == argumentTypes.Count) { // Do full overload match var method = typeof(IScriptEngine).GetMethod(this.MethodName, BindingFlags.Public | BindingFlags.Instance, null, tempArgs.ToArray(), null); if (method != null) { SyntaxUtil.AwaitIfNeeded(method, ref invocation, out var materializedReturnType); if (SyntaxUtil.TryGetScriptTypeFromType(materializedReturnType, out var fromType)) { // Insert cast to destination invocation = SyntaxUtil.CreateCast(fromType, this.ReturnType, invocation) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType)); } } } else { // Fallback to name only lookup var scriptEngineMethods = typeof(IScriptEngine).GetMethods().Where(m => m.Name == this.MethodName); if (scriptEngineMethods.Any()) { //var hasOverload = scriptEngineMethods.Any(m => m.ReturnType == destinationType); //if (hasOverload == false) { var method = scriptEngineMethods.First(); SyntaxUtil.AwaitIfNeeded(method, ref invocation, out var materializedReturnType); if (SyntaxUtil.TryGetScriptTypeFromType(materializedReturnType, out var fromType) && fromType != this.ReturnType) { // Insert cast to destination invocation = SyntaxUtil.CreateCast(fromType, this.ReturnType, invocation) .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType)); } } } } scope.Context.AddExpression(invocation); }