private IEnumerable <string> GetConstraintNames(TypeParameterConstraintClauseSyntax constraintClause, SemanticModel semanticModel) { foreach (var constraint in constraintClause.Constraints) { yield return(constraint switch { TypeConstraintSyntax typeConstraint => semanticModel.GetTypeInfo(typeConstraint.Type).Type.ToString(), _ => constraint.ToString() });
public override void VisitTypeConstraint(TypeConstraintSyntax node) { if (!PreVisit(node)) { return; } node.Type?.Accept(this); base.VisitTypeConstraint(node); PostVisit(node); }
private void StoreTypeConstraint(TypeConstraintSyntax asType, RDomTypeParameter newItem, SemanticModel model) { var newConstraintType = OutputContext.Corporation .Create(asType.Type, newItem, model) .FirstOrDefault() as IReferencedType; StoreConstraintWhitespace(asType, newConstraintType); if (newConstraintType != null) { newItem.ConstraintTypes.AddOrMove(newConstraintType); } }
private void StoreConstraintWhitespace(TypeConstraintSyntax syntax, IReferencedType newItem) { CreateFromWorker.StoreListMemberWhitespace(syntax, SyntaxKind.CommaToken, LanguageElement.Identifier, newItem); //var whitespace2 = newItem.Whitespace2Set[LanguageElement.Identifier]; //if (string.IsNullOrEmpty(whitespace2.LeadingWhitespace)) //{ // var prevNodeOrToken = syntax.Parent // .ChildNodesAndTokens() // .PreviousSiblings(syntax) // .LastOrDefault(); // var sepKind = SyntaxKind.CommaToken; // if (prevNodeOrToken.Kind() == sepKind) // { // var commaToken = prevNodeOrToken.AsToken(); // whitespace2.LeadingWhitespace = commaToken.TrailingTrivia.ToString(); // } //} }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); // TODO: Replace the following code with your own analysis, generating a CodeAction for each fix to suggest Diagnostic diagnostic = context.Diagnostics.First(); TextSpan diagnosticSpan = diagnostic.Location.SourceSpan; // Find the type declaration identified by the diagnostic. IEnumerable <SyntaxNode> ancestorsAndSelf = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf(); NullableTypeSyntax nullableTypeSyntax = ancestorsAndSelf.OfType <NullableTypeSyntax>().FirstOrDefault(); TypeConstraintSyntax typeConstraint = ancestorsAndSelf.OfType <TypeConstraintSyntax>().FirstOrDefault(); NullableDirectiveTriviaSyntax nullableDirective = root.FindTrivia(diagnosticSpan.Start).GetStructure() as NullableDirectiveTriviaSyntax; if (nullableTypeSyntax == null && typeConstraint == null && nullableDirective == null) { return; } // Register a code action that will invoke the fix. Func <CancellationToken, Task <Document> > fix; if (nullableTypeSyntax != null) { fix = c => AddNullableComment(context.Document, nullableTypeSyntax, c); } else if (typeConstraint != null) { fix = c => AddNullableComment(context.Document, typeConstraint, c); } else { fix = c => AddNullableComment(context.Document, nullableDirective, c); } CodeAction codeAction = CodeAction.Create(title, fix, title); context.RegisterCodeFix(codeAction, diagnostic); }
private Doc PrintTypeConstraintSyntax(TypeConstraintSyntax node) { return(this.Print(node.Type)); }
public override void VisitTypeConstraint(TypeConstraintSyntax node) { node.Type?.Accept(this); base.VisitTypeConstraint(node); }
private async Task<Document> AddNullableComment(Document document, TypeConstraintSyntax typeConstraintNode, CancellationToken cancellationToken) { var constraintClause = (TypeParameterConstraintClauseSyntax)typeConstraintNode.Parent; TypeConstraintSyntax[] otherTypeConstraints = constraintClause.ChildNodes().OfType<TypeConstraintSyntax>().Except(new[] { typeConstraintNode }).ToArray(); SyntaxNode root = await document.GetSyntaxRootAsync().ConfigureAwait(false); IdentifierNameSyntax idNameSyntax = constraintClause.ChildNodes().OfType<IdentifierNameSyntax>().First(); SyntaxToken identifierToken = typeConstraintNode.ChildNodes().First().ChildTokens().First(); TypeParameterConstraintClauseSyntax newConstraintClause; if (otherTypeConstraints.Length > 0) { // Only this type constraint must be removed, since the where clause contains others // Adding the starting comment before the type constraint SyntaxToken newIdentifierToken = SyntaxFactory.Identifier(identifierToken.LeadingTrivia.Add(SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.Start)), SyntaxKind.IdentifierName, identifierToken.Text, identifierToken.ValueText, SyntaxTriviaList.Empty); TypeConstraintSyntax newNode = typeConstraintNode.ReplaceToken(identifierToken, newIdentifierToken); // Moving the new type constraint to the first of list SeparatedSyntaxList<TypeParameterConstraintSyntax> newConstraintList = SyntaxFactory.SeparatedList<TypeParameterConstraintSyntax>(otherTypeConstraints.Prepend(newNode)); newConstraintClause = SyntaxFactory.TypeParameterConstraintClause(idNameSyntax.WithLeadingTrivia(SyntaxFactory.Space)).WithConstraints(newConstraintList); // Adding the end type constraint after the first comma. SyntaxToken firstCommaToken = newConstraintClause.ChildTokens().First(token => token.IsKind(SyntaxKind.CommaToken)); SyntaxToken newCommaToken = SyntaxFactory.Token(firstCommaToken.LeadingTrivia, SyntaxKind.CommaToken, firstCommaToken.TrailingTrivia.Insert(0, SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.End))); newConstraintClause = newConstraintClause.ReplaceToken(firstCommaToken, newCommaToken); } else { // the whole where clause needs to be removed, so adding the comments before and after it. SyntaxToken oldWhereKeyword = constraintClause.ChildTokens().First(it => it.IsKind(SyntaxKind.WhereKeyword)); SyntaxToken newWhereKeyword = SyntaxFactory.Token(oldWhereKeyword.LeadingTrivia.Add(SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.Start)), SyntaxKind.WhereKeyword, oldWhereKeyword.TrailingTrivia); SyntaxToken newIdentifierToken = SyntaxFactory.Identifier(identifierToken.LeadingTrivia, SyntaxKind.IdentifierName, identifierToken.Text, identifierToken.ValueText, identifierToken.TrailingTrivia.Insert(0, SyntaxFactory.Comment(NullableReferenceTypeAnalyzer.NullableSyntaxMarker.End))); TypeConstraintSyntax newNode = typeConstraintNode.ReplaceToken(identifierToken, newIdentifierToken); newConstraintClause = SyntaxFactory.TypeParameterConstraintClause(newWhereKeyword, constraintClause.ChildNodes().OfType<IdentifierNameSyntax>().First(), constraintClause.ChildTokens().First(it => it.IsKind(SyntaxKind.ColonToken)), SyntaxFactory.SeparatedList<TypeParameterConstraintSyntax>(new[] { newNode })); } // for some reason Roslyn adds formatting annotations that results in some strange new lines being added // by formatter later in internal CleanupDocumentAsync method of CodeAction class. newConstraintClause = RemoveAnnotationFromDescendantTrivias(newConstraintClause, SyntaxAnnotation.ElasticAnnotation); SyntaxNode newRoot = root.ReplaceNode(constraintClause, newConstraintClause); Document result = document.WithSyntaxRoot(newRoot); return result; }
/// <summary> /// Returns true if the type is a valid constraint type. /// Otherwise returns false and generates a diagnostic. /// </summary> private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbol type, DiagnosticBag diagnostics) { switch (type.SpecialType) { case SpecialType.System_Object: case SpecialType.System_ValueType: case SpecialType.System_Enum: case SpecialType.System_Delegate: case SpecialType.System_MulticastDelegate: case SpecialType.System_Array: // "Constraint cannot be special class '{0}'" Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, type); return(false); } switch (type.TypeKind) { case TypeKind.Error: case TypeKind.TypeParameter: return(true); case TypeKind.Interface: break; case TypeKind.DynamicType: // "Constraint cannot be the dynamic type" Error(diagnostics, ErrorCode.ERR_DynamicTypeAsBound, syntax); return(false); case TypeKind.Class: if (type.IsSealed) { goto case TypeKind.Struct; } else if (type.IsStatic) { // "'{0}': static classes cannot be used as constraints" Error(diagnostics, ErrorCode.ERR_ConstraintIsStaticClass, syntax, type); return(false); } break; case TypeKind.Delegate: case TypeKind.Enum: case TypeKind.Struct: // "'{0}' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter." Error(diagnostics, ErrorCode.ERR_BadBoundType, syntax, type); return(false); case TypeKind.ArrayType: case TypeKind.PointerType: // CS0706 already reported by parser. return(false); case TypeKind.Submission: // script class is synthetized, never used as a constraint default: Debug.Assert(false, "Unexpected type kind: " + type.TypeKind); return(false); } if (type.ContainsDynamic()) { // "Constraint cannot be a dynamic type '{0}'" Error(diagnostics, ErrorCode.ERR_ConstructedDynamicTypeAsBound, syntax, type); return(false); } return(true); }
public override void VisitTypeConstraint(TypeConstraintSyntax node) { }
//public override void VisitTupleExpression(TupleExpressionSyntax node) //{ // base.VisitTupleExpression(node); //} //public override void VisitTupleType(TupleTypeSyntax node) //{ // base.VisitTupleType(node); //} //public override void VisitTypeArgumentList(TypeArgumentListSyntax node) //{ // base.VisitTypeArgumentList(node); //} public override void VisitTypeConstraint(TypeConstraintSyntax node) { Debug.Fail(node.ToString()); base.VisitTypeConstraint(node); }
/// <summary> /// Returns true if the constraint is valid. Otherwise /// returns false and generates a diagnostic. /// </summary> internal static bool IsValidConstraint( string typeParameterName, TypeConstraintSyntax syntax, TypeSymbolWithAnnotations type, TypeParameterConstraintKind constraints, ArrayBuilder <TypeSymbolWithAnnotations> constraintTypes, DiagnosticBag diagnostics) { if (!IsValidConstraintType(syntax, type, diagnostics)) { return(false); } // Ignore nullability when comparing constraints. if (constraintTypes.Contains(c => type.Equals(c, TypeCompareKind.IgnoreNullableModifiersForReferenceTypes))) { // "Duplicate constraint '{0}' for type parameter '{1}'" Error(diagnostics, ErrorCode.ERR_DuplicateBound, syntax, type.TypeSymbol.SetUnknownNullabilityForReferenceTypes(), typeParameterName); return(false); } if (type.TypeKind == TypeKind.Class) { // If there is already a struct or class constraint (class constraint could be // 'class' or explicit type), report an error and drop this class. If we don't // drop this additional class, we may end up with conflicting class constraints. if (constraintTypes.Count > 0) { // "The class type constraint '{0}' must come before any other constraints" Error(diagnostics, ErrorCode.ERR_ClassBoundNotFirst, syntax, type.TypeSymbol); return(false); } if ((constraints & (TypeParameterConstraintKind.ReferenceType)) != 0) { switch (type.SpecialType) { case SpecialType.System_Enum: case SpecialType.System_Delegate: case SpecialType.System_MulticastDelegate: break; default: // "'{0}': cannot specify both a constraint class and the 'class' or 'struct' constraint" Error(diagnostics, ErrorCode.ERR_RefValBoundWithClass, syntax, type.TypeSymbol); return(false); } } else if (type.SpecialType != SpecialType.System_Enum) { if ((constraints & TypeParameterConstraintKind.ValueType) != 0) { // "'{0}': cannot specify both a constraint class and the 'class' or 'struct' constraint" Error(diagnostics, ErrorCode.ERR_RefValBoundWithClass, syntax, type.TypeSymbol); return(false); } else if ((constraints & TypeParameterConstraintKind.Unmanaged) != 0) { // "'{0}': cannot specify both a constraint class and the 'unmanaged' constraint" Error(diagnostics, ErrorCode.ERR_UnmanagedBoundWithClass, syntax, type.TypeSymbol); return(false); } } } return(true); }
public TypeConstraintTranslation(TypeConstraintSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { Type = syntax.Type.Get<TypeTranslation>(this); }
public void VisitTypeConstraint(TypeConstraintSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); node.Type.Accept(this); }
public override SyntaxNode VisitTypeConstraint(TypeConstraintSyntax node) { node = (TypeConstraintSyntax)base.VisitTypeConstraint(node); Classes.Add(node); return(node); }
public TameTypeConstraintSyntax(TypeConstraintSyntax node) { Node = node; AddChildren(); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitTypeConstraint(TypeConstraintSyntax node) { this.OnNodeVisited(node, this.type.IsInstanceOfType(node)); base.VisitTypeConstraint(node); }
/// <summary> /// /// </summary> /// <param name="node"></param> public override sealed void VisitTypeConstraint(TypeConstraintSyntax node) { this.OnNodeVisited(node); if (!this.traverseRootOnly) base.VisitTypeConstraint(node); }
public TypeConstraintTranslation(TypeConstraintSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { Type = syntax.Type.Get <TypeTranslation>(this); }
public override SyntaxNode VisitTypeConstraint(TypeConstraintSyntax node) => Expand(node);
/// <summary> /// Returns true if the type is a valid constraint type. /// Otherwise returns false and generates a diagnostic. /// </summary> private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbolWithAnnotations typeWithAnnotations, DiagnosticBag diagnostics) { TypeSymbol type = typeWithAnnotations.TypeSymbol; switch (type.SpecialType) { case SpecialType.System_Enum: CheckFeatureAvailability(syntax, MessageID.IDS_FeatureEnumGenericTypeConstraint, diagnostics); break; case SpecialType.System_Delegate: case SpecialType.System_MulticastDelegate: CheckFeatureAvailability(syntax, MessageID.IDS_FeatureDelegateGenericTypeConstraint, diagnostics); break; case SpecialType.System_Object: if (typeWithAnnotations.NullableAnnotation == NullableAnnotation.Annotated) { // "Constraint cannot be special class '{0}'" Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, typeWithAnnotations); return(false); } CheckFeatureAvailability(syntax, MessageID.IDS_FeatureObjectGenericTypeConstraint, diagnostics); break; case SpecialType.core_Array_T: // "Constraint cannot be special class '{0}'" Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, type); return(false); } switch (type.TypeKind) { case TypeKind.Error: case TypeKind.TypeParameter: return(true); case TypeKind.Interface: break; case TypeKind.Class: if (type.IsSealed) { goto case TypeKind.Struct; } else if (type.IsStatic) { // "'{0}': static classes cannot be used as constraints" Error(diagnostics, ErrorCode.ERR_ConstraintIsStaticClass, syntax, type); return(false); } break; case TypeKind.Delegate: case TypeKind.Enum: case TypeKind.Struct: if (!(syntax is ConstConstraintSyntax)) { // "'{0}' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter." Error(diagnostics, ErrorCode.ERR_BadBoundType, syntax, type); return(false); } break; case TypeKind.Array: case TypeKind.Pointer: // CS0706 already reported by parser. return(false); case TypeKind.Submission: // script class is synthesized, never used as a constraint default: throw ExceptionUtilities.UnexpectedValue(type.TypeKind); } return(true); }
public override void VisitTypeConstraint(TypeConstraintSyntax node) { // skip }
public override void VisitTypeConstraint(TypeConstraintSyntax node) { AddDependentType(node.Type); base.VisitTypeConstraint(node); }
/// <summary> /// Returns true if the type is a valid constraint type. /// Otherwise returns false and generates a diagnostic. /// </summary> private static bool IsValidConstraintType(TypeConstraintSyntax syntax, TypeSymbol type, DiagnosticBag diagnostics) { switch (type.SpecialType) { case SpecialType.System_Object: case SpecialType.System_ValueType: case SpecialType.System_Enum: case SpecialType.System_Delegate: case SpecialType.System_MulticastDelegate: case SpecialType.System_Array: // "Constraint cannot be special class '{0}'" Error(diagnostics, ErrorCode.ERR_SpecialTypeAsBound, syntax, type); return false; } switch (type.TypeKind) { case TypeKind.Error: case TypeKind.TypeParameter: return true; case TypeKind.Interface: break; case TypeKind.DynamicType: // "Constraint cannot be the dynamic type" Error(diagnostics, ErrorCode.ERR_DynamicTypeAsBound, syntax); return false; case TypeKind.Class: if (type.IsSealed) { goto case TypeKind.Struct; } else if (type.IsStatic) { // "'{0}': static classes cannot be used as constraints" Error(diagnostics, ErrorCode.ERR_ConstraintIsStaticClass, syntax, type); return false; } break; case TypeKind.Delegate: case TypeKind.Enum: case TypeKind.Struct: // "'{0}' is not a valid constraint. A type used as a constraint must be an interface, a non-sealed class or a type parameter." Error(diagnostics, ErrorCode.ERR_BadBoundType, syntax, type); return false; case TypeKind.ArrayType: case TypeKind.PointerType: // CS0706 already reported by parser. return false; case TypeKind.Submission: // script class is synthetized, never used as a constraint default: Debug.Assert(false, "Unexpected type kind: " + type.TypeKind); return false; } if (type.ContainsDynamic()) { // "Constraint cannot be a dynamic type '{0}'" Error(diagnostics, ErrorCode.ERR_ConstructedDynamicTypeAsBound, syntax, type); return false; } return true; }
public static Doc Print(TypeConstraintSyntax node) { return(Node.Print(node.Type)); }
public override void VisitTypeConstraint(TypeConstraintSyntax node) { throw new NotImplementedException(); }
public override Evaluation VisitTypeConstraint(TypeConstraintSyntax node) { node.Type?.Accept <Evaluation>(this); return(base.VisitTypeConstraint(node)); }
// // Summary: // Called when the visitor visits a TypeConstraintSyntax node. public virtual void VisitTypeConstraint(TypeConstraintSyntax node);