Пример #1
0
 public static void AddNamespace(params string[] namespaces)
 {
     foreach (string item in namespaces)
     {
         if (!ReferencedNamespaces.Contains(item))
         {
             ReferencedNamespaces.Add(item);
         }
     }
 }
Пример #2
0
        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);
            }
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }