Esempio n. 1
0
        internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
        {
            if (lazyConstantValue == Microsoft.CodeAnalysis.ConstantValue.Unset)
            {
                ConstantValue value = null;

                if ((flags & FieldAttributes.Literal) != 0)
                {
                    value = this.containingType.ContainingPEModule.Module.GetConstantFieldValue(this.handle);
                }

                // If this is a Decimal, the constant value may come from DecimalConstantAttribute

                if (this.Type.SpecialType == SpecialType.System_Decimal)
                {
                    ConstantValue defaultValue;

                    if (this.containingType.ContainingPEModule.Module.HasDecimalConstantAttribute(Handle, out defaultValue))
                    {
                        value = defaultValue;
                    }
                }

                Interlocked.CompareExchange(
                    ref lazyConstantValue,
                    value,
                    Microsoft.CodeAnalysis.ConstantValue.Unset);
            }

            return(lazyConstantValue);
        }
Esempio n. 2
0
 internal override ConstantValue GetConstantValue(
     ConstantFieldsInProgress inProgress,
     bool earlyDecodingWellKnownAttributes
     )
 {
     return(null);
 }
Esempio n. 3
0
 internal override ConstantValue GetConstantValue(
     ConstantFieldsInProgress inProgress,
     bool earlyDecodingWellKnownAttributes
     )
 {
     throw ExceptionUtilities.Unreachable;
 }
Esempio n. 4
0
 internal override ConstantValue GetConstantValue(
     ConstantFieldsInProgress inProgress,
     bool earlyDecodingWellKnownAttributes
     )
 {
     return(_underlyingField.GetConstantValue(inProgress, earlyDecodingWellKnownAttributes));
 }
Esempio n. 5
0
        public static EvaluatedConstant EvaluateFieldConstant(this FieldSymbol symbol, SyntaxReference equalsValueNodeRef, ConstantFieldsInProgress inProgress)
        {
            Debug.Assert(inProgress != null);
            var diagnostics = DiagnosticBag.GetInstance();
            try
            {
                ConstantValue value;
                if (inProgress.Contains(symbol))
                {
                    var errorField = inProgress.ErrorField;
                    diagnostics.Add(ErrorCode.ERR_CircConstValue, errorField.Locations[0], errorField);
                    value = Roslyn.Compilers.ConstantValue.Bad;
                }
                else
                {
                    var compilation = ((SourceAssemblySymbol)symbol.ContainingAssembly).Compilation;
                    var binderFactory = compilation.GetBinderFactory(equalsValueNodeRef.SyntaxTree);

                    var newInProgress = inProgress.Add(symbol);

                    var equalsValueNode = (EqualsValueClauseSyntax)equalsValueNodeRef.GetSyntax();

                    var binder = binderFactory.GetBinder(equalsValueNode);
                    var inProgressBinder = new ConstantFieldsInProgressBinder(newInProgress, binder);

                    // CONSIDER: Compiler.BindFieldInitializer will make this same call on this same syntax node
                    // to determine the bound value for itself.  We expect this binding to be fairly cheap 
                    // (since constants tend to be simple) and it should only happen twice (regardless of the
                    // number of references to this constant).  If this becomes a performance bottleneck,
                    // the re-binding can be eliminated by caching the BoundNode on this SourceFieldSymbol and
                    // checking for a cached value before binding (here and in Compiler.BindFieldInitializer).
                    var boundValue = inProgressBinder.BindVariableInitializer(equalsValueNode, symbol.Type, diagnostics);
                    var initValueNodeLocation = inProgressBinder.Location(equalsValueNode.Value);

                    value = ConstantValueUtils.GetAndValidateConstantValue(boundValue, symbol, symbol.Type, initValueNodeLocation, diagnostics);
                }
                return new EvaluatedConstant(value, diagnostics.Seal());
            }
            finally
            {
                diagnostics.Free();
            }
        }
Esempio n. 6
0
        internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
        {
            if (_lazyConstantValue == StarkPlatform.Compiler.ConstantValue.Unset)
            {
                ConstantValue value = null;

                if ((_flags & FieldAttributes.Literal) != 0)
                {
                    value = _containingType.ContainingPEModule.Module.GetConstantFieldValue(_handle);
                }

                // If this is a Decimal, the constant value may come from DecimalConstantAttribute

                Interlocked.CompareExchange(
                    ref _lazyConstantValue,
                    value,
                    StarkPlatform.Compiler.ConstantValue.Unset);
            }

            return(_lazyConstantValue);
        }
Esempio n. 7
0
        internal sealed override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
        {
            var value = this.GetLazyConstantValue(earlyDecodingWellKnownAttributes);

            if (value != Microsoft.CodeAnalysis.ConstantValue.Unset)
            {
                return(value);
            }

            if (!inProgress.IsEmpty)
            {
                // Add this field as a dependency of the original field, and
                // return Unset. The outer GetConstantValue caller will call
                // this method again after evaluating any dependencies.
                inProgress.AddDependency(this);
                return(Microsoft.CodeAnalysis.ConstantValue.Unset);
            }

            // Order dependencies.
            var order = ArrayBuilder <ConstantEvaluationHelpers.FieldInfo> .GetInstance();

            this.OrderAllDependencies(order, earlyDecodingWellKnownAttributes);

            // Evaluate fields in order.
            foreach (var info in order)
            {
                // Bind the field value regardless of whether the field represents
                // the start of a cycle. In the cycle case, there will be unevaluated
                // dependencies and the result will be ConstantValue.Bad plus cycle error.
                var field = info.Field;
                field.BindConstantValueIfNecessary(earlyDecodingWellKnownAttributes, startsCycle: info.StartsCycle);
            }

            order.Free();

            // Return the value of this field.
            return(this.GetLazyConstantValue(earlyDecodingWellKnownAttributes));
        }
 internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
 {
     return null;
 }
Esempio n. 9
0
 internal abstract ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes);
 internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
 {
     throw ExceptionUtilities.Unreachable;
 }
Esempio n. 11
0
 internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
 {
     return _underlyingField.GetConstantValue(inProgress, earlyDecodingWellKnownAttributes);
 }
Esempio n. 12
0
 internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
 {
     return(_originalDefinition.GetConstantValue(inProgress, earlyDecodingWellKnownAttributes));
 }
Esempio n. 13
0
        internal sealed override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
        {
            var value = this.GetLazyConstantValue(earlyDecodingWellKnownAttributes);
            if (value != Microsoft.CodeAnalysis.ConstantValue.Unset)
            {
                return value;
            }

            if (!inProgress.IsEmpty)
            {
                // Add this field as a dependency of the original field, and
                // return Unset. The outer GetConstantValue caller will call
                // this method again after evaluating any dependencies.
                inProgress.AddDependency(this);
                return Microsoft.CodeAnalysis.ConstantValue.Unset;
            }

            // Order dependencies.
            var order = ArrayBuilder<ConstantEvaluationHelpers.FieldInfo>.GetInstance();
            this.OrderAllDependencies(order, earlyDecodingWellKnownAttributes);

            // Evaluate fields in order.
            foreach (var info in order)
            {
                // Bind the field value regardless of whether the field represents
                // the start of a cycle. In the cycle case, there will be unevaluated
                // dependencies and the result will be ConstantValue.Bad plus cycle error.
                var field = info.Field;
                field.BindConstantValueIfNecessary(earlyDecodingWellKnownAttributes, startsCycle: info.StartsCycle);
            }

            order.Free();

            // Return the value of this field.
            return this.GetLazyConstantValue(earlyDecodingWellKnownAttributes);
        }
Esempio n. 14
0
        public static EvaluatedConstant EvaluateFieldConstant(this FieldSymbol symbol, SyntaxReference equalsValueNodeRef, ConstantFieldsInProgress inProgress)
        {
            Debug.Assert(inProgress != null);
            var diagnostics = DiagnosticBag.GetInstance();

            try
            {
                ConstantValue value;
                if (inProgress.Contains(symbol))
                {
                    var errorField = inProgress.ErrorField;
                    diagnostics.Add(ErrorCode.ERR_CircConstValue, errorField.Locations[0], errorField);
                    value = Roslyn.Compilers.ConstantValue.Bad;
                }
                else
                {
                    var compilation   = ((SourceAssemblySymbol)symbol.ContainingAssembly).Compilation;
                    var binderFactory = compilation.GetBinderFactory(equalsValueNodeRef.SyntaxTree);

                    var newInProgress = inProgress.Add(symbol);

                    var equalsValueNode = (EqualsValueClauseSyntax)equalsValueNodeRef.GetSyntax();

                    var binder           = binderFactory.GetBinder(equalsValueNode);
                    var inProgressBinder = new ConstantFieldsInProgressBinder(newInProgress, binder);

                    // CONSIDER: Compiler.BindFieldInitializer will make this same call on this same syntax node
                    // to determine the bound value for itself.  We expect this binding to be fairly cheap
                    // (since constants tend to be simple) and it should only happen twice (regardless of the
                    // number of references to this constant).  If this becomes a performance bottleneck,
                    // the re-binding can be eliminated by caching the BoundNode on this SourceFieldSymbol and
                    // checking for a cached value before binding (here and in Compiler.BindFieldInitializer).
                    var boundValue            = inProgressBinder.BindVariableInitializer(equalsValueNode, symbol.Type, diagnostics);
                    var initValueNodeLocation = inProgressBinder.Location(equalsValueNode.Value);

                    value = ConstantValueUtils.GetAndValidateConstantValue(boundValue, symbol, symbol.Type, initValueNodeLocation, diagnostics);
                }
                return(new EvaluatedConstant(value, diagnostics.Seal()));
            }
            finally
            {
                diagnostics.Free();
            }
        }
Esempio n. 15
0
 internal ConstantFieldsInProgressBinder(ConstantFieldsInProgress inProgress, Binder next)
     : base(next, BinderFlags.FieldInitializer | next.Flags)
 {
     _inProgress = inProgress;
 }
Esempio n. 16
0
        internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
        {
            if (_lazyConstantValue == Microsoft.CodeAnalysis.ConstantValue.Unset)
            {
                ConstantValue value = null;

                if ((_flags & FieldAttributes.Literal) != 0)
                {
                    value = _containingType.ContainingPEModule.Module.GetConstantFieldValue(_handle);
                }

                // If this is a Decimal, the constant value may come from DecimalConstantAttribute

                if (this.Type.SpecialType == SpecialType.System_Decimal)
                {
                    ConstantValue defaultValue;

                    if (_containingType.ContainingPEModule.Module.HasDecimalConstantAttribute(Handle, out defaultValue))
                    {
                        value = defaultValue;
                    }
                }

                Interlocked.CompareExchange(
                    ref _lazyConstantValue,
                    value,
                    Microsoft.CodeAnalysis.ConstantValue.Unset);
            }

            return _lazyConstantValue;
        }
Esempio n. 17
0
 internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes)
 {
     return _originalDefinition.GetConstantValue(inProgress, earlyDecodingWellKnownAttributes);
 }
 internal ConstantFieldsInProgressBinder(ConstantFieldsInProgress inProgress, Binder next)
     : base(next, BinderFlags.FieldInitializer | next.Flags)
 {
     this.inProgress = inProgress;
 }