public MemberAccessibility ExtractMemberAccessibility() { MemberAccessibility accessibility = default(MemberAccessibility); if (MethodInfo.Attributes.HasFlag(MethodAttributes.PrivateScope)) { accessibility = accessibility | MemberAccessibility.PrivateScope; } if (MethodInfo.Attributes.HasFlag(MethodAttributes.Private)) { accessibility = accessibility | MemberAccessibility.Private; } if (MethodInfo.Attributes.HasFlag(MethodAttributes.FamANDAssem)) { accessibility = accessibility | MemberAccessibility.FamilyAndAssembly; } if (MethodInfo.Attributes.HasFlag(MethodAttributes.Assembly)) { accessibility = accessibility | MemberAccessibility.Assembly; } if (MethodInfo.Attributes.HasFlag(MethodAttributes.Family)) { accessibility = accessibility | MemberAccessibility.Family; } if (MethodInfo.Attributes.HasFlag(MethodAttributes.FamORAssem)) { accessibility = accessibility | MemberAccessibility.FamilyOrAssembly; } if (MethodInfo.Attributes.HasFlag(MethodAttributes.Public)) { accessibility = accessibility | MemberAccessibility.Public; } return(accessibility); }
internal TypedMemberDataBase(MemberReference member, MemberAccessibility accessibility, TypeReference type, bool isTypeDynamic, MemberFlags flags, DeclaringTypeData declaringType) : base(member, accessibility, flags, declaringType) { this.Type = TypeData.FromType(type); this.IsTypeDynamic = isTypeDynamic; Debug.Assert(this.Type != null, "Unable to get the TypeData."); }
internal MemberDataBase(MemberReference underlyingMember, MemberAccessibility accessibility, MemberFlags memberFlags, DeclaringTypeData declaringType) { this.Accessibility = accessibility; this.DeclaringType = declaringType; this.MemberFlags = memberFlags; this.Name = underlyingMember.Name; }
internal TypeDefinitionData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeKind typeKind, AssemblyData assembly, string fullName, TypeDefinitionFlags typeDefinitionFlags, bool delegateReturnTypeIsDynamic) : base(name, accessibility, memberFlags, typeKind) { _assembly = assembly; this.DelegateReturnTypeIsDynamic = delegateReturnTypeIsDynamic; this.FullName = fullName; this.TypeDefinitionFlags = typeDefinitionFlags; }
internal GenericTypeParameterData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeKind typeKind, AssemblyData assembly, System.Reflection.GenericParameterAttributes genericParameterAttributes, int genericParameterPosition) : base(name, accessibility, memberFlags, typeKind) { _assembly = assembly; this.Constraints = new List <TypeData>(); this.GenericParameterAttributes = genericParameterAttributes; this.GenericParameterPosition = genericParameterPosition; }
internal TypeDefinitionData(TypeDefinition type, MemberAccessibility accessibility, DeclaringTypeData declaringType, AssemblyData assembly) : base(type, accessibility, declaringType) { _assembly = assembly; var typeFlags = TypeDefinitionFlags.None; if (this.TypeKind == TypeKind.Class && type.CustomAttributes.Any(a => a.AttributeType.EqualsType(typeof(ExtensionAttribute)))) { typeFlags |= TypeDefinitionFlags.ExtensionsClass; } if (this.IsSealed == false) { // A type can only be inherited if it has at least one externally visible constructor and any abstract members are also externally visible. var canBeIherited = type.Methods.Where(c => c.IsConstructor && c.GetAccessibility() != null).Any(); if (this.CanBeInherited) { if (type.Methods.Where(m => m.IsSpecialName == false && m.IsConstructor == false && m.GetAccessibility() == null && m.IsAbstract).Any() || type.Events.Where(e => e.AddMethod.GetAccessibility() == null && e.AddMethod.IsAbstract).Any() || type.Properties.Where(p => p.GetMethod != null ? p.GetMethod.GetAccessibility() == null && p.GetMethod.IsAbstract : p.SetMethod.GetAccessibility() == null && p.SetMethod.IsAbstract).Any()) { canBeIherited = false; } } if (canBeIherited) { typeFlags |= TypeDefinitionFlags.CanBeInherited; } } if (this.TypeKind == TypeKind.Enum) { var flagsAttributeData = type.CustomAttributes.Where(a => a.AttributeType.EqualsType(typeof(FlagsAttribute))).SingleOrDefault(); if (flagsAttributeData != null) { typeFlags |= TypeDefinitionFlags.FlagsEnum; } } this.TypeDefinitionFlags = typeFlags; this.FullName = type.FullName; var renamedAttributeData = type.CustomAttributes.Where(a => a.AttributeType.EqualsType(typeof(TypeRenamedAttribute))).SingleOrDefault(); if (renamedAttributeData != null) { this.OldName = renamedAttributeData.ConstructorArguments[0].Value as string; } var typeForwardedFromAttribute = type.CustomAttributes.Where(a => a.AttributeType.EqualsType(typeof(TypeForwardedFromAttribute))).SingleOrDefault(); if (typeForwardedFromAttribute != null) { this.AssemblyData.AddForwardedTypeFromTarget(this, typeForwardedFromAttribute.ConstructorArguments[0].Value.ToString()); } }
/// <summary> /// Creates an instance of the <see cref="MemberDescriptor"/> class. /// </summary> /// <param name="memberAccessibility"> /// Defines the accessibility of the member (Public, NonPublic, or Any) /// </param> /// <param name="memberScope"> /// Defines the declaration scope of the member (Static, Instance, or Any) /// </param> /// <param name="caseInsensitive"> /// Specifies whether the member identifier should be matched without case sensitivity. /// The default value for this parameter is <c>false</c> /// </param> private MemberDescriptor( MemberAccessibility memberAccessibility, MemberScope memberScope = MemberScope.Instance, bool caseInsensitive = false) { MemberAccessibility = memberAccessibility; MemberScope = memberScope; CaseInsensitive = caseInsensitive; }
/// <summary> /// Extension method to return all properties and fields from an object. /// </summary> /// <param name="t">Specifies the type of object to examine.</param> /// <param name="accessiblity">Specifies which properties and fields to return.</param> /// <returns></returns> public static IEnumerable <MemberInfo> GetPropertiesAndFields(this Type t, MemberAccessibility accessiblity = MemberAccessibility.All) { BindingFlags searchFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy; IEnumerable <MemberInfo> fields = t.GetFields(searchFlags); IEnumerable <PropertyInfo> properties = t.GetProperties(searchFlags); switch (accessiblity) { case MemberAccessibility.Readable: properties = properties.Where(p => p.CanRead); break; case MemberAccessibility.Writeable: properties = properties.Where(p => p.CanWrite); break; } return(properties.Concat(fields)); }
private static bool IsMemberReflectable(IMember member, MemberAccessibility memberReflectability) { switch (memberReflectability) { case MemberAccessibility.None: return(false); case MemberAccessibility.PublicAndProtected: return(!member.IsPrivate && !member.IsInternal); case MemberAccessibility.NonPrivate: return(!member.IsPrivate); case MemberAccessibility.All: return(true); default: throw new ArgumentException("reflectability"); } }
private MethodData(MethodDefinition methodDefinition, MemberAccessibility accessibility, DeclaringTypeData declaringType) : base(methodDefinition, accessibility, declaringType) { if (methodDefinition.HasGenericParameters) { MemberDataBase declaringMember = null; if (methodDefinition.DeclaringType.IsGenericInstance == false) { declaringMember = this; } this.GenericParameters = Utilities.GetGenericParameters(methodDefinition.GenericParameters, declaringMember); } else { this.GenericParameters = GenericTypeParameterData.EmptyList; } this.IsExtensionMethod = declaringType.IsExtensionsClass && methodDefinition.CustomAttributes.Any(a => a.AttributeType.EqualsType(typeof(ExtensionAttribute))); }
private static Accessibility ToAccessibility(MemberAccessibility accessibility) { switch (accessibility) { case MemberAccessibility.Public: return(Accessibility.Public); case MemberAccessibility.Protected: return(Accessibility.Protected); case MemberAccessibility.Internal: return(Accessibility.Internal); case MemberAccessibility.Private: return(Accessibility.Private); case MemberAccessibility.ProtectedInternal: return(Accessibility.ProtectedOrInternal); default: throw new NotSupportedException($"Invalid accessibility {accessibility}."); } }
public DefaultPropertyDefinition(TypeDefinition typeDef, string name, GetMethod getter, SetMethod setter, string declaringTypeName, MemberAccessibility memberAccessibility, MemberType memberType) { if (typeDef == null) throw new ArgumentNullException("typeDef"); if (name == null) throw new ArgumentNullException("name"); if (declaringTypeName == null) throw new ArgumentNullException("declaringTypeName"); Name = name; FullName = declaringTypeName + "." + name; this.getter = getter; this.setter = setter; this.memberAccessibility = memberAccessibility; this.memberType = memberType; TypeDef = typeDef; SerializedName = name.IsAutoPropertyBackingField() ? name.AutoPropertyName() : name; }
internal MemberDataBase(string name, MemberAccessibility accessibility, MemberFlags memberFlags) { this.Accessibility = accessibility; this.MemberFlags = memberFlags; this.Name = name; }
internal IndexerData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeData type, bool isTypeDynamic, ParameterCollection parameters, MemberAccessibility?getMethodAccessibility, MemberAccessibility?setMethodAccessibility) : base(name, accessibility, memberFlags, type, isTypeDynamic, getMethodAccessibility, setMethodAccessibility) { this.Parameters = parameters; }
internal EventData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeData type) : base(name, accessibility, memberFlags, type, isTypeDynamic: false) { }
internal TypedMemberDataBase(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeData type, bool isTypeDynamic) : base(name, accessibility, memberFlags) { this.Type = type; this.IsTypeDynamic = isTypeDynamic; }
private EventData(EventDefinition eventDefinition, MemberAccessibility accessibility, DeclaringTypeData declaringType) : base(eventDefinition, accessibility, eventDefinition.EventType, false, Utilities.GetMemberFlags(eventDefinition.AddMethod), declaringType) { }
public Task<ClassDeclarationSyntax> GenerateClientClass(SemanticModel semanticModel, SyntaxGenerator gen, INamedTypeSymbol proxyInterface, string name, Accessibility accessibility, bool includeCancellableAsyncMethods, bool suppressWarningComments, MemberAccessibility constructorAccessibility, bool withInternalProxy) { if (name == null) { if (proxyInterface.Name.StartsWith("I")) name = proxyInterface.Name.Substring(1); if (name.EndsWith("Proxy")) name = name.Substring(0, name.Length - "Proxy".Length); if (!name.EndsWith("Client")) name = name + "Client"; } SyntaxNode targetClass = gen.ClassDeclaration(name, baseType: gen.TypeExpression(semanticModel.Compilation.RequireType<MarshalByRefObject>()), accessibility: accessibility, modifiers: DeclarationModifiers.Sealed); targetClass = gen.AddWarningCommentIf(!suppressWarningComments, targetClass); targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(semanticModel.Compilation.GetSpecialType(SpecialType.System_IDisposable))); targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(proxyInterface)); IEnumerable<IMethodSymbol> methods = GetOperationContractMethods(semanticModel.Compilation, proxyInterface).ToArray(); GenerationNameTable nameTable = new GenerationNameTable(methods.Select(m => m.Name).Concat(new[] { name })); #region Private Fields // ==> private IProxy m_cachedProxy; SyntaxNode cachedProxyField = gen.FieldDeclaration(nameTable[MemberNames.CachedProxyField], gen.TypeExpression(proxyInterface), Accessibility.Private, DeclarationModifiers.None) .PrependLeadingTrivia(gen.CreateRegionTrivia("Private Fields")); targetClass = gen.AddMembers(targetClass, cachedProxyField); // ==> private readonly Func<IProxy> m_proxyFactory; SyntaxNode proxyFactoryTypeExpression = gen.TypeExpression(semanticModel.Compilation.RequireTypeByMetadataName("System.Func`1").Construct(proxyInterface)); targetClass = gen.AddMembers(targetClass, gen.FieldDeclaration(nameTable[MemberNames.ProxyFactoryField], proxyFactoryTypeExpression, Accessibility.Private, DeclarationModifiers.ReadOnly) .AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia()); #endregion #region Constructors // Constructor SyntaxNode constructor = gen.ConstructorDeclaration( parameters: new[] { gen.ParameterDeclaration("proxyFactory", proxyFactoryTypeExpression) }, accessibility: withInternalProxy ? Accessibility.Private : ToAccessibility(constructorAccessibility) ); constructor = gen.AddWarningCommentIf(!suppressWarningComments, constructor); constructor = constructor.PrependLeadingTrivia(gen.CreateRegionTrivia("Constructors")); constructor = gen.WithStatements(constructor, new[] { // ==> if (proxyFactory == null) // ==> throw new System.ArgumentNullException("proxyFactory"); gen.ThrowIfNullStatement("proxyFactory"), // ==> m_proxyFactory = proxyFactory gen.AssignmentStatement( gen.MemberAccessExpression( gen.ThisExpression(), gen.IdentifierName(nameTable[MemberNames.ProxyFactoryField])), gen.IdentifierName("proxyFactory") ) } ).AddNewLineTrivia(); if (!withInternalProxy) constructor = constructor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); targetClass = gen.AddMembers(targetClass, constructor); ClassDeclarationSyntax proxyClass = null; if (withInternalProxy) { IEnumerable<IMethodSymbol> ctors; proxyClass = GenerateProxyClass(semanticModel, gen, proxyInterface, nameTable[MemberNames.ProxyClass], Accessibility.Private, suppressWarningComments, MemberAccessibility.Public, out ctors) .PrependLeadingTrivia(gen.CreateRegionTrivia("Proxy Class").Insert(0, gen.NewLine())) .AddTrailingTrivia(gen.CreateEndRegionTrivia()); // Generate one constructor for each of the proxy's constructors. foreach (var ctorEntry in ctors.AsSmartEnumerable()) { var ctor = ctorEntry.Value; var targetCtor = gen.ConstructorDeclaration(ctor); var lambda = gen.ValueReturningLambdaExpression( gen.ObjectCreationExpression(gen.IdentifierName(gen.GetName(proxyClass)), ctor.Parameters.Select(p => gen.IdentifierName(p.Name))) ); targetCtor = gen.WithThisConstructorInitializer(targetCtor, new[] { lambda }); targetCtor = gen.AddWarningCommentIf(!suppressWarningComments, targetCtor); targetCtor = gen.WithAccessibility(targetCtor, ToAccessibility(constructorAccessibility)); if (ctorEntry.IsLast) { targetCtor = targetCtor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); } targetClass = gen.AddMembers(targetClass, targetCtor.AddNewLineTrivia()); } } #endregion #region Operation Contract Methods // ==> catch // ==> { // ==> this.CloseProxy(false); // ==> throw; // ==> } var catchAndCloseProxyStatement = gen.CatchClause(new SyntaxNode[] { // ==> this.CloseProxy(false); gen.ExpressionStatement( gen.InvocationExpression( gen.MemberAccessExpression( gen.ThisExpression(), nameTable[MemberNames.CloseProxyMethod] ), gen.FalseLiteralExpression() ) ), // throw; gen.ThrowStatement() }); foreach (var sourceMethodEntry in methods.AsSmartEnumerable()) { var sourceMethod = sourceMethodEntry.Value; using (nameTable.PushScope(sourceMethod.Parameters.Select(p => p.Name))) { bool isAsync = ReturnsTask(semanticModel.Compilation, sourceMethod); bool isVoid = sourceMethod.ReturnType.SpecialType == SpecialType.System_Void || sourceMethod.ReturnType.Equals(semanticModel.Compilation.RequireType<Task>()); SyntaxNode targetMethod = gen.MethodDeclaration(sourceMethod); if (sourceMethodEntry.IsFirst) targetMethod = targetMethod.PrependLeadingTrivia(gen.CreateRegionTrivia("Contract Methods")).AddLeadingTrivia(gen.NewLine()); targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod); targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None); targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[] { // ==> try { gen.TryCatchStatement(new SyntaxNode[] { CreateProxyVaraibleDeclaration(gen, nameTable, isAsync), CreateProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod) }, new SyntaxNode[] { catchAndCloseProxyStatement } ) }); targetMethod = targetMethod.AddNewLineTrivia(); if (sourceMethodEntry.IsLast && !(isAsync && includeCancellableAsyncMethods)) targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); targetClass = gen.AddMembers(targetClass, targetMethod); if (isAsync && includeCancellableAsyncMethods) { targetMethod = gen.MethodDeclaration(sourceMethod); targetMethod = gen.AddParameters(targetMethod, new[] { gen.ParameterDeclaration(nameTable[MemberNames.CancellationTokenParameter], gen.TypeExpression(semanticModel.Compilation.RequireType<CancellationToken>())) }); targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None); targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[] { // ==> try { gen.TryCatchStatement(new SyntaxNode[] { CreateProxyVaraibleDeclaration(gen, nameTable, isAsync), CreateCancellableProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod) }, new SyntaxNode[] { catchAndCloseProxyStatement } ) }); targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod.AddNewLineTrivia()); if (sourceMethodEntry.IsLast) targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); targetClass = gen.AddMembers(targetClass, targetMethod); } } } #endregion #region Internal Methods targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, false).AddLeadingTrivia(gen.CreateRegionTrivia("Private Methods")).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, true).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, CreateDisposeMethods(semanticModel.Compilation, gen, nameTable, suppressWarningComments)); if (withInternalProxy) { targetClass = gen.AddMembers(targetClass, proxyClass); } #endregion targetClass = AddGeneratedCodeAttribute(gen, targetClass); return Task.FromResult((ClassDeclarationSyntax)targetClass); }
internal PointerTypeData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeKind typeKind, TypeData elementType) : base(name, accessibility, memberFlags, typeKind, elementType) { }
public ClassDeclarationSyntax GenerateProxyClass(SemanticModel semanticModel, SyntaxGenerator generator, INamedTypeSymbol sourceProxyInterface, string name, Accessibility accessibility, bool suppressWarningComments, MemberAccessibility constructorAccessibility, out IEnumerable<IMethodSymbol> sourceConstructors) { if (name == null) { if (sourceProxyInterface.Name.StartsWith("I")) name = sourceProxyInterface.Name.Substring(1) + "Proxy"; else name = sourceProxyInterface.Name + "Proxy"; } var compilation = semanticModel.Compilation; // Resolve the callback contract if any ITypeSymbol serviceContractAttributeType = compilation.RequireTypeByMetadataName("System.ServiceModel.ServiceContractAttribute"); AttributeData serviceContractAttribute = sourceProxyInterface.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Equals(serviceContractAttributeType)); if (serviceContractAttribute == null) throw new CodeGeneratorException(sourceProxyInterface, $"The interface {sourceProxyInterface.Name} is not decorated with ServiceContractAttribute."); ITypeSymbol callbackContractType; var callbackContractArg = serviceContractAttribute.NamedArguments.FirstOrDefault(arg => arg.Key.Equals("CallbackContract")); if (callbackContractArg.Key != null) callbackContractType = callbackContractArg.Value.Value as ITypeSymbol; else callbackContractType = null; // Resolve the base type (ClientBase or DuplexClientBase depending on whether a CallbackContract exists or not) INamedTypeSymbol baseType; if (callbackContractType != null) { baseType = compilation.RequireTypeByMetadataName("System.ServiceModel.DuplexClientBase`1").Construct(sourceProxyInterface); } else { baseType = compilation.RequireTypeByMetadataName("System.ServiceModel.ClientBase`1").Construct(sourceProxyInterface); } // Create class declaration SyntaxNode targetClass = generator.ClassDeclaration(name, accessibility: accessibility, baseType: generator.TypeExpression(baseType), interfaceTypes: new[] { generator.TypeExpression(sourceProxyInterface) }); targetClass = generator.AddWarningCommentIf(!suppressWarningComments, targetClass); // Copy constructors from base class. sourceConstructors = baseType.Constructors.Where(ctor => ctor.DeclaredAccessibility != Accessibility.Private).ToImmutableArray(); foreach (var baseCtor in sourceConstructors) { var targetCtor = generator.ConstructorDeclaration(baseCtor, baseCtor.Parameters.Select(p => generator.Argument(generator.IdentifierName(p.Name)))); targetCtor = generator.AddWarningCommentIf(!suppressWarningComments, targetCtor); targetCtor = generator.WithAccessibility(targetCtor, ToAccessibility(constructorAccessibility)); targetClass = generator.AddMembers(targetClass, targetCtor.AddNewLineTrivia()); } foreach (IMethodSymbol sourceMethod in GetOperationContractMethods(semanticModel.Compilation, sourceProxyInterface)) { SyntaxNode targetMethod = generator.MethodDeclaration(sourceMethod); targetMethod = generator.AddWarningCommentIf(!suppressWarningComments, targetMethod); targetMethod = generator.WithModifiers(targetMethod, DeclarationModifiers.None); bool isVoid = sourceMethod.ReturnType.SpecialType == SpecialType.System_Void; targetMethod = targetMethod.AddNewLineTrivia().AddNewLineTrivia(); var expression = generator.InvocationExpression( generator.MemberAccessExpression( generator.MemberAccessExpression( generator.BaseExpression(), "Channel" ), sourceMethod.Name ), sourceMethod.Parameters.Select(p => generator.IdentifierName(p.Name)).ToArray() ); SyntaxNode statement; if (!isVoid) statement = generator.ReturnStatement(expression); else statement = generator.ExpressionStatement(expression); targetMethod = generator.WithStatements(targetMethod, new[] { statement } ); targetClass = generator.AddMembers(targetClass, targetMethod.AddNewLineTrivia()); } return (ClassDeclarationSyntax)targetClass; }
private ConstructorData(MethodDefinition methodDefinition, MemberAccessibility accessibility, DeclaringTypeData declaringType) : base(methodDefinition, accessibility, Utilities.GetMemberFlags(methodDefinition), declaringType) { this.Parameters = new ParameterCollection(methodDefinition.Parameters, this); }
internal TypeData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeKind typeKind) : base(name, accessibility, memberFlags) { this.TypeKind = typeKind; }
internal TypeData(TypeReference type, MemberAccessibility accessibility, DeclaringTypeData declaringType) : base(type, accessibility, Utilities.GetMemberFlags(type), declaringType) { this.TypeKind = Utilities.GetTypeKind(type); }
internal MethodData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeData type, bool isTypeDynamic, GenericTypeParameterCollection genericParameters, bool isExtensionMethod, ParameterCollection parameters) : base(name, accessibility, memberFlags, type, isTypeDynamic, parameters) { this.GenericParameters = genericParameters; this.IsExtensionMethod = isExtensionMethod; }
internal PropertyData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeData type, bool isTypeDynamic, MemberAccessibility?getMethodAccessibility, MemberAccessibility?setMethodAccessibility) : base(name, accessibility, memberFlags, type, isTypeDynamic) { this.GetMethodAccessibility = getMethodAccessibility; this.SetMethodAccessibility = setMethodAccessibility; }
internal ArrayTypeData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeKind typeKind, TypeData elementType, byte arrayRank) : base(name, accessibility, memberFlags, typeKind, elementType) { this.ArrayRank = arrayRank; }
public Task <ClassDeclarationSyntax> GenerateClientClass(SemanticModel semanticModel, SyntaxGenerator gen, INamedTypeSymbol proxyInterface, string name, Accessibility accessibility, bool includeCancellableAsyncMethods, bool suppressWarningComments, MemberAccessibility constructorAccessibility, bool withInternalProxy) { if (name == null) { if (proxyInterface.Name.StartsWith("I")) { name = proxyInterface.Name.Substring(1); } if (name.EndsWith("Proxy")) { name = name.Substring(0, name.Length - "Proxy".Length); } if (!name.EndsWith("Client")) { name = name + "Client"; } } SyntaxNode targetClass = gen.ClassDeclaration(name, baseType: gen.TypeExpression(semanticModel.Compilation.RequireType <MarshalByRefObject>()), accessibility: accessibility, modifiers: DeclarationModifiers.Sealed); targetClass = gen.AddWarningCommentIf(!suppressWarningComments, targetClass); targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(semanticModel.Compilation.GetSpecialType(SpecialType.System_IDisposable))); targetClass = gen.AddInterfaceType(targetClass, gen.TypeExpression(proxyInterface)); IEnumerable <IMethodSymbol> methods = GetOperationContractMethods(semanticModel.Compilation, proxyInterface).ToArray(); GenerationNameTable nameTable = new GenerationNameTable(methods.Select(m => m.Name).Concat(new[] { name })); #region Private Fields // ==> private IProxy m_cachedProxy; SyntaxNode cachedProxyField = gen.FieldDeclaration(nameTable[MemberNames.CachedProxyField], gen.TypeExpression(proxyInterface), Accessibility.Private, DeclarationModifiers.None) .PrependLeadingTrivia(gen.CreateRegionTrivia("Private Fields")); targetClass = gen.AddMembers(targetClass, cachedProxyField); // ==> private readonly Func<IProxy> m_proxyFactory; SyntaxNode proxyFactoryTypeExpression = gen.TypeExpression(semanticModel.Compilation.RequireTypeByMetadataName("System.Func`1").Construct(proxyInterface)); targetClass = gen.AddMembers(targetClass, gen.FieldDeclaration(nameTable[MemberNames.ProxyFactoryField], proxyFactoryTypeExpression, Accessibility.Private, DeclarationModifiers.ReadOnly) .AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia()); #endregion #region Constructors // Constructor SyntaxNode constructor = gen.ConstructorDeclaration( parameters: new[] { gen.ParameterDeclaration("proxyFactory", proxyFactoryTypeExpression) }, accessibility: withInternalProxy?Accessibility.Private: ToAccessibility(constructorAccessibility) ); constructor = gen.AddWarningCommentIf(!suppressWarningComments, constructor); constructor = constructor.PrependLeadingTrivia(gen.CreateRegionTrivia("Constructors")); constructor = gen.WithStatements(constructor, new[] { // ==> if (proxyFactory == null) // ==> throw new System.ArgumentNullException("proxyFactory"); gen.ThrowIfNullStatement("proxyFactory"), // ==> m_proxyFactory = proxyFactory gen.AssignmentStatement( gen.MemberAccessExpression( gen.ThisExpression(), gen.IdentifierName(nameTable[MemberNames.ProxyFactoryField])), gen.IdentifierName("proxyFactory") ) } ).AddNewLineTrivia(); if (!withInternalProxy) { constructor = constructor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); } targetClass = gen.AddMembers(targetClass, constructor); ClassDeclarationSyntax proxyClass = null; if (withInternalProxy) { IEnumerable <IMethodSymbol> ctors; proxyClass = GenerateProxyClass(semanticModel, gen, proxyInterface, nameTable[MemberNames.ProxyClass], Accessibility.Private, suppressWarningComments, MemberAccessibility.Public, out ctors) .PrependLeadingTrivia(gen.CreateRegionTrivia("Proxy Class").Insert(0, gen.NewLine())) .AddTrailingTrivia(gen.CreateEndRegionTrivia()); // Generate one constructor for each of the proxy's constructors. foreach (var ctorEntry in ctors.AsSmartEnumerable()) { var ctor = ctorEntry.Value; var targetCtor = gen.ConstructorDeclaration(ctor); var lambda = gen.ValueReturningLambdaExpression( gen.ObjectCreationExpression(gen.IdentifierName(gen.GetName(proxyClass)), ctor.Parameters.Select(p => gen.IdentifierName(p.Name))) ); targetCtor = gen.WithThisConstructorInitializer(targetCtor, new[] { lambda }); targetCtor = gen.AddWarningCommentIf(!suppressWarningComments, targetCtor); targetCtor = gen.WithAccessibility(targetCtor, ToAccessibility(constructorAccessibility)); if (ctorEntry.IsLast) { targetCtor = targetCtor.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); } targetClass = gen.AddMembers(targetClass, targetCtor.AddNewLineTrivia()); } } #endregion #region Operation Contract Methods // ==> catch // ==> { // ==> this.CloseProxy(false); // ==> throw; // ==> } var catchAndCloseProxyStatement = gen.CatchClause(new SyntaxNode[] { // ==> this.CloseProxy(false); gen.ExpressionStatement( gen.InvocationExpression( gen.MemberAccessExpression( gen.ThisExpression(), nameTable[MemberNames.CloseProxyMethod] ), gen.FalseLiteralExpression() ) ), // throw; gen.ThrowStatement() }); foreach (var sourceMethodEntry in methods.AsSmartEnumerable()) { var sourceMethod = sourceMethodEntry.Value; using (nameTable.PushScope(sourceMethod.Parameters.Select(p => p.Name))) { bool isAsync = ReturnsTask(semanticModel.Compilation, sourceMethod); bool isVoid = sourceMethod.ReturnType.SpecialType == SpecialType.System_Void || sourceMethod.ReturnType.Equals(semanticModel.Compilation.RequireType <Task>()); SyntaxNode targetMethod = gen.MethodDeclaration(sourceMethod); if (sourceMethodEntry.IsFirst) { targetMethod = targetMethod.PrependLeadingTrivia(gen.CreateRegionTrivia("Contract Methods")).AddLeadingTrivia(gen.NewLine()); } targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod); targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None); targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[] { // ==> try { gen.TryCatchStatement(new SyntaxNode[] { CreateProxyVaraibleDeclaration(gen, nameTable, isAsync), CreateProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod) }, new SyntaxNode[] { catchAndCloseProxyStatement } ) }); targetMethod = targetMethod.AddNewLineTrivia(); if (sourceMethodEntry.IsLast && !(isAsync && includeCancellableAsyncMethods)) { targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); } targetClass = gen.AddMembers(targetClass, targetMethod); if (isAsync && includeCancellableAsyncMethods) { targetMethod = gen.MethodDeclaration(sourceMethod); targetMethod = gen.AddParameters(targetMethod, new[] { gen.ParameterDeclaration(nameTable[MemberNames.CancellationTokenParameter], gen.TypeExpression(semanticModel.Compilation.RequireType <CancellationToken>())) }); targetMethod = gen.WithModifiers(targetMethod, isAsync ? DeclarationModifiers.Async : DeclarationModifiers.None); targetMethod = gen.WithStatements(targetMethod, new SyntaxNode[] { // ==> try { gen.TryCatchStatement(new SyntaxNode[] { CreateProxyVaraibleDeclaration(gen, nameTable, isAsync), CreateCancellableProxyInvocationStatement(semanticModel.Compilation, gen, nameTable, sourceMethod) }, new SyntaxNode[] { catchAndCloseProxyStatement } ) }); targetMethod = gen.AddWarningCommentIf(!suppressWarningComments, targetMethod.AddNewLineTrivia()); if (sourceMethodEntry.IsLast) { targetMethod = targetMethod.AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia(); } targetClass = gen.AddMembers(targetClass, targetMethod); } } } #endregion #region Internal Methods targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, false).AddLeadingTrivia(gen.CreateRegionTrivia("Private Methods")).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateGetProxyMethod(semanticModel.Compilation, gen, proxyInterface, nameTable, true).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateStaticCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateCloseProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, false).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, gen.AddWarningCommentIf(!suppressWarningComments, CreateEnsureProxyMethod(semanticModel.Compilation, gen, nameTable, true).AddTrailingTrivia(gen.CreateEndRegionTrivia()).AddNewLineTrivia())); targetClass = gen.AddMembers(targetClass, CreateDisposeMethods(semanticModel.Compilation, gen, nameTable, suppressWarningComments)); if (withInternalProxy) { targetClass = gen.AddMembers(targetClass, proxyClass); } #endregion targetClass = AddGeneratedCodeAttribute(gen, targetClass); return(Task.FromResult((ClassDeclarationSyntax)targetClass)); }
internal DeclaringTypeData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeKind typeKind) : base(name, accessibility, memberFlags, typeKind) { _membersByName = new Dictionary <string, List <MemberDataBase> >(); }
internal ConstructorData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, ParameterCollection parameters) : base(name, accessibility, memberFlags) { this.Parameters = parameters; }
internal DeclaringTypeData(TypeReference type, MemberAccessibility accessibility, DeclaringTypeData declaringType) : base(type, accessibility, declaringType) { _membersByName = new Dictionary <string, List <MemberDataBase> >(); }
public extern ReflectableAttribute(MemberAccessibility memberAccessibility);
private static void AccessibilityMatches(MemberAccessibility memberAccessibility, MemberAccessibility requiredAccessibility, bool expected) { DefaultPropertyDefinition sut = CreatePropertyDefinition(memberAccessibility, MemberType.Property); sut.MatchesPropertyFilter(new ObjectParsingOptions { MemberAccessibility = requiredAccessibility, MemberType = MemberType.Property }) .ShouldBe(expected); }
private static DefaultPropertyDefinition CreatePropertyDefinition(MemberAccessibility memberAccessibility, MemberType memberType) { return new DefaultPropertyDefinition(Substitute.For<TypeDefinition>(typeof(object)), string.Empty, null, null, string.Empty, memberAccessibility, memberType); }
internal TypeWithElementData(string name, MemberAccessibility accessibility, MemberFlags memberFlags, TypeKind typeKind, TypeData elementType) : base(name, accessibility, memberFlags, typeKind) { this.ElementType = elementType; }
public ClassDeclarationSyntax GenerateProxyClass(SemanticModel semanticModel, SyntaxGenerator generator, INamedTypeSymbol sourceProxyInterface, string name, Accessibility accessibility, bool suppressWarningComments, MemberAccessibility constructorAccessibility, out IEnumerable <IMethodSymbol> sourceConstructors) { if (name == null) { if (sourceProxyInterface.Name.StartsWith("I")) { name = sourceProxyInterface.Name.Substring(1) + "Proxy"; } else { name = sourceProxyInterface.Name + "Proxy"; } } var compilation = semanticModel.Compilation; // Resolve the callback contract if any ITypeSymbol serviceContractAttributeType = compilation.RequireTypeByMetadataName("System.ServiceModel.ServiceContractAttribute"); AttributeData serviceContractAttribute = sourceProxyInterface.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.Equals(serviceContractAttributeType)); if (serviceContractAttribute == null) { throw new CodeGeneratorException(sourceProxyInterface, $"The interface {sourceProxyInterface.Name} is not decorated with ServiceContractAttribute."); } ITypeSymbol callbackContractType; var callbackContractArg = serviceContractAttribute.NamedArguments.FirstOrDefault(arg => arg.Key.Equals("CallbackContract")); if (callbackContractArg.Key != null) { callbackContractType = callbackContractArg.Value.Value as ITypeSymbol; } else { callbackContractType = null; } // Resolve the base type (ClientBase or DuplexClientBase depending on whether a CallbackContract exists or not) INamedTypeSymbol baseType; if (callbackContractType != null) { baseType = compilation.RequireTypeByMetadataName("System.ServiceModel.DuplexClientBase`1").Construct(sourceProxyInterface); } else { baseType = compilation.RequireTypeByMetadataName("System.ServiceModel.ClientBase`1").Construct(sourceProxyInterface); } // Create class declaration SyntaxNode targetClass = generator.ClassDeclaration(name, accessibility: accessibility, baseType: generator.TypeExpression(baseType), interfaceTypes: new[] { generator.TypeExpression(sourceProxyInterface) }); targetClass = generator.AddWarningCommentIf(!suppressWarningComments, targetClass); // Copy constructors from base class. sourceConstructors = baseType.Constructors.Where(ctor => ctor.DeclaredAccessibility != Accessibility.Private).ToImmutableArray(); foreach (var baseCtor in sourceConstructors) { var targetCtor = generator.ConstructorDeclaration(baseCtor, baseCtor.Parameters.Select(p => generator.Argument(generator.IdentifierName(p.Name)))); targetCtor = generator.AddWarningCommentIf(!suppressWarningComments, targetCtor); targetCtor = generator.WithAccessibility(targetCtor, ToAccessibility(constructorAccessibility)); targetClass = generator.AddMembers(targetClass, targetCtor.AddNewLineTrivia()); } foreach (IMethodSymbol sourceMethod in GetOperationContractMethods(semanticModel.Compilation, sourceProxyInterface)) { SyntaxNode targetMethod = generator.MethodDeclaration(sourceMethod); targetMethod = generator.AddWarningCommentIf(!suppressWarningComments, targetMethod); targetMethod = generator.WithModifiers(targetMethod, DeclarationModifiers.None); bool isVoid = sourceMethod.ReturnType.SpecialType == SpecialType.System_Void; targetMethod = targetMethod.AddNewLineTrivia().AddNewLineTrivia(); var expression = generator.InvocationExpression( generator.MemberAccessExpression( generator.MemberAccessExpression( generator.BaseExpression(), "Channel" ), sourceMethod.Name ), sourceMethod.Parameters.Select(p => generator.IdentifierName(p.Name)).ToArray() ); SyntaxNode statement; if (!isVoid) { statement = generator.ReturnStatement(expression); } else { statement = generator.ExpressionStatement(expression); } targetMethod = generator.WithStatements(targetMethod, new[] { statement } ); targetClass = generator.AddMembers(targetClass, targetMethod.AddNewLineTrivia()); } return((ClassDeclarationSyntax)targetClass); }
private static Accessibility ToAccessibility(MemberAccessibility accessibility) { switch (accessibility) { case MemberAccessibility.Public: return Accessibility.Public; case MemberAccessibility.Protected: return Accessibility.Protected; case MemberAccessibility.Internal: return Accessibility.Internal; case MemberAccessibility.Private: return Accessibility.Private; case MemberAccessibility.ProtectedInternal: return Accessibility.ProtectedOrInternal; default: throw new NotSupportedException($"Invalid accessibility {accessibility}."); } }