private static bool TryGetX(SyntaxNodeAnalysisContext context, out ReflectedMember member, out Name name, out Flags flags, out Types types) { name = default(Name); if (context.Node is InvocationExpressionSyntax candidate) { return(GetX.TryMatchGetConstructor(candidate, context, out member, out flags, out types) || GetX.TryMatchGetEvent(candidate, context, out member, out name, out flags) || GetX.TryMatchGetField(candidate, context, out member, out name, out flags) || GetX.TryMatchGetMethod(candidate, context, out member, out name, out flags, out types) || GetX.TryMatchGetNestedType(candidate, context, out member, out name, out flags) || GetX.TryMatchGetProperty(candidate, context, out member, out name, out flags, out types)); } member = default(ReflectedMember); flags = default(Flags); types = default(Types); return(false); }
internal static bool TryGet(ExpressionSyntax expression, SyntaxNodeAnalysisContext context, out PropertyInfo propertyInfo) { switch (expression) { case InvocationExpressionSyntax invocation when GetX.TryMatchGetProperty(invocation, context, out var member, out _, out _, out _) && member.Symbol is IPropertySymbol property: propertyInfo = new PropertyInfo(member.ReflectedType, property); return(true); } if (expression.IsEither(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression) && context.SemanticModel.TryGetSymbol(expression, context.CancellationToken, out ISymbol local)) { propertyInfo = default(PropertyInfo); return(AssignedValue.TryGetSingle(local, context.SemanticModel, context.CancellationToken, out var assignedValue) && TryGet(assignedValue, context, out propertyInfo)); } propertyInfo = default(PropertyInfo); return(false); }
private static bool TryGet(ExpressionSyntax expression, SyntaxNodeAnalysisContext context, PooledSet <ExpressionSyntax> visited, out ITypeSymbol result, out ExpressionSyntax source) { switch (expression) { case MemberAccessExpressionSyntax memberAccess when memberAccess.Name.Identifier.ValueText == "ReturnType" && memberAccess.Expression is InvocationExpressionSyntax invocation && GetX.TryMatchGetMethod(invocation, context, out var reflectedMember, out _, out _, out _) && reflectedMember.Match == FilterMatch.Single && reflectedMember.Symbol is IMethodSymbol method: source = memberAccess; result = method.ReturnType; return(true); case MemberAccessExpressionSyntax memberAccess when memberAccess.Name.Identifier.ValueText == "FieldType" && memberAccess.Expression is InvocationExpressionSyntax invocation && GetX.TryMatchGetField(invocation, context, out var reflectedMember, out _, out _) && reflectedMember.Match == FilterMatch.Single && reflectedMember.Symbol is IFieldSymbol field: source = memberAccess; result = field.Type; return(true); case MemberAccessExpressionSyntax memberAccess when memberAccess.Name.Identifier.ValueText == "PropertyType" && memberAccess.Expression is InvocationExpressionSyntax invocation && GetX.TryMatchGetProperty(invocation, context, out var reflectedMember, out _, out _, out _) && reflectedMember.Match == FilterMatch.Single && reflectedMember.Symbol is IPropertySymbol field: source = memberAccess; result = field.Type; return(true); case TypeOfExpressionSyntax typeOf: source = typeOf; return(context.SemanticModel.TryGetType(typeOf.Type, context.CancellationToken, out result)); case InvocationExpressionSyntax invocation when invocation.ArgumentList is ArgumentListSyntax args && args.Arguments.Count == 0 && invocation.TryGetMethodName(out var name) && name == "GetType": switch (invocation.Expression) { case MemberAccessExpressionSyntax typeAccess: source = invocation; if (context.SemanticModel.TryGetType(typeAccess.Expression, context.CancellationToken, out result)) { if (result is INamedTypeSymbol namedType && namedType.ConstructedFrom?.SpecialType == SpecialType.System_Nullable_T) { result = namedType.TypeArguments[0]; } return(true); } return(false); case IdentifierNameSyntax _ when expression.TryFirstAncestor(out TypeDeclarationSyntax containingType): source = invocation; return(context.SemanticModel.TryGetSymbol(containingType, context.CancellationToken, out result)); case MemberBindingExpressionSyntax memberBinding when memberBinding.Parent?.Parent is ConditionalAccessExpressionSyntax conditionalAccess: source = invocation; return(context.SemanticModel.TryGetType(conditionalAccess.Expression, context.CancellationToken, out result)); } break; case InvocationExpressionSyntax candidate when TryMatchTypeGetType(candidate, context, out var typeName, out var ignoreCase): source = candidate; result = context.Compilation.GetTypeByMetadataName(typeName, ignoreCase.Value); return(result != null); case InvocationExpressionSyntax candidate when TryMatchAssemblyGetType(candidate, context, out var typeName, out var ignoreCase): source = candidate; result = Assembly.TryGet(candidate.Expression, context, out var assembly) ? assembly.GetTypeByMetadataName(typeName, ignoreCase.Value) : null; return(result != null); case InvocationExpressionSyntax invocation when invocation.TryGetTarget(KnownSymbol.Type.GetGenericTypeDefinition, context.SemanticModel, context.CancellationToken, out _) && invocation.Expression is MemberAccessExpressionSyntax memberAccess && TryGet(memberAccess.Expression, context, visited, out var definingType, out _) && definingType is INamedTypeSymbol namedType: source = invocation; result = namedType.ConstructedFrom; return(true); case InvocationExpressionSyntax invocation when GetX.TryMatchGetNestedType(invocation, context, out var reflectedMember, out _, out _): source = invocation; result = reflectedMember.Symbol as ITypeSymbol; return(result != null && reflectedMember.Match == FilterMatch.Single); case InvocationExpressionSyntax invocation when invocation.TryGetTarget(KnownSymbol.Type.MakeGenericType, context.SemanticModel, context.CancellationToken, out _) && invocation.Expression is MemberAccessExpressionSyntax memberAccess && TypeArguments.TryCreate(invocation, context, out var typeArguments) && typeArguments.TryGetArgumentsTypes(context, out var types): #pragma warning disable IDISP003 // Dispose previous before re-assigning. using (visited = visited.IncrementUsage()) #pragma warning restore IDISP003 // Dispose previous before re-assigning. { if (visited.Add(invocation) && TryGet(memberAccess.Expression, context, visited, out var definition, out _) && definition is INamedTypeSymbol namedType) { source = invocation; result = namedType.Construct(types); return(result != null); } } break; case ConditionalAccessExpressionSyntax conditionalAccess: source = conditionalAccess; return(TryGet(conditionalAccess.WhenNotNull, context, out result, out _)); } if (expression.IsEither(SyntaxKind.IdentifierName, SyntaxKind.SimpleMemberAccessExpression) && context.SemanticModel.TryGetSymbol(expression, context.CancellationToken, out ISymbol local)) { #pragma warning disable IDISP003 // Dispose previous before re-assigning. using (visited = visited.IncrementUsage()) #pragma warning restore IDISP003 // Dispose previous before re-assigning. { source = null; result = null; return(AssignedValue.TryGetSingle(local, context.SemanticModel, context.CancellationToken, out var assignedValue) && visited.Add(assignedValue) && TryGet(assignedValue, context, visited, out result, out source)); } } source = null; result = null; return(false); }