private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress, bool early) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); var currentBounds = _lazyBounds; if (!currentBounds.IsSet(early)) { var diagnostics = DiagnosticBag.GetInstance(); var bounds = this.ResolveBounds(inProgress, early, diagnostics); if (ReferenceEquals(Interlocked.CompareExchange(ref _lazyBounds, bounds, currentBounds), currentBounds)) { if (_lazyBounds?.IsEarly != true) { this.CheckConstraintTypeConstraints(diagnostics); this.CheckUnmanagedConstraint(diagnostics); this.CheckNullableAnnotationsInConstraints(diagnostics); this.AddDeclarationDiagnostics(diagnostics); _state.NotePartComplete(CompletionPart.TypeParameterConstraints); } } diagnostics.Free(); } return(_lazyBounds); }
private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress, bool canIgnoreNullableContext) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); if (!_lazyBounds.HasValue(canIgnoreNullableContext)) { var diagnostics = DiagnosticBag.GetInstance(); var bounds = this.ResolveBounds(inProgress, canIgnoreNullableContext, diagnostics); if (TypeParameterBoundsExtensions.InterlockedUpdate(ref _lazyBounds, bounds) && _lazyBounds.HasValue(canIgnoreNullableContext: false)) { this.CheckConstraintTypeConstraints(diagnostics); this.CheckUnmanagedConstraint(diagnostics); this.EnsureAttributesFromConstraints(diagnostics); this.AddDeclarationDiagnostics(diagnostics); _state.NotePartComplete(CompletionPart.TypeParameterConstraints); } diagnostics.Free(); } return(_lazyBounds); }
private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress, bool early) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); var currentBounds = _lazyBounds; if (currentBounds == TypeParameterBounds.Unset) { var constraintTypes = GetDeclaredConstraintTypes(); Debug.Assert(!constraintTypes.IsDefault); var bounds = new TypeParameterBounds(constraintTypes); Interlocked.CompareExchange(ref _lazyBounds, bounds, currentBounds); currentBounds = _lazyBounds; } if (!currentBounds.IsSet(early)) { var constraintTypes = currentBounds.ConstraintTypes; var diagnostics = ArrayBuilder <TypeParameterDiagnosticInfo> .GetInstance(); ArrayBuilder <TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null; bool inherited = (_containingSymbol.Kind == SymbolKind.Method) && ((MethodSymbol)_containingSymbol).IsOverride; var bounds = this.ResolveBounds(this.ContainingAssembly.CorLibrary, inProgress.Prepend(this), constraintTypes, inherited, currentCompilation: null, diagnosticsBuilder: diagnostics, useSiteDiagnosticsBuilder: ref useSiteDiagnosticsBuilder); DiagnosticInfo errorInfo = null; if (diagnostics.Count > 0) { errorInfo = diagnostics[0].DiagnosticInfo; } else if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0) { foreach (var diag in useSiteDiagnosticsBuilder) { if (diag.DiagnosticInfo.Severity == DiagnosticSeverity.Error) { errorInfo = diag.DiagnosticInfo; break; } else if ((object)errorInfo == null) { errorInfo = diag.DiagnosticInfo; } } } diagnostics.Free(); Interlocked.CompareExchange(ref _lazyConstraintsUseSiteErrorInfo, errorInfo, CSDiagnosticInfo.EmptyErrorInfo); Interlocked.CompareExchange(ref _lazyBounds, bounds, currentBounds); } return(_lazyBounds); }
private static ConsList<FieldSymbol> SubstituteFields(ConsList<FieldSymbol> fields, TypeMap typeMap) { if (!fields.Any()) { return ConsList<FieldSymbol>.Empty; } var head = SubstituteField(fields.Head, typeMap); var tail = SubstituteFields(fields.Tail, typeMap); return tail.Prepend(head); }
internal DisplayClassVariable(string name, DisplayClassVariableKind kind, DisplayClassInstance displayClassInstance, ConsList<FieldSymbol> displayClassFields) { Debug.Assert(displayClassFields.Any()); this.Name = name; this.Kind = kind; this.DisplayClassInstance = displayClassInstance; this.DisplayClassFields = displayClassFields; // Verify all type parameters are substituted. Debug.Assert(this.ContainingSymbol.IsContainingSymbolOfAllTypeParameters(this.Type)); }
internal DisplayClassVariable(string name, DisplayClassVariableKind kind, DisplayClassInstance displayClassInstance, ConsList <FieldSymbol> displayClassFields) { Debug.Assert(displayClassFields.Any()); this.Name = name; this.Kind = kind; this.DisplayClassInstance = displayClassInstance; this.DisplayClassFields = displayClassFields; // Verify all type parameters are substituted. Debug.Assert(this.ContainingSymbol.IsContainingSymbolOfAllTypeParameters(this.Type)); }
private static ConsList <FieldSymbol> SubstituteFields(ConsList <FieldSymbol> fields, TypeMap typeMap) { if (!fields.Any()) { return(ConsList <FieldSymbol> .Empty); } var head = SubstituteField(fields.Head, typeMap); var tail = SubstituteFields(fields.Tail, typeMap); return(tail.Prepend(head)); }
private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset)) { var constraintTypes = GetDeclaredConstraintTypes(); Debug.Assert(!constraintTypes.IsDefault); //var diagnostics = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance(); //ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null; bool inherited = (_containingSymbol.Kind == SymbolKind.Method) && ((MethodSymbol)_containingSymbol).IsOverride; //var bounds = this.ResolveBounds(this.ContainingAssembly.CorLibrary, inProgress.Prepend(this), constraintTypes, inherited, currentCompilation: null, // diagnosticsBuilder: diagnostics, useSiteDiagnosticsBuilder: ref useSiteDiagnosticsBuilder); var bounds = new TypeParameterBounds(ImmutableArray <TypeSymbol> .Empty, ImmutableArray <NamedTypeSymbol> .Empty, null, null); //DiagnosticInfo errorInfo = null; //if (diagnostics.Count > 0) //{ // errorInfo = diagnostics[0].DiagnosticInfo; //} //else if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0) //{ // foreach (var diag in useSiteDiagnosticsBuilder) // { // if (diag.DiagnosticInfo.Severity == DiagnosticSeverity.Error) // { // errorInfo = diag.DiagnosticInfo; // break; // } // else if ((object)errorInfo == null) // { // errorInfo = diag.DiagnosticInfo; // } // } //} //diagnostics.Free(); //Interlocked.CompareExchange(ref _lazyBoundsErrorInfo, errorInfo, CSDiagnosticInfo.EmptyErrorInfo); Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset); } //Debug.Assert(!ReferenceEquals(_lazyBoundsErrorInfo, CSDiagnosticInfo.EmptyErrorInfo)); return(_lazyBounds); }
// removes region directives from stack but leaves everything else private static ConsList <Directive> CompleteRegion(ConsList <Directive> stack) { // if we get to the top, the default rule is to include anything that follows if (!stack.Any()) { return(stack); } if (stack.Head.Kind == SyntaxKind.RegionDirectiveTrivia) { return(stack.Tail); } var newStack = CompleteRegion(stack.Tail); newStack = new ConsList <Directive>(stack.Head, newStack); return(newStack); }
private static ConsList <Directive> SkipInsignificantDirectives(ConsList <Directive> directives) { for (; directives != null && directives.Any(); directives = directives.Tail) { switch (directives.Head.Kind) { case SyntaxKind.IfDirectiveTrivia: case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: case SyntaxKind.EndIfDirectiveTrivia: case SyntaxKind.DefineDirectiveTrivia: case SyntaxKind.UndefDirectiveTrivia: case SyntaxKind.RegionDirectiveTrivia: case SyntaxKind.EndRegionDirectiveTrivia: return(directives); } } return(directives); }
// removes unfinished if & related directives from stack and leaves active branch directives private static ConsList <Directive> CompleteIf(DirectiveTriviaSyntax branchEndSyntax, ConsList <Directive> stack, out bool include) { // if we get to the top, the default rule is to include anything that follows if (!stack.Any()) { include = true; return(stack); } // if we reach the #if directive, then we stop unwinding and start // rebuilding the stack w/o the #if/#elif/#else/#endif directives // only including content from sections that are considered included var head = stack.Head; if (head.Kind.IsIfLikeDirective()) { include = head.BranchTaken; head.BranchEnd = branchEndSyntax; return(stack.Tail); } var newStack = CompleteIf(branchEndSyntax, stack.Tail, out include); switch (stack.Head.Kind) { case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: include = stack.Head.BranchTaken; break; default: if (include) { newStack = new ConsList <Directive>(head, newStack); } break; } return(newStack); }
private TypeParameterBounds GetBounds(ConsList <TypeParameterSymbol> inProgress) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset)) { var diagnostics = DiagnosticBag.GetInstance(); var bounds = this.ResolveBounds(inProgress, diagnostics); if (ReferenceEquals(Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset), TypeParameterBounds.Unset)) { this.CheckConstraintTypeConstraints(diagnostics); this.AddDeclarationDiagnostics(diagnostics); _state.NotePartComplete(CompletionPart.TypeParameterConstraints); } diagnostics.Free(); } return(_lazyBounds); }
private ImmutableArray <TypeWithAnnotations> GetDeclaredConstraintTypes(ConsList <PETypeParameterSymbol> inProgress) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); if (_lazyDeclaredConstraintTypes.IsDefault) { ImmutableArray <TypeWithAnnotations> declaredConstraintTypes; var moduleSymbol = ((PEModuleSymbol)this.ContainingModule); PEModule peModule = moduleSymbol.Module; GenericParameterConstraintHandleCollection constraints = GetConstraintHandleCollection(peModule); bool hasUnmanagedModreqPattern = false; if (constraints.Count > 0) { var symbolsBuilder = ArrayBuilder <TypeWithAnnotations> .GetInstance(); MetadataDecoder tokenDecoder = GetDecoder(moduleSymbol); TypeWithAnnotations bestObjectConstraint = default; var metadataReader = peModule.MetadataReader; foreach (var constraintHandle in constraints) { TypeWithAnnotations type = GetConstraintTypeOrDefault(moduleSymbol, metadataReader, tokenDecoder, constraintHandle, ref hasUnmanagedModreqPattern); if (!type.HasType) { // Dropped 'System.ValueType' constraint type when the 'valuetype' constraint was also specified. continue; } // Drop 'System.Object' constraint type. if (ConstraintsHelper.IsObjectConstraint(type, ref bestObjectConstraint)) { continue; } symbolsBuilder.Add(type); } if (bestObjectConstraint.HasType) { // See if we need to put Object! or Object~ back in order to preserve nullability information for the type parameter. if (ConstraintsHelper.IsObjectConstraintSignificant(CalculateIsNotNullableFromNonTypeConstraints(), bestObjectConstraint)) { Debug.Assert(!HasNotNullConstraint && !HasValueTypeConstraint); if (symbolsBuilder.Count == 0) { if (bestObjectConstraint.NullableAnnotation.IsOblivious() && !HasReferenceTypeConstraint) { bestObjectConstraint = default; } } else { inProgress = inProgress.Prepend(this); foreach (TypeWithAnnotations constraintType in symbolsBuilder) { if (!ConstraintsHelper.IsObjectConstraintSignificant(IsNotNullableFromConstraintType(constraintType, inProgress, out _), bestObjectConstraint)) { bestObjectConstraint = default; break; } } } if (bestObjectConstraint.HasType) { symbolsBuilder.Insert(0, bestObjectConstraint); } } } declaredConstraintTypes = symbolsBuilder.ToImmutableAndFree(); } else { declaredConstraintTypes = ImmutableArray <TypeWithAnnotations> .Empty; } // - presence of unmanaged pattern has to be matched with `valuetype` // - IsUnmanagedAttribute is allowed iff there is an unmanaged pattern if (hasUnmanagedModreqPattern && (_flags & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0 || hasUnmanagedModreqPattern != peModule.HasIsUnmanagedAttribute(_handle)) { // we do not recognize these combinations as "unmanaged" hasUnmanagedModreqPattern = false; _lazyCachedConstraintsUseSiteInfo.InterlockedCompareExchange(primaryDependency: null, new UseSiteInfo <AssemblySymbol>(new CSDiagnosticInfo(ErrorCode.ERR_BindToBogus, this))); } _lazyHasIsUnmanagedConstraint = hasUnmanagedModreqPattern.ToThreeState(); ImmutableInterlocked.InterlockedInitialize(ref _lazyDeclaredConstraintTypes, declaredConstraintTypes); } return(_lazyDeclaredConstraintTypes); }
// removes region directives from stack but leaves everything else private static ConsList<Directive> CompleteRegion(ConsList<Directive> stack) { // if we get to the top, the default rule is to include anything that follows if (!stack.Any()) { return stack; } if (stack.Head.Kind == SyntaxKind.RegionDirectiveTrivia) { return stack.Tail; } var newStack = CompleteRegion(stack.Tail); newStack = new ConsList<Directive>(stack.Head, newStack); return newStack; }
private static ConsList<Directive> SkipInsignificantDirectives(ConsList<Directive> directives) { for (; directives != null && directives.Any(); directives = directives.Tail) { switch (directives.Head.Kind) { case SyntaxKind.IfDirectiveTrivia: case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: case SyntaxKind.EndIfDirectiveTrivia: case SyntaxKind.DefineDirectiveTrivia: case SyntaxKind.UndefDirectiveTrivia: case SyntaxKind.RegionDirectiveTrivia: case SyntaxKind.EndRegionDirectiveTrivia: return directives; } } return directives; }
// removes unfinished if & related directives from stack and leaves active branch directives private static ConsList<Directive> CompleteIf(ConsList<Directive> stack, out bool include) { // if we get to the top, the default rule is to include anything that follows if (!stack.Any()) { include = true; return stack; } // if we reach the #if directive, then we stop unwinding and start // rebuilding the stack w/o the #if/#elif/#else/#endif directives // only including content from sections that are considered included if (stack.Head.Kind.IsIfLikeDirective()) { include = stack.Head.BranchTaken; return stack.Tail; } var newStack = CompleteIf(stack.Tail, out include); switch (stack.Head.Kind) { case SyntaxKind.ElifDirectiveTrivia: case SyntaxKind.ElseDirectiveTrivia: include = stack.Head.BranchTaken; break; default: if (include) { newStack = new ConsList<Directive>(stack.Head, newStack); } break; } return newStack; }
private TypeParameterBounds GetBounds(ConsList<TypeParameterSymbol> inProgress) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset)) { var constraintTypes = GetDeclaredConstraintTypes(); Debug.Assert(!constraintTypes.IsDefault); var diagnostics = ArrayBuilder<TypeParameterDiagnosticInfo>.GetInstance(); ArrayBuilder<TypeParameterDiagnosticInfo> useSiteDiagnosticsBuilder = null; bool inherited = (_containingSymbol.Kind == SymbolKind.Method) && ((MethodSymbol)_containingSymbol).IsOverride; var bounds = this.ResolveBounds(this.ContainingAssembly.CorLibrary, inProgress.Prepend(this), constraintTypes, inherited, currentCompilation: null, diagnosticsBuilder: diagnostics, useSiteDiagnosticsBuilder: ref useSiteDiagnosticsBuilder); DiagnosticInfo errorInfo = null; if (diagnostics.Count > 0) { errorInfo = diagnostics[0].DiagnosticInfo; } else if (useSiteDiagnosticsBuilder != null && useSiteDiagnosticsBuilder.Count > 0) { foreach (var diag in useSiteDiagnosticsBuilder) { if (diag.DiagnosticInfo.Severity == DiagnosticSeverity.Error) { errorInfo = diag.DiagnosticInfo; break; } else if ((object)errorInfo == null) { errorInfo = diag.DiagnosticInfo; } } } diagnostics.Free(); Interlocked.CompareExchange(ref _lazyBoundsErrorInfo, errorInfo, CSDiagnosticInfo.EmptyErrorInfo); Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset); } Debug.Assert(!ReferenceEquals(_lazyBoundsErrorInfo, CSDiagnosticInfo.EmptyErrorInfo)); return _lazyBounds; }
private static string GetDebuggerDisplay(string expr, ConsList <FieldSymbol> fields) { return(fields.Any() ? $"{GetDebuggerDisplay(expr, fields.Tail)}.{fields.Head.Name}" : expr); }
private TypeParameterBounds GetBounds(ConsList<TypeParameterSymbol> inProgress) { Debug.Assert(!inProgress.ContainsReference(this)); Debug.Assert(!inProgress.Any() || ReferenceEquals(inProgress.Head.ContainingSymbol, this.ContainingSymbol)); if (ReferenceEquals(_lazyBounds, TypeParameterBounds.Unset)) { var diagnostics = DiagnosticBag.GetInstance(); var bounds = this.ResolveBounds(inProgress, diagnostics); if (ReferenceEquals(Interlocked.CompareExchange(ref _lazyBounds, bounds, TypeParameterBounds.Unset), TypeParameterBounds.Unset)) { this.CheckConstraintTypeConstraints(diagnostics); this.AddDeclarationDiagnostics(diagnostics); _state.NotePartComplete(CompletionPart.TypeParameterConstraints); } diagnostics.Free(); } return _lazyBounds; }