public static ConstantValue EvaluateFieldConstant( SourceFieldSymbol symbol, EqualsValueClauseSyntax equalsValueNode, HashSet <SourceFieldSymbolWithSyntaxReference> dependencies, bool earlyDecodingWellKnownAttributes, BindingDiagnosticBag diagnostics) { var compilation = symbol.DeclaringCompilation; var binderFactory = compilation.GetBinderFactory((SyntaxTree)symbol.Locations[0].SourceTree); var binder = binderFactory.GetBinder(equalsValueNode); if (earlyDecodingWellKnownAttributes) { binder = new EarlyWellKnownAttributeBinder(binder); } var inProgressBinder = new ConstantFieldsInProgressBinder(new ConstantFieldsInProgress(symbol, dependencies), binder); BoundFieldEqualsValue boundValue = BindFieldOrEnumInitializer(inProgressBinder, symbol, equalsValueNode, diagnostics); var initValueNodeLocation = equalsValueNode.Value.Location; var value = GetAndValidateConstantValue(boundValue.Value, symbol, symbol.Type, initValueNodeLocation, diagnostics); Debug.Assert(value != null); return(value); }
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(); } }
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(); } }
public static ConstantValue EvaluateFieldConstant( SourceFieldSymbol symbol, EqualsValueClauseSyntax equalsValueNode, HashSet<SourceFieldSymbolWithSyntaxReference> dependencies, bool earlyDecodingWellKnownAttributes, DiagnosticBag diagnostics) { var compilation = symbol.DeclaringCompilation; var binderFactory = compilation.GetBinderFactory((SyntaxTree)symbol.Locations[0].SourceTree); var binder = binderFactory.GetBinder(equalsValueNode); if (earlyDecodingWellKnownAttributes) { binder = new EarlyWellKnownAttributeBinder(binder); } var inProgressBinder = new ConstantFieldsInProgressBinder(new ConstantFieldsInProgress(symbol, dependencies), binder); var boundValue = BindFieldOrEnumInitializer(inProgressBinder, symbol, equalsValueNode, diagnostics); var initValueNodeLocation = equalsValueNode.Value.Location; var value = GetAndValidateConstantValue(boundValue, symbol, symbol.Type, initValueNodeLocation, diagnostics); Debug.Assert(value != null); return value; }