private static async Task <Document> RefactorAsync( Document document, SyntaxNode node, ConstraintKind constraintKind, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); TypeParameterConstraintSyntax constraint = CreateConstraint(constraintKind); SyntaxNode newNode = node; switch (node.Kind()) { case SyntaxKind.MethodDeclaration: { newNode = GetNewNode((MethodDeclarationSyntax)node, constraint, semanticModel, cancellationToken); break; } case SyntaxKind.ClassDeclaration: { newNode = GetNewNode((ClassDeclarationSyntax)node, constraint, semanticModel); break; } case SyntaxKind.RecordDeclaration: case SyntaxKind.RecordStructDeclaration: { newNode = GetNewNode((RecordDeclarationSyntax)node, constraint, semanticModel); break; } case SyntaxKind.StructDeclaration: { newNode = GetNewNode((StructDeclarationSyntax)node, constraint, semanticModel); break; } case SyntaxKind.InterfaceDeclaration: { newNode = GetNewNode((InterfaceDeclarationSyntax)node, constraint, semanticModel); break; } case SyntaxKind.DelegateDeclaration: { newNode = GetNewNode((DelegateDeclarationSyntax)node, constraint, semanticModel); break; } case SyntaxKind.LocalFunctionStatement: { newNode = GetNewNode((LocalFunctionStatementSyntax)node, constraint, semanticModel, cancellationToken); break; } } return(await document.ReplaceNodeAsync(node, newNode, cancellationToken).ConfigureAwait(false)); }
internal static TypeParameterConstraintInfo Create( TypeParameterConstraintSyntax constraint, bool allowMissing = false) { if (!(constraint?.Parent is TypeParameterConstraintClauseSyntax constraintClause)) { return(default);
private TypeParameterConstraintInfo( TypeParameterConstraintSyntax constraint, TypeParameterConstraintClauseSyntax constraintClause) { Constraint = constraint; ConstraintClause = constraintClause; }
private static SyntaxNode GetNewNode( DelegateDeclarationSyntax delegateDeclaration, TypeParameterConstraintSyntax constraint, SemanticModel semanticModel, CancellationToken cancellationToken) { TypeParameterListSyntax typeParameterList = delegateDeclaration.TypeParameterList; INamedTypeSymbol delegateSymbol = semanticModel.GetDeclaredSymbol(delegateDeclaration, cancellationToken); int position = (typeParameterList != null) ? typeParameterList.SpanStart : delegateDeclaration.Identifier.SpanStart; string name = GetTypeParameterName(position, semanticModel); DelegateDeclarationSyntax newNode = delegateDeclaration.AddTypeParameterListParameters(TypeParameter(Identifier(name).WithRenameAnnotation())); if (constraint != null) { newNode = newNode.AddConstraintClauses(TypeParameterConstraintClause(name, constraint)); } return(newNode); }
private void MoveConstraint( CodeFixContext context, Diagnostic diagnostic, TypeParameterConstraintSyntax constraint, SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints, int index) { CodeAction codeAction = CodeAction.Create( $"Move constraint '{constraint}'", cancellationToken => { var constraintClause = (TypeParameterConstraintClauseSyntax)constraint.Parent; SeparatedSyntaxList <TypeParameterConstraintSyntax> newConstraints = constraints.Remove(constraint).Insert(index, constraint); TypeParameterConstraintClauseSyntax newNode = constraintClause .WithConstraints(newConstraints) .WithFormatterAnnotation(); return(context.Document.ReplaceNodeAsync(constraintClause, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); }
private static bool IsDuplicateConstraint(TypeParameterConstraintSyntax constraint, SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints) { int index = constraints.IndexOf(constraint); SyntaxKind kind = constraint.Kind(); switch (kind) { case SyntaxKind.ClassConstraint: case SyntaxKind.StructConstraint: { for (int i = 0; i < index; i++) { if (constraints[i].Kind() == kind) { return(true); } } break; } } return(false); }
private void RemoveConstraint( CodeFixContext context, Diagnostic diagnostic, TypeParameterConstraintSyntax constraint) { CodeAction codeAction = CodeAction.Create( $"Remove constraint '{constraint}'", ct => context.Document.RemoveNodeAsync(constraint, ct), GetEquivalenceKey(diagnostic, constraint.Kind().ToString())); context.RegisterCodeFix(codeAction, diagnostic); }
// Private Methods private static ConstraintInfo Convert2(TypeParameterConstraintSyntax src, LangParseContext context) { if (src is ConstructorConstraintSyntax) { return new ConstraintInfo { Kind = ConstraintKind.ParameterlessConstructor } } ; throw new NotSupportedException(src.GetType().ToString()); }
static void reportOverrideWithConstraints( ref bool reportedOverrideWithConstraints, TypeParameterConstraintSyntax syntax, BindingDiagnosticBag diagnostics ) { if (!reportedOverrideWithConstraints) { diagnostics.Add(ErrorCode.ERR_OverrideWithConstraints, syntax.GetLocation()); reportedOverrideWithConstraints = true; } }
private static void RemoveConstraint( CodeFixContext context, Diagnostic diagnostic, TypeParameterConstraintSyntax constraint) { CodeAction codeAction = CodeAction.Create( $"Remove constraint '{constraint}'", cancellationToken => context.Document.RemoveNodeAsync(constraint, RemoveHelper.GetRemoveOptions(constraint), cancellationToken), GetEquivalenceKey(diagnostic, constraint.Kind().ToString())); context.RegisterCodeFix(codeAction, diagnostic); }
public static bool TryGetContainingList(TypeParameterConstraintSyntax constraint, out SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints) { if (constraint.IsParentKind(SyntaxKind.TypeParameterConstraintClause)) { var constraintClause = (TypeParameterConstraintClauseSyntax)constraint.Parent; constraints = constraintClause.Constraints; return(true); } constraints = default(SeparatedSyntaxList <TypeParameterConstraintSyntax>); return(false); }
private TypeParameterConstraintInfo( TypeParameterConstraintSyntax constraint, TypeParameterConstraintClauseSyntax constraintClause, SyntaxNode declaration, TypeParameterListSyntax typeParameterList, SyntaxList <TypeParameterConstraintClauseSyntax> constraintClauses) { Constraint = constraint; ConstraintClause = constraintClause; Declaration = declaration; TypeParameterList = typeParameterList; ConstraintClauses = constraintClauses; }
public static bool IsEnumerator(this TypeParameterConstraintSyntax typeParameterConstraintSyntax, SyntaxNodeAnalysisContext context) { if (typeParameterConstraintSyntax is TypeConstraintSyntax typeConstraintSyntax) { var typeSymbol = context.SemanticModel.GetTypeInfo(typeConstraintSyntax.Type).Type; if (typeSymbol is object && (typeSymbol.IsEnumerator(context.Compilation, out _) || typeSymbol.IsAsyncEnumerator(context.Compilation, out _))) { return(true); } } return(false); }
private static SyntaxNode GetNewNode( StructDeclarationSyntax structDeclaration, TypeParameterConstraintSyntax typeParameterConstraint, SemanticModel semanticModel) { string name = GetTypeParameterName(structDeclaration.OpenBraceToken.SpanStart, semanticModel); StructDeclarationSyntax newNode = structDeclaration.AddTypeParameterListParameters(TypeParameter(Identifier(name).WithRenameAnnotation())); if (typeParameterConstraint != null) { newNode = newNode.AddConstraintClauses(TypeParameterConstraintClause(name, typeParameterConstraint)); } return(newNode); }
private static InterfaceDeclarationSyntax GetNewNode( InterfaceDeclarationSyntax interfaceDeclaration, TypeParameterConstraintSyntax constraint, SemanticModel semanticModel) { string name = GetTypeParameterName(interfaceDeclaration.OpenBraceToken.SpanStart, semanticModel); InterfaceDeclarationSyntax newNode = interfaceDeclaration.AddTypeParameterListParameters(TypeParameter(Identifier(name).WithRenameAnnotation())); if (constraint != null) { newNode = newNode.AddConstraintClauses(TypeParameterConstraintClause(name, constraint)); } return(newNode); }
private static LocalFunctionStatementSyntax GetNewNode( LocalFunctionStatementSyntax localFunctionStatement, TypeParameterConstraintSyntax constraint, SemanticModel semanticModel, CancellationToken cancellationToken) { string name = GetMethodTypeParameterName(semanticModel, localFunctionStatement.BodyOrExpressionBody().SpanStart, cancellationToken); LocalFunctionStatementSyntax newNode = localFunctionStatement.AddTypeParameterListParameters(TypeParameter(Identifier(name).WithRenameAnnotation())); if (constraint != null) { newNode = newNode.AddConstraintClauses(TypeParameterConstraintClause(name, constraint)); } return(newNode); }
private void RemoveConstraint( CodeFixContext context, Diagnostic diagnostic, TypeParameterConstraintSyntax constraint) { SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints; if (GenericDeclarationHelper.TryGetContainingList(constraint, out constraints)) { CodeAction codeAction = CodeAction.Create( $"Remove constraint '{constraint}'", cancellationToken => context.Document.RemoveNodeAsync(constraint, RemoveHelper.GetRemoveOptions(constraint), cancellationToken), GetEquivalenceKey(diagnostic, constraint.Kind().ToString())); context.RegisterCodeFix(codeAction, diagnostic); } }
private static RecordDeclarationSyntax GetNewNode( RecordDeclarationSyntax recordDeclaration, TypeParameterConstraintSyntax constraint, SemanticModel semanticModel) { int position = (recordDeclaration.OpenBraceToken != default) ? recordDeclaration.OpenBraceToken.SpanStart : recordDeclaration.SemicolonToken.SpanStart; string name = GetTypeParameterName(position, semanticModel); RecordDeclarationSyntax newNode = recordDeclaration.AddTypeParameterListParameters(TypeParameter(Identifier(name).WithRenameAnnotation())); if (constraint != null) { newNode = newNode.AddConstraintClauses(TypeParameterConstraintClause(name, constraint)); } return(newNode); }
private static SyntaxNode GetNewNode( MethodDeclarationSyntax methodDeclaration, TypeParameterConstraintSyntax constraint, SemanticModel semanticModel, CancellationToken cancellationToken) { TypeParameterListSyntax typeParameterList = methodDeclaration.TypeParameterList; IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); string name = GetMethodTypeParameterName(semanticModel, methodDeclaration.BodyOrExpressionBody().SpanStart, cancellationToken); MethodDeclarationSyntax newNode = methodDeclaration.AddTypeParameterListParameters(TypeParameter(Identifier(name).WithRenameAnnotation())); if (constraint != null) { newNode = newNode.AddConstraintClauses(TypeParameterConstraintClause(name, constraint)); } return(newNode); }
private static SyntaxNode GetNewNode( InterfaceDeclarationSyntax interfaceDeclaration, TypeParameterConstraintSyntax constraint, SemanticModel semanticModel, CancellationToken cancellationToken) { TypeParameterListSyntax typeParameterList = interfaceDeclaration.TypeParameterList; INamedTypeSymbol interfaceSymbol = semanticModel.GetDeclaredSymbol(interfaceDeclaration, cancellationToken); string name = GetTypeParameterName(interfaceDeclaration.OpenBraceToken.SpanStart, semanticModel); InterfaceDeclarationSyntax newNode = interfaceDeclaration.AddTypeParameterListParameters(TypeParameter(Identifier(name).WithRenameAnnotation())); if (constraint != null) { newNode = newNode.AddConstraintClauses(TypeParameterConstraintClause(name, constraint)); } return(newNode); }
private static string TransformTypeConstraint(TypeParameterConstraintSyntax constraint) { if (constraint is TypeConstraintSyntax) { return(" <% " + TypeProcessor.ConvertType(constraint.As <TypeConstraintSyntax>().Type)); } else if (constraint is ClassOrStructConstraintSyntax) { if (constraint.As <ClassOrStructConstraintSyntax>().ClassOrStructKeyword.Kind() == SyntaxKind.ClassKeyword) { return(" >: Null"); } else { throw new Exception("struct type constraint not supported " + Utility.Descriptor(constraint)); } } else { throw new Exception(constraint.GetType().Name); } }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsAnyCodeFixEnabled( CodeFixIdentifiers.RemoveConstraint, CodeFixIdentifiers.MoveConstraint)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out TypeParameterConstraintSyntax constraint)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.NewConstraintMustBeLastConstraintSpecified: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.MoveConstraint)) { break; } SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints; if (GenericDeclarationHelper.TryGetContainingList(constraint, out constraints)) { MoveConstraint(context, diagnostic, constraint, constraints, constraints.Count - 1); } break; } case CompilerDiagnosticIdentifiers.DuplicateConstraintForTypeParameter: { if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstraint)) { RemoveConstraint(context, diagnostic, constraint); } break; } case CompilerDiagnosticIdentifiers.ClassOrStructConstraintMustComeBeforeAnyOtherConstraints: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.MoveConstraint)) { break; } SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints; if (GenericDeclarationHelper.TryGetContainingList(constraint, out constraints)) { if (IsDuplicateConstraint(constraint, constraints)) { RemoveConstraint(context, diagnostic, constraint); } else { MoveConstraint(context, diagnostic, constraint, constraints, 0); } } break; } case CompilerDiagnosticIdentifiers.CannotSpecifyBothConstraintClassAndClassOrStructConstraint: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstraint)) { break; } RemoveConstraint(context, diagnostic, constraint); SeparatedSyntaxList <TypeParameterConstraintSyntax> constraintClauses; if (GenericDeclarationHelper.TryGetContainingList(constraint, out constraintClauses)) { TypeParameterConstraintSyntax classConstraint = constraintClauses.Find(SyntaxKind.ClassConstraint); if (classConstraint != null) { RemoveConstraint(context, diagnostic, classConstraint); } TypeParameterConstraintSyntax structConstraint = constraintClauses.Find(SyntaxKind.StructConstraint); if (structConstraint != null) { RemoveConstraint(context, diagnostic, structConstraint); } } break; } case CompilerDiagnosticIdentifiers.NewConstraintCannotBeUsedWithStructConstraint: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstraint)) { break; } RemoveConstraint(context, diagnostic, constraint); SeparatedSyntaxList <TypeParameterConstraintSyntax> constraintClauses; if (GenericDeclarationHelper.TryGetContainingList(constraint, out constraintClauses)) { TypeParameterConstraintSyntax structConstraint = constraintClauses.Find(SyntaxKind.StructConstraint); RemoveConstraint(context, diagnostic, structConstraint); } break; } } } }
public TameTypeParameterConstraintSyntax(TypeParameterConstraintSyntax node) { Node = node; AddChildren(); }
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindFirstAncestorOrSelf(root, context.Span, out TypeParameterConstraintSyntax constraint)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.CS0401_NewConstraintMustBeLastConstraintSpecified: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MoveConstraint, context.Document, root.SyntaxTree)) { break; } TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint); if (!constraintInfo.Success) { break; } MoveConstraint(context, diagnostic, constraintInfo, constraintInfo.Constraints.Count - 1); break; } case CompilerDiagnosticIdentifiers.CS0405_DuplicateConstraintForTypeParameter: { if (IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstraint, context.Document, root.SyntaxTree)) { RemoveConstraint(context, diagnostic, constraint); } break; } case CompilerDiagnosticIdentifiers.CS0449_ClassOrStructConstraintMustComeBeforeAnyOtherConstraints: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.MoveConstraint, context.Document, root.SyntaxTree)) { break; } TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint); if (!constraintInfo.Success) { break; } if (constraintInfo.IsDuplicateConstraint) { RemoveConstraint(context, diagnostic, constraint); } else { MoveConstraint(context, diagnostic, constraintInfo, 0); } break; } case CompilerDiagnosticIdentifiers.CS0450_CannotSpecifyBothConstraintClassAndClassOrStructConstraint: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstraint, context.Document, root.SyntaxTree)) { break; } TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint); if (!constraintInfo.Success) { break; } RemoveConstraint(context, diagnostic, constraint); TypeParameterConstraintSyntax classConstraint = constraintInfo.Constraints.Find(SyntaxKind.ClassConstraint); if (classConstraint != null) { RemoveConstraint(context, diagnostic, classConstraint); } TypeParameterConstraintSyntax structConstraint = constraintInfo.Constraints.Find(SyntaxKind.StructConstraint); if (structConstraint != null) { RemoveConstraint(context, diagnostic, structConstraint); } break; } case CompilerDiagnosticIdentifiers.CS0451_NewConstraintCannotBeUsedWithStructConstraint: { if (!IsEnabled(diagnostic.Id, CodeFixIdentifiers.RemoveConstraint, context.Document, root.SyntaxTree)) { break; } RemoveConstraint(context, diagnostic, constraint); TypeParameterConstraintInfo constraintInfo = SyntaxInfo.TypeParameterConstraintInfo(constraint); if (!constraintInfo.Success) { break; } TypeParameterConstraintSyntax structConstraint = constraintInfo.Constraints.Find(SyntaxKind.StructConstraint); RemoveConstraint(context, diagnostic, structConstraint); break; } } } }
public static SeparatedSyntaxList <TypeParameterConstraintSyntax> GetContainingList(TypeParameterConstraintSyntax constraint) { SeparatedSyntaxList <TypeParameterConstraintSyntax> constraints; if (!TryGetContainingList(constraint, out constraints)) { throw new ArgumentException("", nameof(constraint)); } return(constraints); }
public TypeParameterConstraintTranslation(TypeParameterConstraintSyntax syntax, SyntaxTranslation parent) : base(syntax, parent) { }
/// <summary> /// Creates a new <see cref="Syntax.GenericInfo"/> from the specified type parameter constraint. /// </summary> /// <param name="typeParameterConstraint"></param> /// <returns></returns> public static GenericInfo GenericInfo(TypeParameterConstraintSyntax typeParameterConstraint) { return(Syntax.GenericInfo.Create(typeParameterConstraint)); }
internal static GenericInfo Create(TypeParameterConstraintSyntax typeParameterConstraint) { return(Create(typeParameterConstraint?.Parent as TypeParameterConstraintClauseSyntax)); }
/// <summary> /// Creates a new <see cref="Syntax.TypeParameterConstraintInfo"/> from the specified constraint. /// </summary> /// <param name="constraint"></param> /// <param name="allowMissing"></param> /// <returns></returns> internal static TypeParameterConstraintInfo TypeParameterConstraintInfo(TypeParameterConstraintSyntax constraint, bool allowMissing = false) { return(Syntax.TypeParameterConstraintInfo.Create(constraint, allowMissing)); }
internal static TypeParameterConstraintInfo Create( TypeParameterConstraintSyntax constraint, bool allowMissing = false) { if (!(constraint?.Parent is TypeParameterConstraintClauseSyntax constraintClause)) { return(Default); } IdentifierNameSyntax name = constraintClause.Name; if (!Check(name, allowMissing)) { return(Default); } SyntaxNode parent = constraintClause.Parent; switch (parent?.Kind()) { case SyntaxKind.ClassDeclaration: { var classDeclaration = (ClassDeclarationSyntax)parent; TypeParameterListSyntax typeParameterList = classDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) { return(Default); } return(new TypeParameterConstraintInfo(constraint, constraintClause, classDeclaration, typeParameterList, classDeclaration.ConstraintClauses)); } case SyntaxKind.DelegateDeclaration: { var delegateDeclaration = (DelegateDeclarationSyntax)parent; TypeParameterListSyntax typeParameterList = delegateDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) { return(Default); } return(new TypeParameterConstraintInfo(constraint, constraintClause, delegateDeclaration, typeParameterList, delegateDeclaration.ConstraintClauses)); } case SyntaxKind.InterfaceDeclaration: { var interfaceDeclaration = (InterfaceDeclarationSyntax)parent; TypeParameterListSyntax typeParameterList = interfaceDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) { return(Default); } return(new TypeParameterConstraintInfo(constraint, constraintClause, interfaceDeclaration, interfaceDeclaration.TypeParameterList, interfaceDeclaration.ConstraintClauses)); } case SyntaxKind.LocalFunctionStatement: { var localFunctionStatement = (LocalFunctionStatementSyntax)parent; TypeParameterListSyntax typeParameterList = localFunctionStatement.TypeParameterList; if (!Check(typeParameterList, allowMissing)) { return(Default); } return(new TypeParameterConstraintInfo(constraint, constraintClause, localFunctionStatement, typeParameterList, localFunctionStatement.ConstraintClauses)); } case SyntaxKind.MethodDeclaration: { var methodDeclaration = (MethodDeclarationSyntax)parent; TypeParameterListSyntax typeParameterList = methodDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) { return(Default); } return(new TypeParameterConstraintInfo(constraint, constraintClause, methodDeclaration, typeParameterList, methodDeclaration.ConstraintClauses)); } case SyntaxKind.StructDeclaration: { var structDeclaration = (StructDeclarationSyntax)parent; TypeParameterListSyntax typeParameterList = structDeclaration.TypeParameterList; if (!Check(typeParameterList, allowMissing)) { return(Default); } return(new TypeParameterConstraintInfo(constraint, constraintClause, structDeclaration, typeParameterList, structDeclaration.ConstraintClauses)); } } return(Default); }
private static TypeParameterConstraintClauseSyntax AddConstraint( this TypeParameterConstraintClauseSyntax @this, TypeParameterConstraintSyntax @typeParameterConstraintSyntax) { var result = @this.Constraints .Any(x => x == @typeParameterConstraintSyntax); if (result) return @this; return @this.AddConstraints( @typeParameterConstraintSyntax); }