Пример #1
0
        public void GenericTypeArguments(Type type, params string[] expected)
        {
            var symbol = Compilation.GetTypeByMetadataName(type);
            var actual = SyntaxTools.GenericTypeArguments(symbol);

            actual.Select(SyntaxTools.GetFullName).ShouldBe(expected);
        }
        public void GetNamespace(Type type, string expected)
        {
            var symbol = Compilation.GetTypeByMetadataName(type);

            symbol.ShouldNotBeNull();

            SyntaxTools.GetNamespace(symbol).ShouldBe(expected);
        }
 public ParameterDescription(IParameterSymbol parameter)
 {
     Name       = parameter.Name;
     Type       = SyntaxTools.GetFullName(parameter.Type);
     TypeSymbol = parameter.Type;
     IsOut      = parameter.IsOut();
     IsRef      = parameter.IsRef();
 }
        public void IsInterface(Type type, bool expected)
        {
            var symbol = Compilation.GetTypeByMetadataName(type);

            symbol.ShouldNotBeNull();

            SyntaxTools.IsInterface(symbol).ShouldBe(expected);
        }
        public void IsAssignableFrom(Type type, Type expected, bool result)
        {
            var symbol = Compilation.GetTypeByMetadataName(type);

            symbol.ShouldNotBeNull();

            SyntaxTools.IsAssignableFrom(symbol, expected).ShouldBe(result);
        }
Пример #6
0
 public MethodDescription(IMethodSymbol source)
 {
     Source           = source;
     Name             = source.Name;
     ReturnType       = SyntaxTools.GetFullName(source.ReturnType);
     ReturnTypeSymbol = source.ReturnType;
     TypeArguments    = source.TypeArguments.Select(SyntaxTools.GetFullName).ToArray();
     Parameters       = source.Parameters.Select(i => new ParameterDescription(i)).ToArray();
 }
        public void GetInterfaceImplementation()
        {
            var i1Symbol = Compilation.GetTypeByMetadataName(typeof(I1));

            foreach (var method in SyntaxTools.GetInstanceMethods(i1Symbol))
            {
                i1Symbol.GetInterfaceImplementation(method).ShouldNotBeNull();
            }
        }
        public void GetInstanceMethods()
        {
            var i1Symbol = Compilation.GetTypeByMetadataName(typeof(I1));

            i1Symbol.ShouldNotBeNull();

            var methods = SyntaxTools.GetInstanceMethods(i1Symbol).ToList();

            methods.Count.ShouldBe(2);
        }
Пример #9
0
        public void GetServiceOperationName(Type type, string methodName, string expected)
        {
            var symbol = _compilation.GetTypeByMetadataName(type);

            symbol.ShouldNotBeNull();

            var method = SyntaxTools.GetInstanceMethods(symbol).First(i => i.Name == methodName);

            ServiceContract.GetServiceOperationName(method).ShouldBe(expected);
        }
Пример #10
0
        public InterfaceTree(INamedTypeSymbol rootType)
        {
            Services   = new List <(string ServiceName, INamedTypeSymbol ServiceType)>();
            Interfaces = new List <INamedTypeSymbol>();

            var interfaces = SyntaxTools.ExpandInterface(rootType).ToList();

            ExtractServiceContracts(interfaces);
            ExtractAttachedContracts(interfaces);
            Interfaces.AddRange(interfaces);
        }
        private void ThrowInvalidSignature(string?additionalInfo = null)
        {
            var message = new StringBuilder()
                          .AppendFormat("Method signature [{0}] is not supported.", SyntaxTools.GetSignature(Method.Source));

            if (!string.IsNullOrEmpty(additionalInfo))
            {
                message.Append(" ").Append(additionalInfo);
            }

            throw new NotSupportedException(message.ToString());
        }
        public void ExpandClassInterface()
        {
            var s1Symbol = Compilation.GetTypeByMetadataName(typeof(S1));

            s1Symbol.ShouldNotBeNull();

            var actual = SyntaxTools.ExpandInterface(s1Symbol);

            actual.Count.ShouldBe(2);
            actual.ShouldNotContain(s1Symbol);

            actual.ShouldContain(Compilation.GetTypeByMetadataName(typeof(I1)));
        }
        private (MessageDescription RequestType, int[] DataIndexes, MessageDescription?HeaderType, int[] HeaderIndexes) GetRequestType()
        {
            if (Method.Parameters.Length == 0)
            {
                return(MessageDescription.Empty(), Array.Empty <int>(), null, Array.Empty <int>());
            }

            var dataParameters       = new List <ITypeSymbol>();
            var dataParameterIndexes = new List <int>();
            var streamingIndex       = -1;

            for (var i = 0; i < Method.Parameters.Length; i++)
            {
                var parameter = Method.Parameters[i];
                if (IsDataParameter(parameter.TypeSymbol))
                {
                    if (SyntaxTools.IsAsyncEnumerable(parameter.TypeSymbol))
                    {
                        streamingIndex = i;
                    }
                    else
                    {
                        dataParameters.Add(parameter.TypeSymbol);
                        dataParameterIndexes.Add(i);
                    }
                }
            }

            if (streamingIndex >= 0)
            {
                var requestType = CreateMessage(Method.Parameters[streamingIndex].TypeSymbol.GenericTypeArguments()[0]);
                MessageDescription?headerType = null;
                if (dataParameters.Count > 0)
                {
                    headerType = CreateMessage(dataParameters.ToArray());
                }

                return(
                    requestType,
                    new[] { streamingIndex },
                    headerType,
                    dataParameterIndexes.ToArray());
            }

            return(
                CreateMessage(dataParameters.ToArray()),
                dataParameterIndexes.ToArray(),
                null,
                Array.Empty <int>());
        }
        public void ExpandInterface()
        {
            var i1Symbol = Compilation.GetTypeByMetadataName(typeof(I1));

            i1Symbol.ShouldNotBeNull();

            var actual = SyntaxTools.ExpandInterface(i1Symbol);

            actual.Count.ShouldBe(2);
            actual.ShouldContain(i1Symbol);

            var disposableSymbol = actual.First(i => !SymbolEqualityComparer.Default.Equals(i, i1Symbol));

            disposableSymbol.Name.ShouldBe(nameof(IDisposable));
        }
        public OperationDescription(IMethodSymbol method, string serviceName)
        {
            ServiceName = serviceName;
            Method      = new MethodDescription(method);
            ValidateSignature();

            OperationName = ServiceContract.GetServiceOperationName(method);
            (ResponseType, ResponseTypeIndex, HeaderResponseType, HeaderResponseTypeInput) = CreateResponseType(method.ReturnType);
            (RequestType, RequestTypeInput, HeaderRequestType, HeaderRequestTypeInput)     = GetRequestType();
            OperationType              = GetOperationType();
            ContextInput               = GetContextInput();
            IsAsync                    = SyntaxTools.IsTask(method.ReturnType);
            GrpcMethodName             = "Method" + OperationName;
            GrpcMethodInputHeaderName  = "MethodInputHeader" + OperationName;
            GrpcMethodOutputHeaderName = "MethodOutputHeader" + OperationName;
        }
        public void GetCustomAttribute(Type type, Type attributeType, bool expected)
        {
            var symbol = Compilation.GetTypeByMetadataName(type);

            symbol.ShouldNotBeNull();

            var actual = SyntaxTools.GetCustomAttribute(symbol, attributeType.FullName !);

            if (expected)
            {
                actual.ShouldNotBeNull();
            }
            else
            {
                actual.ShouldBeNull();
            }
        }
        private static IEnumerable <TestCaseData> GetFullNameCases()
        {
            var type = Compilation.GetTypeByMetadataName(typeof(FullNameCases));

            type.ShouldNotBeNull();

            foreach (var method in SyntaxTools.GetInstanceMethods(type))
            {
                var attribute = SyntaxTools.GetCustomAttribute(method, typeof(DisplayNameAttribute).FullName !);
                var expected  = (string)attribute !.ConstructorArguments[0].Value !;
                expected.ShouldNotBeNull();

                yield return(new TestCaseData(method.ReturnType, expected)
                {
                    TestName = "FullName." + method.Name
                });
            }
        }
        public ContractDescription(INamedTypeSymbol serviceType)
        {
            Interfaces = new List <InterfaceDescription>();
            Services   = new List <InterfaceDescription>();

            AnalyzeServiceAndInterfaces(serviceType);
            FindDuplicates();

            BaseClassName           = GetBaseClassName(serviceType);
            ClientClassName         = BaseClassName + "Client";
            ClientBuilderClassName  = BaseClassName + "ClientBuilder";
            ContractClassName       = BaseClassName + "Contract";
            EndpointClassName       = BaseClassName + "Endpoint";
            EndpointBinderClassName = BaseClassName + "EndpointBinder";

            ContractInterfaceName = SyntaxTools.GetFullName(serviceType);
            ContractInterface     = serviceType;
            SortAll();
        }
Пример #19
0
        private static string GetDataContainerName(ITypeSymbol type)
        {
            var    attribute     = SyntaxTools.GetCustomAttribute(type, "System.Runtime.Serialization.DataContractAttribute");
            string?attributeName = null;

            if (attribute != null)
            {
                for (var i = 0; i < attribute.NamedArguments.Length; i++)
                {
                    var pair = attribute.NamedArguments[i];
                    if ("Name".Equals(pair.Key))
                    {
                        attributeName = (string?)pair.Value.Value;
                        break;
                    }
                }
            }

            return(string.IsNullOrWhiteSpace(attributeName) ? type.Name : attributeName !);
        }
        private MethodType GetOperationType()
        {
            var returnType = Method.ReturnTypeSymbol;

            if (SyntaxTools.IsTask(Method.ReturnTypeSymbol))
            {
                var args = returnType.GenericTypeArguments();
                returnType = args.IsEmpty ? returnType : args[0];
            }

            var responseIsStreaming = SyntaxTools.IsAsyncEnumerable(returnType) ||
                                      (SyntaxTools.IsValueTuple(returnType) && returnType.GenericTypeArguments().Any(SyntaxTools.IsAsyncEnumerable));

            var requestIsStreaming = Method.Parameters.Select(i => i.TypeSymbol).Any(SyntaxTools.IsAsyncEnumerable);

            if (responseIsStreaming)
            {
                return(requestIsStreaming ? MethodType.DuplexStreaming : MethodType.ServerStreaming);
            }

            return(requestIsStreaming ? MethodType.ClientStreaming : MethodType.Unary);
        }
        private static IEnumerable <TestCaseData> GetResponseTypeCases()
        {
            var type = Compilation.GetTypeByMetadataName(typeof(ResponseTypeCases));

            type.ShouldNotBeNull();

            foreach (var method in SyntaxTools.GetInstanceMethods(type))
            {
                var response       = method.GetAttributes().First(i => i.AttributeClass !.Name == nameof(ResponseTypeAttribute));
                var responseHeader = method.GetAttributes().FirstOrDefault(i => i.AttributeClass !.Name == nameof(HeaderResponseTypeAttribute));

                yield return(new TestCaseData(
                                 method,
                                 response.ConstructorArguments[0].Value,
                                 response.ConstructorArguments[1].Value,
                                 responseHeader?.ConstructorArguments[0].Value,
                                 responseHeader?.ConstructorArguments[1].Values.Select(i => (int)i.Value !).ToArray(),
                                 responseHeader?.ConstructorArguments[2].Values.Select(i => (string)i.Value !).ToArray(),
                                 responseHeader?.ConstructorArguments[3].Value)
                {
                    TestName = "ResponseType." + method.Name
                });
        private void ValidateSignature()
        {
            if (Method.TypeArguments.Length != 0)
            {
                ThrowInvalidSignature();
            }

            var hasInputStreaming = false;

            for (var i = 0; i < Method.Parameters.Length; i++)
            {
                var parameter = Method.Parameters[i];

                if (parameter.IsOut || parameter.IsRef)
                {
                    ThrowInvalidSignature();
                }

                if (IsDataParameter(parameter.TypeSymbol))
                {
                    if (SyntaxTools.IsAsyncEnumerable(parameter.TypeSymbol))
                    {
                        if (hasInputStreaming)
                        {
                            ThrowInvalidSignature();
                        }

                        hasInputStreaming = true;
                    }
                }
                else if (!IsContextParameter(parameter.TypeSymbol))
                {
                    ThrowInvalidSignature();
                }
            }
        }
 private static bool IsDataParameter(ITypeSymbol type)
 {
     return(!SyntaxTools.IsTask(type) &&
            !IsContextParameter(type) &&
            !SyntaxTools.IsStream(type));
 }
 public InterfaceDescription(INamedTypeSymbol interfaceType)
 {
     InterfaceType     = interfaceType;
     InterfaceTypeName = SyntaxTools.GetFullName(interfaceType);
 }
Пример #25
0
 public static bool IsServiceContractInterface(INamedTypeSymbol type)
 {
     return(SyntaxTools.IsInterface(type) &&
            !type.IsUnboundGenericType &&
            GetServiceContractAttribute(type) != null);
 }
Пример #26
0
 private static AttributeData?GetServiceContractAttribute(ITypeSymbol type)
 {
     return(SyntaxTools.GetCustomAttribute(type, "System.ServiceModel.ServiceContractAttribute"));
 }
Пример #27
0
 private static AttributeData?GetOperationContractAttribute(IMethodSymbol method)
 {
     return(SyntaxTools.GetCustomAttribute(method, "System.ServiceModel.OperationContractAttribute"));
 }
        public void IsValueTuple(Type type, bool expected)
        {
            var symbol = Compilation.GetTypeByMetadataName(type);

            SyntaxTools.IsValueTuple(symbol).ShouldBe(expected);
        }
 public void GetFullName(ITypeSymbol type, string expected)
 {
     SyntaxTools.GetFullName(type).ShouldBe(expected);
 }
        private (MessageDescription ResponseType, int Index, MessageDescription?HeaderType, int[] HeaderIndexes) CreateResponseType(ITypeSymbol returnType)
        {
            if (SyntaxTools.IsVoid(returnType))
            {
                return(MessageDescription.Empty(), 0, null, Array.Empty <int>());
            }

            var responseType = returnType;

            if (SyntaxTools.IsTask(returnType))
            {
                var genericArguments = responseType.GenericTypeArguments();
                if (genericArguments.IsEmpty)
                {
                    return(MessageDescription.Empty(), 0, null, Array.Empty <int>());
                }

                responseType = genericArguments[0];
            }

            if (SyntaxTools.IsValueTuple(responseType) && responseType.GenericTypeArguments().Any(SyntaxTools.IsAsyncEnumerable))
            {
                if (!SyntaxTools.IsTask(returnType))
                {
                    ThrowInvalidSignature("Wrap return type with Task<> or ValueTask<>.");
                }

                var genericArguments = responseType.GenericTypeArguments();
                if (genericArguments.Length == 1)
                {
                    ThrowInvalidSignature("Unwrap return type from ValueTuple<>.");
                }

                var streamIndex   = -1;
                var headerIndexes = new List <int>();
                var headerTypes   = new List <ITypeSymbol>();
                for (var i = 0; i < genericArguments.Length; i++)
                {
                    var genericArgument = genericArguments[i];
                    if (SyntaxTools.IsAsyncEnumerable(genericArgument))
                    {
                        responseType = genericArgument.GenericTypeArguments()[0];
                        if (streamIndex >= 0 || IsContextParameter(responseType) || !IsDataParameter(responseType))
                        {
                            ThrowInvalidSignature();
                        }

                        streamIndex = i;
                    }
                    else if (IsContextParameter(genericArgument) || !IsDataParameter(genericArgument))
                    {
                        ThrowInvalidSignature();
                    }
                    else
                    {
                        headerIndexes.Add(i);
                        headerTypes.Add(genericArgument);
                    }
                }

                return(
                    CreateMessage(responseType),
                    streamIndex,
                    CreateMessage(headerTypes.ToArray()),
                    headerIndexes.ToArray());
            }

            if (SyntaxTools.IsAsyncEnumerable(responseType))
            {
                responseType = responseType.GenericTypeArguments()[0];
            }

            if (IsContextParameter(responseType) || !IsDataParameter(responseType))
            {
                ThrowInvalidSignature();
            }

            return(CreateMessage(responseType), 0, null, Array.Empty <int>());
        }