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); }
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); }
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); }
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(); }
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); }
public static bool IsServiceContractInterface(INamedTypeSymbol type) { return(SyntaxTools.IsInterface(type) && !type.IsUnboundGenericType && GetServiceContractAttribute(type) != null); }
private static AttributeData?GetServiceContractAttribute(ITypeSymbol type) { return(SyntaxTools.GetCustomAttribute(type, "System.ServiceModel.ServiceContractAttribute")); }
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>()); }