Beispiel #1
0
        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));
            }