예제 #1
0
        private bool CandidateOperators(
            ArrayBuilder <UnaryOperatorSignature> operators,
            BoundExpression operand,
            ArrayBuilder <UnaryOperatorAnalysisResult> results,
            ref CompoundUseSiteInfo <AssemblySymbol> useSiteInfo
            )
        {
            bool anyApplicable = false;

            foreach (var op in operators)
            {
                var conversion = Conversions.ClassifyConversionFromExpression(
                    operand,
                    op.OperandType,
                    ref useSiteInfo
                    );
                if (conversion.IsImplicit)
                {
                    anyApplicable = true;
                    results.Add(UnaryOperatorAnalysisResult.Applicable(op, conversion));
                }
                else
                {
                    results.Add(UnaryOperatorAnalysisResult.Inapplicable(op, conversion));
                }
            }

            return(anyApplicable);
        }
예제 #2
0
        protected BoundExpression ConvertCaseExpression(CSharpSyntaxNode node, BoundExpression caseExpression, Binder sectionBinder, ref ConstantValue constantValueOpt, DiagnosticBag diagnostics, bool isGotoCaseExpr = false)
        {
            if (isGotoCaseExpr)
            {
                // SPEC VIOLATION for Dev10 COMPATIBILITY:

                // Dev10 compiler violates the SPEC comment below:
                //      "if the constant-expression is not implicitly convertible (§6.1) to
                //      the governing type of the nearest enclosing switch statement,
                //      a compile-time error occurs"

                // If there is no implicit conversion from gotoCaseExpression to switchGoverningType,
                // but there exists an explicit conversion, Dev10 compiler generates a warning "WRN_GotoCaseShouldConvert"
                // instead of an error. See test "CS0469_NoImplicitConversionWarning".

                HashSet <DiagnosticInfo> useSiteDiagnostics = null;
                Conversion conversion = Conversions.ClassifyConversionFromExpression(caseExpression, SwitchGoverningType, ref useSiteDiagnostics);
                diagnostics.Add(node, useSiteDiagnostics);
                if (!conversion.IsValid)
                {
                    GenerateImplicitConversionError(diagnostics, node, conversion, caseExpression, SwitchGoverningType);
                }
                else if (!conversion.IsImplicit)
                {
                    diagnostics.Add(ErrorCode.WRN_GotoCaseShouldConvert, node.Location, SwitchGoverningType);
                }

                caseExpression = CreateConversion(caseExpression, conversion, SwitchGoverningType, diagnostics);
            }

            return(ConvertPatternExpression(SwitchGoverningType, node, caseExpression, ref constantValueOpt, diagnostics));
        }
예제 #3
0
        private BoundExpression ConvertCaseExpression(TypeSymbol switchGoverningType, CSharpSyntaxNode node, BoundExpression caseExpression, ref ConstantValue constantValueOpt, DiagnosticBag diagnostics, bool isGotoCaseExpr = false)
        {
            BoundExpression convertedCaseExpression;

            if (!isGotoCaseExpr)
            {
                // NOTE: This will allow user-defined conversions, even though they're not allowed here.  This is acceptable
                // because the result of a user-defined conversion does not have a ConstantValue and we'll report a diagnostic
                // to that effect below (same error code as Dev10).
                convertedCaseExpression = GenerateConversionForAssignment(switchGoverningType, caseExpression, diagnostics);
            }
            else
            {
                // SPEC VIOLATION for Dev10 COMPATIBILITY:

                // Dev10 compiler violates the SPEC comment below:
                //      "if the constant-expression is not implicitly convertible (§6.1) to
                //      the governing type of the nearest enclosing switch statement,
                //      a compile-time error occurs"

                // If there is no implicit conversion from gotoCaseExpression to switchGoverningType,
                // but there exists an explicit conversion, Dev10 compiler generates a warning "WRN_GotoCaseShouldConvert"
                // instead of an error. See test "CS0469_NoImplicitConversionWarning".

                // CONSIDER: Should we introduce a breaking change and violate Dev10 compatibility and follow the spec?

                HashSet <DiagnosticInfo> useSiteDiagnostics = null;
                Conversion conversion = Conversions.ClassifyConversionFromExpression(caseExpression, switchGoverningType, ref useSiteDiagnostics);
                diagnostics.Add(node, useSiteDiagnostics);
                if (!conversion.IsValid)
                {
                    GenerateImplicitConversionError(diagnostics, node, conversion, caseExpression, switchGoverningType);
                }
                else if (!conversion.IsImplicit)
                {
                    diagnostics.Add(ErrorCode.WRN_GotoCaseShouldConvert, node.Location, switchGoverningType);
                }

                convertedCaseExpression = this.CreateConversion(caseExpression, conversion, switchGoverningType, diagnostics);
            }

            if (switchGoverningType.IsNullableType() &&
                convertedCaseExpression.Kind == BoundKind.Conversion
                // Null is a special case here because we want to compare null to the Nullable<T> itself, not to the underlying type.
                && (convertedCaseExpression.ConstantValue == null || !convertedCaseExpression.ConstantValue.IsNull))
            {
                var operand = ((BoundConversion)convertedCaseExpression).Operand;

                // We are not intested in the diagnostic that get created here
                var diagnosticBag = DiagnosticBag.GetInstance();
                constantValueOpt = CreateConversion(operand, switchGoverningType.GetNullableUnderlyingType(), diagnosticBag).ConstantValue;
                diagnosticBag.Free();
            }
            else
            {
                constantValueOpt = convertedCaseExpression.ConstantValue;
            }

            return(convertedCaseExpression);
        }