Bridge.React.Analyser.DynamicChildrenUniqueIdWorkaroundAnalyser.LookForElementFactoryMethodParamsThatAreGivenAnArrayInsteadOfIndividualStaticElements C# (CSharp) Method

LookForElementFactoryMethodParamsThatAreGivenAnArrayInsteadOfIndividualStaticElements() private method

private LookForElementFactoryMethodParamsThatAreGivenAnArrayInsteadOfIndividualStaticElements ( SyntaxNodeAnalysisContext context ) : void
context SyntaxNodeAnalysisContext
return void
		private void LookForElementFactoryMethodParamsThatAreGivenAnArrayInsteadOfIndividualStaticElements(SyntaxNodeAnalysisContext context)
		{
			var invocation = context.Node as InvocationExpressionSyntax;
			if (invocation == null)
				return;

			// The element factory methods are always of the form
			//   public extern static ReactElement A(AnchorAttributes properties, params Union<ReactElement, string>[] children);
			// so the first do-no-more-work condition is if there are not precisely two arguments passed
			var arguments = invocation.ArgumentList.Arguments;
			if (arguments.Count != 2)
				return;

			// The next early exit is to leave now if the second argument isn't a named reference, invocation, member access, etc.. - actually, it's easier to look
			// for values which CAN'T result in a dynamic array being returned, which basically means a literal value (such as null) or a cast from a literal. If we
			// can break out now then we can avoid doing the more expensive work around determining the type of the second argument in case it's the array type that
			// we're looking for).
			var secondArgument = invocation.ArgumentList.Arguments[1].Expression;
			if (IsLiteralOrCastFromLiteral(secondArgument))
				return;

			var method = context.SemanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;
			if (method == null)
				return; // If the method call is not valid then there's no way to confirm or deny that the call is acceptable (or even to determine whether it's a Bridge.React.DOM method)

			// If the method isn't a Bridge.React.DOM element factory method then it's not something that we should be checking
			if ((method.ContainingAssembly.Identity.Name != "Bridge.React") || (method.ContainingType.Name != "DOM"))
				return;

			// Try to confirm that the last argument of the method is "Union<ReactElement, string>[]" since that's the type that enable the warning to be bypassed
			// most easily
			if (!IsAnyOrUnionReactElementOrStringArray(method.Parameters.Last().Type))
				return;

			// Try to confirm that the value specified as the parameter value is "Union<ReactElement, string>[]" (since this argument will be a params array in the
			// factory methods, it's possible that the value could be a single ReactElement or a single string - which would be fine)
			// - context.SemanticModel.GetTypeInfo will never return null since it returns a struct value
			// - We're interested in the ConvertedType of the value, for cases where the value itself is not an "Union<ReactElement, string>[]" but one which may
			//   be cast to that type, since that's what's important here
			var argumentValueType = context.SemanticModel.GetTypeInfo(secondArgument).ConvertedType;
			if ((argumentValueType == null) || (argumentValueType is IErrorTypeSymbol) || !IsAnyOrUnionReactElementOrStringArray(argumentValueType))
				return;

			context.ReportDiagnostic(Diagnostic.Create(
				DynamicChildrenUniqueIdWarningBypassRule,
				secondArgument.GetLocation(),
				method.Name
			));
		}