public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor) { Debug.Assert(symbol.Equals(symbol.ConstructedFrom)); visitor.WriteSymbolKey(symbol.ReducedFrom); visitor.WriteSymbolKey(symbol.ReceiverType); }
private SyntaxNode FixMethod( bool keepVoid, IMethodSymbol methodSymbol, MethodDeclarationSyntax method, ITypeSymbol taskType, INamedTypeSymbol taskOfTType) { var newReturnType = method.ReturnType; if (methodSymbol.ReturnsVoid) { if (!keepVoid) { newReturnType = taskType.GenerateTypeSyntax(); } } else { if (!IsTaskLike(methodSymbol.ReturnType, taskType, taskOfTType)) { // If it's not already Task-like, then wrap the existing return type // in Task<>. newReturnType = taskOfTType.Construct(methodSymbol.ReturnType).GenerateTypeSyntax(); } } var newModifiers = method.Modifiers.Add(s_asyncToken); return method.WithReturnType(newReturnType).WithModifiers(newModifiers); }
/// <summary> /// Process a method declaration for documentation. /// </summary> /// <param name="symbol">The method in question.</param> /// <returns><c>Docs</c> if the method contains any, otherwise <c>null</c>.</returns> public static Doc ForMethod(IMethodSymbol symbol) { var doc = symbol.GetDocumentationCommentXml(); if (string.IsNullOrEmpty(doc)) { return null; } var sections = new List<Tuple<int, string, string>>(); var xdoc = XDocument.Parse(doc).Root; ProcessFull(xdoc, sections); var cursor = sections.FindIndex(t => t.Item2 == "Summary"); var paramsSection = ProcessParameters(xdoc, symbol.Parameters.Select(p => p.Name).ToList()); sections.Insert(cursor + 1, paramsSection); var returnElement = xdoc.Element("returns"); if (returnElement != null) { var content = ProcessContent(returnElement); if (!string.IsNullOrEmpty(content)) { sections.Insert(cursor + 2, Tuple.Create(2, "Return value", $"<p>{content}</p>")); } } var resultString = string.Join("\n", sections.Select(t => $"<h{t.Item1 + 2}>{t.Item2}</h{t.Item1 + 2}>{t.Item3}")); return new Doc { Format = "text/html", Data = resultString }; }
private static MethodDeclarationSyntax GenerateMethodDeclarationWorker( IMethodSymbol method, CodeGenerationDestination destination, CodeGenerationOptions options) { var hasNoBody = !options.GenerateMethodBodies || destination == CodeGenerationDestination.InterfaceType || method.IsAbstract; var explicitInterfaceSpecifier = GenerateExplicitInterfaceSpecifier(method.ExplicitInterfaceImplementations); var returnType = method.ReturnsByRef ? method.ReturnType.GenerateRefTypeSyntax() : method.ReturnType.GenerateTypeSyntax(); return AddCleanupAnnotationsTo(SyntaxFactory.MethodDeclaration( attributeLists: GenerateAttributes(method, options, explicitInterfaceSpecifier != null), modifiers: GenerateModifiers(method, destination, options), returnType: returnType, explicitInterfaceSpecifier: explicitInterfaceSpecifier, identifier: method.Name.ToIdentifierToken(), typeParameterList: GenerateTypeParameterList(method, options), parameterList: ParameterGenerator.GenerateParameterList(method.Parameters, explicitInterfaceSpecifier != null, options), constraintClauses: GenerateConstraintClauses(method), body: hasNoBody ? null : StatementGenerator.GenerateBlock(method), expressionBody: default(ArrowExpressionClauseSyntax), semicolonToken: hasNoBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : new SyntaxToken())); }
private static bool IsDestructor(IMethodSymbol method) { if (method.MethodKind == MethodKind.Destructor) { return true; // for C# } if (method.Name != "Finalize" || method.Parameters.Length != 0 || !method.ReturnsVoid) { return false; } var overridden = method.OverriddenMethod; if (overridden == null) { return false; } for (var o = overridden.OverriddenMethod; o != null; o = o.OverriddenMethod) { overridden = o; } return overridden.ContainingType.SpecialType == SpecialType.System_Object; // it is object.Finalize }
private static OperatorDeclarationSyntax GenerateOperatorDeclarationWorker( IMethodSymbol method, CodeGenerationDestination destination, CodeGenerationOptions options) { var hasNoBody = !options.GenerateMethodBodies || method.IsExtern; var operatorSyntaxKind = SyntaxFacts.GetOperatorKind(method.MetadataName); if (operatorSyntaxKind == SyntaxKind.None) { throw new ArgumentException(string.Format(WorkspacesResources.Cannot_generate_code_for_unsupported_operator_0, method.Name), nameof(method)); } var operatorToken = SyntaxFactory.Token(operatorSyntaxKind); return SyntaxFactory.OperatorDeclaration( attributeLists: AttributeGenerator.GenerateAttributeLists(method.GetAttributes(), options), modifiers: GenerateModifiers(method), returnType: method.ReturnType.GenerateTypeSyntax(), operatorKeyword: SyntaxFactory.Token(SyntaxKind.OperatorKeyword), operatorToken: operatorToken, parameterList: ParameterGenerator.GenerateParameterList(method.Parameters, isExplicit: false, options: options), body: hasNoBody ? null : StatementGenerator.GenerateBlock(method), semicolonToken: hasNoBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : new SyntaxToken()); }
private IEnumerable<SignatureHelpParameter> GetDelegateTypeParameters(IMethodSymbol invokeMethod, SemanticModel semanticModel, int position, CancellationToken cancellationToken) { const string TargetName = "target"; var parts = new List<SymbolDisplayPart>(); parts.AddRange(invokeMethod.ReturnType.ToMinimalDisplayParts(semanticModel, position)); parts.Add(Space()); parts.Add(Punctuation(SyntaxKind.OpenParenToken)); var first = true; foreach (var parameter in invokeMethod.Parameters) { if (!first) { parts.Add(Punctuation(SyntaxKind.CommaToken)); parts.Add(Space()); } first = false; parts.AddRange(parameter.Type.ToMinimalDisplayParts(semanticModel, position)); } parts.Add(Punctuation(SyntaxKind.CloseParenToken)); parts.Add(Space()); parts.Add(new SymbolDisplayPart(SymbolDisplayPartKind.ParameterName, null, TargetName)); yield return new SignatureHelpParameter( TargetName, isOptional: false, documentationFactory: null, displayParts: parts); }
private static ConversionOperatorDeclarationSyntax GenerateConversionDeclarationWorker( IMethodSymbol method, CodeGenerationDestination destination, CodeGenerationOptions options) { var hasNoBody = !options.GenerateMethodBodies || method.IsExtern; var reusableSyntax = GetReuseableSyntaxNodeForSymbol<ConversionOperatorDeclarationSyntax>(method, options); if (reusableSyntax != null) { return reusableSyntax; } var operatorToken = SyntaxFactory.Token(SyntaxFacts.GetOperatorKind(method.MetadataName)); var keyword = method.MetadataName == WellKnownMemberNames.ImplicitConversionName ? SyntaxFactory.Token(SyntaxKind.ImplicitKeyword) : SyntaxFactory.Token(SyntaxKind.ExplicitKeyword); return SyntaxFactory.ConversionOperatorDeclaration( attributeLists: AttributeGenerator.GenerateAttributeLists(method.GetAttributes(), options), modifiers: GenerateModifiers(method), implicitOrExplicitKeyword: keyword, operatorKeyword: SyntaxFactory.Token(SyntaxKind.OperatorKeyword), type: method.ReturnType.GenerateTypeSyntax(), parameterList: ParameterGenerator.GenerateParameterList(method.Parameters, isExplicit: false, options: options), body: hasNoBody ? null : StatementGenerator.GenerateBlock(method), semicolonToken: hasNoBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : new SyntaxToken()); }
/// <summary> /// Is this a method on <see cref="Enumerable" /> which takes only a single parameter? /// </summary> /// <remarks> /// Many of the methods we target, like Last, have overloads that take a filter delegate. It is /// completely appropriate to use such methods even with <see cref="IReadOnlyList{T}" />. Only the single parameter /// ones are suspect /// </remarks> private static bool IsSingleParameterLinqMethod(IMethodSymbol methodSymbol, ITypeSymbol enumerableType) { Debug.Assert(methodSymbol.ReducedFrom == null); return methodSymbol.ContainingSymbol.Equals(enumerableType) && methodSymbol.Parameters.Length == 1; }
protected static bool IsAcceptableOverload(IMethodSymbol methodSymbol, SemanticModel model) { var stringComparisonType = WellKnownTypes.StringComparison(model.Compilation); return methodSymbol.IsStatic ? IsAcceptableStaticOverload(methodSymbol, stringComparisonType) : IsAcceptableInstanceOverload(methodSymbol, stringComparisonType); }
private static bool IsMethodCandidate(IMethodSymbol methodSymbol, Compilation compilation) { return methodSymbol.IsAsync && methodSymbol.ReturnsVoid && methodSymbol.IsChangeable() && !methodSymbol.IsProbablyEventHandler(compilation); }
public UnusedParametersAnalyzer(IMethodSymbol method) { // Initialization: Assume all parameters are unused. var parameters = method.Parameters.Where(p => !p.IsImplicitlyDeclared && p.Locations.Length > 0); _unusedParameters = new HashSet<IParameterSymbol>(parameters); _unusedParameterNames = new HashSet<string>(parameters.Select(p => p.Name)); }
/// <summary> /// Returns a list of method symbols from a given list of the method symbols, which has its parameter type as /// expectedParameterType as its last parameter in addition to matching all the other parameter types of the /// selectedOverload method symbol /// </summary> /// <param name="methods">List of <see cref="IMethodSymbol"/> to scan for possible overloads</param> /// <param name="selectedOverload"><see cref="IMethodSymbol"/> that is currently picked by the user</param> /// <param name="expectedTrailingParameterType"><see cref="INamedTypeSymbol"/> type of the leading parameter or the trailing parameter</param> public static IEnumerable<IMethodSymbol> GetMethodOverloadsWithDesiredParameterAtTrailing( this IEnumerable<IMethodSymbol> methods, IMethodSymbol selectedOverload, INamedTypeSymbol expectedTrailingParameterType) { return GetMethodOverloadsWithDesiredParameterAtLeadingOrTrailing(methods, selectedOverload, expectedTrailingParameterType, trailingOnly: true); }
private static string ExpandedMethodName(IMethodSymbol method) { var ret = new StringBuilder(20); ret.Append(method.Name); ret.Append("_"); foreach (var param in method.Parameters) { ret.Append(param.Type.Name); var named = param.Type as INamedTypeSymbol; if (named != null) { foreach (var typeArg in named.TypeArguments) { if (typeArg.TypeKind != TypeKind.TypeParameter) ret.Append(typeArg.Name); } } ret.Append("_"); } ret.Remove(ret.Length - 1, 1); return ret.ToString(); }
private static bool ParameterTypesMatch(SemanticDocument document, IList<ITypeSymbol> parameterTypes, IMethodSymbol method) { if (method == null) { return false; } if (parameterTypes.Count < method.Parameters.Length) { return false; } var compilation = document.SemanticModel.Compilation; var semanticFactsService = document.Document.GetLanguageService<ISemanticFactsService>(); for (var i = 0; i < parameterTypes.Count; i++) { var type1 = parameterTypes[i]; if (type1 != null) { var type2 = method.Parameters[i].Type; if (!semanticFactsService.IsAssignableTo(type1, type2, compilation)) { return false; } } } return true; }
internal static ConstructorDeclarationSyntax GenerateConstructorDeclaration( IMethodSymbol constructor, CodeGenerationDestination destination, CodeGenerationOptions options) { options = options ?? CodeGenerationOptions.Default; var reusableSyntax = GetReuseableSyntaxNodeForSymbol<ConstructorDeclarationSyntax>(constructor, options); if (reusableSyntax != null) { return reusableSyntax; } bool hasNoBody = !options.GenerateMethodBodies; var declaration = SyntaxFactory.ConstructorDeclaration( attributeLists: AttributeGenerator.GenerateAttributeLists(constructor.GetAttributes(), options), modifiers: GenerateModifiers(constructor, options), identifier: CodeGenerationConstructorInfo.GetTypeName(constructor).ToIdentifierToken(), parameterList: ParameterGenerator.GenerateParameterList(constructor.Parameters, isExplicit: false, options: options), initializer: GenerateConstructorInitializer(constructor), body: hasNoBody ? null : GenerateBlock(constructor), semicolonToken: hasNoBody ? SyntaxFactory.Token(SyntaxKind.SemicolonToken) : default(SyntaxToken)); return AddCleanupAnnotationsTo( ConditionallyAddDocumentationCommentTo(declaration, constructor, options)); }
internal static IPropertySymbol CreatePropertySymbol( INamedTypeSymbol containingType, IList<AttributeData> attributes, Accessibility accessibility, DeclarationModifiers modifiers, ITypeSymbol type, IPropertySymbol explicitInterfaceSymbol, string name, IList<IParameterSymbol> parameters, IMethodSymbol getMethod, IMethodSymbol setMethod, bool isIndexer = false, SyntaxNode initializer = null) { var result = new CodeGenerationPropertySymbol( containingType, attributes, accessibility, modifiers, type, explicitInterfaceSymbol, name, isIndexer, parameters, getMethod, setMethod); CodeGenerationPropertyInfo.Attach(result, modifiers.IsNew, modifiers.IsUnsafe, initializer); return result; }
private async Task<Solution> RenameThenRemoveAsyncTokenAsync(Document document, SyntaxNode node, IMethodSymbol methodSymbol, CancellationToken cancellationToken) { var name = methodSymbol.Name; var newName = name.Substring(0, name.Length - AsyncSuffix.Length); var solution = document.Project.Solution; var options = solution.Workspace.Options; // Store the path to this node. That way we can find it post rename. var syntaxPath = new SyntaxPath(node); // Rename the method to remove the 'Async' suffix, then remove the 'async' keyword. var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, newName, options, cancellationToken).ConfigureAwait(false); var newDocument = newSolution.GetDocument(document.Id); var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); SyntaxNode newNode; if (syntaxPath.TryResolve<SyntaxNode>(newRoot, out newNode)) { var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken); return await RemoveAsyncTokenAsync(newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false); } return newSolution; }
public static ChangeType CompareTo(this IMethodSymbol symbol, IMethodSymbol comparedTo) { if (symbol == null) return ChangeType.Added; if (comparedTo == null) return ChangeType.Deleted; if (symbol.ReturnType != comparedTo.ReturnType) return ChangeType.Rewritten; if (symbol.DeclaredAccessibility != comparedTo.DeclaredAccessibility) return ChangeType.Rewritten; if (symbol.Parameters.Count != comparedTo.Parameters.Count) return ChangeType.Rewritten; for (var index = 0; index < symbol.Parameters.Count; index++) { if (symbol.Parameters.ElementAt(index).Type == symbol.Parameters.ElementAt(index).Type) return ChangeType.Rewritten; } return ChangeType.None; }
private void RenderMethodSymbol(IMethodSymbol methodSymbol) { var nonInferredTypeArguments = NonInferredTypeArguments(methodSymbol); _sb.Append(methodSymbol.Name); if (nonInferredTypeArguments.Any()) { _sb.Append("<"); var last = nonInferredTypeArguments.Last(); foreach (var arg in nonInferredTypeArguments) { RenderSnippetStartMarker(); _sb.Append(arg); RenderSnippetEndMarker(); if (arg != last) { _sb.Append(", "); } } _sb.Append(">"); } RenderParameters(methodSymbol); if (methodSymbol.ReturnsVoid && IncludeMarkers) { _sb.Append(";"); } }
public override IParameterSymbol GetThisParameter(IMethodSymbol method) { ParameterSymbol thisParameter; return ((MethodSymbol)method).TryGetThisParameter(out thisParameter) ? thisParameter : null; }
public static bool TryGetParameterSymbol(ArgumentSyntax argument, ArgumentListSyntax argumentList, IMethodSymbol method, out IParameterSymbol parameter) { parameter = null; if (!argumentList.Arguments.Contains(argument) || method == null || method.IsVararg) { return false; } if (argument.NameColon != null) { parameter = method.Parameters .FirstOrDefault(symbol => symbol.Name == argument.NameColon.Name.Identifier.ValueText); return parameter != null; } var argumentIndex = argumentList.Arguments.IndexOf(argument); var parameterIndex = argumentIndex; if (parameterIndex >= method.Parameters.Length) { var lastParameter = method.Parameters.Last(); parameter = lastParameter.IsParams ? lastParameter : null; return parameter != null; } parameter = method.Parameters[parameterIndex]; return true; }
protected override void ReadSymbol(IMethodSymbol methodSymbol) { // we don't need to know about static members // because they won't be delegated from child to mixin if (methodSymbol.IsStatic) return; // skip methods that are not visible to the outside world if (methodSymbol.DeclaredAccessibility == Accessibility.Private || methodSymbol.DeclaredAccessibility == Accessibility.Protected) return; // skip all property accessors and ctors if (methodSymbol.MethodKind == MethodKind.Ordinary) { var isOverrideFromObject = methodSymbol.IsOverride && methodSymbol.OverriddenMethod ?.ContainingType.SpecialType == SpecialType.System_Object; var method = new Method( methodSymbol.Name, methodSymbol.ReturnType, isOverrideFromObject) { IsAbstract = methodSymbol.IsAbstract, IsOverride = methodSymbol.IsOverride, IsInternal = methodSymbol.DeclaredAccessibility.HasFlag(Accessibility.Internal), Documentation = new DocumentationComment(methodSymbol.GetDocumentationCommentXml()) }; var parameterReader = new ParameterSymbolReader(method); parameterReader.VisitSymbol(methodSymbol); _methods.AddMethod(method); } }
private SyntaxNode GetInvertedStatement( SyntaxGenerator generator, IMethodSymbol containingOperator, Compilation compilation) { if (containingOperator.Name == WellKnownMemberNames.EqualityOperatorName) { return generator.ReturnStatement( generator.LogicalNotExpression( generator.ValueEqualsExpression( generator.IdentifierName(containingOperator.Parameters[0].Name), generator.IdentifierName(containingOperator.Parameters[1].Name)))); } else if (containingOperator.Name == WellKnownMemberNames.InequalityOperatorName) { return generator.ReturnStatement( generator.LogicalNotExpression( generator.ValueNotEqualsExpression( generator.IdentifierName(containingOperator.Parameters[0].Name), generator.IdentifierName(containingOperator.Parameters[1].Name)))); } else { // If it's a < > <= or >= operator then we can't simply invert a call // to the existing operator. i.e. the body of the "<" method should *not* be: // return !(a > b); // Just provide a throwing impl for now. return generator.DefaultMethodStatement(compilation); } }
private static bool IsGetHashCodeOverride(IMethodSymbol method) { return method.IsOverride && method.ReturnType.SpecialType == SpecialType.System_Int32 && method.Parameters.Length == 0 && IsObjectMethodOverride(method); }
private static bool MarkedWithStringFormatMethodAttribute(IMethodSymbol method) { return method.GetAttributes() .Select(a => a.AttributeClass.FullName()) .Any(a => a == "JetBrains.Annotations.StringFormatMethodAttribute"); }
public static SyntaxNode getMethodDeclaration(IMethodSymbol el) { var meth = (el.PartialImplementationPart != null) ? el.PartialImplementationPart : el; var declarings = meth.DeclaringSyntaxReferences; if (declarings == null || declarings.Count() == 0) return null; return declarings.First().GetSyntax(); }
public static IParameterSymbol GetParameterSymbol(ArgumentSyntax argument, ArgumentListSyntax argumentList, IMethodSymbol method) { if (!argumentList.Arguments.Contains(argument) || method == null) { return null; } if (argument.NameColon != null) { return method.Parameters .FirstOrDefault(symbol => symbol.Name == argument.NameColon.Name.Identifier.ValueText); } var argumentIndex = argumentList.Arguments.IndexOf(argument); var parameterIndex = argumentIndex; if (parameterIndex >= method.Parameters.Length) { var p = method.Parameters.Last(); return p.IsParams ? p : null; } var parameter = method.Parameters[parameterIndex]; return parameter; }
public static bool IsFormattableCall(IMethodSymbol method, SemanticModel semanticModel) { _formattableMembersByNamedTypes = GetFormattableMembers(semanticModel); LazyInitializer.EnsureInitialized(ref _formattableMembersByFullName, () => GetFormattableMembersByFullName()); // Some well-known types we know upfront string methodName; if (_formattableMembersByNamedTypes.TryGetValue(method.ReceiverType, out methodName)) { if (method.Name == methodName) { return true; } } // But some types we can't reference from Portable library, for instance, System.Console if (_formattableMembersByFullName.TryGetValue(method.ReceiverType.FullName(), out methodName)) { // Valid only if method has 'format' argument! // TODO: need to extend the dictionary and provide format argument name! if (method.Name == methodName && method.Parameters.Any(p => p.Name == expectedFormatArgumentName)) { return true; } } if (MarkedWithStringFormatMethodAttribute(method)) { return true; } return false; }
private static bool IsEqualsOverride(IMethodSymbol method) { return method.IsOverride && method.ReturnType.SpecialType == SpecialType.System_Boolean && method.Parameters.Length == 1 && method.Parameters[0].Type.SpecialType == SpecialType.System_Object; }
protected override bool ShallAnalyze(IMethodSymbol symbol) => symbol.IsExtensionMethod;
private static bool IsEventAccessor(IMethodSymbol method, Compilation compilation) { return(method.IsEventAccessor()); }
private static bool IsIndexerGetter(IMethodSymbol method, Compilation compilation) { return(method.IsIndexerGetter()); }
private static bool IsPropertyGetter(IMethodSymbol method, Compilation compilation) { return(method.IsPropertyGetter()); }
internal void OnConfigureMethodFound(IMethodSymbol method) { ConfigureMethodFound?.Invoke(this, method); }
private static bool IsToStringMethod(IMethodSymbol methodSymbol) => methodSymbol is {
internal static bool TryGetMethod(this ITypeSymbol type, string name, out IMethodSymbol property) { return(type.TryGetSingleMember(name, out property)); }
/// <summary> /// Checks if the given method implements IDisposable.Dispose() /// </summary> public static bool IsDisposeImplementation(this IMethodSymbol method, Compilation compilation) { INamedTypeSymbol iDisposable = WellKnownTypes.IDisposable(compilation); return(method.IsDisposeImplementation(iDisposable)); }
private bool IsOverride(IMethodSymbol methodDefinition) { return(methodDefinition != null && methodDefinition.IsOverride && !methodDefinition.IsVirtual); }
/// <summary> /// Checks if the given method is an implementation of the given interface method /// Substituted with the given typeargument. /// </summary> public static bool IsImplementationOfInterfaceMethod(this IMethodSymbol method, ITypeSymbol typeArgument, INamedTypeSymbol interfaceType, string interfaceMethodName) { INamedTypeSymbol constructedInterface = typeArgument != null?interfaceType?.Construct(typeArgument) : interfaceType; return(constructedInterface?.GetMembers(interfaceMethodName).Single() is IMethodSymbol interfaceMethod && method.Equals(method.ContainingType.FindImplementationForInterfaceMember(interfaceMethod))); }
protected override bool ShallAnalyze(IMethodSymbol symbol) => symbol.IsAsyncTaskBased() is false && base.ShallAnalyze(symbol);
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { Document document = context.Document; CancellationToken cancellationToken = context.CancellationToken; SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); MethodDeclarationSyntax methodDeclaration = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <MethodDeclarationSyntax>(); if (methodDeclaration == null) { return; } SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); Debug.Assert(methodSymbol != null, $"{nameof(methodSymbol)} is null"); if (methodSymbol != null) { foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case DiagnosticIdentifiers.AsynchronousMethodNameShouldEndWithAsync: { string oldName = methodDeclaration.Identifier.ValueText; string newName = await Identifier.EnsureUniqueAsyncMethodNameAsync( methodSymbol, oldName, document.Project.Solution, cancellationToken).ConfigureAwait(false); CodeAction codeAction = CodeAction.Create( $"Rename '{oldName}' to '{newName}'", c => Renamer.RenameSymbolAsync(document, methodSymbol, newName, c), diagnostic.Id + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, diagnostic); break; } case DiagnosticIdentifiers.AddReturnStatementThatReturnsDefaultValue: { CodeAction codeAction = CodeAction.Create( "Add return statement that returns default value", c => AddReturnStatementThatReturnsDefaultValueRefactoring.RefactorAsync(document, methodDeclaration, c), diagnostic.Id + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, diagnostic); break; } case DiagnosticIdentifiers.NonAsynchronousMethodNameShouldNotEndWithAsync: { string name = methodDeclaration.Identifier.ValueText; string newName = name.Remove(name.Length - AsyncSuffix.Length); newName = await Identifier.EnsureUniqueMemberNameAsync( methodSymbol, newName, document.Project.Solution, cancellationToken).ConfigureAwait(false); CodeAction codeAction = CodeAction.Create( $"Rename '{name}' to '{newName}'", c => Renamer.RenameSymbolAsync(document, methodSymbol, newName, c), diagnostic.Id + EquivalenceKeySuffix); context.RegisterCodeFix(codeAction, diagnostic); break; } } } } }
Constructor(Context cx, IMethodSymbol init) : base(cx, init) { }
protected abstract bool IsViableExtensionMethod(IMethodSymbol method, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFacts syntaxFacts, CancellationToken cancellationToken);
private static void CheckForIsAssignableFrom(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation, MemberAccessExpressionSyntax memberAccess, IMethodSymbol methodSymbol, ExpressionSyntax argument) { if (methodSymbol.Name != "IsAssignableFrom" || !TypeExaminationOnSystemType.IsGetTypeCall(argument as InvocationExpressionSyntax, context.SemanticModel)) { return; } if (memberAccess.Expression is TypeOfExpressionSyntax) { context.ReportDiagnostic(Diagnostic.Create(rule, invocation.GetLocation(), ImmutableDictionary <string, string> .Empty .Add(UseIsOperatorKey, true.ToString()) .Add(ShouldRemoveGetType, true.ToString()), MessageIsOperator)); } else { context.ReportDiagnostic(Diagnostic.Create(rule, invocation.GetLocation(), ImmutableDictionary <string, string> .Empty .Add(UseIsOperatorKey, false.ToString()) .Add(ShouldRemoveGetType, true.ToString()), MessageIsInstanceOfType)); } }
internal static string FindBetterName(IMethodSymbol symbol) => symbol.Name.WithoutSuffix(Constants.AsyncSuffix);
private async Task <Solution> RenameThenRemoveAsyncTokenAsync(Document document, SyntaxNode node, IMethodSymbol methodSymbol, CancellationToken cancellationToken) { var name = methodSymbol.Name; var newName = name.Substring(0, name.Length - AsyncSuffix.Length); var solution = document.Project.Solution; // Store the path to this node. That way we can find it post rename. var syntaxPath = new SyntaxPath(node); // Rename the method to remove the 'Async' suffix, then remove the 'async' keyword. var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, new SymbolRenameOptions(), newName, cancellationToken).ConfigureAwait(false); var newDocument = newSolution.GetDocument(document.Id); var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); if (syntaxPath.TryResolve(newRoot, out SyntaxNode newNode)) { var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken); return(await RemoveAsyncTokenAsync(newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false)); } return(newSolution); }
public RoslynMethodMetadata(IMethodSymbol symbol) { this.symbol = symbol; }
private static AccessorDeclarationSyntax GetAccessorSyntax(IMethodSymbol methodSymbol) { return(methodSymbol?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() as AccessorDeclarationSyntax); }
private static void CheckForIsInstanceOfType(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation, MemberAccessExpressionSyntax memberAccess, IMethodSymbol methodSymbol) { if (methodSymbol.Name != "IsInstanceOfType") { return; } if (memberAccess.Expression is TypeOfExpressionSyntax) { context.ReportDiagnostic(Diagnostic.Create(rule, invocation.GetLocation(), ImmutableDictionary <string, string> .Empty .Add(UseIsOperatorKey, true.ToString()) .Add(ShouldRemoveGetType, false.ToString()), MessageIsOperator)); } }
private static bool IsPublicOrInternal([NotNull] IMethodSymbol method) { return(method.DeclaredAccessibility == Accessibility.Public || method.DeclaredAccessibility == Accessibility.Internal); }
protected abstract SyntaxNode RemoveAsyncTokenAndFixReturnType(IMethodSymbol methodSymbolOpt, SyntaxNode node, KnownTypes knownTypes);
public static bool IsXmlTextReaderCtorDerived(IMethodSymbol method, CompilationSecurityTypes xmlTypes) { return(method != null && method.MatchMethodDerivedByName(xmlTypes.XmlTextReader, WellKnownMemberNames.InstanceConstructorName)); }
private static bool TryGetFirstMismatch(IMethodSymbol methodSymbol, AttributeSyntax attributeSyntax, SyntaxNodeAnalysisContext context, out AttributeArgumentSyntax attributeArgument) { attributeArgument = null; if (methodSymbol.Parameters.Length > 0 && methodSymbol.Parameters != null && attributeSyntax.ArgumentList is AttributeArgumentListSyntax argumentList && argumentList.Arguments.Count > 0) { for (var i = 0; i < Math.Min(CountArgs(attributeSyntax), methodSymbol.Parameters.Length); i++) { var argument = argumentList.Arguments[i]; var parameter = methodSymbol.Parameters[i]; if (argument is null || argument.NameEquals != null || parameter is null) { attributeArgument = argument; return(true); } if (parameter.IsParams && parameter.Type is IArrayTypeSymbol arrayType) { for (var j = i; j < CountArgs(attributeSyntax); j++) { if (!IsTypeMatch(arrayType.ElementType, argument)) { attributeArgument = argument; return(true); } } return(false); } if (!IsTypeMatch(parameter.Type, argument)) { attributeArgument = argument; return(true); } } } return(false); bool IsTypeMatch(ITypeSymbol parameterType, AttributeArgumentSyntax argument) { if (parameterType == KnownSymbol.Object) { return(true); } if (parameterType is ITypeParameterSymbol typeParameter) { foreach (var constraintType in typeParameter.ConstraintTypes) { if (constraintType is INamedTypeSymbol namedType && namedType.IsGenericType && namedType.TypeArguments.Any(x => x is ITypeParameterSymbol)) { // Lazy here. continue; } if (!IsTypeMatch(constraintType, argument)) { return(false); } } return(true); } if (argument.Expression.IsKind(SyntaxKind.NullLiteralExpression)) { if (parameterType.IsValueType && parameterType.Name != "Nullable") { return(false); } return(true); } if (!argument.Expression.IsAssignableTo(parameterType, context.SemanticModel)) { return(false); } return(true); } }
public static int GetXsltSettingsParameterIndex(IMethodSymbol method, CompilationSecurityTypes xmlTypes) { return(GetSpecifiedParameterIndex(method, xmlTypes, IsXsltSettingsType)); }
public static bool IsXsltSettingsCtor(IMethodSymbol method, CompilationSecurityTypes xmlTypes) { return(method != null && method.MatchMethodByName(xmlTypes.XsltSettings, WellKnownMemberNames.InstanceConstructorName)); }
private static bool IsDefinedBy(IMethodSymbol method, INamedTypeSymbol baseType, out IMethodSymbol actualMethod) { actualMethod = method; while (actualMethod.OverriddenMethod != null) { actualMethod = actualMethod.OverriddenMethod; } return(actualMethod.ContainingType.Equals(baseType)); }
public static int HasXmlReaderParameter(IMethodSymbol method, CompilationSecurityTypes xmlTypes) { return(GetSpecifiedParameterIndex(method, xmlTypes, IsXmlReaderType)); }
protected abstract TInvocationExpressionSyntax GetSubstituteInvocationExpressionSyntaxWithoutConstructorArguments(TInvocationExpressionSyntax invocationExpressionSyntax, IMethodSymbol methodSymbol);
public static bool IsXslCompiledTransformLoad(IMethodSymbol method, CompilationSecurityTypes xmlTypes) { return(method != null && method.MatchMethodByName(xmlTypes.XslCompiledTransform, SecurityMemberNames.Load)); }