Repository: PowerShell/PowerShell
File: src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs (C#)

Code before:

        object ICustomAstVisitor.VisitBlockStatement(BlockStatementAst blockStatementAst)
        {
            return blockStatementAst.Body.Accept(this);
        }

        object ICustomAstVisitor.VisitUsingExpression(UsingExpressionAst usingExpressionAst)
        {
            return usingExpressionAst.SubExpression.Accept(this);
        }

        object ICustomAstVisitor.VisitVariableExpression(VariableExpressionAst ast)
        {
            var inferredTypes = new List<PSTypeName>();
            InferTypeFrom(ast, inferredTypes);
            return inferredTypes;
        }

        object ICustomAstVisitor.VisitMergingRedirection(MergingRedirectionAst mergingRedirectionAst)
        {
            return TypeInferenceContext.EmptyPSTypeNameArray;
        }

        object ICustomAstVisitor.VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            // TODO: Handle other kinds of expressions on the right side.
            if (binaryExpressionAst.Operator == TokenKind.As && binaryExpressionAst.Right is TypeExpressionAst typeExpression)
            {
                var type = typeExpression.TypeName.GetReflectionType();
                var psTypeName = type != null ? new PSTypeName(type) : new PSTypeName(typeExpression.TypeName.FullName);
                return new[] { psTypeName };
            }

            switch (binaryExpressionAst.Operator)
            {
                case TokenKind.Xor:
                case TokenKind.And:
                case TokenKind.Or:
                case TokenKind.Icontains:
                case TokenKind.Inotcontains:
                case TokenKind.Ccontains:
                case TokenKind.Cnotcontains:
                case TokenKind.Iin:
                case TokenKind.Inotin:
                case TokenKind.Cin:
                case TokenKind.Cnotin:
                case TokenKind.Is:
                case TokenKind.IsNot:
                    // Always returns a bool
                    return BinaryExpressionAst.BoolTypeNameArray;


Review comment (suggestion):
- I'd move previous `if (binaryExpressionAst.Operator == TokenKind.As ...` to the switch too.
- And comment there ask to improve right side - can we do? Or better in another PR?
- Please add a test for the code too.

Code after:

        object ICustomAstVisitor.VisitBlockStatement(BlockStatementAst blockStatementAst)
        {
            return blockStatementAst.Body.Accept(this);
        }

        object ICustomAstVisitor.VisitUsingExpression(UsingExpressionAst usingExpressionAst)
        {
            return usingExpressionAst.SubExpression.Accept(this);
        }

        object ICustomAstVisitor.VisitVariableExpression(VariableExpressionAst ast)
        {
            var inferredTypes = new List<PSTypeName>();
            InferTypeFrom(ast, inferredTypes);
            return inferredTypes;
        }

        object ICustomAstVisitor.VisitMergingRedirection(MergingRedirectionAst mergingRedirectionAst)
        {
            return TypeInferenceContext.EmptyPSTypeNameArray;
        }

        object ICustomAstVisitor.VisitBinaryExpression(BinaryExpressionAst binaryExpressionAst)
        {
            switch (binaryExpressionAst.Operator)
            {
                case TokenKind.And:
                case TokenKind.Ccontains:
                case TokenKind.Cin:
                case TokenKind.Cnotcontains:
                case TokenKind.Cnotin:
                case TokenKind.Icontains:
                case TokenKind.Iin:
                case TokenKind.Inotcontains:
                case TokenKind.Inotin:
                case TokenKind.Is:
                case TokenKind.IsNot:
                case TokenKind.Or:
                case TokenKind.Xor:
                    // Always returns a bool
                    return BinaryExpressionAst.BoolTypeNameArray;

                case TokenKind.As:
                    // TODO: Handle other kinds of expressions on the right side.
                    if (binaryExpressionAst.Right is TypeExpressionAst typeExpression)
                    {
                        var type = typeExpression.TypeName.GetReflectionType();
                        var psTypeName = type != null ? new PSTypeName(type) : new PSTypeName(typeExpression.TypeName.FullName);
                        return new[] { psTypeName };
                    }