protected override void InferFieldType(ConsList <FieldSymbol> fieldsBeingBound, Binder binder) { var nodeToBind = _nodeToBind.GetSyntax(); if ((object)_containingFieldOpt != null && nodeToBind.Kind() != SyntaxKind.VariableDeclarator) { binder = binder.WithContainingMemberOrLambda(_containingFieldOpt).WithAdditionalFlags(BinderFlags.FieldInitializer); } fieldsBeingBound = new ConsList <FieldSymbol>(this, fieldsBeingBound); binder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var diagnostics = DiagnosticBag.GetInstance(); switch (nodeToBind.Kind()) { case SyntaxKind.VariableDeclarator: // This occurs, for example, in // int x, y[out var Z, 1 is int I]; // for (int x, y[out var Z, 1 is int I]; ;) {} binder.BindDeclaratorArguments((VariableDeclaratorSyntax)nodeToBind, diagnostics); break; default: binder.BindExpression((ExpressionSyntax)nodeToBind, diagnostics); break; } diagnostics.Free(); }
internal sealed override TypeSymbol GetFieldType(ConsList<FieldSymbol> fieldsBeingBound) { Debug.Assert(fieldsBeingBound != null); if ((object)_lazyType != null) { return _lazyType; } var declarator = VariableDeclaratorNode; var fieldSyntax = GetFieldDeclaration(declarator); var typeSyntax = fieldSyntax.Declaration.Type; var compilation = this.DeclaringCompilation; var diagnostics = DiagnosticBag.GetInstance(); TypeSymbol type; // When we have multiple declarators, we report the type diagnostics on only the first. DiagnosticBag diagnosticsForFirstDeclarator = DiagnosticBag.GetInstance(); Symbol associatedPropertyOrEvent = this.AssociatedSymbol; if ((object)associatedPropertyOrEvent != null && associatedPropertyOrEvent.Kind == SymbolKind.Event) { EventSymbol @event = (EventSymbol)associatedPropertyOrEvent; if (@event.IsWindowsRuntimeEvent) { NamedTypeSymbol tokenTableType = this.DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T); Binder.ReportUseSiteDiagnostics(tokenTableType, diagnosticsForFirstDeclarator, this.ErrorLocation); // CONSIDER: Do we want to guard against the possibility that someone has created their own EventRegistrationTokenTable<T> // type that has additional generic constraints? type = tokenTableType.Construct(@event.Type); } else { type = @event.Type; } } else { var binderFactory = compilation.GetBinderFactory(SyntaxTree); var binder = binderFactory.GetBinder(typeSyntax); binder = binder.WithContainingMemberOrLambda(this); if (!ContainingType.IsScriptClass) { type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator); if (IsFixed) { type = new PointerTypeSymbol(type); } } else { bool isVar; type = binder.BindType(typeSyntax, diagnostics, out isVar); Debug.Assert((object)type != null || isVar); if (isVar) { if (this.IsConst) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, typeSyntax.Location); } if (fieldsBeingBound.ContainsReference(this)) { diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this); type = null; } else if (fieldSyntax.Declaration.Variables.Count > 1) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, typeSyntax.Location); } else { fieldsBeingBound = new ConsList<FieldSymbol>(this, fieldsBeingBound); var initializerBinder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var initializerOpt = initializerBinder.BindInferredVariableInitializer(diagnostics, declarator.Initializer, declarator); if (initializerOpt != null) { if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType()) { type = initializerOpt.Type; } _lazyFieldTypeInferred = 1; } } if ((object)type == null) { type = binder.CreateErrorType("var"); } } } if (IsFixed) { if (ContainingType.TypeKind != TypeKind.Struct) { diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation); } var elementType = ((PointerTypeSymbol)type).PointedAtType; int elementSize = elementType.FixedBufferElementSizeInBytes(); if (elementSize == 0) { var loc = typeSyntax.Location; diagnostics.Add(ErrorCode.ERR_IllegalFixedType, loc); } if (!binder.InUnsafeRegion) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_UnsafeNeeded, declarator.Location); } } } // update the lazyType only if it contains value last seen by the current thread: if ((object)Interlocked.CompareExchange(ref _lazyType, type, null) == null) { TypeChecks(type, fieldSyntax, declarator, diagnostics); // CONSIDER: SourceEventFieldSymbol would like to suppress these diagnostics. compilation.DeclarationDiagnostics.AddRange(diagnostics); bool isFirstDeclarator = fieldSyntax.Declaration.Variables[0] == declarator; if (isFirstDeclarator) { compilation.DeclarationDiagnostics.AddRange(diagnosticsForFirstDeclarator); } state.NotePartComplete(CompletionPart.Type); } diagnostics.Free(); diagnosticsForFirstDeclarator.Free(); return _lazyType; }
internal sealed override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { Debug.Assert(fieldsBeingBound != null); if (!_lazyType.IsNull) { return(_lazyType.ToType()); } var declarator = VariableDeclaratorNode; var fieldSyntax = GetFieldDeclaration(declarator); var typeSyntax = fieldSyntax.Declaration.Type; var compilation = this.DeclaringCompilation; var diagnostics = DiagnosticBag.GetInstance(); TypeSymbolWithAnnotations type; // When we have multiple declarators, we report the type diagnostics on only the first. DiagnosticBag diagnosticsForFirstDeclarator = DiagnosticBag.GetInstance(); Symbol associatedPropertyOrEvent = this.AssociatedSymbol; if ((object)associatedPropertyOrEvent != null && associatedPropertyOrEvent.Kind == SymbolKind.Event) { EventSymbol @event = (EventSymbol)associatedPropertyOrEvent; if (@event.IsWindowsRuntimeEvent) { NamedTypeSymbol tokenTableType = this.DeclaringCompilation.GetWellKnownType(WellKnownType.System_Runtime_InteropServices_WindowsRuntime_EventRegistrationTokenTable_T); Binder.ReportUseSiteDiagnostics(tokenTableType, diagnosticsForFirstDeclarator, this.ErrorLocation); // CONSIDER: Do we want to guard against the possibility that someone has created their own EventRegistrationTokenTable<T> // type that has additional generic constraints? type = TypeSymbolWithAnnotations.Create(tokenTableType.Construct(ImmutableArray.Create(@event.Type))); } else { type = @event.Type; } } else { var binderFactory = compilation.GetBinderFactory(SyntaxTree); var binder = binderFactory.GetBinder(typeSyntax); binder = binder.WithContainingMemberOrLambda(this); if (!ContainingType.IsScriptClass) { type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator); } else { bool isVar; type = binder.BindTypeOrVarKeyword(typeSyntax, diagnostics, out isVar); Debug.Assert(!type.IsNull || isVar); if (isVar) { if (this.IsConst) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, typeSyntax.Location); } if (fieldsBeingBound.ContainsReference(this)) { diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this); type = default; } else if (fieldSyntax.Declaration.Variables.Count > 1) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableMultipleDeclarator, typeSyntax.Location); } else if (this.IsConst && this.ContainingType.IsScriptClass) { // For const var in script, we won't try to bind the initializer (case below), as it can lead to an unbound recursion type = default; } else { fieldsBeingBound = new ConsList <FieldSymbol>(this, fieldsBeingBound); var initializerBinder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var initializerOpt = initializerBinder.BindInferredVariableInitializer(diagnostics, RefKind.None, (EqualsValueClauseSyntax)declarator.Initializer, declarator); if (initializerOpt != null) { if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType()) { type = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, initializerOpt.Type); } _lazyFieldTypeInferred = 1; } } if (type.IsNull) { type = TypeSymbolWithAnnotations.Create(nonNullTypesContext: this, binder.CreateErrorType("var")); } } } if (IsFixed) { type = TypeSymbolWithAnnotations.Create(new PointerTypeSymbol(type)); if (ContainingType.TypeKind != TypeKind.Struct) { diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation); } var elementType = ((PointerTypeSymbol)type.TypeSymbol).PointedAtType.TypeSymbol; int elementSize = elementType.FixedBufferElementSizeInBytes(); if (elementSize == 0) { var loc = typeSyntax.Location; diagnostics.Add(ErrorCode.ERR_IllegalFixedType, loc); } if (!binder.InUnsafeRegion) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_UnsafeNeeded, declarator.Location); } } } // update the lazyType only if it contains value last seen by the current thread: if (_lazyType.InterlockedInitialize(type.WithModifiers(this.RequiredCustomModifiers))) { TypeChecks(type.TypeSymbol, diagnostics); // CONSIDER: SourceEventFieldSymbol would like to suppress these diagnostics. compilation.DeclarationDiagnostics.AddRange(diagnostics); bool isFirstDeclarator = fieldSyntax.Declaration.Variables[0] == declarator; if (isFirstDeclarator) { compilation.DeclarationDiagnostics.AddRange(diagnosticsForFirstDeclarator); } state.NotePartComplete(CompletionPart.Type); } diagnostics.Free(); diagnosticsForFirstDeclarator.Free(); return(_lazyType.ToType()); }
internal TypeSymbol GetVOGlobalType(CSharpCompilation compilation, TypeSyntax typeSyntax, Binder binder, ConsList <FieldSymbol> fieldsBeingBound) { var xNode = this.SyntaxNode.XNode; if (compilation.Options.HasOption(CompilerOption.ResolveTypedFunctionPointersToPtr, this.SyntaxNode)) { if (xNode is XP.ClassvarContext && xNode.Parent is XP.ClassVarListContext) { var cvl = xNode.Parent as XP.ClassVarListContext; var dt = cvl.DataType; if (dt is XP.PtrDatatypeContext) { // So we have a global as typed ptr // change the type from typed ptr to just ptr var ptrdtc = dt as XP.PtrDatatypeContext; if (ptrdtc.TypeName.Name != null) // User Define Typename PTR { string name = ptrdtc.TypeName.Name.GetText(); // Lookup name ? return(compilation.GetSpecialType(SpecialType.System_IntPtr)); } } } if (xNode is XP.VostructmemberContext smc) { var dt = smc.DataType; if (dt is XP.PtrDatatypeContext) { // So we have a global as typed ptr // change the type from typed ptr to just ptr var ptrdtc = dt as XP.PtrDatatypeContext; if (ptrdtc.TypeName.Name != null) // User Define Typename PTR { string name = ptrdtc.TypeName.Name.GetText(); // Lookup name ? return(compilation.GetSpecialType(SpecialType.System_IntPtr)); } } } } TypeSymbol type = null; if (xNode is XP.VodefineContext && !this.IsConst) { var vodef = xNode as XP.VodefineContext; DiagnosticBag diagnostics = DiagnosticBag.GetInstance(); type = binder.BindType(typeSyntax, diagnostics); // parser could not determine the type fieldsBeingBound = new ConsList <FieldSymbol>(this, fieldsBeingBound); var declarator = (VariableDeclaratorSyntax)this.DeclaringSyntaxReferences.AsSingleton().GetSyntax(); var initializerBinder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var initializerOpt = initializerBinder.BindInferredVariableInitializer(diagnostics, RefKind.None, declarator.Initializer, declarator); if (initializerOpt != null && !type.IsPsz()) { if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType()) { type = initializerOpt.Type; if (!type.IsVoidPointer() && initializerOpt.ConstantValue != null && !this.IsConst) { this._modifiers |= DeclarationModifiers.Const; this._modifiers |= DeclarationModifiers.Static; this._modifiers &= ~DeclarationModifiers.ReadOnly; } if (type.IsEnumType()) { type = type.GetEnumUnderlyingType(); } } } if (type == null) { type = compilation.GetSpecialType(SpecialType.System_Object); } //System.Diagnostics.Debug.WriteLine($"Looking for type of define {vodef.Name.ToString()}, found {type.ToString()}, const: {IsConst}"); return(type); } return(null); }
internal sealed override TypeSymbolWithAnnotations GetFieldType(ConsList <FieldSymbol> fieldsBeingBound) { Debug.Assert(fieldsBeingBound != null); if (!_lazyType.IsNull) { return(_lazyType.ToType()); } var declarator = VariableDeclarationNode; var fieldSyntax = GetFieldDeclaration(declarator); var typeSyntax = fieldSyntax.Declaration.Type; var compilation = this.DeclaringCompilation; var diagnostics = DiagnosticBag.GetInstance(); TypeSymbolWithAnnotations type = default; // When we have multiple declarators, we report the type diagnostics on only the first. DiagnosticBag diagnosticsForFirstDeclarator = DiagnosticBag.GetInstance(); Symbol associatedPropertyOrEvent = this.AssociatedSymbol; if ((object)associatedPropertyOrEvent != null && associatedPropertyOrEvent.Kind == SymbolKind.Event) { EventSymbol @event = (EventSymbol)associatedPropertyOrEvent; type = @event.Type; } else { var binderFactory = compilation.GetBinderFactory(SyntaxTree); var binder = binderFactory.GetBinder(declarator); binder = binder.WithAdditionalFlagsAndContainingMemberOrLambda(BinderFlags.SuppressConstraintChecks, this); if (!ContainingType.IsScriptClass) { type = binder.BindType(typeSyntax, diagnosticsForFirstDeclarator); } else if (typeSyntax == null) { if (this.IsConst) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_ImplicitlyTypedVariableCannotBeConst, typeSyntax.Location); } if (fieldsBeingBound.ContainsReference(this)) { diagnostics.Add(ErrorCode.ERR_RecursivelyTypedVariable, this.ErrorLocation, this); type = default; } else if (this.IsConst && this.ContainingType.IsScriptClass) { // For const var in script, we won't try to bind the initializer (case below), as it can lead to an unbound recursion type = default; } else { fieldsBeingBound = new ConsList <FieldSymbol>(this, fieldsBeingBound); var initializerBinder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var initializerOpt = initializerBinder.BindInferredVariableInitializer(diagnostics, RefKind.None, (EqualsValueClauseSyntax)declarator.Initializer, declarator); if (initializerOpt != null) { if ((object)initializerOpt.Type != null && !initializerOpt.Type.IsErrorType()) { type = TypeSymbolWithAnnotations.Create(initializerOpt.Type); } _lazyFieldTypeInferred = 1; } } if (type.IsNull) { type = TypeSymbolWithAnnotations.Create(binder.CreateErrorType("var")); } } else { type = binder.BindType(typeSyntax, diagnostics); } if (IsFixedSizeBuffer) { type = TypeSymbolWithAnnotations.Create(new PointerTypeSymbol(type)); if (ContainingType.TypeKind != TypeKind.Struct) { diagnostics.Add(ErrorCode.ERR_FixedNotInStruct, ErrorLocation); } var elementType = ((PointerTypeSymbol)type.TypeSymbol).PointedAtType.TypeSymbol; int elementSize = elementType.FixedBufferElementSizeInBytes(); if (elementSize == 0) { var loc = typeSyntax.Location; diagnostics.Add(ErrorCode.ERR_IllegalFixedType, loc); } if (!binder.InUnsafeRegion) { diagnosticsForFirstDeclarator.Add(ErrorCode.ERR_UnsafeNeeded, declarator.Location); } } } // update the lazyType only if it contains value last seen by the current thread: if (_lazyType.InterlockedInitialize(type.WithModifiers(this.RequiredCustomModifiers))) { TypeChecks(type.TypeSymbol, diagnostics); // CONSIDER: SourceEventFieldSymbol would like to suppress these diagnostics. compilation.DeclarationDiagnostics.AddRange(diagnostics); compilation.DeclarationDiagnostics.AddRange(diagnosticsForFirstDeclarator); state.NotePartComplete(CompletionPart.Type); } diagnostics.Free(); diagnosticsForFirstDeclarator.Free(); return(_lazyType.ToType()); }
protected override void InferFieldType(ConsList<FieldSymbol> fieldsBeingBound, Binder binder) { var nodeToBind = _nodeToBind.GetSyntax(); if ((object)_containingFieldOpt != null && nodeToBind.Kind() != SyntaxKind.VariableDeclarator) { binder = binder.WithContainingMemberOrLambda(_containingFieldOpt).WithAdditionalFlags(BinderFlags.FieldInitializer); } fieldsBeingBound = new ConsList<FieldSymbol>(this, fieldsBeingBound); binder = new ImplicitlyTypedFieldBinder(binder, fieldsBeingBound); var diagnostics = DiagnosticBag.GetInstance(); switch (nodeToBind.Kind()) { case SyntaxKind.VariableDeclarator: // This occurs, for example, in // int x, y[out var Z, 1 is int I]; // for (int x, y[out var Z, 1 is int I]; ;) {} binder.BindDeclaratorArguments((VariableDeclaratorSyntax)nodeToBind, diagnostics); break; default: binder.BindExpression((ExpressionSyntax)nodeToBind, diagnostics); break; } diagnostics.Free(); }