Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pattern Matching edge cases #413

Closed
belav opened this issue Aug 23, 2021 · 15 comments · Fixed by #431
Closed

Pattern Matching edge cases #413

belav opened this issue Aug 23, 2021 · 15 comments · Fixed by #431
Assignees
Milestone

Comments

@belav
Copy link
Owner

belav commented Aug 23, 2021

MethodInfo needs a space after it

                target = member switch
                {
                    PropertyInfo property => Expression.Property(target, property),
                    MethodInfo{ IsStatic: true } getter => Expression.Call(getter, target),
                    FieldInfo field => Field(target, field),
                    MethodInfo getter => Expression.Call(target, getter),
                    _
                      => throw new ArgumentOutOfRangeException(
                          nameof(member),
                          member,
                          "Unexpected member."
                      )
                };
@belav
Copy link
Owner Author

belav commented Aug 23, 2021

The { IsAbstract: true } doesn't need to be break

        public static Expression GenerateConstructorExpression(Type type) =>
            type switch
            {
                { IsValueType: true } => Default(type),
                Type stringType when stringType == typeof(string) => Constant(string.Empty),
                { IsInterface: true } => CreateInterfaceExpression(type),
                {
                    IsAbstract: true
                }
                  => InvalidType(type, $"Cannot create an instance of abstract type {type}."),
                _ => CallConstructor(type)
            };

// also
                {
                    ConstructorMap: { CanResolve: true } constructorMap
                }
                  => ConstructorMapping(constructorMap),

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

The second case probably shouldn't break

                switch (expressionToCheck)
                {
                    case MemberExpression
                    {
                        Member: var member,
                        Expression: { NodeType: ExpressionType.Parameter or ExpressionType.Convert }
                    }:
                        return member;
                    case UnaryExpression
                    {
                        Operand: var operand
                    }:
                        expressionToCheck = operand;
                        break;
                    default:
                        break;

@belav belav changed the title Pattern Matching needs space before brace Pattern Matching edge cases Aug 23, 2021
@belav
Copy link
Owner Author

belav commented Aug 23, 2021

Random extra space

        var location = declaringSyntax.GetSyntax() switch
        {
            CSharpSyntax.ClassDeclarationSyntax s => s.Identifier.GetLocation(),
             { } otherSyntax => otherSyntax.GetLocation()
        };

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

This looks a little jank

                if (
                    !(
                        symbol
                        is
                        {
                            Kind: SymbolKind.Local,
                            DeclaringSyntaxReferences: { Length: 1 } syntaxRefs
                        }
                    )
                ) {
                    return null;
                }

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

What about this?

                if (
                    blockParent
                    is MemberDeclarationSyntax
                    or AccessorDeclarationSyntax
                    or AnonymousFunctionExpressionSyntax
                ) {

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

See also

            else if (
                constantValue
                is (sbyte)-1
                or (short)-1
                or (int)-1
                or (long)-1
                or -1.0
                or -1.0f
                or -1.0m
            ) {

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

                typeNode = objectCreation.Parent.Parent switch
                {
                    LocalFunctionStatementSyntax localFunction => localFunction.ReturnType,
                    MethodDeclarationSyntax method => method.ReturnType,
                    ConversionOperatorDeclarationSyntax conversion => conversion.Type,
                    OperatorDeclarationSyntax op => op.ReturnType,
                    BasePropertyDeclarationSyntax property => property.Type,
                    AccessorDeclarationSyntax{
                        RawKind: (int)SyntaxKind.GetAccessorDeclaration,
                        Parent: AccessorListSyntax
                        {
                            Parent: BasePropertyDeclarationSyntax baseProperty
                        }
                    } accessor
                      => baseProperty.Type,
                    _ => null,
                };

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

            switch (operation)
            {
                case IBinaryOperation
                {
                    OperatorKind: BinaryOperatorKind.Equals
                } op:
                    return ParseConstantPattern(op);

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

The is shouldn't need to break

            if (
                suppressMessageAttributeType.Equals(attribute.AttributeClass)
                && attribute.AttributeConstructor?.Parameters.Length >= 2
                && attribute.AttributeConstructor.Parameters[1].Name == "checkId"
                && attribute.AttributeConstructor.Parameters[1].Type.SpecialType
                    == SpecialType.System_String
                && attribute.ConstructorArguments.Length >= 2
                && attribute.ConstructorArguments[1]
                    is
                    {
                        Kind: TypedConstantKind.Primitive,
                        Value: string checkId
                    }
            ) {

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

The first arm shouldn't need to break

            return operation.Syntax switch
            {
                TConditionalExpressionSyntax{
                    Parent: TParenthesizedExpressionSyntax parent
                }
                  => parent,
                var syntax => syntax,
            };

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

Double space

            if (!(statements[0] is IReturnOperation { ReturnedValue:  { } returnedValue }))
            {

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

Probably already covered

            var (originalGroup, isAddressOf) = source switch
            {
                BoundMethodGroup m => (m, false),
                BoundUnconvertedAddressOfOperator{ Operand:  { } m } => (m, true),

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

Shouldn't need to break

                    Debug.Assert(
                        scriptClassBinder.ContainingMemberOrLambda
                            is NamedTypeSymbol
                            {
                                IsScriptClass: true
                            }
                    );

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

Shouldn't need to break

            switch (left.Kind, right.Kind)
            {
                case
                (BoundKind.DefaultLiteral, _) when !isEquality:
                case
                (_, BoundKind.DefaultLiteral) when !isEquality:
                    // other than == and !=, binary operators are disallowed on `default` literal
                    Error(
                        diagnostics,
                        ErrorCode.ERR_BadOpOnNullOrDefaultOrNew,
                        node,
                        operatorToken.Text,
                        "default"
                    );
                    return;

@belav
Copy link
Owner Author

belav commented Aug 23, 2021

This comes in right at 100 but breaks. If even breaks below 100 (the is .... line)

class ClassName
{
    void MethodName()
    {
        if (true)
        {
            while (
                expressionType
                    is ArrayTypeSymbol { ElementType: var e1, IsSZArray: var sz1, Rank: var r1 }
            ) { }
        }
    }
}

@belav belav self-assigned this Aug 30, 2021
@belav belav added this to the 0.9.10 milestone Aug 30, 2021
shocklateboy92 pushed a commit that referenced this issue Sep 7, 2021
* Handling a large number of edge cases for pattern matching.

closes #413
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant