public MultiplicationMemoryOp(int offset, int scalar, ConstantValue constant, ConstantValue multiplicationConstant)
 {
     Offset = offset;
     Scalar = scalar;
     Constant = constant;
     MultiplicationConstant = multiplicationConstant;
 }
 internal SourceStrictComplexParameterSymbol(
     DiagnosticBag diagnostics,
     Binder binder,
     Symbol owner,
     int ordinal,
     TypeSymbol parameterType,
     RefKind refKind,
     string name,
     ImmutableArray<Location> locations,
     SyntaxReference syntaxRef,
     ConstantValue defaultSyntaxValue,
     bool isParams,
     bool isExtensionMethodThis)
 : base(
     owner: owner,
     ordinal: ordinal,
     parameterType: parameterType,
     refKind: refKind,
     name: name,
     locations: locations,
     syntaxRef: syntaxRef,
     defaultSyntaxValue: defaultSyntaxValue,
     isParams: isParams,
     isExtensionMethodThis: isExtensionMethodThis)
 {
     _tempBinder = binder;
     var unused = GetAttributesBag(diagnostics);
     _lazyDefaultSyntaxValue = MakeDefaultExpression(diagnostics, binder);
     _tempBinder = null; // no need to keep it around anymore, just uses up a lot of memory
 }
        private BoundExpression MakeLiteral(CSharpSyntaxNode syntax, ConstantValue constantValue, TypeSymbol type, BoundLiteral oldNodeOpt = null)
        {
            Debug.Assert(constantValue != null);

            if (constantValue.IsDecimal)
            {
                //  Rewrite decimal literal
                Debug.Assert((object)type != null);
                Debug.Assert(type.SpecialType == SpecialType.System_Decimal);

                return MakeDecimalLiteral(syntax, constantValue);
            }
            else if (constantValue.IsDateTime)
            {
                // C# does not support DateTime constants but VB does; we might have obtained a 
                // DateTime constant by calling a method with an optional parameter with a DateTime
                // for its default value.
                Debug.Assert((object)type != null);
                Debug.Assert(type.SpecialType == SpecialType.System_DateTime);
                return MakeDateTimeLiteral(syntax, constantValue);
            }
            else if (oldNodeOpt != null)
            {
                return oldNodeOpt.Update(constantValue, type);
            }
            else
            {
                return new BoundLiteral(syntax, constantValue, type, hasErrors: constantValue.IsBad);
            }
        }
 public CriteriaOperator PrepareCriteria(CriteriaOperator op)
 {
     if (op is FunctionOperator)
     {
         var funcOp = new FunctionOperator();
         for (int i = 0; i < (op as FunctionOperator).Operands.Count; i++)
             funcOp.Operands.Add(PrepareCriteria((op as FunctionOperator).Operands[i]));
         return funcOp;
     }
     else if (op is ConstantValue)
     {
         var cnst = new ConstantValue((op as ConstantValue).Value);
         if (String.Concat((op as ConstantValue).Value).ToLower().IndexOf("@this") > -1)
         {
             IMemberInfo info;
             cnst.Value = ObjectFormatValues.GetValueRecursive((op as ConstantValue).Value.ToString().Replace("@This.", "").Replace("@This", "").Replace("@this.", "").Replace("@this", ""), CurrentObject, out info);
         }
         return cnst;
     }
     else if (op is BinaryOperator)
     {
         var binary = new BinaryOperator();
         binary.LeftOperand = PrepareCriteria((op as BinaryOperator).LeftOperand);
         binary.RightOperand = PrepareCriteria((op as BinaryOperator).RightOperand);
         return binary;
     }
     else
     {
         return op;
     }
 }
        private BoundExpression MakeFieldAccess(
            CSharpSyntaxNode syntax,
            BoundExpression rewrittenReceiver,
            FieldSymbol fieldSymbol,
            ConstantValue constantValueOpt,
            LookupResultKind resultKind,
            TypeSymbol type,
            BoundFieldAccess oldNodeOpt = null)
        {

            if (fieldSymbol.IsTupleField)
            {
                return MakeTupleFieldAccess(syntax, fieldSymbol, rewrittenReceiver, constantValueOpt, resultKind);
            }
            
            BoundExpression result = oldNodeOpt != null ?
                oldNodeOpt.Update(rewrittenReceiver, fieldSymbol, constantValueOpt, resultKind, type) :
                new BoundFieldAccess(syntax, rewrittenReceiver, fieldSymbol, constantValueOpt, resultKind, type);

            if (fieldSymbol.IsFixed)
            {
                // a reference to a fixed buffer is translated into its address
                result = new BoundConversion(syntax,
                    new BoundAddressOfOperator(syntax, result, syntax != null && SyntaxFacts.IsFixedStatementExpression(syntax), type, false),
                    new Conversion(ConversionKind.PointerToPointer), false, false, default(ConstantValue), type, false);
            }

            return result;
        }
        private static BoundExpression RewriteConditionalOperator(
            CSharpSyntaxNode syntax,
            BoundExpression rewrittenCondition,
            BoundExpression rewrittenConsequence,
            BoundExpression rewrittenAlternative,
            ConstantValue constantValueOpt,
            TypeSymbol rewrittenType)
        {
            // NOTE: This optimization assumes that a constant has no side effects. In the future we 
            // might wish to represent nodes that are known to the optimizer as having constant
            // values as a sequence of side effects and a constant value; in that case the result
            // of this should be a sequence containing the side effect and the consequence or alternative.

            ConstantValue conditionConstantValue = rewrittenCondition.ConstantValue;
            if (conditionConstantValue == ConstantValue.True)
            {
                return rewrittenConsequence;
            }
            else if (conditionConstantValue == ConstantValue.False)
            {
                return rewrittenAlternative;
            }
            else
            {
                return new BoundConditionalOperator(
                    syntax,
                    rewrittenCondition,
                    rewrittenConsequence,
                    rewrittenAlternative,
                    constantValueOpt,
                    rewrittenType);
            }
        }
Exemple #7
0
 public SourceLabelSymbol(
     MethodSymbol containingMethod,
     ConstantValue switchCaseLabelConstant)
 {
     _containingMethod = containingMethod;
     _identifierNodeOrToken = default(SyntaxToken);
     _switchCaseLabelConstant = switchCaseLabelConstant;
 }
 public SourceLabelSymbol(
     MethodSymbol containingMethod,
     ConstantValue switchCaseLabelConstant = null)
     : base(switchCaseLabelConstant.ToString())
 {
     this.containingMethod = containingMethod;
     this.identifierNodeOrToken = default(SyntaxToken);
     this.switchCaseLabelConstant = switchCaseLabelConstant;
 }
Exemple #9
0
 public FieldVariable(ChelaModule module)
     : base(module)
 {
     this.flags = MemberFlags.Default;
     this.slot = -1;
     this.initializer = null;
     this.parentScope = null;
     this.position = null;
 }
Exemple #10
0
 public BoundFieldAccess(
     CSharpSyntaxNode syntax,
     BoundExpression receiver,
     FieldSymbol fieldSymbol,
     ConstantValue constantValueOpt,
     bool hasErrors = false)
     : this(syntax, receiver, fieldSymbol, constantValueOpt, LookupResultKind.Viable, fieldSymbol.Type, hasErrors)
 {
 }
Exemple #11
0
 public SourceLabelSymbol(
     MethodSymbol containingMethod,
     SyntaxNodeOrToken identifierNodeOrToken,
     ConstantValue switchCaseLabelConstant = null)
 {
     _containingMethod = containingMethod;
     _identifierNodeOrToken = identifierNodeOrToken;
     _switchCaseLabelConstant = switchCaseLabelConstant;
 }
Exemple #12
0
 public BoundFieldAccess Update(
     BoundExpression receiver,
     FieldSymbol fieldSymbol,
     ConstantValue constantValueOpt,
     LookupResultKind resultKind,
     TypeSymbol typeSymbol)
 {
     return this.Update(receiver, fieldSymbol, constantValueOpt, resultKind, this.IsByValue, typeSymbol);
 }
 public SourceLabelSymbol(
     MethodSymbol containingMethod,
     SyntaxNodeOrToken identifierNodeOrToken,
     ConstantValue switchCaseLabelConstant = null)
     : base(identifierNodeOrToken.IsToken ? identifierNodeOrToken.AsToken().ValueText : identifierNodeOrToken.ToString())
 {
     this.containingMethod = containingMethod;
     this.identifierNodeOrToken = identifierNodeOrToken;
     this.switchCaseLabelConstant = switchCaseLabelConstant;
 }
 public SynthesizedFieldSymbol(
     NamedTypeSymbol containing,
     TypeSymbol type,
     string name,
     Accessibility accessibility,
     ConstantValue constant)
     :this(containing, type, name, accessibility, true)
 {
     _const = constant;
 }
Exemple #15
0
 public FieldVariable(string name, MemberFlags flags, IChelaType type, Scope parentScope)
     : base(type, parentScope.GetModule())
 {
     SetName(name);
     this.flags = flags;
     this.parentScope = parentScope;
     this.slot = -1;
     this.initializer = null;
     this.position = null;
 }
Exemple #16
0
 public BoundFieldAccess(
     CSharpSyntaxNode syntax,
     BoundExpression receiver,
     FieldSymbol fieldSymbol,
     ConstantValue constantValueOpt,
     LookupResultKind resultKind,
     TypeSymbol type,
     bool hasErrors = false)
     : this(syntax, receiver, fieldSymbol, constantValueOpt, resultKind, NeedsByValueFieldAccess(receiver, fieldSymbol), type, hasErrors)
 {
 }
 public EELocalConstantSymbol(
     MethodSymbol method,
     string name,
     TypeSymbol type,
     ConstantValue value)
 {
     _method = method;
     _name = name;
     _type = type;
     _value = value;
 }
Exemple #18
0
        public static ITypeRef Create(ConstantValue c)
        {
            Contract.ThrowIfNull(c);

            switch (c.SpecialType)
            {
                case SpecialType.System_Int32:
                case SpecialType.System_Int64: return LongTypeRef;
                case SpecialType.System_String: return StringTypeRef;
                case SpecialType.System_Double: return DoubleTypeRef;
                case SpecialType.System_Boolean: return BoolTypeRef;
                default:
                    throw new NotImplementedException();
            }
        }
Exemple #19
0
        /// <summary>
        /// Converts access to a tuple instance into access into the underlying ValueTuple(s).
        ///
        /// For instance, tuple.Item8
        /// produces fieldAccess(field=Item1, receiver=fieldAccess(field=Rest, receiver=ValueTuple for tuple))
        /// </summary>
        private BoundExpression MakeTupleFieldAccess(
            CSharpSyntaxNode syntax,
            FieldSymbol tupleField, 
            BoundExpression rewrittenReceiver,
            ConstantValue constantValueOpt,
            LookupResultKind resultKind,
            TypeSymbol type)
        {
            var tupleType = tupleField.ContainingType;

            NamedTypeSymbol currentLinkType = tupleType.TupleUnderlyingType;
            FieldSymbol underlyingField = tupleField.TupleUnderlyingField;

            if ((object)underlyingField == null)
            {
                // Use-site error must have been reported elsewhere.
                return new BoundFieldAccess(syntax, rewrittenReceiver, tupleField, constantValueOpt, resultKind, type, hasErrors: true);
            }

            if (underlyingField.ContainingType != currentLinkType)
            {
                WellKnownMember wellKnownTupleRest = TupleTypeSymbol.GetTupleTypeMember(TupleTypeSymbol.RestPosition, TupleTypeSymbol.RestPosition);
                var tupleRestField = (FieldSymbol)TupleTypeSymbol.GetWellKnownMemberInType(currentLinkType.OriginalDefinition, wellKnownTupleRest, _diagnostics, syntax);

                if ((object)tupleRestField == null)
                {
                    // error tolerance for cases when Rest is missing
                    return new BoundFieldAccess(syntax, rewrittenReceiver, tupleField, constantValueOpt, resultKind, type, hasErrors: true);
                }

                // make nested field accesses to Rest
                do
                {
                    FieldSymbol nestedFieldSymbol = tupleRestField.AsMember(currentLinkType);

                    currentLinkType = currentLinkType.TypeArgumentsNoUseSiteDiagnostics[TupleTypeSymbol.RestPosition - 1].TupleUnderlyingType;
                    rewrittenReceiver = new BoundFieldAccess(syntax, rewrittenReceiver, nestedFieldSymbol, ConstantValue.NotAvailable, LookupResultKind.Viable, currentLinkType);
                }
                while (underlyingField.ContainingType != currentLinkType);
            }

            // make a field access for the most local access
            return new BoundFieldAccess(syntax, rewrittenReceiver, underlyingField, constantValueOpt, resultKind, type);
        }
        internal SourcePrimaryConstructorParameterSymbolWithBackingField(
            Symbol owner,
            int ordinal,
            TypeSymbol parameterType,
            RefKind refKind,
            string name,
            ImmutableArray<Location> locations,
            ParameterSyntax syntax,
            ConstantValue defaultSyntaxValue,
            bool isParams,
            bool isExtensionMethodThis,
            DiagnosticBag diagnostics
        ) : base(owner, ordinal, parameterType, refKind, ImmutableArray<CustomModifier>.Empty, false, name, locations, syntax.GetReference(), defaultSyntaxValue, isParams, isExtensionMethodThis)
        {
            bool modifierErrors;
            var modifiers = SourceMemberFieldSymbol.MakeModifiers(owner.ContainingType, syntax.Identifier, syntax.Modifiers, diagnostics, out modifierErrors, ignoreParameterModifiers: true);

            backingField = new BackingField(this, modifiers, modifierErrors, diagnostics);
        }
 protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
 {
     var methodDeclaration = _highlighting.MethodDeclaration;
     methodDeclaration.SetStatic(true);
     var factory = CSharpElementFactory.GetInstance(methodDeclaration.GetPsiModule());
     var type = TypeFactory.CreateTypeByCLRName(DllImportMissingAnalyzer.DllImportAttribute, methodDeclaration.GetPsiModule());
     var constantValue = new ConstantValue("name.dll", methodDeclaration.GetPsiModule());
     var attributeValue = new AttributeValue(constantValue);
     var attribute = factory.CreateAttribute(type.GetTypeElement(), new[] { attributeValue }, new Pair<string, AttributeValue>[0]);
     var addedAttribute = methodDeclaration.AddAttributeAfter(attribute, null);
     var firstParameter = addedAttribute.ConstructorArgumentExpressions.FirstOrDefault();
     if (firstParameter == null)
     {
         return null;
     }
     var documentRange = firstParameter.GetDocumentRange();
     documentRange = documentRange.TrimLeft(1).TrimRight(1);
     var rangeMarker =  documentRange.CreateRangeMarker(DocumentManager.GetInstance(solution));
     return control => control.Selection.SetRange(rangeMarker.Range);
 }
            private static ulong GetBucketSize(ConstantValue startConstant, ConstantValue endConstant)
            {
                Debug.Assert(!BucketOverflowUInt64Limit(startConstant, endConstant));
                Debug.Assert(endConstant.Discriminator == startConstant.Discriminator);

                ulong bucketSize;

                if (startConstant.IsNegativeNumeric || endConstant.IsNegativeNumeric)
                {
                    Debug.Assert(endConstant.Int64Value >= startConstant.Int64Value);
                    bucketSize = unchecked((ulong)(endConstant.Int64Value - startConstant.Int64Value + 1));
                }
                else
                {
                    Debug.Assert(endConstant.UInt64Value >= startConstant.UInt64Value);
                    bucketSize = endConstant.UInt64Value - startConstant.UInt64Value + 1;
                }

                return bucketSize;
            }
        internal SourceComplexParameterSymbol(
            Symbol owner,
            int ordinal,
            TypeSymbol parameterType,
            RefKind refKind,
            ImmutableArray<CustomModifier> customModifiers,
            bool hasByRefBeforeCustomModifiers,
            string name,
            ImmutableArray<Location> locations,
            SyntaxReference syntaxRef,
            ConstantValue defaultSyntaxValue,
            bool isParams,
            bool isExtensionMethodThis)
            : base(owner, parameterType, ordinal, refKind, name, locations)
        {
            Debug.Assert((syntaxRef == null) || (syntaxRef.GetSyntax().IsKind(SyntaxKind.Parameter)));
            Debug.Assert(!customModifiers.IsDefault);

            _lazyHasOptionalAttribute = ThreeState.Unknown;
            _syntaxRef = syntaxRef;

            if (isParams)
            {
                _parameterSyntaxKind |= ParameterSyntaxKind.ParamsParameter;
            }

            if (isExtensionMethodThis)
            {
                _parameterSyntaxKind |= ParameterSyntaxKind.ExtensionThisParameter;
            }

            var parameterSyntax = this.CSharpSyntaxNode;
            if (parameterSyntax != null && parameterSyntax.Default != null)
            {
                _parameterSyntaxKind |= ParameterSyntaxKind.DefaultParameter;
            }

            _lazyDefaultSyntaxValue = defaultSyntaxValue;
            _customModifiers = customModifiers;
            _hasByRefBeforeCustomModifiers = hasByRefBeforeCustomModifiers;
        }
Exemple #24
0
        /// <summary>
        /// Add a registry requirement to an existing deployment type
        /// </summary>
        public static void AddRequirement(string applicationName, string authoringScopeId, string logicalName, string settingLogicalName, string value, string dataType, string expressionOperator, string server)
        {
            Application app = CMApplication.GetApplicationByName(applicationName, server);
            DeploymentType deploymentType = app.DeploymentTypes[0];

            CustomCollection<ExpressionBase> settingsOperands = new CustomCollection<ExpressionBase>();
            GlobalSettingReference settingReferences = null;
            ConstantValue constant = null;

            switch (dataType)
            {
                case "Version":
                    settingReferences = new GlobalSettingReference(authoringScopeId, logicalName, DataType.Version, settingLogicalName, ConfigurationItemSettingSourceType.Registry);
                    constant = new ConstantValue(value, DataType.Version);
                    break;
                default:
                    break;
            }

            settingsOperands.Add(settingReferences);
            settingsOperands.Add(constant);

            Expression expression = null;

            switch (expressionOperator)
            {
                case "IsEquals":
                    expression = new Expression(ExpressionOperator.IsEquals, settingsOperands);
                    break;
                case "LessEquals":
                    expression = new Expression(ExpressionOperator.LessEquals, settingsOperands);
                    break;
                default:
                    break;
            }

            Rule rule = new Rule(Guid.NewGuid().ToString("N"), NoncomplianceSeverity.Critical, null, expression);

            deploymentType.Requirements.Add(rule);
            CMApplication.Save(app, server);
        }
        public void Returns_a_warning_when_tag_is_zero()
        {
            var mockPsiModule = new Mock<IPsiModule>();
            

            var mockName = new Mock<IReferenceName>();
            mockName.Setup(n => n.ShortName).Returns("ProtoMember");
            var mockConstructorExpression = new Mock<ICSharpExpression>();
            mockConstructorExpression.Setup(e => e.IsConstantValue()).Returns(true);
            var constantValue = new ConstantValue(0, mockPsiModule.Object, DiagnosticResolveContext.Instance);
            mockConstructorExpression.Setup(e => e.ConstantValue).Returns(constantValue);

            var mockAttributeElement = new Mock<IAttribute>();
            mockAttributeElement.Setup(a => a.Name).Returns(mockName.Object);
            var expressionTree = new TreeNodeCollection<ICSharpExpression>(new[] {mockConstructorExpression.Object});
            mockAttributeElement.Setup(a => a.ConstructorArgumentExpressions).Returns(expressionTree);
            
            var mockConsumer = new Mock<IHighlightingConsumer>();
            
            var analyzer = new TagValueAnalyzer();
            analyzer.Analyze(mockAttributeElement.Object, mockConsumer.Object);
            mockConsumer.Verify(v => v.ConsumeHighlighting(It.IsAny<HighlightingInfo>()));
        }
        public SynthesizedParameterSymbol(
            MethodSymbol container,
            TypeSymbol type,
            int ordinal,
            RefKind refKind,
            string name = "",
            ImmutableArray<CustomModifier> customModifiers = default(ImmutableArray<CustomModifier>),
            ushort countOfCustomModifiersPrecedingByRef = 0,
            ConstantValue explicitDefaultConstantValue = null)
        {
            Debug.Assert((object)type != null);
            Debug.Assert(name != null);
            Debug.Assert(ordinal >= 0);

            _container = container;
            _type = type;
            _ordinal = ordinal;
            _refKind = refKind;
            _name = name;
            _customModifiers = customModifiers.NullToEmpty();
            _countOfCustomModifiersPrecedingByRef = countOfCustomModifiersPrecedingByRef;
            _explicitDefaultConstantValue = explicitDefaultConstantValue;
        }
        public IEnumerable <GaugeValueSource> SetupGauges()
        {
            var gauge = new GaugeValueSource("test_gauge", ConstantValue.Provider(0.5), Unit.Calls, Tags);

            return(new[] { gauge });
        }
Exemple #28
0
        private void CheckForBitwiseOrSignExtend(BoundExpression node, BinaryOperatorKind operatorKind, BoundExpression leftOperand, BoundExpression rightOperand)
        {
            // We wish to give a warning for situations where an unexpected sign extension wipes
            // out some bits. For example:
            //
            // int x = 0x0ABC0000;
            // short y = -2; // 0xFFFE
            // int z = x | y;
            //
            // The user might naively expect the result to be 0x0ABCFFFE. But the short is sign-extended
            // when it is converted to int before the bitwise or, so this is in fact the same as:
            //
            // int x = 0x0ABC0000;
            // short y = -2; // 0xFFFE
            // int ytemp = y; // 0xFFFFFFFE
            // int z = x | ytemp;
            //
            // Which gives 0xFFFFFFFE, not 0x0ABCFFFE.
            //
            // However, we wish to suppress the warning if:
            //
            // * The sign extension is "expected" -- for instance, because there was an explicit cast
            //   from short to int:  "int z = x | (int)y;" should not produce the warning.
            //   Note that "uint z = (uint)x | (uint)y;" should still produce the warning because
            //   the user might not realize that converting y to uint does a sign extension.
            //
            // * There is the same amount of sign extension on both sides. For example, when
            //   doing "short | sbyte", both sides are sign extended. The left creates two FF bytes
            //   and the right creates three, so we are potentially wiping out information from the
            //   left side. But "short | short" adds two FF bytes on both sides, so no information is lost.
            //
            // The native compiler also suppresses this warning in a bizarre and inconsistent way. If
            // the side whose bits are going to be wiped out by sign extension is a *constant*, then the
            // warning is suppressed *if the constant, when converted to a signed long, fits into the
            // range of the type that is being sign-extended.*
            //
            // Consider the effects of this rule:
            //
            // (uint)0xFFFF0000 | y -- gives the warning because 0xFFFF0000 as a long is not in the range of a short,
            //                         *even though the result will not be affected by the sign extension*.
            // (ulong)0xFFFFFFFFFFFFFFFF | y -- suppresses the warning, because 0xFFFFFFFFFFFFFFFF as a signed long fits into a short.
            // (int)0x0000ABCD | y -- suppresses the warning, even though the 0000 is going to be wiped out by the sign extension.
            //
            // It seems clear that the intention of the heuristic is to *suppress the warning when the bits being hammered
            // on are either all zero, or all one.*  Therefore that is the heuristic we will *actually* implement here.
            //

            switch (operatorKind)
            {
            case BinaryOperatorKind.LiftedUInt32Or:
            case BinaryOperatorKind.LiftedInt32Or:
            case BinaryOperatorKind.LiftedUInt64Or:
            case BinaryOperatorKind.LiftedInt64Or:
            case BinaryOperatorKind.UInt32Or:
            case BinaryOperatorKind.Int32Or:
            case BinaryOperatorKind.UInt64Or:
            case BinaryOperatorKind.Int64Or:
                break;

            default:
                return;
            }

            // The native compiler skips this warning if both sides of the operator are constants.
            //
            // CONSIDER: Is that sensible? It seems reasonable that if we would warn on int | short
            // when they are non-constants, or when one is a constant, that we would similarly warn
            // when both are constants.

            if (node.ConstantValue != null)
            {
                return;
            }

            // Start by determining *which bits on each side are going to be unexpectedly turned on*.

            ulong left  = FindSurprisingSignExtensionBits(leftOperand);
            ulong right = FindSurprisingSignExtensionBits(rightOperand);

            // If they are all the same then there's no warning to give.

            if (left == right)
            {
                return;
            }

            // Suppress the warning if one side is a constant, and either all the unexpected
            // bits are already off, or all the unexpected bits are already on.

            ConstantValue constVal = GetConstantValueForBitwiseOrCheck(leftOperand);

            if (constVal != null)
            {
                ulong val = constVal.UInt64Value;
                if ((val & right) == right || (~val & right) == right)
                {
                    return;
                }
            }

            constVal = GetConstantValueForBitwiseOrCheck(rightOperand);
            if (constVal != null)
            {
                ulong val = constVal.UInt64Value;
                if ((val & left) == left || (~val & left) == left)
                {
                    return;
                }
            }

            // CS0675: Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first
            Error(ErrorCode.WRN_BitwiseOrSignExtend, node);
        }
Exemple #29
0
 public Literal(ConstantValue value, ITypeSymbol resultType, SyntaxNode syntax)
 {
     _value          = value;
     this.ResultType = resultType;
     this.Syntax     = syntax;
 }
 public BoundObjectCreationExpression(SyntaxNode syntax, MethodSymbol constructor, ImmutableArray <BoundExpression> arguments, ImmutableArray <string> argumentNamesOpt,
                                      ImmutableArray <RefKind> argumentRefKindsOpt, bool expanded, ImmutableArray <int> argsToParamsOpt, ConstantValue constantValueOpt,
                                      BoundObjectInitializerExpressionBase initializerExpressionOpt, Binder binderOpt, TypeSymbol type, bool hasErrors = false)
     : this(syntax, constructor, ImmutableArray <MethodSymbol> .Empty, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, constantValueOpt, initializerExpressionOpt, binderOpt, type, hasErrors)
 {
 }
Exemple #31
0
        private BoundExpression MakeDecimalLiteral(CSharpSyntaxNode syntax, ConstantValue constantValue)
        {
            Debug.Assert(constantValue != null);
            Debug.Assert(constantValue.IsDecimal);

            var value = constantValue.DecimalValue;
            var parts = new ConstantValueUtils.DecimalValue(value);
            var scale = parts.Scale;

            var           arguments = new ArrayBuilder <BoundExpression>();
            SpecialMember member;

            // check if we can call a simpler constructor, or use a predefined constant
            if (scale == 0 && int.MinValue <= value && value <= int.MaxValue)
            {
                // If we are building static constructor of System.Decimal, accessing static fields
                // would be bad.
                var curMethod = _factory.CurrentMethod;
                if ((curMethod.MethodKind != MethodKind.SharedConstructor ||
                     curMethod.ContainingType.SpecialType != SpecialType.System_Decimal) &&
                    !_inExpressionLambda)
                {
                    Symbol useField = null;

                    if (value == decimal.Zero)
                    {
                        useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__Zero);
                    }
                    else if (value == decimal.One)
                    {
                        useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__One);
                    }
                    else if (value == decimal.MinusOne)
                    {
                        useField = _compilation.GetSpecialTypeMember(SpecialMember.System_Decimal__MinusOne);
                    }

                    if ((object)useField != null &&
                        !useField.HasUseSiteError &&
                        !useField.ContainingType.HasUseSiteError)
                    {
                        var fieldSymbol = (FieldSymbol)useField;
                        return(new BoundFieldAccess(syntax, null, fieldSymbol, constantValue));
                    }
                }

                //new decimal(int);
                member = SpecialMember.System_Decimal__CtorInt32;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((int)value), _compilation.GetSpecialType(SpecialType.System_Int32)));
            }
            else if (scale == 0 && uint.MinValue <= value && value <= uint.MaxValue)
            {
                //new decimal(uint);
                member = SpecialMember.System_Decimal__CtorUInt32;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((uint)value), _compilation.GetSpecialType(SpecialType.System_UInt32)));
            }
            else if (scale == 0 && long.MinValue <= value && value <= long.MaxValue)
            {
                //new decimal(long);
                member = SpecialMember.System_Decimal__CtorInt64;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((long)value), _compilation.GetSpecialType(SpecialType.System_Int64)));
            }
            else if (scale == 0 && ulong.MinValue <= value && value <= ulong.MaxValue)
            {
                //new decimal(ulong);
                member = SpecialMember.System_Decimal__CtorUInt64;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create((ulong)value), _compilation.GetSpecialType(SpecialType.System_UInt64)));
            }
            else
            {
                //new decimal(int low, int mid, int high, bool isNegative, byte scale);
                member = SpecialMember.System_Decimal__CtorInt32Int32Int32BooleanByte;
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.Low), _compilation.GetSpecialType(SpecialType.System_Int32)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.Mid), _compilation.GetSpecialType(SpecialType.System_Int32)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.High), _compilation.GetSpecialType(SpecialType.System_Int32)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.IsNegative), _compilation.GetSpecialType(SpecialType.System_Boolean)));
                arguments.Add(new BoundLiteral(syntax, ConstantValue.Create(parts.Scale), _compilation.GetSpecialType(SpecialType.System_Byte)));
            }

            var ctor = (MethodSymbol)_compilation.Assembly.GetSpecialTypeMember(member);

            Debug.Assert((object)ctor != null);
            Debug.Assert(ctor.ContainingType.SpecialType == SpecialType.System_Decimal);

            return(new BoundObjectCreationExpression(
                       syntax, ctor, arguments.ToImmutableAndFree(),
                       default(ImmutableArray <string>), default(ImmutableArray <RefKind>), false, default(ImmutableArray <int>),
                       constantValue, null, ctor.ContainingType));
        }
Exemple #32
0
        /// <summary>
        /// Tries to convert <paramref name="value"/> to a <see cref="ConstantValue"/> if possible.
        /// Argument that doesn't have value or values which cannot be represented as <see cref="ConstantValue"/> causes a <c>null</c> reference to be returned.
        /// </summary>
        /// <param name="value">Optional boced value.</param>
        /// <returns><see cref="ConstantValue"/> instance if possible. Otherwise a <c>null</c> reference.</returns>
        public static ConstantValue ToConstantValueOrNull(this Optional <object> value)
        {
            if (value.HasValue)
            {
                var obj = value.Value;
                if (obj == null)
                {
                    return(ConstantValue.Null);
                }
                if (obj is int)
                {
                    return(ConstantValue.Create((int)obj));
                }
                if (obj is long)
                {
                    return(ConstantValue.Create((long)obj));
                }
                if (obj is string)
                {
                    return(ConstantValue.Create((string)obj));
                }
                if (obj is bool)
                {
                    return(ConstantValue.Create((bool)obj));
                }
                if (obj is double)
                {
                    return(ConstantValue.Create((double)obj));
                }
                if (obj is float)
                {
                    return(ConstantValue.Create((float)obj));
                }
                if (obj is decimal)
                {
                    return(ConstantValue.Create((decimal)obj));
                }
                if (obj is ulong)
                {
                    return(ConstantValue.Create((ulong)obj));
                }
                if (obj is uint)
                {
                    return(ConstantValue.Create((uint)obj));
                }
                if (obj is sbyte)
                {
                    return(ConstantValue.Create((sbyte)obj));
                }
                if (obj is short)
                {
                    return(ConstantValue.Create((short)obj));
                }
                if (obj is DateTime)
                {
                    return(ConstantValue.Create((DateTime)obj));
                }
            }

            return(null);
        }
Exemple #33
0
 protected static object KeyForConstant(ConstantValue constantValue)
 {
     Debug.Assert((object)constantValue != null);
     return(constantValue.IsNull ? s_nullKey : constantValue.Value);
 }
Exemple #34
0
 float INumericTC <float> .FromConstantValue(ConstantValue constantValue) => constantValue.IsBad ? 0.0F : constantValue.SingleValue;
Exemple #35
0
 ConstantValue INumericTC <float> .ToConstantValue(float value) => ConstantValue.Create(value);
Exemple #36
0
        /// <summary>
        /// Write Code-Entry into C# Code
        /// </summary>
        /// <param name="inOutput"></param>
        /// <param name="inCodeEntry"></param>
        private TypeContainer CodeEntryHandling(ICodeEntry inCodeEntry, FieldNameFinder inNameFinder, TypeContainer inReturnType = null)
        {
            if (inCodeEntry == null)
            {
                return(null);
            }
            TypeContainer tmpReturnType = null;

            if (inCodeEntry is VariableDeclaration)
            {
                var tmpVarDecl = inCodeEntry as VariableDeclaration;
                inNameFinder.VariableList.Add(tmpVarDecl);

                var tmpConstant = new ConstantValue()
                {
                    Type = tmpVarDecl.Type
                };
                GetGlobalTypeForType(new FieldNameFinder(inNameFinder), tmpConstant, tmpVarDecl.Type.Name);
                tmpVarDecl.Type = tmpConstant.Type;
            }
            else if (inCodeEntry is ConstantValue)
            {
                var tmpConstant = (inCodeEntry as ConstantValue);
                var tmpVal      = tmpConstant.Value?.ToString() ?? tmpConstant.Type.Name;
                if (tmpConstant.Value is FieldContainer)
                {
                    tmpVal = (tmpConstant.Value as FieldContainer).Name;
                }
                else if (tmpConstant.Value is VariableDeclaration)
                {
                    tmpVal = (tmpConstant.Value as VariableDeclaration).Name;
                }
                else if (tmpVal.EndsWith("\""))
                {
                    //It's a number, nothing to do
                    tmpReturnType = ProjectInformation.GetAliasType("string")?.Type ?? tmpReturnType;
                }
                else if (RegexHelper.NumberCheck.IsMatch(tmpVal))
                {
                    //It's a number, nothing to do
                    tmpReturnType = ProjectInformation.GetAliasType("int")?.Type ?? tmpReturnType;
                }
                else
                {
                    //Access to Variable, Field, Param or static Class, so we need to do a lot here for Code-link
                    if (tmpVal == "this")
                    {
                        inNameFinder.VariableList = new List <VariableDeclaration>();
                        tmpConstant.Type          = inNameFinder.MethodeParentClass.Type;
                    }
                    else if (tmpVal == "base")
                    {
                        inNameFinder.Class = inNameFinder.Class.InterfaceList
                                             .Select(inItem => ProjectInformation.GetClassForType(inItem.Type.Name, new List <string> {
                            inItem.Type.Namespace
                        }))
                                             .FirstOrDefault(inItem => !inItem.IsInterface());
                        inNameFinder.VariableList = new List <VariableDeclaration>();
                        tmpConstant.Type          = inNameFinder.Class.GetParentClass().Type;
                    }
                    else if (tmpVal.StartsWith("\"") && tmpVal.EndsWith("\""))
                    {
                        //GetGlobalTypeForType(inNameFinder, tmpConstant, "String");
                    }
                    else if (new Regex("^\\-?[0-9]*(\\.[0-9]*)?(S|D|F|L)?$").IsMatch(tmpVal))
                    {
                        var tmpConstValue = tmpConstant.Value;
                        if (tmpVal.EndsWith("L"))
                        {
                            GetGlobalTypeForType(inNameFinder, tmpConstant, "long");
                        }
                        else if (tmpVal.EndsWith("D"))
                        {
                            GetGlobalTypeForType(inNameFinder, tmpConstant, "double");
                        }
                        else if (tmpVal.EndsWith("S"))
                        {
                            GetGlobalTypeForType(inNameFinder, tmpConstant, "short");
                        }
                        else if (tmpVal.EndsWith("F"))
                        {
                            GetGlobalTypeForType(inNameFinder, tmpConstant, "float");
                        }
                        else
                        {
                            GetGlobalTypeForType(inNameFinder, tmpConstant, "int");
                        }
                        tmpConstant.Value = tmpConstValue;
                    }
                    else
                    {
                        GetGlobalTypeForType(inNameFinder, tmpConstant, tmpVal);
                    }
                    tmpReturnType = tmpConstant.Type;
                }
            }
            else if (inCodeEntry is StatementCode)
            {
                var tmpStatement = inCodeEntry as StatementCode;
                if (tmpStatement.StatementType == Enum.StatementTypeEnum.If ||
                    tmpStatement.StatementType == Enum.StatementTypeEnum.Else ||
                    tmpStatement.StatementType == Enum.StatementTypeEnum.For ||
                    tmpStatement.StatementType == Enum.StatementTypeEnum.While)
                {
                    if (tmpStatement.InnerContent != null)
                    {
                        foreach (var tmpEntry in tmpStatement.InnerContent.CodeEntries)
                        {
                            CodeEntryHandling(tmpEntry, new FieldNameFinder(inNameFinder));
                        }
                    }
                    if (tmpStatement.StatementCodeBlocks != null)
                    {
                        foreach (var tmpEntry in tmpStatement.StatementCodeBlocks.SelectMany(inItem => inItem.CodeEntries))
                        {
                            CodeEntryHandling(tmpEntry, new FieldNameFinder(inNameFinder));
                        }
                    }
                }
                else if (tmpStatement.StatementType == Enum.StatementTypeEnum.Assert ||
                         tmpStatement.StatementType == Enum.StatementTypeEnum.Elvis)
                {
                    foreach (var tmpCodeBlock in tmpStatement.StatementCodeBlocks)
                    {
                        foreach (var tmpEntry in tmpCodeBlock.CodeEntries)
                        {
                            CodeEntryHandling(tmpEntry, new FieldNameFinder(inNameFinder));
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException("CodeEntryHandling: StatementCode Handling not Implemented");
                }
            }
            else if (inCodeEntry is SetFieldWithValue)
            {
                var tmpFieldVal = inCodeEntry as SetFieldWithValue;
                foreach (var tmpEntry in tmpFieldVal.VariableToAccess.CodeEntries)
                {
                    CodeEntryHandling(tmpEntry, new FieldNameFinder(inNameFinder));
                }
                foreach (var tmpEntry in tmpFieldVal.ValueToSet.CodeEntries)
                {
                    CodeEntryHandling(tmpEntry, new FieldNameFinder(inNameFinder));
                }
            }
            else if (inCodeEntry is VariableAccess)
            {
                var tmpVarAccess = inCodeEntry as VariableAccess;
                inNameFinder.StackVariables(true, true);
                ClassContainer tmpPrevClass = null;
                if (!(tmpVarAccess.Access is VariableDeclaration))
                {
                    tmpReturnType = CodeEntryHandling(tmpVarAccess.Access, inNameFinder);
                    tmpPrevClass  = inNameFinder.Class;
                    if (tmpReturnType != null)
                    {
                        inNameFinder.Class = ProjectInformation.ClassFromBaseType(tmpReturnType);
                    }
                    else
                    {
                        inNameFinder.Class = null;
                    }
                }
                if (tmpVarAccess.Child != null)
                {
                    tmpReturnType = CodeEntryHandling(tmpVarAccess.Child, inNameFinder, inReturnType);
                }
                inNameFinder.Class = tmpPrevClass;

                inNameFinder.UnstackVariableList();
                if (tmpVarAccess.BaseDataSource != null)
                {
                    CodeEntryHandling(tmpVarAccess.BaseDataSource, inNameFinder, inReturnType);
                }
            }
            else if (inCodeEntry is ReturnCodeEntry)
            {
                foreach (var tmpEntry in (inCodeEntry as ReturnCodeEntry).CodeEntries)
                {
                    CodeEntryHandling(tmpEntry, inNameFinder);
                }
            }
            else if (inCodeEntry is NewObjectDeclaration)
            {
                var tmpObjectDecl = (inCodeEntry as NewObjectDeclaration);
                CodeEntryHandling(tmpObjectDecl.InnerCode, inNameFinder);
                if (tmpObjectDecl.ArgumentList != null)
                {
                    foreach (var tmpArgument in tmpObjectDecl.ArgumentList)
                    {
                        foreach (var tmpEntry in tmpArgument.CodeEntries)
                        {
                            CodeEntryHandling(tmpEntry, inNameFinder);
                        }
                    }
                }
            }
            else if (inCodeEntry is MethodeCall)
            {
                var tmpMethodeCall = inCodeEntry as MethodeCall;
                var tmpParentClass = inNameFinder.Class;
                while (tmpParentClass != null)
                {
                    tmpMethodeCall.MethodeLink = tmpParentClass.MethodeList.FirstOrDefault(inItem => inItem.Name == tmpMethodeCall.Name);
                    if (tmpMethodeCall.MethodeLink != null)
                    {
                        break;
                    }
                    tmpParentClass = tmpParentClass.GetParentClass();

                    foreach (var tmpParam in tmpMethodeCall.Parameter)
                    {
                        foreach (var tmpEntry in tmpParam.CodeEntries)
                        {
                            CodeEntryHandling(tmpEntry, new FieldNameFinder()
                            {
                                VariableList       = inNameFinder.GetMethodeVariableList(),
                                Class              = inNameFinder.MethodeParentClass ?? inNameFinder.Class,
                                MethodeParentClass = inNameFinder.MethodeParentClass
                            });
                        }
                    }
                }
                if (tmpMethodeCall.MethodeLink == null)
                {
                    //TODO Implement Extension Methode finding
                    if (inNameFinder.Class is UnknownTypeClass ||
                        inNameFinder.Class is ClassContainer)
                    {
                        if (tmpMethodeCall.Parameter.Count > 0)
                        {
                            foreach (var tmpParam in tmpMethodeCall.Parameter)
                            {
                                for (var tmpI = 0; tmpI < tmpParam.CodeEntries.Count; tmpI++)
                                {
                                    var tmpCodeBlock = tmpParam.CodeEntries[tmpI];
                                    CodeEntryHandling(tmpCodeBlock, new FieldNameFinder()
                                    {
                                        VariableList       = inNameFinder.GetMethodeVariableList(),
                                        Class              = inNameFinder.MethodeParentClass ?? inNameFinder.Class,
                                        MethodeParentClass = inNameFinder.MethodeParentClass
                                    });
                                }
                            }
                        }
                        var tmpMethode = Create.AddMethode(inNameFinder.Class, tmpMethodeCall.Name, inReturnType ?? TypeContainer.Void);
                        tmpMethode.ReturnType = /*inReturnType ??*/ TypeContainer.Void;
                        tmpReturnType         = tmpMethode.ReturnType;
                    }
                    else if (inNameFinder.Class == null)
                    {
                    }
                    else
                    {
                        throw new NotImplementedException("Unknown Methode on Class");
                    }
                }
                else
                {
                    if (tmpMethodeCall.Parameter.Count > 0)
                    {
                        foreach (var tmpParam in tmpMethodeCall.Parameter)
                        {
                            for (var tmpI = 0; tmpI < tmpParam.CodeEntries.Count; tmpI++)
                            {
                                var tmpCodeBlock = tmpParam.CodeEntries[tmpI];
                                CodeEntryHandling(tmpCodeBlock, new FieldNameFinder()
                                {
                                    VariableList       = inNameFinder.GetMethodeVariableList(),
                                    Class              = inNameFinder.MethodeParentClass ?? inNameFinder.Class,
                                    MethodeParentClass = inNameFinder.MethodeParentClass
                                });
                            }
                        }
                    }
                    tmpReturnType = tmpMethodeCall.MethodeLink.ReturnType;
                }
            }
            else if (inCodeEntry is CodeExpression)
            {
                var tmpExpr = inCodeEntry as CodeExpression;
                tmpReturnType = inReturnType;
                foreach (var tmpSubClause in tmpExpr.SubClauseEntries)
                {
                    foreach (var tmpCodeEntry in tmpSubClause.CodeEntries)
                    {
                        tmpReturnType = CodeEntryHandling(tmpCodeEntry, inNameFinder, tmpReturnType);
                    }
                }
            }
            else if (inCodeEntry is CodeBlockContainer)
            {
                var tmpExpr = inCodeEntry as CodeBlockContainer;
                tmpReturnType = inReturnType;
                foreach (var tmpEntry in tmpExpr.InnerBlock.CodeEntries)
                {
                    tmpReturnType = CodeEntryHandling(tmpEntry, inNameFinder);
                }
            }
            else if (inCodeEntry is TypeConversion)
            {
                var tmpExpr = inCodeEntry as TypeConversion;
                tmpReturnType = tmpExpr.Type;
                foreach (var tmpEntry in tmpExpr.PreconversionValue.CodeEntries)
                {
                    CodeEntryHandling(tmpEntry, inNameFinder);
                }
            }
            else
            {
                throw new NotImplementedException("Code Entry Type not Implement");
            }
            return(tmpReturnType);
        }
Exemple #37
0
        public BoundDecisionDag SimplifyDecisionDagIfConstantInput(BoundExpression input)
        {
            if (input.ConstantValue == null)
            {
                return(this);
            }
            else
            {
                ConstantValue inputConstant = input.ConstantValue;
                return(Rewrite(makeReplacement));

                // Make a replacement for a given node, using the precomputed replacements for its successors.
                BoundDecisionDagNode makeReplacement(BoundDecisionDagNode dag, Func <BoundDecisionDagNode, BoundDecisionDagNode> replacement)
                {
                    if (dag is BoundTestDecisionDagNode p)
                    {
                        // This is the key to the optimization. The result of a top-level test might be known if the input is constant.
                        switch (knownResult(p.Test))
                        {
                        case true:
                            return(replacement(p.WhenTrue));

                        case false:
                            return(replacement(p.WhenFalse));
                        }
                    }

                    return(TrivialReplacement(dag, replacement));
                }

                // Is the decision's result known because the input is a constant?
                bool?knownResult(BoundDagTest choice)
                {
                    if (!choice.Input.IsOriginalInput)
                    {
                        // This is a test of something other than the main input; result unknown
                        return(null);
                    }

                    switch (choice)
                    {
                    case BoundDagExplicitNullTest d:
                        return(inputConstant.IsNull);

                    case BoundDagNonNullTest d:
                        return(!inputConstant.IsNull);

                    case BoundDagValueTest d:
                        return(d.Value == inputConstant);

                    case BoundDagTypeTest d:
                        return(inputConstant.IsNull ? (bool?)false : null);

                    case BoundDagRelationalTest d:
                        var f = ValueSetFactory.ForType(input.Type);
                        if (f is null)
                        {
                            return(null);
                        }
                        return(f.Related(d.Relation.Operator(), inputConstant, d.Value));

                    default:
                        throw ExceptionUtilities.UnexpectedValue(choice);
                    }
                }
            }
        }
Exemple #38
0
        protected BoundExpression ConvertCaseExpression(CSharpSyntaxNode node, BoundExpression caseExpression, Binder sectionBinder, out ConstantValue constantValueOpt, DiagnosticBag diagnostics, bool isGotoCaseExpr = false)
        {
            bool hasErrors = 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);
                    hasErrors = true;
                }
                else if (!conversion.IsImplicit)
                {
                    diagnostics.Add(ErrorCode.WRN_GotoCaseShouldConvert, node.Location, SwitchGoverningType);
                    hasErrors = true;
                }

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

            return(ConvertPatternExpression(SwitchGoverningType, node, caseExpression, out constantValueOpt, hasErrors, diagnostics));
        }
Exemple #39
0
        private static void ReportAsOperatorConstantWarnings(
            CSharpSyntaxNode node,
            DiagnosticBag diagnostics,
            TypeSymbol operandType,
            TypeSymbol targetType,
            ConversionKind conversionKind,
            ConstantValue operandConstantValue)
        {
            // NOTE:    Even though BoundIsOperator and BoundAsOperator will always have no ConstantValue
            // NOTE:    (they are non-constant expressions according to Section 7.19 of the specification),
            // NOTE:    we want to perform constant analysis of is/as expressions to generate warnings if the
            // NOTE:    expression will always be true/false/null.

            ConstantValue constantValue = GetAsOperatorConstantResult(operandType, targetType, conversionKind, operandConstantValue);
            if (constantValue != null)
            {
                Debug.Assert(constantValue.IsNull);
                Error(diagnostics, ErrorCode.WRN_AlwaysNull, node, targetType);
            }
        }
Exemple #40
0
        internal static ConstantValue GetIsOperatorConstantResult(TypeSymbol operandType, TypeSymbol targetType, ConversionKind conversionKind, ConstantValue operandConstantValue)
        {
            Debug.Assert((object)targetType != null);

            // SPEC:    The result of the operation depends on D and T as follows:
            // SPEC:    1)	If T is a reference type, the result is true if D and T are the same type, if D is a reference type and
            // SPEC:        an implicit reference conversion from D to T exists, or if D is a value type and a boxing conversion from D to T exists.
            // SPEC:    2)	If T is a nullable type, the result is true if D is the underlying type of T.
            // SPEC:    3)	If T is a non-nullable value type, the result is true if D and T are the same type.
            // SPEC:    4)	Otherwise, the result is false.

            // NOTE:    The language specification talks about the runtime evaluation of the is operation.
            // NOTE:    However, we are interested in computing the compile time constant value for the expression.
            // NOTE:    Even though BoundIsOperator and BoundAsOperator will always have no ConstantValue
            // NOTE:    (they are non-constant expressions according to Section 7.19 of the specification),
            // NOTE:    we want to perform constant analysis of is/as expressions during binding to generate warnings (always true/false/null)
            // NOTE:    and during rewriting for optimized codegen.
            // NOTE: 
            // NOTE:    Because the heuristic presented here is used to change codegen, it must be conservative. It is acceptable
            // NOTE:    for us to fail to report a warning in cases where humans could logically deduce that the operator will
            // NOTE:    always return false. It is not acceptable to inaccurately warn that the operator will always return false
            // NOTE:    if there are cases where it might succeed.
            // 

            // To begin our heuristic: if the operand is literal null then we automatically return that the
            // result is false. You might think that we can simply check to see if the conversion is 
            // ConversionKind.NullConversion, but "null is T" for a type parameter T is actually classified
            // as an implicit reference conversion if T is constrained to reference types. Rather
            // than deal with all those special cases we can simply bail out here.

            if (operandConstantValue == ConstantValue.Null)
            {
                return ConstantValue.False;
            }

            Debug.Assert((object)operandType != null);

            switch (conversionKind)
            {
                case ConversionKind.NoConversion:
                    // Oddly enough, "x is T" can be true even if there is no conversion from x to T! 
                    //
                    // Scenario 1: Type parameter compared to System.Enum.
                    //
                    // bool M1<X>(X x) where X : struct { return x is Enum; }
                    //
                    // There is no conversion from X to Enum, not even an explicit conversion. But
                    // nevertheless, X could be constructed as an enumerated type.
                    // However, we can sometimes know that the result will be false.
                    //
                    // Scenario 2: Constrained type parameter compared to reference type.
                    //
                    // bool M2<X>(X x) where X : struct { return x is string; }
                    //
                    // We know that X, constrained to struct, will never be string.
                    //
                    // Scenario 3: Value type compared to type parameter.
                    //
                    // bool M3<T>(int x) { return x is T; }
                    //
                    // There is no conversion from int to T, but T could nevertheless be int.
                    //
                    // Scenario 4: Constructed type compared to open type
                    //
                    // bool M4<T>(C<int> x) { return x is C<T>; } 
                    //
                    // There is no conversion from C<int> to C<T>, but nevertheless, T might be int.
                    //
                    // Scenario 5: Open type compared to constructed type:
                    //
                    // bool M5<X>(C<X> x) { return x is C<int>);
                    //
                    // Again, X could be int.
                    // 
                    // We could then go on to get more complicated. For example, 
                    //
                    // bool M6<X>(C<X> x) where X : struct { return x is C<string>; }
                    //
                    // We know that C<X> is never convertible to C<string> no matter what
                    // X is. Or:
                    //
                    // bool M7<T>(Dictionary<int, int> x) { return x is List<T>; }
                    //
                    // We know that no matter what T is, the conversion will never succeed.
                    //
                    // As noted above, we must be conservative. We follow the lead of the native compiler,
                    // which uses the following algorithm:
                    //
                    // * If neither type is open and there is no conversion then the result is always false:

                    if (!operandType.ContainsTypeParameter() && !targetType.ContainsTypeParameter())
                    {
                        return ConstantValue.False;
                    }

                    // * Otherwise, at least one of them is of an open type. If the operand is of value type 
                    //   and the target is a class type other than System.Enum, then we are in scenario 2, 
                    //   not scenario 1, and can correctly deduce that the result is false.

                    if (operandType.IsValueType && targetType.IsClassType() && targetType.SpecialType != SpecialType.System_Enum)
                    {
                        return ConstantValue.False;
                    }

                    // * Otherwise, we give up. Though there are other situations in which we can deduce that
                    //   the result will always be false, such as scenarios 6 and 7, but we do not attempt
                    //   to deduce this.

                    // CONSIDER: we could use TypeUnification.CanUnify to do additional compile-time checking.

                    return null;

                case ConversionKind.ImplicitNumeric:
                case ConversionKind.ExplicitNumeric:
                case ConversionKind.ImplicitEnumeration:
                // case ConversionKind.ExplicitEnumeration: // Handled separately below.
                case ConversionKind.ImplicitConstant:
                case ConversionKind.ImplicitUserDefined:
                case ConversionKind.ExplicitUserDefined:
                case ConversionKind.IntPtr:

                    // Consider all the cases where we know that "x is T" must be false just from
                    // the conversion classification.
                    //
                    // If we have "x is T" and the conversion from x to T is numeric or enum then the result must be false.
                    //
                    // If we have "null is T" then obviously that must be false.
                    //
                    // If we have "1 is long" then that must be false. (If we have "1 is int" then it is an identity conversion,
                    // not an implicit constant conversion.
                    //
                    // User-defined and IntPtr conversions are always false for "is".

                    return ConstantValue.False;

                case ConversionKind.ExplicitEnumeration:
                    // Enum-to-enum conversions should be treated the same as unsuccessful struct-to-struct
                    // conversions (i.e. make allowances for type unification, etc)
                    if (operandType.IsEnumType() && targetType.IsEnumType())
                    {
                        goto case ConversionKind.NoConversion;
                    }

                    return ConstantValue.False;

                case ConversionKind.ExplicitNullable:

                    // An explicit nullable conversion is a conversion of one of the following forms:
                    //
                    // 1) X? --> Y?, where X --> Y is an explicit conversion.  (If X --> Y is an implicit
                    //    conversion then X? --> Y? is an implicit nullable conversion.) In this case we
                    //    know that "X? is Y?" must be false because either X? is null, or we have an
                    //    explicit conversion from struct type X to struct type Y, and so X is never of type Y.)
                    //
                    // 2) X --> Y?, where again, X --> Y is an explicit conversion. By the same reasoning
                    //    as in case 1, this must be false.

                    if (targetType.IsNullableType())
                    {
                        return ConstantValue.False;
                    }

                    Debug.Assert(operandType.IsNullableType());

                    // 3) X? --> X. In this case, this is just a different way of writing "x != null".
                    //    We do not know what the result will be.
                    //    CONSIDER: If we know statically that the operand is going to be null or non-null
                    //    CONSIDER: then we could give a better result here.

                    if (Conversions.HasIdentityConversion(operandType.GetNullableUnderlyingType(), targetType))
                    {
                        return null;
                    }

                    // 4) X? --> Y where the conversion X --> Y is an implicit or explicit value type conversion.
                    //    "X? is Y" again must be false.

                    return ConstantValue.False;

                case ConversionKind.ImplicitReference:
                case ConversionKind.ExplicitReference:
                case ConversionKind.Unboxing:
                    // In these three cases, the expression type must be a reference type. Therefore,
                    // the result cannot be determined. The expression could be null, resulting 
                    // in false, or it could be a non-null reference to the appropriate type,
                    // resulting in true.
                    return null;

                case ConversionKind.Identity:
                    // The result of "x is T" can be statically determined to be true if x is an expression 
                    // of non-nullable value type T. If x is of reference or nullable value type then
                    // we cannot know, because again, the expression value could be null or it could be good. 
                    // If it is of pointer type then we have already given an error.
                    return (operandType.IsValueType && !operandType.IsNullableType()) ? ConstantValue.True : null;

                case ConversionKind.Boxing:

                    // A boxing conversion might be a conversion:
                    //
                    // * From a non-nullable value type to a reference type
                    // * From a nullable value type to a reference type
                    // * From a type parameter that *could* be a value type under construction
                    //   to a reference type
                    //
                    // In the first case we know that the conversion will always succeed and that the
                    // operand is never null, and therefore "is" will always result in true. 
                    //
                    // In the second two cases we do not know; either the nullable value type could be
                    // null, or the type parameter could be constructed with a reference type, and it
                    // could be null.

                    return operandType.IsValueType && !operandType.IsNullableType() ? ConstantValue.True : null;

                case ConversionKind.ImplicitNullable:
                    // We have "x is T" in one of the following situations:
                    // 1) x is of type X and T is X?.  The value is always true.
                    // 2) x is of type X and T is Y? where X is convertible to Y via an implicit numeric conversion. Eg, 
                    //    x is of type int and T is decimal?.  The value is always false.
                    // 3) x is of type X? and T is Y? where X is convertible to Y via an implicit numeric conversion.
                    //    The value is always false.

                    Debug.Assert(targetType.IsNullableType());
                    return (operandType == targetType.GetNullableUnderlyingType()) ? ConstantValue.True : ConstantValue.False;

                default:
                case ConversionKind.ImplicitDynamic:
                case ConversionKind.ExplicitDynamic:
                case ConversionKind.PointerToInteger:
                case ConversionKind.PointerToPointer:
                case ConversionKind.PointerToVoid:
                case ConversionKind.IntegerToPointer:
                case ConversionKind.NullToPointer:
                case ConversionKind.AnonymousFunction:
                case ConversionKind.NullLiteral:
                case ConversionKind.MethodGroup:
                    // We've either replaced Dynamic with Object, or already bailed out with an error.
                    throw ExceptionUtilities.UnexpectedValue(conversionKind);
            }
        }
Exemple #41
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)
            {
                constantValueOpt = ((BoundConversion)convertedCaseExpression).Operand.ConstantValue;
            }
            else
            {
                constantValueOpt = convertedCaseExpression.ConstantValue;
            }

            return(convertedCaseExpression);
        }
        private ConstantValue DecodeDefaultParameterValueAttribute(CSharpAttributeData attribute, AttributeSyntax node, bool diagnose, DiagnosticBag diagnosticsOpt)
        {
            Debug.Assert(!diagnose || diagnosticsOpt != null);

            if (HasDefaultArgumentSyntax)
            {
                // error CS1745: Cannot specify default parameter value in conjunction with DefaultParameterAttribute or OptionalAttribute
                if (diagnose)
                {
                    diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueUsedWithAttributes, node.Name.Location);
                }
                return(ConstantValue.Bad);
            }

            // BREAK: In dev10, DefaultParameterValueAttribute could not be applied to System.Type or array parameters.
            // When this was attempted, dev10 produced CS1909, ERR_DefaultValueBadParamType.  Roslyn takes a different
            // approach: instead of looking at the parameter type, we look at the argument type.  There's nothing wrong
            // with providing a default value for a System.Type or array parameter, as long as the default parameter
            // is not a System.Type or an array (i.e. null is fine).  Since we are no longer interested in the type of
            // the parameter, all occurrences of CS1909 have been replaced with CS1910, ERR_DefaultValueBadValueType,
            // to indicate that the argument type, rather than the parameter type, is the source of the problem.

            Debug.Assert(attribute.CommonConstructorArguments.Length == 1);

            // the type of the value is the type of the expression in the attribute:
            var arg = attribute.CommonConstructorArguments[0];

            SpecialType specialType = arg.Kind == TypedConstantKind.Enum ?
                                      ((INamedTypeSymbol)arg.Type).EnumUnderlyingType.SpecialType :
                                      arg.Type.SpecialType;

            var compilation = this.DeclaringCompilation;
            var constantValueDiscriminator = ConstantValue.GetDiscriminator(specialType);
            HashSet <DiagnosticInfo> useSiteDiagnostics = null;

            if (constantValueDiscriminator == ConstantValueTypeDiscriminator.Bad)
            {
                if (arg.Kind != TypedConstantKind.Array && arg.Value == null)
                {
                    if (this.Type.IsReferenceType)
                    {
                        constantValueDiscriminator = ConstantValueTypeDiscriminator.Null;
                    }
                    else
                    {
                        // error CS1908: The type of the argument to the DefaultParameterValue attribute must match the parameter type
                        if (diagnose)
                        {
                            diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueTypeMustMatch, node.Name.Location);
                        }
                        return(ConstantValue.Bad);
                    }
                }
                else
                {
                    // error CS1910: Argument of type '{0}' is not applicable for the DefaultParameterValue attribute
                    if (diagnose)
                    {
                        diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueBadValueType, node.Name.Location, arg.Type);
                    }
                    return(ConstantValue.Bad);
                }
            }
            else if (!compilation.Conversions.ClassifyConversion((TypeSymbol)arg.Type, this.Type, ref useSiteDiagnostics).Kind.IsImplicitConversion())
            {
                // error CS1908: The type of the argument to the DefaultParameterValue attribute must match the parameter type
                if (diagnose)
                {
                    diagnosticsOpt.Add(ErrorCode.ERR_DefaultValueTypeMustMatch, node.Name.Location);
                    diagnosticsOpt.Add(node.Name.Location, useSiteDiagnostics);
                }
                return(ConstantValue.Bad);
            }

            if (diagnose)
            {
                diagnosticsOpt.Add(node.Name.Location, useSiteDiagnostics);
            }

            return(ConstantValue.Create(arg.Value, constantValueDiscriminator));
        }
 public int FromConstantValue(ConstantValue constantValue)
 {
     // We could have a negate value in source, but it won't get past NonNegativeIntValueSetFactory.Related
     return(constantValue.IsBad ? 0 : constantValue.Int32Value);
 }
Exemple #44
0
        private BoundExpression BindInterpolatedString(InterpolatedStringExpressionSyntax node, DiagnosticBag diagnostics)
        {
            var builder = ArrayBuilder <BoundExpression> .GetInstance();

            var stringType = GetSpecialType(SpecialType.System_String, diagnostics, node);
            var objectType = GetSpecialType(SpecialType.System_Object, diagnostics, node);
            var intType    = GetSpecialType(SpecialType.System_Int32, diagnostics, node);

            foreach (var content in node.Contents)
            {
                switch (content.Kind())
                {
                case SyntaxKind.Interpolation:
                {
                    var interpolation = (InterpolationSyntax)content;
                    var value         = BindValue(interpolation.Expression, diagnostics, Binder.BindValueKind.RValue);
                    // We need to ensure the argument is not a lambda, method group, etc. It isn't nice to wait until lowering,
                    // when we perform overload resolution, to report a problem. So we do that check by calling
                    // GenerateConversionForAssignment with objectType. However we want to preserve the original expression's
                    // natural type so that overload resolution may select a specialized implementation of string.Format,
                    // so we discard the result of that call and only preserve its diagnostics.
                    var             discarded = GenerateConversionForAssignment(objectType, value, diagnostics);
                    BoundExpression alignment = null, format = null;
                    if (interpolation.AlignmentClause != null)
                    {
                        alignment = GenerateConversionForAssignment(intType, BindValue(interpolation.AlignmentClause.Value, diagnostics, Binder.BindValueKind.RValue), diagnostics);
                        var alignmentConstant = alignment.ConstantValue;
                        if (alignmentConstant != null && !alignmentConstant.IsBad)
                        {
                            const int magnitudeLimit = 32767;
                            // check that the magnitude of the alignment is "in range".
                            int alignmentValue = alignmentConstant.Int32Value;
                            //  We do the arithmetic using negative numbers because the largest negative int has no corresponding positive (absolute) value.
                            alignmentValue = (alignmentValue > 0) ? -alignmentValue : alignmentValue;
                            if (alignmentValue < -magnitudeLimit)
                            {
                                diagnostics.Add(ErrorCode.WRN_AlignmentMagnitude, alignment.Syntax.Location, alignmentConstant.Int32Value, magnitudeLimit);
                            }
                        }
                        else if (!alignment.HasErrors)
                        {
                            diagnostics.Add(ErrorCode.ERR_ConstantExpected, interpolation.AlignmentClause.Value.Location);
                        }
                    }

                    if (interpolation.FormatClause != null)
                    {
                        var  text = interpolation.FormatClause.FormatStringToken.ValueText;
                        char lastChar;
                        bool hasErrors = false;
                        if (text.Length == 0)
                        {
                            diagnostics.Add(ErrorCode.ERR_EmptyFormatSpecifier, interpolation.FormatClause.Location);
                            hasErrors = true;
                        }
                        else if (SyntaxFacts.IsWhitespace(lastChar = text[text.Length - 1]) || SyntaxFacts.IsNewLine(lastChar))
                        {
                            diagnostics.Add(ErrorCode.ERR_TrailingWhitespaceInFormatSpecifier, interpolation.FormatClause.Location);
                            hasErrors = true;
                        }

                        format = new BoundLiteral(interpolation.FormatClause, ConstantValue.Create(text), stringType, hasErrors);
                    }

                    builder.Add(new BoundStringInsert(interpolation, value, alignment, format, null));
                    continue;
                }

                case SyntaxKind.InterpolatedStringText:
                {
                    var text = ((InterpolatedStringTextSyntax)content).TextToken.ValueText;
                    builder.Add(new BoundLiteral(node, ConstantValue.Create(text, SpecialType.System_String), stringType));
                    continue;
                }

                default:
                    throw ExceptionUtilities.Unreachable;
                }
            }

            return(new BoundInterpolatedString(node, builder.ToImmutableAndFree(), stringType));
        }
 /// <summary>
 /// TBD ?!?
 /// </summary>
 public object ParseItem(XmlReader reader)
 {
     switch (reader.NodeType)
     {
     case XmlNodeType.Element:
         if (reader.Name.ToLower() == "filter")
         {
             reader.Read();
             return(ParseItem(reader));
         }
         if (reader.Name.ToLower() == "propertyisequalto")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             FixedValue fixedValue = (FixedValue)ParseItem(reader);
             reader.Read();
             return(new BinaryComparisionOperation(fieldValue, fixedValue, WFSBinaryComparisionOperator.EqualTo));
         }
         if (reader.Name.ToLower() == "propertyisgreaterthan")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             FixedValue fixedValue = (FixedValue)ParseItem(reader);
             reader.Read();
             return(new BinaryComparisionOperation(fieldValue, fixedValue, WFSBinaryComparisionOperator.GreaterThan));
         }
         if (reader.Name.ToLower() == "propertyisgreaterthanorequalto")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             FixedValue fixedValue = (FixedValue)ParseItem(reader);
             reader.Read();
             return(new BinaryComparisionOperation(fieldValue, fixedValue, WFSBinaryComparisionOperator.GreaterOrEqualTo));
         }
         if (reader.Name.ToLower() == "propertyislessthanorequalto")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             FixedValue fixedValue = (FixedValue)ParseItem(reader);
             reader.Read();
             return(new BinaryComparisionOperation(fieldValue, fixedValue, WFSBinaryComparisionOperator.LessOrEqualTo));
         }
         if (reader.Name.ToLower() == "propertyislessthan")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             FixedValue fixedValue = (FixedValue)ParseItem(reader);
             reader.Read();
             return(new BinaryComparisionOperation(fieldValue, fixedValue, WFSBinaryComparisionOperator.LessThan));
         }
         if (reader.Name.ToLower() == "propertyislike")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             FixedValue fixedValue = (FixedValue)ParseItem(reader);
             reader.Read();
             return(new BinaryComparisionOperation(fieldValue, fixedValue, WFSBinaryComparisionOperator.Like));
         }
         if (reader.Name.ToLower() == "propertyisnotequalto")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             FixedValue fixedValue = (FixedValue)ParseItem(reader);
             reader.Read();
             return(new BinaryComparisionOperation(fieldValue, fixedValue, WFSBinaryComparisionOperator.NotEqualTo));
         }
         if (reader.Name.ToLower() == "propertyisnull")
         {
             reader.Read();
             FieldValue fieldValue = (FieldValue)ParseItem(reader);
             reader.Read();
             return(new UnaryComparisionOperation(fieldValue, WFSUnaryComparisionOperator.IsNull));
         }
         if (reader.Name.ToLower() == "or")
         {
             reader.Read();
             FormulaOperation leftOperand = (FormulaOperation)ParseItem(reader);
             reader.Read();
             FormulaOperation rightOperand = (FormulaOperation)ParseItem(reader);
             reader.Read();
             return(new BinaryLogicalOperation(leftOperand, rightOperand, WFSBinaryLogicalOperator.Or));
         }
         if (reader.Name.ToLower() == "and")
         {
             reader.Read();
             FormulaOperation leftOperand = (FormulaOperation)ParseItem(reader);
             reader.Read();
             FormulaOperation rightOperand = (FormulaOperation)ParseItem(reader);
             reader.Read();
             return(new BinaryLogicalOperation(leftOperand, rightOperand, WFSBinaryLogicalOperator.And));
         }
         if (reader.Name.ToLower() == "not")
         {
             reader.Read();
             FormulaOperation operand = (FormulaOperation)ParseItem(reader);
             reader.Read();
             return(new UnaryLogicalOperation(operand, WFSUnaryLogicalOperator.Not));
         }
         if (reader.Name.ToLower() == "propertyname")     // leaf
         {
             reader.Read();
             FieldValue fieldValue = new FieldValue(reader.Value);
             reader.Read();
             return(fieldValue);
         }
         if (reader.Name.ToLower() == "literal")     // leaf
         {
             reader.Read();
             ConstantValue constantValue = new ConstantValue(reader.Value);
             reader.Read();
             return(constantValue);
         }
         break;
     }
     reader.Read();
     return(null);
 }
        private BoundExpression MakeEventAccess(
            CSharpSyntaxNode syntax,
            BoundExpression rewrittenReceiver,
            EventSymbol eventSymbol,
            ConstantValue constantValueOpt,
            LookupResultKind resultKind,
            TypeSymbol type)
        {
            Debug.Assert(eventSymbol.HasAssociatedField);

            FieldSymbol fieldSymbol = eventSymbol.AssociatedField;

            Debug.Assert((object)fieldSymbol != null);

            if (!eventSymbol.IsWindowsRuntimeEvent)
            {
                return(MakeFieldAccess(syntax, rewrittenReceiver, fieldSymbol, constantValueOpt, resultKind, type));
            }

            NamedTypeSymbol fieldType = (NamedTypeSymbol)fieldSymbol.Type;

            Debug.Assert(fieldType.Name == "EventRegistrationTokenTable");

            // _tokenTable
            BoundFieldAccess fieldAccess = new BoundFieldAccess(
                syntax,
                fieldSymbol.IsStatic ? null : rewrittenReceiver,
                fieldSymbol,
                constantValueOpt: null)
            {
                WasCompilerGenerated = true
            };

            BoundExpression getOrCreateCall;

            MethodSymbol getOrCreateMethod;

            if (TryGetWellKnownTypeMember(syntax, WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__GetOrCreateEventRegistrationTokenTable, out getOrCreateMethod))
            {
                getOrCreateMethod = getOrCreateMethod.AsMember(fieldType);

                // EventRegistrationTokenTable<Event>.GetOrCreateEventRegistrationTokenTable(ref _tokenTable)
                getOrCreateCall = BoundCall.Synthesized(
                    syntax,
                    receiverOpt: null,
                    method: getOrCreateMethod,
                    arguments: fieldAccess);
            }
            else
            {
                getOrCreateCall = new BoundBadExpression(syntax, LookupResultKind.NotInvocable, ImmutableArray <Symbol> .Empty, ImmutableArray.Create <BoundNode>(fieldAccess), ErrorTypeSymbol.UnknownResultType);
            }

            PropertySymbol invocationListProperty;

            if (TryGetWellKnownTypeMember(syntax, WellKnownMember.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T__InvocationList, out invocationListProperty))
            {
                MethodSymbol invocationListAccessor = invocationListProperty.GetMethod;

                if ((object)invocationListAccessor == null)
                {
                    string accessorName = SourcePropertyAccessorSymbol.GetAccessorName(invocationListProperty.Name,
                                                                                       getNotSet: true,
                                                                                       isWinMdOutput: invocationListProperty.IsCompilationOutputWinMdObj());
                    diagnostics.Add(new CSDiagnosticInfo(ErrorCode.ERR_MissingPredefinedMember, invocationListProperty.ContainingType, accessorName), syntax.Location);
                }
                else
                {
                    invocationListAccessor = invocationListAccessor.AsMember(fieldType);
                    return(factory.Call(getOrCreateCall, invocationListAccessor));
                }
            }

            return(new BoundBadExpression(syntax, LookupResultKind.NotInvocable, ImmutableArray <Symbol> .Empty, ImmutableArray.Create <BoundNode>(getOrCreateCall), ErrorTypeSymbol.UnknownResultType));
        }
 public BoundObjectCreationExpression Update(MethodSymbol constructor, ImmutableArray <BoundExpression> arguments, ImmutableArray <string> argumentNamesOpt, ImmutableArray <RefKind> argumentRefKindsOpt, bool expanded,
                                             ImmutableArray <int> argsToParamsOpt, ConstantValue constantValueOpt, BoundObjectInitializerExpressionBase initializerExpressionOpt, Binder binderOpt, TypeSymbol type)
 {
     return(this.Update(constructor, ImmutableArray <MethodSymbol> .Empty, arguments, argumentNamesOpt, argumentRefKindsOpt, expanded, argsToParamsOpt, constantValueOpt, initializerExpressionOpt, binderOpt, type));
 }
Exemple #48
0
 ConstantValue INumericTC <char> .ToConstantValue(char value) =>
 ConstantValue.Create(value);
Exemple #49
0
        /// <summary>
        /// Translates the value of a constant returned by <see cref="ISymUnmanagedConstant.GetValue(out object)"/> to a <see cref="ConstantValue"/>.
        /// </summary>
        public static ConstantValue GetSymConstantValue(ITypeSymbolInternal type, object symValue)
        {
            if (type.TypeKind == TypeKind.Enum)
            {
                type = ((INamedTypeSymbolInternal)type).EnumUnderlyingType;
            }

            return((type.SpecialType, symValue) switch
            {
                (SpecialType.System_Boolean, short shortVal) => ConstantValue.Create(shortVal != 0),
                (SpecialType.System_Byte, short shortVal)when unchecked ((byte)shortVal) == shortVal => ConstantValue.Create((byte)shortVal),
                (SpecialType.System_SByte, short shortVal)when unchecked ((sbyte)shortVal) == shortVal => ConstantValue.Create((sbyte)shortVal),
                (SpecialType.System_Int16, short shortVal) => ConstantValue.Create(shortVal),
                (SpecialType.System_Char, ushort ushortVal) => ConstantValue.Create((char)ushortVal),
                (SpecialType.System_UInt16, ushort ushortVal) => ConstantValue.Create(ushortVal),
                (SpecialType.System_Int32, int intVal) => ConstantValue.Create(intVal),
                (SpecialType.System_UInt32, uint uintVal) => ConstantValue.Create(uintVal),
                (SpecialType.System_Int64, long longVal) => ConstantValue.Create(longVal),
                (SpecialType.System_UInt64, ulong ulongVal) => ConstantValue.Create(ulongVal),
                (SpecialType.System_Single, float floatVal) => ConstantValue.Create(floatVal),
                (SpecialType.System_Double, double doubleVal) => ConstantValue.Create(doubleVal),
                (SpecialType.System_String, 0) => ConstantValue.Null,
                (SpecialType.System_String, null) => ConstantValue.Create(string.Empty),
                (SpecialType.System_String, string str) => ConstantValue.Create(str),
                (SpecialType.System_Object, 0) => ConstantValue.Null,
                (SpecialType.System_Decimal, decimal decimalValue) => ConstantValue.Create(decimalValue),
                (SpecialType.System_DateTime, double doubleVal) => ConstantValue.Create(DateTimeUtilities.ToDateTime(doubleVal)),
                (SpecialType.None, 0)when type.IsReferenceType => ConstantValue.Null,
                _ => ConstantValue.Bad,
            });
Exemple #50
0
        /// <summary>
        /// Generates a submission initialization part of a Script type constructor that represents an interactive submission.
        /// </summary>
        /// <remarks>
        /// The constructor takes a parameter of type Microsoft.CodeAnalysis.Scripting.Session - the session reference.
        /// It adds the object being constructed into the session by calling Microsoft.CSharp.RuntimeHelpers.SessionHelpers.SetSubmission,
        /// and retrieves strongly typed references on all previous submission script classes whose members are referenced by this submission.
        /// The references are stored to fields of the submission (<paramref name="synthesizedFields"/>).
        /// </remarks>
        private static void MakeSubmissionInitialization(
            ArrayBuilder <BoundStatement> statements,
            SyntaxNode syntax,
            MethodSymbol submissionConstructor,
            SynthesizedSubmissionFields synthesizedFields,
            CSharpCompilation compilation)
        {
            Debug.Assert(submissionConstructor.ParameterCount == 1);

            var submissionArrayReference = new BoundParameter(syntax, submissionConstructor.Parameters[0])
            {
                WasCompilerGenerated = true
            };

            var intType       = compilation.GetSpecialType(SpecialType.System_Int32);
            var objectType    = compilation.GetSpecialType(SpecialType.System_Object);
            var thisReference = new BoundThisReference(syntax, submissionConstructor.ContainingType)
            {
                WasCompilerGenerated = true
            };

            var slotIndex = compilation.GetSubmissionSlotIndex();

            Debug.Assert(slotIndex >= 0);

            // <submission_array>[<slot_index] = this;
            statements.Add(new BoundExpressionStatement(syntax,
                                                        new BoundAssignmentOperator(syntax,
                                                                                    new BoundArrayAccess(syntax,
                                                                                                         submissionArrayReference,
                                                                                                         ImmutableArray.Create <BoundExpression>(new BoundLiteral(syntax, ConstantValue.Create(slotIndex), intType)
            {
                WasCompilerGenerated = true
            }),
                                                                                                         objectType)
            {
                WasCompilerGenerated = true
            },
                                                                                    thisReference,
                                                                                    RefKind.None,
                                                                                    thisReference.Type)
            {
                WasCompilerGenerated = true
            })
            {
                WasCompilerGenerated = true
            });

            var hostObjectField = synthesizedFields.GetHostObjectField();

            if ((object)hostObjectField != null)
            {
                // <host_object> = (<host_object_type>)<submission_array>[0]
                statements.Add(
                    new BoundExpressionStatement(syntax,
                                                 new BoundAssignmentOperator(syntax,
                                                                             new BoundFieldAccess(syntax, thisReference, hostObjectField, ConstantValue.NotAvailable)
                {
                    WasCompilerGenerated = true
                },
                                                                             BoundConversion.Synthesized(syntax,
                                                                                                         new BoundArrayAccess(syntax,
                                                                                                                              submissionArrayReference,
                                                                                                                              ImmutableArray.Create <BoundExpression>(new BoundLiteral(syntax, ConstantValue.Create(0), intType)
                {
                    WasCompilerGenerated = true
                }),
                                                                                                                              objectType),
                                                                                                         Conversion.ExplicitReference,
                                                                                                         false,
                                                                                                         true,
                                                                                                         ConstantValue.NotAvailable,
                                                                                                         hostObjectField.Type
                                                                                                         ),
                                                                             hostObjectField.Type)
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                });
            }

            foreach (var field in synthesizedFields.FieldSymbols)
            {
                var targetScriptType      = (ImplicitNamedTypeSymbol)field.Type;
                var targetSubmissionIndex = targetScriptType.DeclaringCompilation.GetSubmissionSlotIndex();
                Debug.Assert(targetSubmissionIndex >= 0);

                // this.<field> = (<target_script_type>)<submission_array>[<target_submission_index>];
                statements.Add(
                    new BoundExpressionStatement(syntax,
                                                 new BoundAssignmentOperator(syntax,
                                                                             new BoundFieldAccess(syntax, thisReference, field, ConstantValue.NotAvailable)
                {
                    WasCompilerGenerated = true
                },
                                                                             BoundConversion.Synthesized(syntax,
                                                                                                         new BoundArrayAccess(syntax,
                                                                                                                              submissionArrayReference,
                                                                                                                              ImmutableArray.Create <BoundExpression>(new BoundLiteral(syntax, ConstantValue.Create(targetSubmissionIndex), intType)
                {
                    WasCompilerGenerated = true
                }),
                                                                                                                              objectType)
                {
                    WasCompilerGenerated = true
                },
                                                                                                         Conversion.ExplicitReference,
                                                                                                         false,
                                                                                                         true,
                                                                                                         ConstantValue.NotAvailable,
                                                                                                         targetScriptType
                                                                                                         ),
                                                                             targetScriptType
                                                                             )
                {
                    WasCompilerGenerated = true
                })
                {
                    WasCompilerGenerated = true
                });
            }
        }
Exemple #51
0
        private PEParameterSymbol(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            int ordinal,
            bool isByRef,
            TypeSymbol type,
            ParameterHandle handle,
            int countOfCustomModifiers,
            out bool isBad)
        {
            Debug.Assert((object)moduleSymbol != null);
            Debug.Assert((object)containingSymbol != null);
            Debug.Assert(ordinal >= 0);
            Debug.Assert((object)type != null);

            isBad             = false;
            _moduleSymbol     = moduleSymbol;
            _containingSymbol = containingSymbol;
            _ordinal          = (ushort)ordinal;

            _handle = handle;

            RefKind refKind = RefKind.None;

            if (handle.IsNil)
            {
                refKind = isByRef ? RefKind.Ref : RefKind.None;

                type  = TupleTypeSymbol.TransformToTupleIfCompatible(type);
                _type = type;

                _lazyCustomAttributes = ImmutableArray <CSharpAttributeData> .Empty;
                _lazyHiddenAttributes = ImmutableArray <CSharpAttributeData> .Empty;
                _lazyDefaultValue     = ConstantValue.NotAvailable;
                _lazyIsParams         = ThreeState.False;
            }
            else
            {
                try
                {
                    moduleSymbol.Module.GetParamPropsOrThrow(handle, out _name, out _flags);
                }
                catch (BadImageFormatException)
                {
                    isBad = true;
                }

                if (isByRef)
                {
                    ParameterAttributes inOutFlags = _flags & (ParameterAttributes.Out | ParameterAttributes.In);

                    if (inOutFlags == ParameterAttributes.Out)
                    {
                        refKind = RefKind.Out;
                    }
                    else if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle))
                    {
                        refKind = RefKind.In;
                    }
                    else
                    {
                        refKind = RefKind.Ref;
                    }
                }

                // CONSIDER: Can we make parameter type computation lazy?
                type = DynamicTypeDecoder.TransformType(type, countOfCustomModifiers, handle, moduleSymbol, refKind);

                _type = TupleTypeDecoder.DecodeTupleTypesIfApplicable(type, handle, moduleSymbol);
            }

            bool hasNameInMetadata = !string.IsNullOrEmpty(_name);

            if (!hasNameInMetadata)
            {
                // As was done historically, if the parameter doesn't have a name, we give it the name "value".
                _name = "value";
            }

            _packedFlags = new PackedFlags(refKind, attributesAreComplete: handle.IsNil, hasNameInMetadata: hasNameInMetadata);

            Debug.Assert(refKind == this.RefKind);
            Debug.Assert(hasNameInMetadata == this.HasNameInMetadata);
        }
Exemple #52
0
        private void CheckVacuousComparisons(BoundBinaryOperator tree, ConstantValue constantValue, BoundNode operand)
        {
            Debug.Assert(tree != null);
            Debug.Assert(constantValue != null);
            Debug.Assert(operand != null);

            // We wish to detect comparisons between integers and constants which are likely to be wrong
            // because we know at compile time whether they will be true or false. For example:
            //
            // const short s = 1000;
            // byte b = whatever;
            // if (b < s)
            //
            // We know that this will always be true because when b and s are both converted to int for
            // the comparison, the left side will always be less than the right side.
            //
            // We only give the warning if there is no explicit conversion involved on the operand.
            // For example, if we had:
            //
            // const uint s = 1000;
            // sbyte b = whatever;
            // if ((byte)b < s)
            //
            // Then we do not give a warning.
            //
            // Note that the native compiler has what looks to be some dead code. It checks to see
            // if the conversion on the operand is from an enum type. But this is unnecessary if
            // we are rejecting cases with explicit conversions. The only possible cases are:
            //
            // enum == enumConstant           -- enum types must be the same, so it must be in range.
            // enum == integralConstant       -- not legal unless the constant is zero, which is in range.
            // enum == (ENUM)anyConstant      -- if the constant is out of range then this is not legal in the first place
            //                                   unless we're in an unchecked context, in which case, the user probably does
            //                                   not want the warning.
            // integral == enumConstant       -- never legal in the first place
            //
            // Since it seems pointless to try to check enums, we simply look for vacuous comparisons of
            // integral types here.

            for (BoundConversion conversion = operand as BoundConversion;
                 conversion != null;
                 conversion = conversion.Operand as BoundConversion)
            {
                if (conversion.ConversionKind != ConversionKind.ImplicitNumeric &&
                    conversion.ConversionKind != ConversionKind.ImplicitConstant)
                {
                    return;
                }

                // As in dev11, we don't dig through explicit casts (see ExpressionBinder::WarnAboutBadRelationals).
                if (conversion.ExplicitCastInCode)
                {
                    return;
                }

                if (!conversion.Operand.Type.SpecialType.IsIntegralType() || !conversion.Type.SpecialType.IsIntegralType())
                {
                    return;
                }

                if (!Binder.CheckConstantBounds(conversion.Operand.Type.SpecialType, constantValue))
                {
                    Error(ErrorCode.WRN_VacuousIntegralComp, tree, conversion.Operand.Type);
                    return;
                }
            }
        }
Exemple #53
0
 public EvaluatedConstant(ConstantValue value, ImmutableArray <Diagnostic> diagnostics)
 {
     this.Value       = value;
     this.Diagnostics = diagnostics.NullToEmpty();
 }
Exemple #54
0
 char INumericTC <char> .FromConstantValue(ConstantValue constantValue) =>
 constantValue.IsBad ? (char)0 : constantValue.CharValue;
Exemple #55
0
 public ReadOp(int offset, int repeated, ConstantValue constant)
 {
     Offset   = offset;
     Constant = constant;
     Repeated = repeated;
 }
Exemple #56
0
        private PEParameterSymbol(
            PEModuleSymbol moduleSymbol,
            Symbol containingSymbol,
            int ordinal,
            bool isByRef,
            TypeWithAnnotations typeWithAnnotations,
            ParameterHandle handle,
            Symbol nullableContext,
            int countOfCustomModifiers,
            out bool isBad)
        {
            Debug.Assert((object)moduleSymbol != null);
            Debug.Assert((object)containingSymbol != null);
            Debug.Assert(ordinal >= 0);
            Debug.Assert(typeWithAnnotations.HasType);

            isBad             = false;
            _moduleSymbol     = moduleSymbol;
            _containingSymbol = containingSymbol;
            _ordinal          = (ushort)ordinal;

            _handle = handle;

            RefKind refKind = RefKind.None;

            if (handle.IsNil)
            {
                refKind = isByRef ? RefKind.Ref : RefKind.None;
                byte?value = nullableContext.GetNullableContextValue();
                if (value.HasValue)
                {
                    typeWithAnnotations = NullableTypeDecoder.TransformType(typeWithAnnotations, value.GetValueOrDefault(), default);
                }
                _lazyCustomAttributes = ImmutableArray <CSharpAttributeData> .Empty;
                _lazyHiddenAttributes = ImmutableArray <CSharpAttributeData> .Empty;
                _lazyDefaultValue     = ConstantValue.NotAvailable;
                _lazyIsParams         = ThreeState.False;
            }
            else
            {
                try
                {
                    moduleSymbol.Module.GetParamPropsOrThrow(handle, out _name, out _flags);
                }
                catch (BadImageFormatException)
                {
                    isBad = true;
                }

                if (isByRef)
                {
                    ParameterAttributes inOutFlags = _flags & (ParameterAttributes.Out | ParameterAttributes.In);

                    if (inOutFlags == ParameterAttributes.Out)
                    {
                        refKind = RefKind.Out;
                    }
                    else if (moduleSymbol.Module.HasIsReadOnlyAttribute(handle))
                    {
                        refKind = RefKind.In;
                    }
                    else
                    {
                        refKind = RefKind.Ref;
                    }
                }

                var typeSymbol = DynamicTypeDecoder.TransformType(typeWithAnnotations.Type, countOfCustomModifiers, handle, moduleSymbol, refKind);
                typeSymbol          = NativeIntegerTypeDecoder.TransformType(typeSymbol, handle, moduleSymbol);
                typeWithAnnotations = typeWithAnnotations.WithTypeAndModifiers(typeSymbol, typeWithAnnotations.CustomModifiers);
                // Decode nullable before tuple types to avoid converting between
                // NamedTypeSymbol and TupleTypeSymbol unnecessarily.

                // The containing type is passed to NullableTypeDecoder.TransformType to determine access
                // for property parameters because the property does not have explicit accessibility in metadata.
                var accessSymbol = containingSymbol.Kind == SymbolKind.Property ? containingSymbol.ContainingSymbol : containingSymbol;
                typeWithAnnotations = NullableTypeDecoder.TransformType(typeWithAnnotations, handle, moduleSymbol, accessSymbol: accessSymbol, nullableContext: nullableContext);
                typeWithAnnotations = TupleTypeDecoder.DecodeTupleTypesIfApplicable(typeWithAnnotations, handle, moduleSymbol);
            }

            _typeWithAnnotations = typeWithAnnotations;

            bool hasNameInMetadata = !string.IsNullOrEmpty(_name);

            if (!hasNameInMetadata)
            {
                // As was done historically, if the parameter doesn't have a name, we give it the name "value".
                _name = "value";
            }

            _packedFlags = new PackedFlags(refKind, attributesAreComplete: handle.IsNil, hasNameInMetadata: hasNameInMetadata);

            Debug.Assert(refKind == this.RefKind);
            Debug.Assert(hasNameInMetadata == this.HasNameInMetadata);
        }
Exemple #57
0
        private static bool ReportAsOperatorConversionDiagnostics(
            CSharpSyntaxNode node,
            DiagnosticBag diagnostics,
            Compilation compilation,
            TypeSymbol operandType,
            TypeSymbol targetType,
            ConversionKind conversionKind,
            ConstantValue operandConstantValue)
        {
            // SPEC:    In an operation of the form E as T, E must be an expression and T must be a reference type,
            // SPEC:    a type parameter known to be a reference type, or a nullable type.
            // SPEC:    Furthermore, at least one of the following must be true, or otherwise a compile-time error occurs:
            // SPEC:    •	An identity (§6.1.1), implicit nullable (§6.1.4), implicit reference (§6.1.6), boxing (§6.1.7), 
            // SPEC:        explicit nullable (§6.2.3), explicit reference (§6.2.4), or unboxing (§6.2.5) conversion exists
            // SPEC:        from E to T.
            // SPEC:    •	The type of E or T is an open type.
            // SPEC:    •	E is the null literal.

            // SPEC VIOLATION:  The specification contains an error in the list of legal conversions above.
            // SPEC VIOLATION:  If we have "class C<T, U> where T : U where U : class" then there is
            // SPEC VIOLATION:  an implicit conversion from T to U, but it is not an identity, reference or
            // SPEC VIOLATION:  boxing conversion. It will be one of those at runtime, but at compile time
            // SPEC VIOLATION:  we do not know which, and therefore cannot classify it as any of those.
            // SPEC VIOLATION:  See Microsoft.CodeAnalysis.CSharp.UnitTests.SyntaxBinderTests.TestAsOperator_SpecErrorCase() test for an example.

            // SPEC VIOLATION:  The specification also unintentionally allows the case where requirement 2 above:
            // SPEC VIOLATION:  "The type of E or T is an open type" is true, but type of E is void type, i.e. T is an open type.
            // SPEC VIOLATION:  Dev10 compiler correctly generates an error for this case and we will maintain compatibility.

            bool hasErrors = false;
            switch (conversionKind)
            {
                case ConversionKind.ImplicitReference:
                case ConversionKind.Boxing:
                case ConversionKind.ImplicitNullable:
                case ConversionKind.Identity:
                case ConversionKind.ExplicitNullable:
                case ConversionKind.ExplicitReference:
                case ConversionKind.Unboxing:
                    break;

                default:
                    // Generate an error if there is no possible legal conversion and both the operandType
                    // and the targetType are closed types OR operandType is void type, otherwise we need a runtime check
                    if (!operandType.ContainsTypeParameter() && !targetType.ContainsTypeParameter() ||
                        operandType.SpecialType == SpecialType.System_Void)
                    {
                        SymbolDistinguisher distinguisher = new SymbolDistinguisher(compilation, operandType, targetType);
                        Error(diagnostics, ErrorCode.ERR_NoExplicitBuiltinConv, node, distinguisher.First, distinguisher.Second);
                        hasErrors = true;
                    }

                    break;
            }

            if (!hasErrors)
            {
                ReportAsOperatorConstantWarnings(node, diagnostics, operandType, targetType, conversionKind, operandConstantValue);
            }

            return hasErrors;
        }
Exemple #58
0
 /// <exception cref="BadImageFormatException"></exception>
 /// <exception cref="UnsupportedSignatureContent"></exception>
 public override void DecodeLocalConstant(ref BlobReader reader, out TypeSymbol type, out ConstantValue value)
 {
     _metadataDecoder.DecodeLocalConstantBlobOrThrow(ref reader, out type, out value);
 }
Exemple #59
0
        internal static ConstantValue GetAsOperatorConstantResult(TypeSymbol operandType, TypeSymbol targetType, ConversionKind conversionKind, ConstantValue operandConstantValue)
        {
            // NOTE:    Even though BoundIsOperator and BoundAsOperator will always have no ConstantValue
            // NOTE:    (they are non-constant expressions according to Section 7.19 of the specification),
            // NOTE:    we want to perform constant analysis of is/as expressions during binding to generate warnings (always true/false/null)
            // NOTE:    and during rewriting for optimized codegen.

            ConstantValue isOperatorConstantResult = GetIsOperatorConstantResult(operandType, targetType, conversionKind, operandConstantValue);
            if (isOperatorConstantResult != null && !isOperatorConstantResult.BooleanValue)
            {
                return ConstantValue.Null;
            }

            return null;
        }
Exemple #60
0
        private void AppendConstantValue([NotNull] ConstantValue constantValue, bool treatEnumAsIntegral)
        {
            if (constantValue.IsBadValue())
            {
                AppendText("bad value", null);
                return;
            }

            IEnum enumType = constantValue.Type.GetEnumType();

            if (enumType != null)
            {
                if (treatEnumAsIntegral)
                {
                    AppendText(constantValue.Value?.ToString() ?? String.Empty, _highlighterIdProvider.Number);
                    return;
                }
                if (AppendEnumValue(constantValue, enumType))
                {
                    return;
                }
            }

            string presentation = constantValue.GetPresentation(CSharpLanguage.Instance);

            if (CSharpLexer.IsKeyword(presentation))
            {
                AppendText(presentation, _highlighterIdProvider.Keyword);
                return;
            }

            IType type = constantValue.Type;

            if (type.IsNullable())
            {
                type = type.GetNullableUnderlyingType();
            }

            if (type == null)
            {
                AppendText(presentation, null);
                return;
            }

            if (type.IsString())
            {
                AppendText(presentation, _highlighterIdProvider.String);
            }
            else if (type.IsChar())
            {
                AppendText(presentation, _highlighterIdProvider.String);
            }
            else if (type.IsPredefinedNumeric())
            {
                AppendText(presentation, _highlighterIdProvider.Number);
            }
            else
            {
                AppendText(presentation, null);
            }
        }