/// <summary> /// In regular C#, all field initializers are assignments to fields and the assigned expressions /// may not reference instance members. /// </summary> private static void BindRegularCSharpFieldInitializers( CSharpCompilation compilation, ImmutableArray <ImmutableArray <FieldInitializer> > initializers, ArrayBuilder <BoundInitializer> boundInitializers, DiagnosticBag diagnostics, bool generateDebugInfo, out ConsList <Imports> firstDebugImports) { firstDebugImports = null; foreach (ImmutableArray <FieldInitializer> siblingInitializers in initializers) { // All sibling initializers share the same parent node and tree so we can reuse the binder // factory across siblings. Unfortunately, we cannot reuse the binder itself, because // individual fields might have their own binders (e.g. because of being declared unsafe). BinderFactory binderFactory = null; foreach (FieldInitializer initializer in siblingInitializers) { FieldSymbol fieldSymbol = initializer.Field; Debug.Assert((object)fieldSymbol != null); // A constant field of type decimal needs a field initializer, so // check if it is a metadata constant, not just a constant to exclude // decimals. Other constants do not need field initializers. if (!fieldSymbol.IsMetadataConstant) { //Can't assert that this is a regular C# compilation, because we could be in a nested type of a script class. SyntaxReference syntaxRef = initializer.Syntax; var initializerNode = (CSharpSyntaxNode)syntaxRef.GetSyntax(); if (binderFactory == null) { binderFactory = compilation.GetBinderFactory(syntaxRef.SyntaxTree); } Binder parentBinder = binderFactory.GetBinder(initializerNode); Debug.Assert(parentBinder.ContainingMemberOrLambda == fieldSymbol.ContainingType || //should be the binder for the type fieldSymbol.ContainingType.IsImplicitClass); //however, we also allow fields in namespaces to help support script scenarios if (generateDebugInfo && firstDebugImports == null) { firstDebugImports = parentBinder.ImportsList; } BoundInitializer boundInitializer = BindFieldInitializer( new LocalScopeBinder(parentBinder.WithPrimaryConstructorParametersIfNecessary(fieldSymbol.ContainingType, shadowBackingFields: true)). WithAdditionalFlagsAndContainingMemberOrLambda(parentBinder.Flags | BinderFlags.FieldInitializer, fieldSymbol), fieldSymbol, (EqualsValueClauseSyntax)initializerNode, diagnostics); boundInitializers.Add(boundInitializer); } } } }
private static BoundStatement RewriteInitializersAsStatements(BoundInitializer initializer) { switch (initializer.Kind) { case BoundKind.FieldEqualsValue: return(RewriteFieldInitializer((BoundFieldEqualsValue)initializer)); case BoundKind.GlobalStatementInitializer: return(((BoundGlobalStatementInitializer)initializer).Statement); default: throw ExceptionUtilities.UnexpectedValue(initializer.Kind); } }
private BoundVariableDeclaration BindVariableDeclarator(VariableDeclaratorSyntax syntax, TypeSymbol variableType, Func <VariableDeclaratorSyntax, TypeSymbol, VariableSymbol> createSymbol) { variableType = BindArrayRankSpecifiers(syntax.ArrayRankSpecifiers, variableType); var symbol = createSymbol(syntax, variableType); AddSymbol(symbol, syntax.Identifier.SourceRange); var boundQualifiers = new List <BoundVariableQualifier>(); foreach (var qualifier in syntax.Qualifiers) { boundQualifiers.Add(Bind(qualifier, BindVariableQualifier)); } BoundInitializer initializer = null; if (syntax.Initializer != null) { initializer = BindInitializer(syntax.Initializer); } return(new BoundVariableDeclaration(symbol, variableType, boundQualifiers.ToImmutableArray(), initializer)); }
protected virtual void VisitInitializer(BoundInitializer node) { switch (node.Kind) { case BoundNodeKind.EqualsValue: VisitEqualsValueInitializer((BoundEqualsValue)node); break; case BoundNodeKind.SamplerState: VisitSamplerStateInitializer((BoundSamplerStateInitializer)node); break; case BoundNodeKind.StateInitializer: VisitStateInitializer((BoundStateInitializer)node); break; case BoundNodeKind.StateArrayInitializer: VisitStateArrayInitializer((BoundStateArrayInitializer)node); break; default: throw new InvalidOperationException(node.Kind.ToString()); } }
private static BoundStatement RewriteInitializersAsStatements(BoundInitializer initializer) { switch (initializer.Kind) { case BoundKind.FieldInitializer: return RewriteFieldInitializer((BoundFieldInitializer)initializer); case BoundKind.GlobalStatementInitializer: return ((BoundGlobalStatementInitializer)initializer).Statement; default: throw ExceptionUtilities.UnexpectedValue(initializer.Kind); } }