public override IExpression VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node) { var o = this.semanticModel.GetTypeInfo(node); var t = this.mapper.Map(o.Type); var operand = this.Visit(node.Operand); UnaryOperation op = null; switch (node.CSharpKind()) { case SyntaxKind.BitwiseNotExpression: op = new OnesComplement(); break; case SyntaxKind.UnaryMinusExpression: op = new UnaryNegation(); op.Type = operand.Type; break; case SyntaxKind.PreDecrementExpression: case SyntaxKind.PreIncrementExpression: BinaryOperation bo; if (node.OperatorToken.CSharpKind() == SyntaxKind.MinusMinusToken) { bo = new Subtraction(); } else { bo = new Addition(); } object one = GetConstantOneOfMatchingTypeForIncrementDecrement(operand.Type.ResolvedType); // REVIEW: Do we really need to resolve? bo.LeftOperand = operand; bo.RightOperand = new CompileTimeConstant() { Type = operand.Type, Value = one, }; bo.Type = operand.Type; var assign = new Assignment() { Source = bo, Target = Helper.MakeTargetExpression(operand), Type = operand.Type, }; return(assign); case SyntaxKind.LogicalNotExpression: op = new LogicalNot(); break; default: var typeName = node.GetType().ToString(); var msg = String.Format("Was unable to convert a {0} node to CCI because the kind '{1}' wasn't handled", typeName, node.CSharpKind().ToString()); throw new ConverterException(msg); } op.Operand = operand; return(op); }
public override SyntaxNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node) { switch (node.CSharpKind()) { case SyntaxKind.PreIncrementExpression: return SyntaxFactory.BinaryExpression(SyntaxKind.AddAssignmentExpression, node.Operand, SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(1))); case SyntaxKind.PreDecrementExpression: return SyntaxFactory.BinaryExpression(SyntaxKind.SubtractAssignmentExpression, node.Operand, SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(1))); #if NEGATE_EXPRESSION case SyntaxKind.NegateExpression: if (node.Operand.CSharpKind() == SyntaxKind.NumericLiteralExpression) { dynamic newvalue = -((dynamic)((LiteralExpressionSyntax)node.Operand).Token.Value); return SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(newvalue)); } return node; #endif case SyntaxKind.LogicalNotExpression: return SyntaxFactory.BinaryExpression(SyntaxKind.NotEqualsExpression, node.Operand, SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression)); } throw new NotImplementedException("Unary prefix " + node.CSharpKind().ToString()); }
private IEnumerable<ITypeSymbol> InferTypeInPrefixUnaryExpression(PrefixUnaryExpressionSyntax prefixUnaryExpression, SyntaxToken? previousToken = null) { // If we have a position, then we must be after the prefix token. Contract.ThrowIfTrue(previousToken.HasValue && previousToken.Value != prefixUnaryExpression.OperatorToken); switch (prefixUnaryExpression.CSharpKind()) { case SyntaxKind.AwaitExpression: // await <expression> var types = InferTypes(prefixUnaryExpression); var task = this.Compilation.TaskType(); var taskOfT = this.Compilation.TaskOfTType(); if (task == null || taskOfT == null) { break; } if (!types.Any()) { return SpecializedCollections.SingletonEnumerable(task); } return types.Select(t => t.SpecialType == SpecialType.System_Void ? task : taskOfT.Construct(t)); case SyntaxKind.PreDecrementExpression: case SyntaxKind.PreIncrementExpression: case SyntaxKind.UnaryPlusExpression: case SyntaxKind.UnaryMinusExpression: case SyntaxKind.BitwiseNotExpression: // ++, --, +Foo(), -Foo(), ~Foo(); return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Int32)); case SyntaxKind.LogicalNotExpression: // !Foo() return SpecializedCollections.SingletonEnumerable(this.Compilation.GetSpecialType(SpecialType.System_Boolean)); } return SpecializedCollections.EmptyEnumerable<ITypeSymbol>(); }
public override JsNode VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node) { switch (node.CSharpKind()) { case SyntaxKind.AwaitExpression: var operand = (JsExpression)node.Operand.Accept(this); /* * var expressionInfo = stateGenerator.Transformer.model.GetAwaitExpressionInfo(node); * if (expressionInfo.GetResultMethod == null) * { * var classText = node.FirstAncestorOrSelf<ClassDeclarationSyntax>().NormalizeWhitespace().ToString(); * var diagnostics = model.GetDiagnostics().Select(x => x.ToString()).ToArray(); * } * * var returnsVoid = expressionInfo.GetResultMethod.ReturnsVoid; */ var expressionInfo = stateGenerator.Transformer.model.GetTypeInfo(node).ConvertedType; var returnsVoid = expressionInfo.SpecialType == SpecialType.System_Void; var operandType = model.GetTypeInfo(node.Operand).ConvertedType; var awaiterMethodName = ((INamedTypeSymbol)operandType).GetMethodByName("GetAwaiter").GetMemberName(); // Store the awaiter in a field var awaiterIdentifier = stateGenerator.HoistVariable(new LiftedVariableKey("$awaiter")); var awaiter = awaiterIdentifier.GetReference(); stateGenerator.CurrentState.Add(awaiter.Assign(operand.Member(awaiterMethodName).Invoke()).Express()); var nextState = stateGenerator.InsertState(); JsExpression result = null; if (!returnsVoid) { // If the await returns a value, store it in a field var resultIdentifier = stateGenerator.HoistVariable(new LiftedVariableKey("$result")); result = resultIdentifier.GetReference(); // Make sure the field gets set from the awaiter at the beginning of the next state. nextState.Add(result.Assign(awaiter.Member("GetResult").Invoke()).Express()); } else { // We still need to call GetResult even if void in order to propagate exceptions nextState.Add(awaiter.Member("GetResult").Invoke().Express()); } // Set the state to the next state stateGenerator.CurrentState.Add(stateGenerator.ChangeState(nextState)); stateGenerator.CurrentState.Add(Js.If( awaiter.Member("get_IsCompleted").Invoke(), // If the awaiter is already completed, go to the next state stateGenerator.GotoTop(), // Otherwise await for completion Js.Block( // Start the async process Js.Reference(builder) .Member("TrueAwaitOnCompleted") .Invoke(awaiterIdentifier.GetReference(), Js.Reference(stateMachine)) .Express(), Js.Return() ) )); stateGenerator.CurrentState = nextState; return(result ?? Js.Null()); } return(base.VisitPrefixUnaryExpression(node)); }