public static void AddNamespace(params string[] namespaces) { foreach (string item in namespaces) { if (!ReferencedNamespaces.Contains(item)) { ReferencedNamespaces.Add(item); } } }
private void RecordReferencedNamespaceAndAssembly(string nspace, string assembly) { if (!String.IsNullOrEmpty((nspace))) { if (!ReferencedNamespaces.Contains(nspace) && ReferencedNamespace.Name != nspace) { ReferencedNamespaces.Add(nspace); } } if (!ReferencedAssemblies.Contains(assembly) && grainAssembly.GetName().Name + "Client" != assembly) { ReferencedAssemblies.Add(assembly); } }
/// <summary> /// Generates a wrapper method that takes arguments of the original method. /// </summary> protected virtual CodeTypeMember GetBasicReferenceMethod(MethodInfo methodInfo, CodeTypeParameterCollection genericTypeParam, bool isObserver) { SerializerGenerationManager.RecordTypeToGenerate(methodInfo.ReturnType); foreach (var paramInfo in methodInfo.GetParameters()) { SerializerGenerationManager.RecordTypeToGenerate(paramInfo.ParameterType); } CodeTypeReference returnType; if (!isObserver) { // Method is expected to return either a Task or a grin reference if (!GrainInterfaceData.IsTaskType(methodInfo.ReturnType) && !typeof(IAddressable).IsAssignableFrom(methodInfo.ReturnType)) { throw new InvalidOperationException( string.Format("Unsupported return type {0}. Method Name={1} Declaring Type={2}", methodInfo.ReturnType.FullName, methodInfo.Name, TypeUtils.GetFullName(methodInfo.DeclaringType))); } returnType = CreateCodeTypeReference(methodInfo.ReturnType); } else { returnType = new CodeTypeReference(typeof(void)); } var referenceMethod = new CodeMemberMethod { Name = methodInfo.Name, ReturnType = returnType }; foreach (var param in methodInfo.GetParameters()) { CodeParameterDeclarationExpression p = param.ParameterType.IsGenericType ? new CodeParameterDeclarationExpression( TypeUtils.GetParameterizedTemplateName(param.ParameterType, true, tt => CurrentNamespace != tt.Namespace && !ReferencedNamespaces.Contains(tt.Namespace)), param.Name) : new CodeParameterDeclarationExpression(param.ParameterType, param.Name); p.Direction = FieldDirection.In; referenceMethod.Parameters.Add(p); } referenceMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final; var pit = new CodeTypeReference(GetGenericTypeName(methodInfo.DeclaringType, type => { }, t => false)); referenceMethod.PrivateImplementationType = pit; var methodImpl = new CodeSnippetStatement(GetBasicMethodImpl(methodInfo)); referenceMethod.Statements.Add(methodImpl); return(referenceMethod); }
protected virtual CodeTypeDeclaration GetStateClass( GrainInterfaceData grainInterfaceData, Action <Type> referred, string stateClassBaseName, string stateClassName, out bool hasStateClass) { var sourceType = grainInterfaceData.Type; stateClassName = FixupTypeName(stateClassName); CodeTypeParameterCollection genericTypeParams = grainInterfaceData.GenericTypeParams; Func <Type, bool> nonamespace = t => CurrentNamespace == t.Namespace || ReferencedNamespaces.Contains(t.Namespace); Type persistentInterface = GetPersistentInterface(sourceType); Dictionary <string, PropertyInfo> asyncProperties = GrainInterfaceData.GetPersistentProperties(persistentInterface) .ToDictionary(p => p.Name.Substring(p.Name.LastIndexOf('.') + 1), p => p); Dictionary <string, string> properties = asyncProperties.ToDictionary(p => p.Key, p => GetGenericTypeName(GrainInterfaceData.GetPromptType(p.Value.PropertyType), referred, nonamespace)); var stateClass = new CodeTypeDeclaration(stateClassBaseName); if (genericTypeParams != null) { stateClass.TypeParameters.AddRange(genericTypeParams); } stateClass.IsClass = true; if (persistentInterface != null) { stateClass.TypeAttributes = persistentInterface.IsPublic ? TypeAttributes.Public : TypeAttributes.NotPublic; } else { stateClass.TypeAttributes = TypeAttributes.Public; } stateClass.BaseTypes.Add(new CodeTypeReference(typeof(GrainState), CodeTypeReferenceOptions.GlobalReference)); MarkAsGeneratedCode(stateClass); referred(typeof(GrainState)); if (persistentInterface != null) { stateClass.BaseTypes.Add(new CodeTypeReference(GetGenericTypeName(persistentInterface, referred, nonamespace))); } stateClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(SerializableAttribute).Name)); stateClass.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(GrainStateAttribute), CodeTypeReferenceOptions.GlobalReference), new CodeAttributeArgument(new CodePrimitiveExpression(grainInterfaceData.Type.Namespace + "." + TypeUtils.GetParameterizedTemplateName(grainInterfaceData.Type))))); referred(typeof(SerializableAttribute)); referred(typeof(OnDeserializedAttribute)); var initStateFields = new CodeMemberMethod { Name = "InitStateFields" }; initStateFields.Attributes = (initStateFields.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Private; foreach (var peoperty in asyncProperties) { Type propertyType = peoperty.Value.PropertyType; bool noCreateNew = propertyType.IsPrimitive || typeof(string).IsAssignableFrom(propertyType) || // Primative types propertyType.IsAbstract || propertyType.IsInterface || propertyType.IsGenericParameter || // No concrete implementation propertyType.GetConstructor(Type.EmptyTypes) == null; // No default constructor var initExpression = noCreateNew // Pre-initialize this type to default value ? (CodeExpression) new CodeDefaultValueExpression(new CodeTypeReference(GetGenericTypeName(propertyType, referred, nonamespace))) : new CodeObjectCreateExpression(new CodeTypeReference(GetGenericTypeName(propertyType, referred, nonamespace))); initStateFields.Statements.Add(new CodeAssignStatement( new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), peoperty.Key), initExpression)); } hasStateClass = properties.Count > 0; if (hasStateClass) { foreach (var pair in properties) { GenerateStateClassProperty(stateClass, asyncProperties[pair.Key], pair.Key, pair.Value); } var returnType = new CodeTypeReference("System.Collections.Generic.IDictionary", new CodeTypeReference(typeof(string)), new CodeTypeReference(typeof(object))); var concreteType = new CodeTypeReference("System.Collections.Generic.Dictionary", new CodeTypeReference(typeof(string)), new CodeTypeReference(typeof(object))); var asDictionary = new CodeMemberMethod { Name = "AsDictionary", Attributes = MemberAttributes.Public | MemberAttributes.Override, ReturnType = returnType }; asDictionary.Statements.Add(new CodeVariableDeclarationStatement(concreteType, "result", new CodeObjectCreateExpression(concreteType))); foreach (var pair in properties) { asDictionary.Statements.Add(new CodeAssignStatement( new CodeIndexerExpression(new CodeVariableReferenceExpression("result"), new CodePrimitiveExpression(pair.Key)), new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), pair.Key))); } asDictionary.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("result"))); stateClass.Members.Add(asDictionary); GenerateSetAll(stateClass, properties); GenerateToString(stateClass, stateClassName, properties); } // Copier, serializer, and deserializer for the state class var copier = SerializerGenerationUtilities.GenerateCopier("_Copier", stateClassName, genericTypeParams); var serializer = SerializerGenerationUtilities.GenerateSerializer("_Serializer", stateClassName, genericTypeParams); var deserializer = SerializerGenerationUtilities.GenerateDeserializer("_Deserializer", stateClassName, genericTypeParams); var ctor = new CodeConstructor { Attributes = (copier.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public }; ctor.BaseConstructorArgs.Add(new CodePrimitiveExpression(TypeUtils.GetFullName(grainInterfaceData.Type))); ctor.Statements.Add(new CodeMethodInvokeExpression( new CodeThisReferenceExpression(), "InitStateFields")); copier.Statements.Add(new CodeMethodReturnStatement( new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("input"), "DeepCopy"))); serializer.Statements.Add( new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("input"), "SerializeTo", new CodeArgumentReferenceExpression("stream"))); deserializer.Statements.Add(new CodeVariableDeclarationStatement(stateClassName, "result", new CodeObjectCreateExpression(stateClassName))); deserializer.Statements.Add(new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("result"), "DeserializeFrom", new CodeArgumentReferenceExpression("stream"))); deserializer.Statements.Add(new CodeMethodReturnStatement( new CodeVariableReferenceExpression("result"))); stateClass.Members.Add(ctor); stateClass.Members.Add(initStateFields); stateClass.Members.Add(copier); stateClass.Members.Add(serializer); stateClass.Members.Add(deserializer); return(stateClass); }
protected override string GetGenericTypeName(Type type) { // Add in the namespace of the type and the assembly file in which the type is defined AddReferencedAssembly(type); // Add in the namespace of the type and the assembly file in which any generic argument types are defined if (type.IsGenericType) { foreach (Type argument in type.GetGenericArguments()) { AddReferencedAssembly(argument); } } var typeName = TypeUtils.GetTemplatedName(type, t => CurrentNamespace != t.Namespace && !ReferencedNamespaces.Contains(t.Namespace)); typeName = GetNestedClassName(typeName); typeName = typeName.Replace("<", "(Of ").Replace(">", ")"); return(typeName); }