private void ReplaceMethodSignatureToAsync([NotNull] IParametersOwner parametersOwner, [NotNull] IMethodDeclaration methodDeclaration) { var returnType = parametersOwner.ReturnType; var psiModule = methodDeclaration.GetPsiModule(); IDeclaredType newReturnValue; if (returnType.IsVoid()) { newReturnValue = TypeFactory.CreateTypeByCLRName("System.Threading.Tasks.Task", psiModule); } else { var task = TypeFactory.CreateTypeByCLRName("System.Threading.Tasks.Task`1", psiModule).GetTypeElement(); if (task == null) { return; } newReturnValue = TypeFactory.CreateType(task, returnType); } var name = GenerateAsyncMethodName(methodDeclaration.DeclaredName); SetSignature(methodDeclaration, newReturnValue, name); if (awaitEliderChecker.CanElide(methodDeclaration)) { awaitElider.Elide(methodDeclaration); } }
public override bool IsAvailable(IUserDataHolder cache) { callMethod = error?.Reference?.Resolve().DeclaredElement as IParametersOwner; if (callMethod == null) { return(false); } // ReSharper disable once PossibleNullReferenceException var callTreeNode = error?.Reference.GetTreeNode(); classDeclaration = callTreeNode.FindParent <IClassDeclaration>(); if (classDeclaration == null) { return(false); } // ReSharper disable once AssignNullToNotNullAttribute file = callTreeNode.GetContainingFile() as ICSharpFile; if (file == null) { return(false); } superTypes = classDeclaration.SuperTypes.SelectMany(x => x.GetAllSuperTypes()).Concat(classDeclaration.SuperTypes).ToArray(); return(superTypes.Any(x => x.GetClassType()?.Methods.Any(y => y.ShortName == "NewMock") ?? false)); }
private static bool IsParametersOwnerNotSynthetic(IParametersOwner containingParametersOwner) { // Exclude ReSharper's fake (called "synthetic") parameter owners (methods), like ASP.NET WebForms' Render-method, or // Razor's Write-methods, because these look like regular project methods but should be excluded from Implicit // Nullability because the developer cannot override the result with explicit annotations. return(!containingParametersOwner.IsSynthetic()); }
public FSharpMethodParameter(FSharpParameter fsParam, [NotNull] IParametersOwner owner, int index, IType type) { FSharpSymbol = fsParam; Type = type; Owner = owner; Index = index; }
private static ITreeNode GetCaptureHighlightingRange( [NotNull] ITreeNode topDeclaration, [CanBeNull] IParametersOwner thisElement, [NotNull] IDeclaredElement capture, out DocumentRange range) { var declarations = capture.GetDeclarations(); if (declarations.Count == 0) // accessors 'value' parameter { if (thisElement is IAccessor accessor && Equals(accessor.ValueVariable, capture)) { var identifier = ((IAccessorDeclaration)topDeclaration).NameIdentifier; range = identifier.GetDocumentRange(); return(identifier); } range = DocumentRange.InvalidRange; return(null); } var declaration = declarations[0]; range = declaration.GetNameDocumentRange(); #if RESHARPER2016_3 var nameEndOffset = range.EndOffset; #else var nameEndOffset = range.TextRange.EndOffset; #endif if (declaration is ILocalVariableDeclaration variableDeclaration) { var multiple = MultipleLocalVariableDeclarationNavigator.GetByDeclarator(variableDeclaration); if (multiple != null && multiple.Declarators[0] == variableDeclaration) { var documentRange = multiple.GetTypeRange(); range = documentRange.SetEndTo(nameEndOffset); return(variableDeclaration); } return(null); } if (declaration is IRegularParameterDeclaration parameterDeclaration) { if (range.TextRange.Length < 3) { range = parameterDeclaration.TypeUsage.GetDocumentRange().SetEndTo(nameEndOffset); } return(parameterDeclaration); } if (declaration is IAnonymousMethodParameterDeclaration anonymousParameter) { range = anonymousParameter.TypeUsage.GetDocumentRange().SetEndTo(nameEndOffset); return(anonymousParameter); } return(declaration); }
protected override void Run(ITreeNode element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer) { IParametersOwner function = null; ILocalScope topScope = null; if (element is ICSharpFunctionDeclaration functionDeclaration) { function = functionDeclaration.DeclaredElement; topScope = functionDeclaration.Body as ILocalScope; } if (element is IExpressionBodyOwnerDeclaration expressionBodyOwner) { #if RESHARPER2017_1 var arrowExpression = expressionBodyOwner.ArrowClause; #else var arrowExpression = expressionBodyOwner.ArrowExpression; #endif if (arrowExpression != null) { #if RESHARPER2016_3 function = expressionBodyOwner.GetParametersOwner(); topScope = arrowExpression as ILocalScope; #else function = expressionBodyOwner.GetFunction(); topScope = arrowExpression; #endif } else { if (element is IAccessorOwnerDeclaration) { return; } } } var inspector = new ClosureInspector(element, function); element.ProcessDescendants(inspector); // report closures allocations if (inspector.Closures.Count > 0) { ReportClosureAllocations(element, function, topScope, inspector, consumer); } // report non-cached generic lambda expressions if (function != null && inspector.ClosurelessLambdas.Count > 0) { ReportClosurelessAllocations(element, function, inspector, consumer); } // report anonymous types in query expressions if (inspector.AnonymousTypes.Count > 0) { ReportAnonymousTypes(inspector, consumer); } }
public ClosureInspector([NotNull] ITreeNode topLevelNode, [CanBeNull] IParametersOwner thisElement) { myParametersOwner = thisElement; myClosures = new Stack <ITreeNode>(); myClosures.Push(topLevelNode); Closures = new Dictionary <ITreeNode, JetHashSet <IDeclaredElement> >(); AnonymousTypes = new JetHashSet <IQueryRangeVariableDeclaration>(); ClosurelessLambdas = new List <ITreeNode>(); }
public FSharpMethodParameter(FSharpParameter fsParam, [NotNull] IParametersOwner parametersOwner, int parameterIndex, ParameterKind kind, IType type, string name) { FSharpSymbol = fsParam; Type = type; Kind = kind; ShortName = name; myParametersOwner = parametersOwner; myParameterIndex = parameterIndex; }
private static void AppendParameters(this StringBuilder identifier, IParametersOwner parametersOwner, ISubstitution substitution, IDictionary <DeclaredElementInstance, IName> seenElements) { identifier.Append('(') .Append( parametersOwner.Parameters.GetNames(substitution, seenElements) .Select(p => p.Identifier) .Join(", ")) .Append(')'); }
public void InitForNewMethod(IParametersOwner declaredElement = null) { myCurrentMethodVariableNames.Push(new List <string>()); if (declaredElement == null) { return; } foreach (var parameter in declaredElement.Parameters) { GetNextVariable(parameter.ShortName); } }
private ArgumentRoleTooltipContent TryGetArgumentRoleContent([NotNull] ITreeNode node, [NotNull] IContextBoundSettingsStore settings) { if (!settings.GetValue((IdentifierTooltipSettings s) => s.ShowArgumentsRole)) { return(null); } var argument = node.GetContainingNode <IArgument>(); DeclaredElementInstance <IParameter> parameterInstance = argument?.MatchingParameter; if (parameterInstance == null) { return(null); } IParameter parameter = parameterInstance.Element; IParametersOwner parametersOwner = parameter.ContainingParametersOwner; if (parametersOwner == null) { return(null); } HighlighterIdProvider highlighterIdProvider = _highlighterIdProviderFactory.CreateProvider(settings); RichText final = new RichText("Argument of ", TextStyle.Default); final.Append(_colorizerPresenter.TryPresent( new DeclaredElementInstance(parametersOwner, parameterInstance.Substitution), PresenterOptions.ForArgumentRoleParametersOwnerToolTip(settings), argument.Language, highlighterIdProvider)); final.Append(": ", TextStyle.Default); final.Append(_colorizerPresenter.TryPresent( parameterInstance, PresenterOptions.ForArgumentRoleParameterToolTip(settings), argument.Language, highlighterIdProvider)); var content = new ArgumentRoleTooltipContent(final, argument.GetDocumentRange().TextRange) { Description = TryGetDescription(parameter, parameter.Module, argument.Language, DeclaredElementDescriptionStyle.NO_OBSOLETE_SUMMARY_STYLE) }; if (settings.GetValue((IdentifierTooltipSettings s) => s.ShowIcon)) { content.Icon = PsiSymbolsThemedIcons.Parameter.Id; } return(content); }
private IMethod GetReplacementMethod(IParametersOwner shouldMethod) { var returnType = shouldMethod.ReturnType.GetTypeElement(); var result = returnType ?.Methods .FirstOrDefault(x => x.ShortName == GetReplacementMethodName()); if (result != null) { return(result); } return(returnType.GetSuperTypesWithoutCircularDependent() .SelectMany(x => x.GetTypeElement()?.Methods) .FirstOrDefault(x => x.ShortName == GetReplacementMethodName())); }
private static bool IsImplicitNullabilityApplicableToParameterOwner([CanBeNull] IParametersOwner parametersOwner) { // IFunction includes methods, constructors, operator overloads, delegate (methods), but also implicitly // defined ("synthetic") methods, which we want to exclude because the developer cannot // override the implicit annotation. // IProperty includes indexer parameters. switch (parametersOwner) { case IFunction function: return !IsDelegateBeginInvokeFunction(function) && IsParametersOwnerNotSynthetic(parametersOwner); case IProperty _: return true; } return false; }
private static void ReportClosurelessAllocations( [NotNull] ITreeNode element, [NotNull] IParametersOwner function, [NotNull] ClosureInspector inspector, [NotNull] IHighlightingConsumer consumer) { var typeParametersOwner = function as ITypeParametersOwner; if (typeParametersOwner != null && typeParametersOwner.TypeParameters.Count != 0) { foreach (var lambda in inspector.ClosurelessLambdas) { if (IsExpressionLambda(lambda)) { continue; } var closureRange = GetClosureRange(lambda); if (!closureRange.IsValid()) { continue; } // note: Roslyn compiler implements caching of such closures if (!element.IsCSharp6Supported()) { consumer.AddHighlighting( new DelegateAllocationHighlighting(lambda, "from generic anonymous function (always non cached)"), closureRange); } } } foreach (var lambda in inspector.ClosurelessLambdas) { if (!IsExpressionLambda(lambda)) { continue; } var closureRange = GetClosureRange(lambda); if (closureRange.IsValid()) { consumer.AddHighlighting( new ObjectAllocationHighlighting(lambda, "expression tree construction"), closureRange); } } }
public FindingReslt FindEquivalentAsyncMethod(IParametersOwner originalMethod, IType invokedType) { if (!originalMethod.IsValid()) { return(FindingReslt.CreateFail()); } var @class = classForSearchResolver.GetClassForSearch(originalMethod, invokedType); if (@class == null) { return(FindingReslt.CreateFail()); } var originalReturnType = originalMethod.Type(); foreach (var candidateMethod in @class.Methods) { if (originalMethod.ShortName + "Async" != candidateMethod.ShortName) { continue; } var returnType = candidateMethod.Type(); if (!returnType.IsTaskOf(originalReturnType)) { continue; } var parameterCompareResult = parameterComparer.ComparerParameters(candidateMethod.Parameters, originalMethod.Parameters); if (!parameterCompareResult.CanBeConvertedToAsync()) { continue; } return(new FindingReslt { Method = candidateMethod, ParameterCompareResult = parameterCompareResult, }); } return(FindingReslt.CreateFail()); }
public static IMethod FindEquivalentAsyncMethod([NotNull] IParametersOwner originalMethod, [CanBeNull] IType invokedObjectType, [NotNull] IPsiModule psiModule) { if (!originalMethod.IsValid()) { return(null); } var @class = GetClassForMethodSearch(invokedObjectType, originalMethod, psiModule); if (@class == null) { return(null); } var originalReturnType = originalMethod.Type(); foreach (var candidateMethod in @class.Methods) { if (originalMethod.ShortName + "Async" != candidateMethod.ShortName) { continue; } var returnType = candidateMethod.Type(); if (returnType.IsTask() && !originalReturnType.IsVoid()) { continue; } if (!returnType.IsGenericTaskOf(originalReturnType)) { continue; } if (!IsParameterEquals(candidateMethod.Parameters, originalMethod.Parameters)) { continue; } return(candidateMethod); } return(null); }
private static ITypeElement GetClassForMethodSearch(IType invokedObjectType, [NotNull] IParametersOwner originalMethod, [NotNull] IPsiModule psiModule) { var containingType = originalMethod.GetContainingType(); if (containingType == null) { return(null); } if (!invokedObjectType.IsGenericIQueryable() || !IsEnumerable(containingType)) { return(containingType); } var queryableName = new ClrTypeName("System.Data.Entity.QueryableExtensions"); var queryableType = TypeFactory.CreateTypeByCLRName(queryableName, psiModule); var queryableTypeElement = queryableType.GetTypeElement(); return(queryableTypeElement); }
public ITypeElement GetClassForSearch(IParametersOwner originalMethod, IType invokedType) { var containingType = originalMethod.GetContainingType(); if (containingType == null) { return(null); } if (!invokedType.IsGenericIQueryable() || !containingType.IsEnumerableClass()) { return(null); } var queryableName = new ClrTypeName("System.Data.Entity.QueryableExtensions"); var queryableType = TypeFactory.CreateTypeByCLRName(queryableName, NullableAnnotation.Unknown, invokedType.Module); var queryableTypeElement = queryableType.GetTypeElement(); return(queryableTypeElement); }
private static IType GetMethodReturnValueType([NotNull] IParametersOwner function, [NotNull] ICSharpFunctionDeclaration declaration) { var returnType = function.ReturnType; if (returnType.IsVoid()) { return(null); } if (declaration.IsIterator) { return(null); } // todo: replace this shit with return type util from R# if (declaration.IsAsync) { if (returnType.IsTask()) { return(null); } // unwrap return type from Task<T> var genericTask = returnType as IDeclaredType; if (genericTask.IsGenericTask()) { var typeElement = genericTask.GetTypeElement(); if (typeElement != null) { var typeParameters = typeElement.TypeParameters; if (typeParameters.Count == 1) { var typeParameter = typeParameters[0]; return(genericTask.GetSubstitution()[typeParameter]); } } } } return(returnType); }
private static IType GetMethodReturnValueType([NotNull] IParametersOwner function, [NotNull] ICSharpFunctionDeclaration declaration) { var returnType = function.ReturnType; if (returnType.IsVoid()) { return(null); } if (declaration.IsIterator) { return(null); } if (declaration.IsAsync) { if (returnType.IsTask()) { return(null); } // unwrap return type from Task<T> var genericTask = returnType as IDeclaredType; // ReSharper disable once MergeSequentialChecks if (genericTask != null && genericTask.IsGenericTask()) { var typeElement = genericTask.GetTypeElement(); if (typeElement != null) { var typeParameters = typeElement.TypeParameters; if (typeParameters.Count == 1) { var typeParameter = typeParameters[0]; return(genericTask.GetSubstitution()[typeParameter]); } } } } return(returnType); }
public static void ReplaceMethodSignatureToAsync([NotNull] IParametersOwner methodDeclaredElement, [NotNull] IPsiModule psiModule, [NotNull] IMethodDeclaration methodDeclaration) { var returnType = methodDeclaredElement.ReturnType; IDeclaredType newReturnValue; if (returnType.IsVoid()) { newReturnValue = TypeFactory.CreateTypeByCLRName("System.Threading.Tasks.Task", psiModule); } else { var task = TypeFactory.CreateTypeByCLRName("System.Threading.Tasks.Task`1", psiModule).GetTypeElement(); if (task == null) { return; } newReturnValue = TypeFactory.CreateType(task, returnType); } var name = GenerateAsyncMethodName(methodDeclaration.DeclaredName); SetSignature(methodDeclaration, newReturnValue, name); }
/// <summary> /// Returns an xml string of the documentation for an element. /// </summary> /// <param name="owner"> /// The owner of the doc comment block. /// </param> /// <param name="docConfig"> /// The config for the current ProjectFile. /// </param> /// <returns> /// A string of the declarations summary text. /// </returns> private static string CreateDocumentationForElement(IDocCommentBlockOwnerNode owner, DocumentationRulesConfiguration docConfig) { ITreeNode element = owner; IDeclaredElement declaredElement = (element is IDeclaration) ? ((IDeclaration)element).DeclaredElement : null; StringBuilder text = new StringBuilder(); text.AppendLine("<summary>"); string summaryText = string.Empty; if (element is IConstructorDeclaration) { summaryText = Utils.CreateSummaryForConstructorDeclaration((IConstructorDeclaration)element); } if (element is IDestructorDeclaration) { summaryText = Utils.CreateSummaryForDestructorDeclaration((IDestructorDeclaration)element); } if (element is IPropertyDeclaration) { summaryText = Utils.CreateSummaryDocumentationForProperty((IPropertyDeclaration)element); } text.AppendLine(summaryText); text.AppendLine("</summary>"); ICSharpParametersOwnerDeclaration declarationWithParameters = element as ICSharpParametersOwnerDeclaration; if (declarationWithParameters != null) { foreach (IRegularParameterDeclaration parameterDeclaration in declarationWithParameters.ParameterDeclarations) { text.AppendLine(Utils.CreateDocumentationForParameter(parameterDeclaration)); } } ICSharpTypeDeclaration typeDeclaration = element as ICSharpTypeDeclaration; if (typeDeclaration != null && (typeDeclaration.TypeParameters.Count > 0)) { foreach (ITypeParameterOfTypeDeclaration typeParameter in typeDeclaration.TypeParameters) { text.AppendLine(Utils.CreateDocumentationForParameter(typeParameter)); } } ITypeParametersOwner typeParametersOwner = element as ITypeParametersOwner; if (typeParametersOwner != null && (typeParametersOwner.TypeParameters.Count > 0)) { foreach (ITypeParameter typeParameter in typeParametersOwner.TypeParameters) { text.AppendLine(Utils.CreateDocumentationForTypeParameterDeclaration((ITypeParameterDeclaration)typeParameter)); } } IMethodDeclaration methodDeclaration = element as IMethodDeclaration; if (methodDeclaration != null && (methodDeclaration.TypeParameterDeclarations.Count > 0)) { foreach (ITypeParameterOfMethodDeclaration typeParameter in methodDeclaration.TypeParameterDeclarations) { text.AppendLine(Utils.CreateDocumentationForParameter(typeParameter)); } } IParametersOwner parametersOwner = declaredElement as IParametersOwner; if ((parametersOwner != null && ((parametersOwner is IMethod) || (parametersOwner is IOperator))) && !parametersOwner.ReturnType.Equals(parametersOwner.Module.GetPredefinedType().Void)) { text.AppendLine("<returns></returns>"); } bool ruleIsEnabled = docConfig.GetStyleCopRuleEnabled("PropertyDocumentationMustHaveValue"); if (element is IPropertyDeclaration && ruleIsEnabled) { text.AppendLine(Utils.CreateValueDocumentationForProperty((IPropertyDeclaration)element)); } List <IType> exceptions = new List <IType>(); ICSharpFunctionDeclaration functionDeclaration = element as ICSharpFunctionDeclaration; if (functionDeclaration != null && functionDeclaration.Body != null) { CollectExceptions(functionDeclaration.Body, exceptions); } IPropertyDeclaration propertyDeclaration = element as IPropertyDeclaration; if (propertyDeclaration != null) { CollectExceptions(propertyDeclaration.AccessorDeclarations, exceptions); } IIndexerDeclaration indexerDeclaration = element as IIndexerDeclaration; if (indexerDeclaration != null) { CollectExceptions(indexerDeclaration.AccessorDeclarations, exceptions); } IEventDeclaration eventDeclaration = element as IEventDeclaration; if (eventDeclaration != null) { CollectExceptions(eventDeclaration.AccessorDeclarations, exceptions); } foreach (IType exception in exceptions) { string presentableName = exception.GetPresentableName(CSharpLanguage.Instance); string a = Utils.StripClassName(presentableName); string b = exception.ToString(); text.AppendLine("<exception cref=\"" + Utils.SwapGenericTypeToDocumentation(a) + "\"></exception>"); } return(text.ToString()); }
public FSharpGeneratedParameter([NotNull] IParametersOwner owner, [CanBeNull] ITypeOwner origin) { Owner = owner; Origin = origin; }
public FSharpMethodParameter(FSharpParameter fsParam, [NotNull] IParametersOwner owner, int index, [NotNull] IType type) : base(owner, index, type) =>
public CommonMember GetCommonMember(IParametersOwner member) { return(new CommonMember(member.ShortName, member.ReturnType.ToCommon())); }
protected FSharpMethodParameterBase([NotNull] IParametersOwner owner, int index, [NotNull] IType type) { Type = type; Owner = owner; Index = index; }
public FSharpExtensionMemberParameter([NotNull] IParametersOwner owner, [NotNull] IType type) : base(owner, 0, type) { }
private static void ReportClosureAllocations( [NotNull] ITreeNode topDeclaration, [CanBeNull] IParametersOwner thisElement, [CanBeNull] ILocalScope topScope, [NotNull] ClosureInspector inspector, [NotNull] IHighlightingConsumer consumer) { var scopesMap = new Dictionary <IDeclaredElement, ILocalScope>(); var captureScopes = new Dictionary <ILocalScope, JetHashSet <IDeclaredElement> >(); // group captures by their scope, report non-cached delegates foreach (var closure in inspector.Closures) { foreach (var capture in closure.Value) { ILocalScope scope = null; if (capture is IFunction) { scope = topScope; // 'this' capture } else { var declarations = capture.GetDeclarations(); if (declarations.Count == 0) // accessors 'value' parameter { if (thisElement is IAccessor accessor && Equals(accessor.ValueVariable, capture)) { scope = topScope; } } else { foreach (var declaration in declarations) { if (declaration is IRegularParameterDeclaration) { scope = topScope; } else { #if RESHARPER2017_1 scope = declaration.GetContainingScope <ILocalScope>(); #else scope = declaration.GetContainingNode <ILocalScope>(); #endif } break; } } } if (scope == null) { continue; } if (!captureScopes.TryGetValue(scope, out var captures)) { captureScopes[scope] = captures = new JetHashSet <IDeclaredElement>(); } captures.Add(capture); scopesMap[capture] = scope; } { var highlightingRange = GetClosureRange(closure.Key); if (highlightingRange.IsValid()) { if (IsExpressionLambda(closure.Key)) { var highlighting = new ObjectAllocationHighlighting(closure.Key, "expression tree construction"); consumer.AddHighlighting(highlighting, highlightingRange); } else { var description = FormatClosureDescription(closure.Value); var highlighting = new DelegateAllocationHighlighting(closure.Key, "capture of " + description); consumer.AddHighlighting(highlighting, highlightingRange); ReportClosurelessOverloads(closure.Key, consumer); } } } } // highlight first captured entity per every scope foreach (var scopeToCaptures in captureScopes) { var firstOffset = TreeOffset.MaxValue; IDeclaredElement firstCapture = null; foreach (var capture in scopeToCaptures.Value) { if (capture is IFunction) { continue; } var offset = GetCaptureStartOffset(capture); if (offset < firstOffset) { firstOffset = offset; firstCapture = capture; } } var scopeClosure = FormatClosureDescription(scopeToCaptures.Value); // collect outer captures JetHashSet <IDeclaredElement> outerCaptures = null; foreach (var closureToCaptures in inspector.Closures) { if (!scopeToCaptures.Key.Contains(closureToCaptures.Key)) { continue; } foreach (var capture in closureToCaptures.Value) { if (!scopesMap.TryGetValue(capture, out var scope)) { continue; } if (scopeToCaptures.Key.Contains(scope)) { continue; } outerCaptures = outerCaptures ?? new JetHashSet <IDeclaredElement>(); outerCaptures.Add(capture); } } if (outerCaptures != null) { var description = FormatClosureDescription(outerCaptures); scopeClosure += $" + (outer closure of {description})"; } if (firstCapture != null) { var anchor = GetCaptureHighlightingRange(topDeclaration, thisElement, firstCapture, out var highlightingRange); if (anchor != null && highlightingRange.IsValid()) { consumer.AddHighlighting(new ClosureAllocationHighlighting(anchor, scopeClosure), highlightingRange); } } } }
public ITypeElement GetClassForSearch(IParametersOwner originalMethod, IType invokedType) { return(originalMethod.GetContainingType()); }
public static bool HasBurstProhibitedReturnValue([NotNull] IParametersOwner invokedMethod) { return(invokedMethod.ReturnType.Classify == TypeClassification.REFERENCE_TYPE); }