private void InspectTryGetSymbol(MethodParameterLookupBase <TArgumentSyntax> lookup, object expectedArguments, TArgumentSyntax[] arguments) { lookup.TryGetSymbol(SpecialArgument, out var parameter).Should().Be(false); foreach (var argument in arguments) { if (lookup.TryGetSymbol(argument, out var symbol)) { var value = ExtractArgumentValue(argument); var expected = ExtractExpectedValue(expectedArguments, symbol.Name); if (symbol.IsParams) { ((IEnumerable)expected).Should().Contain(value); // Expected contains all values {1, 2, 3} for ParamArray/params, but foreach is probing one at a time } else { value.Should().Be(expected); } } else { Assert.Fail($"TryGetParameterSymbol missing {argument.ToString()}"); } } }
protected void CheckConstructorParameterSyntax(SyntaxNodeAnalysisContext c) { if (c.SemanticModel.GetSymbolInfo(c.Node).Symbol is IMethodSymbol ctor) { MethodParameterLookupBase <TArgumentSyntax> methodParamLookup = null; // Cache, there might be more of them // Validation for TryGetNonParamsSyntax, ParamArray/params and therefore array arguments are not inspected foreach (var param in ctor.Parameters.Where(x => !x.IsParams && IsValidationDelegateType(x.Type))) { methodParamLookup ??= CreateParameterLookup(c.Node, ctor); if (methodParamLookup.TryGetNonParamsSyntax(param, out var expression)) { TryReportLocations(new InspectionContext(c), ExpressionLocation(expression), expression); } } } }
private void InspectTryGetSyntax(MethodParameterLookupBase <TArgumentSyntax> lookup, object expectedArguments, IMethodSymbol method) { lookup.TryGetSyntax(SpecialParameter, out var symbol).Should().Be(false); foreach (var parameter in method.Parameters) { if (parameter.IsParams && lookup.TryGetSyntax(parameter, out var expressions)) { expressions.Select(x => ConstantValue(x)).Should().BeEquivalentTo((IEnumerable)ExtractExpectedValue(expectedArguments, parameter.Name)); } else if (!parameter.IsParams && lookup.TryGetNonParamsSyntax(parameter, out var expression)) { ConstantValue(expression).Should().Be(ExtractExpectedValue(expectedArguments, parameter.Name)); } else if (!parameter.IsOptional && !parameter.IsParams) { Assert.Fail($"TryGetSyntax missing {parameter.Name}"); } // Else it's OK } }
internal void ReportIncorrectlyOrderedParameters(SyntaxNodeAnalysisContext analysisContext, MethodParameterLookupBase <TArgumentSyntax> methodParameterLookup, SeparatedSyntaxList <TArgumentSyntax> argumentList, Func <Location> getLocationToReport) { var argumentParameterMappings = methodParameterLookup.GetAllArgumentParameterMappings() .ToDictionary(pair => pair.SyntaxNode, pair => pair.Symbol); var methodSymbol = methodParameterLookup.MethodSymbol; if (methodSymbol == null) { return; } var parameterNames = argumentParameterMappings.Values .Select(symbol => symbol.Name) .Distinct() .ToList(); var argumentIdentifiers = argumentList .Select(argument => ConvertToArgumentIdentifier(argument)) .ToList(); var identifierNames = argumentIdentifiers .Select(p => p.IdentifierName) .ToList(); if (parameterNames.Intersect(identifierNames).Any() && HasIncorrectlyOrderedParameters(argumentIdentifiers, argumentParameterMappings, parameterNames, identifierNames, analysisContext.SemanticModel)) { // for VB the symbol does not contain the method syntax reference var secondaryLocations = methodSymbol.DeclaringSyntaxReferences .Select(s => GetMethodDeclarationIdentifierLocation(s.GetSyntax())) .WhereNotNull(); analysisContext.ReportDiagnosticWhenActive(Diagnostic.Create(SupportedDiagnostics[0], getLocationToReport(), additionalLocations: secondaryLocations, messageArgs: methodSymbol.Name)); } }