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); }
internal override ConstantValue GetConstantValue( ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes ) { return(null); }
internal override ConstantValue GetConstantValue( ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes ) { throw ExceptionUtilities.Unreachable; }
internal override ConstantValue GetConstantValue( ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes ) { return(_underlyingField.GetConstantValue(inProgress, earlyDecodingWellKnownAttributes)); }
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(); } }
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); }
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; }
internal abstract ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes);
internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes) { throw ExceptionUtilities.Unreachable; }
internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes) { return _underlyingField.GetConstantValue(inProgress, earlyDecodingWellKnownAttributes); }
internal override ConstantValue GetConstantValue(ConstantFieldsInProgress inProgress, bool earlyDecodingWellKnownAttributes) { return(_originalDefinition.GetConstantValue(inProgress, earlyDecodingWellKnownAttributes)); }
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); }
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(); } }
internal ConstantFieldsInProgressBinder(ConstantFieldsInProgress inProgress, Binder next) : base(next, BinderFlags.FieldInitializer | next.Flags) { _inProgress = inProgress; }
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; }
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; }