Пример #1
0
        private static bool IsPreferGetMemberThenAccessor(ReflectedMember member, Name name, Flags flags, Types types, SyntaxNodeAnalysisContext context, out string callText)
        {
            if (member.Invocation?.Expression is MemberAccessExpressionSyntax memberAccess)
            {
                if (member.Symbol is IMethodSymbol method)
                {
                    if (method.AssociatedSymbol is IPropertySymbol property &&
                        Flags.TryGetExpectedBindingFlags(property.ContainingType, property, out var bindingFlags))
                    {
                        return TryGetPropertyAccessor(MemberName(property), bindingFlags, property.Type, out callText);
                    }

                    if (method.AssociatedSymbol is IEventSymbol eventSymbol &&
                        Flags.TryGetExpectedBindingFlags(eventSymbol.ContainingType, eventSymbol, out bindingFlags))
                    {
                        return TryGetEventAccessor(MemberName(eventSymbol), bindingFlags, out callText);
                    }
                }
                //// For symbols not in source and not visible in metadata.
                else if (member.Symbol is null &&
                         types.Argument == null &&
                         flags.Explicit.HasFlagFast(BindingFlags.NonPublic))
                {
                    if (TryGetInvisibleMemberName("get_", out var memberName) ||
                        TryGetInvisibleMemberName("set_", out memberName))
                    {
                        return TryGetPropertyAccessor(memberName, flags.Explicit, null, out callText);
                    }

                    if (TryGetInvisibleMemberName("add_", out memberName) ||
                        TryGetInvisibleMemberName("remove_", out memberName) ||
                        TryGetInvisibleMemberName("raise_", out memberName))
                    {
                        return TryGetEventAccessor(memberName, flags.Explicit, out callText);
                    }
                }
            }

            callText = null;
            return false;

            bool TryGetPropertyAccessor(string propertyName, BindingFlags bindingFlags, ITypeSymbol type, out string result)
            {
                if (name.MetadataName.StartsWith("get_", StringComparison.OrdinalIgnoreCase))
                {
                    result = types.Argument == null
                        ? $"{memberAccess.Expression}.GetProperty({propertyName}, {bindingFlags.ToDisplayString(memberAccess)}).GetMethod"
                        : $"{memberAccess.Expression}.GetProperty({propertyName}, {bindingFlags.ToDisplayString(memberAccess)}, null, typeof({type.ToString(context)}), {types.Argument}, null).GetMethod";
                    return true;
                }

                if (name.MetadataName.StartsWith("set_", StringComparison.OrdinalIgnoreCase))
                {
                    result = types.Argument == null
                        ? $"{memberAccess.Expression}.GetProperty({propertyName}, {bindingFlags.ToDisplayString(memberAccess)}).SetMethod"
                        : $"{memberAccess.Expression}.GetProperty({propertyName}, {bindingFlags.ToDisplayString(memberAccess)}, null, typeof({type.ToString(context)}), {types.Argument}, null).SetMethod";

                    return true;
                }

                result = null;
                return false;
            }

            bool TryGetEventAccessor(string eventName, BindingFlags bindingFlags, out string result)
            {
                if (name.MetadataName.StartsWith("add_", StringComparison.OrdinalIgnoreCase))
                {
                    result = $"{memberAccess.Expression}.GetEvent({eventName}, {bindingFlags.ToDisplayString(memberAccess)}).AddMethod";
                    return true;
                }

                if (name.MetadataName.StartsWith("remove_", StringComparison.OrdinalIgnoreCase))
                {
                    result = $"{memberAccess.Expression}.GetEvent({eventName}, {bindingFlags.ToDisplayString(memberAccess)}).RemoveMethod";
                    return true;
                }

                if (name.MetadataName.StartsWith("raise_", StringComparison.OrdinalIgnoreCase))
                {
                    result = $"{memberAccess.Expression}.GetEvent({eventName}, {bindingFlags.ToDisplayString(memberAccess)}).RaiseMethod";
                    return true;
                }

                result = null;
                return false;
            }

            bool TryGetInvisibleMemberName(string prefix, out string memberName)
            {
                if (name.MetadataName is string metadataName &&
                    metadataName.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
                {
                    memberName = $"\"{metadataName.Substring(prefix.Length)}\"";
                    return true;
                }

                memberName = null;
                return false;
            }

            string MemberName(ISymbol associatedSymbol)
            {
                if (associatedSymbol is IPropertySymbol property &&
                    property.IsIndexer)
                {
                    return $"\"{associatedSymbol.MetadataName}\"";
                }

                if (context.ContainingSymbol.ContainingType == associatedSymbol.ContainingType)
                {
                    if (member.Symbol.IsStatic)
                    {
                        return $"nameof({associatedSymbol.Name})";
                    }

                    return context.SemanticModel.UnderscoreFields() ? associatedSymbol.Name : $"nameof(this.{associatedSymbol.Name})";
                }

                return context.SemanticModel.IsAccessible(context.Node.SpanStart, associatedSymbol)
                    ? $"nameof({associatedSymbol.ContainingType.ToString(context)}.{associatedSymbol.Name})"
                    : $"\"{associatedSymbol.Name}\"";
            }
        }
Пример #2
0
        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;
        }
 private static FilterMatch TryGetMember(IMethodSymbol getX, ITypeSymbol type, Name name, BindingFlags flags, Types types, Compilation compilation, out ISymbol?member)
 {
     if (type is INamedTypeSymbol {
         IsUnboundGenericType : true
     })
Пример #4
0
        private static bool IsPreferGetMemberThenAccessor(ReflectedMember member, Name name, Flags flags, Types types, SyntaxNodeAnalysisContext context, out string callText)
        {
            if (member.Invocation?.Expression is MemberAccessExpressionSyntax memberAccess)
            {
                if (member.Symbol is IMethodSymbol method &&
                    member.Match == FilterMatch.Single)
                {
                    if (method.AssociatedSymbol is IPropertySymbol property &&
                        Flags.TryGetExpectedBindingFlags(property.ContainingType, property, out var bindingFlags))
                    {
                        return(TryGetPropertyAccessor(MemberName(property), bindingFlags, property.Type, out callText));
                    }

                    if (method.AssociatedSymbol is IEventSymbol eventSymbol &&
                        Flags.TryGetExpectedBindingFlags(eventSymbol.ContainingType, eventSymbol, out bindingFlags))
                    {
                        return(TryGetEventAccessor(MemberName(eventSymbol), bindingFlags, out callText));
                    }
                }
                else if (member.Match == FilterMatch.PotentiallyInvisible &&
                         types.Argument == null &&
                         flags.Explicit.HasFlagFast(BindingFlags.NonPublic))
                {
                    if (TryGetInvisibleMemberName("get_", out var memberName) ||
                        TryGetInvisibleMemberName("set_", out memberName))
                    {
                        return(TryGetPropertyAccessor(memberName, flags.Explicit, null, out callText));
                    }

                    if (TryGetInvisibleMemberName("add_", out memberName) ||
                        TryGetInvisibleMemberName("remove_", out memberName) ||
                        TryGetInvisibleMemberName("raise_", out memberName))
                    {
                        return(TryGetEventAccessor(memberName, flags.Explicit, out callText));
                    }
                }
            }
        internal static bool TryCreate(IMethodSymbol getX, InvocationExpressionSyntax invocation, INamedTypeSymbol type, ExpressionSyntax typeSource, Name name, BindingFlags flags, Types types, Compilation compilation, out ReflectedMember member)
        {
            var match = TryGetMember(getX, type, name, flags, types, compilation, out var memberSymbol);

            member = new ReflectedMember(type, typeSource, memberSymbol, getX, invocation, match);
            return(true);
        }