public void Add() { CodeTypeParameter tp1 = new CodeTypeParameter(); CodeTypeParameter tp2 = new CodeTypeParameter(); CodeTypeParameterCollection coll = new CodeTypeParameterCollection(); Assert.AreEqual(0, coll.Add(tp1), "#1"); Assert.AreEqual(1, coll.Count, "#2"); Assert.AreEqual(0, coll.IndexOf(tp1), "#3"); Assert.AreEqual(1, coll.Add(tp2), "#4"); Assert.AreEqual(2, coll.Count, "#5"); Assert.AreEqual(1, coll.IndexOf(tp2), "#6"); }
public void Constructor2() { CodeTypeParameter tp1 = new CodeTypeParameter(); CodeTypeParameter tp2 = new CodeTypeParameter(); CodeTypeParameterCollection c = new CodeTypeParameterCollection(); c.Add(tp1); c.Add(tp2); CodeTypeParameterCollection coll = new CodeTypeParameterCollection(c); Assert.AreEqual(2, coll.Count, "#1"); Assert.AreEqual(0, coll.IndexOf(tp1), "#2"); Assert.AreEqual(1, coll.IndexOf(tp2), "#3"); }
static void PopulateGenericParameters(IGenericParameterProvider publicType, CodeTypeParameterCollection parameters, HashSet <string> excludeAttributes) { foreach (var parameter in publicType.GenericParameters) { // A little hacky. Means we get "in" and "out" prefixed on any constraints, but it's either that // or add it as a custom attribute var name = parameter.Name; if (parameter.IsCovariant) { name = "out " + name; } if (parameter.IsContravariant) { name = "in " + name; } var attributeCollection = new CodeAttributeDeclarationCollection(); if (parameter.HasCustomAttributes) { PopulateCustomAttributes(parameter, attributeCollection, excludeAttributes); } var typeParameter = new CodeTypeParameter(name) { HasConstructorConstraint = parameter.HasDefaultConstructorConstraint && !parameter.HasNotNullableValueTypeConstraint }; typeParameter.CustomAttributes.AddRange(attributeCollection.OfType <CodeAttributeDeclaration>().ToArray()); if (parameter.HasNotNullableValueTypeConstraint) { typeParameter.Constraints.Add(" struct"); // Extra space is a hack! } if (parameter.HasReferenceTypeConstraint) { typeParameter.Constraints.Add(" class"); } foreach (var constraint in parameter.Constraints.Where(t => t.FullName != "System.ValueType")) { // for generic constraints like IEnumerable<T> call to GetElementType() returns TypeReference with Name = !0 typeParameter.Constraints.Add(CreateCodeTypeReference(constraint /*.GetElementType()*/)); } parameters.Add(typeParameter); } }
private void FillGenericParameters(CodeTypeParameterCollection codes, IEnumerable <GenericParameter> defines) { foreach (var genericParameter in defines) { CodeTypeParameter t = new CodeTypeParameter(genericParameter.FullName); if (genericParameter.IsContravariant) { t.HasConstructorConstraint = true; } foreach (var constraint in genericParameter.Constraints) { t.Constraints.Add(new CodeTypeReference(constraint.FullName)); } FillCustomAttribute(t.CustomAttributes, genericParameter.CustomAttributes); codes.Add(t); } }
private static void PopulateGenericParameters(IGenericParameterProvider publicType, CodeTypeParameterCollection parameters) { foreach (var parameter in publicType.GenericParameters) { if (parameter.HasCustomAttributes) { throw new NotImplementedException("Attributes on type parameters is not supported. And weird"); } // A little hacky. Means we get "in" and "out" prefixed on any constraints, but it's either that // or add it as a custom attribute, which looks even weirder var name = parameter.Name; if (parameter.IsCovariant) { name = "out " + name; } if (parameter.IsContravariant) { name = "in " + name; } var typeParameter = new CodeTypeParameter(name) { HasConstructorConstraint = parameter.HasDefaultConstructorConstraint && !parameter.HasNotNullableValueTypeConstraint }; if (parameter.HasNotNullableValueTypeConstraint) { typeParameter.Constraints.Add(" struct"); // Extra space is a hack! } if (parameter.HasReferenceTypeConstraint) { typeParameter.Constraints.Add(" class"); } foreach (var constraint in parameter.Constraints.Where(t => t.FullName != "System.ValueType")) { typeParameter.Constraints.Add(CreateCodeTypeReference(constraint.GetElementType())); } parameters.Add(typeParameter); } }
void WriteTypeParameters(CodeTypeParameterCollection typeParameters, IndentedTextWriter writer, out string typeConstraints) { var constraints = string.Empty; if (typeParameters.Count > 0) { var parameterDeclarations = typeParameters.Cast <CodeTypeParameter>().Select(p => { if (p.Constraints.Count > 0 || p.HasConstructorConstraint) { var parameterConstraints = new List <string>(p.Constraints.Count); parameterConstraints.AddRange(p.Constraints.Cast <CodeTypeReference>().Select(type => { if (type.BaseType == "System.ValueType") { return("struct"); } else if (type.BaseType == "System.Object") { return("class"); } else { return(GetTypeOutput(type)); } })); if (p.HasConstructorConstraint) { parameterConstraints.Add("new()"); } constraints += $" where {p.Name} : {string.Join(", ", parameterConstraints)}"; } return(p.Name); }); writer.Write($"<{string.Join(", ", parameterDeclarations)}>"); } typeConstraints = constraints; }
public static CodeTypeParameterCollection GenericTypeParameters(Type t) { if (!t.IsGenericType) { return(null); } var p = new CodeTypeParameterCollection(); foreach (var genericParameter in t.GetGenericTypeDefinition().GetGenericArguments()) { var param = new CodeTypeParameter(genericParameter.Name); if ((genericParameter.GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != GenericParameterAttributes.None) { param.Constraints.Add(" class"); } if ((genericParameter.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != GenericParameterAttributes.None) { param.Constraints.Add(" struct"); } var constraints = genericParameter.GetGenericParameterConstraints(); foreach (var constraintType in constraints) { param.Constraints.Add( new CodeTypeReference(TypeUtils.GetParameterizedTemplateName(constraintType, false, x => true))); } if ((genericParameter.GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) != GenericParameterAttributes.None) { param.HasConstructorConstraint = true; } p.Add(param); } return(p); }
/// <summary> /// Generates a wrapper method that takes arguments of the original method. /// </summary> protected override CodeTypeMember GetBasicReferenceMethod(MethodInfo methodInfo, CodeTypeParameterCollection genericTypeParam, bool isObserver) { SerializerGenerationManager.RecordTypeToGenerate(methodInfo.ReturnType); foreach (ParameterInfo paramInfo in methodInfo.GetParameters()) { SerializerGenerationManager.RecordTypeToGenerate(paramInfo.ParameterType); } if (!isObserver) { var parameterList = new StringBuilder(); var first = true; foreach (var p in methodInfo.GetParameters()) { if (!first) { parameterList.Append(", "); } first = false; parameterList.AppendFormat("{0} As {1}", p.Name, GetGenericTypeName(p.ParameterType, type => { }, t => false)); } var snippet = new StringBuilder(); snippet.AppendFormat("Public Function {0}({1}) As {2} Implements {3}.{0}\n", methodInfo.Name, parameterList, GetGenericTypeName(methodInfo.ReturnType, type => { }, t => false), GetGenericTypeName(methodInfo.DeclaringType, type => { }, t => false)); snippet.AppendFormat(" {0}\n", GetBasicMethodImpl(methodInfo)); snippet.Append(" End Function\n"); return(new CodeSnippetTypeMember(snippet.ToString())); } var referenceMethod = new CodeMemberMethod { Name = methodInfo.Name, ReturnType = GetReturnTypeReference(methodInfo.ReturnType, SerializeFlag.DeserializeResult) }; foreach (var paramInfo in methodInfo.GetParameters()) { referenceMethod.Parameters.Add(new CodeParameterDeclarationExpression( new CodeTypeReference(paramInfo.ParameterType), GrainInterfaceData.GetParameterName(paramInfo))); } 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); }
public CodeTypeParameterCollection(CodeTypeParameterCollection value) { }
public void Add_Null() { CodeTypeParameterCollection coll = new CodeTypeParameterCollection(); coll.Add((CodeTypeParameter)null); }
private void AddMethods(MethodInfo[] methods, CodeTypeDeclaration referenceClass, CodeTypeParameterCollection genericTypeParam, bool isObserver) { methodIdCollisionDetection.Clear(); if (methods == null || methods.Length <= 0) { return; } foreach (var methodInfo in methods) { AddMethod(methodInfo, referenceClass, genericTypeParam, isObserver); } }
private CodeTypeDeclaration GetInvokerClass(GrainInterfaceData si, bool isClient) { Type grainType = si.Type; CodeTypeParameterCollection genericTypeParams = si.GenericTypeParams; var invokerClass = new CodeTypeDeclaration(si.InvokerClassBaseName); if (genericTypeParams != null) { invokerClass.TypeParameters.AddRange(genericTypeParams); } invokerClass.IsClass = true; MarkAsGeneratedCode(invokerClass); invokerClass.BaseTypes.Add(si.IsExtension ? new CodeTypeReference(typeof(IGrainExtensionMethodInvoker), CodeTypeReferenceOptions.GlobalReference) : new CodeTypeReference(typeof(IGrainMethodInvoker), CodeTypeReferenceOptions.GlobalReference)); GrainInterfaceInfo grainInterfaceInfo = GetInterfaceInfo(grainType); var interfaceId = grainInterfaceInfo.Interfaces.Keys.First(); invokerClass.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(MethodInvokerAttribute), CodeTypeReferenceOptions.GlobalReference), new CodeAttributeArgument(new CodePrimitiveExpression(grainType.Namespace + "." + TypeUtils.GetParameterizedTemplateName(grainType))), new CodeAttributeArgument(new CodePrimitiveExpression(interfaceId)))); var interfaceIdProperty = new CodeMemberProperty { Name = "InterfaceId", Attributes = MemberAttributes.Public | MemberAttributes.Final, Type = new CodeTypeReference(typeof(int)) }; interfaceIdProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(interfaceId))); interfaceIdProperty.PrivateImplementationType = new CodeTypeReference(typeof(IGrainMethodInvoker), CodeTypeReferenceOptions.GlobalReference); invokerClass.Members.Add(interfaceIdProperty); //Add invoke method for Orleans message var orleansInvoker = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = "Invoke", ReturnType = new CodeTypeReference(typeof(Task <object>), CodeTypeReferenceOptions.GlobalReference) }; orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(IAddressable), CodeTypeReferenceOptions.GlobalReference), "grain")); orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "interfaceId")); orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "methodId")); orleansInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "arguments")); orleansInvoker.PrivateImplementationType = new CodeTypeReference(typeof(IGrainMethodInvoker), CodeTypeReferenceOptions.GlobalReference); var orleansInvokerImpl = new CodeSnippetStatement(GetInvokerImpl(si, invokerClass, grainType, grainInterfaceInfo, isClient)); orleansInvoker.Statements.Add(orleansInvokerImpl); invokerClass.Members.Add(orleansInvoker); //Add TryInvoke method for Orleans message, if the type is an extension interface if (si.IsExtension) { var orleansTryInvoker = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Final, Name = "Invoke", ReturnType = new CodeTypeReference(typeof(Task <object>), CodeTypeReferenceOptions.GlobalReference) }; orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(IGrainExtension), CodeTypeReferenceOptions.GlobalReference), "grain")); orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "interfaceId")); orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "methodId")); orleansTryInvoker.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object[]), "arguments")); orleansTryInvoker.PrivateImplementationType = new CodeTypeReference(typeof(IGrainExtensionMethodInvoker), CodeTypeReferenceOptions.GlobalReference); var orleansTryInvokerImp = new CodeSnippetStatement(GetInvokerImpl(si, invokerClass, grainType, grainInterfaceInfo, isClient)); orleansTryInvoker.Statements.Add(orleansTryInvokerImp); invokerClass.Members.Add(orleansTryInvoker); } //Add GetMethodName() method var getMethodName = new CodeMemberMethod { Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Static, Name = "GetMethodName", ReturnType = new CodeTypeReference(typeof(string)) }; getMethodName.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "interfaceId")); getMethodName.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "methodId")); var orleansGetMethodNameImpl = new CodeSnippetStatement(GetOrleansGetMethodNameImpl(grainType, grainInterfaceInfo)); getMethodName.Statements.Add(orleansGetMethodNameImpl); invokerClass.Members.Add(getMethodName); return(invokerClass); }
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); }
public void AddRange(CodeTypeParameterCollection value) {}
public void Remove_Null() { CodeTypeParameterCollection coll = new CodeTypeParameterCollection(); coll.Remove((CodeTypeParameter)null); }
public void Constructor1_Null() { CodeTypeParameterCollection coll = new CodeTypeParameterCollection( (CodeTypeParameter[])null); }
public void Remove_NotInCollection() { CodeTypeParameterCollection coll = new CodeTypeParameterCollection(); coll.Remove(new CodeTypeParameter()); }
public void AddRange_Null_Collection() { CodeTypeParameterCollection coll = new CodeTypeParameterCollection(); coll.AddRange((CodeTypeParameterCollection)null); }
public void Insert_Null() { CodeTypeParameterCollection coll = new CodeTypeParameterCollection(); coll.Insert(0, (CodeTypeParameter)null); }
protected override 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 => false; 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)); hasStateClass = properties.Count > 0; if (!hasStateClass) { return(null); } var typeAccess = (persistentInterface != null && !persistentInterface.IsPublic) ? "internal" : "public"; StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<System.CodeDom.Compiler.GeneratedCodeAttribute(""{0}"", ""{1}"")>]", CODE_GENERATOR_NAME, CodeGeneratorVersion); StartNewLine(); generatedCode.AppendFormat(@"[<System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"[<System.SerializableAttribute()>]"); StartNewLine(); var grainName = grainInterfaceData.Type.Namespace + "." + TypeUtils.GetParameterizedTemplateName(grainInterfaceData.Type); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.GrainStateAttribute(""{0}"")>]", grainName); StartNewLine(); generatedCode.AppendFormat(@"type {0} {1}", typeAccess, stateClassBaseName); if (genericTypeParams != null && genericTypeParams.Count > 0) { generatedCode.Append('<'); for (int p = 0; p < genericTypeParams.Count; ++p) { if (p > 0) { generatedCode.Append(','); } CodeTypeParameter param = genericTypeParams[p]; generatedCode.Append('\'').Append(param.Name); } generatedCode.Append('>'); } generatedCode.AppendFormat(@"() ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"inherit global.Orleans.CodeGeneration.GrainState(""{0}"")", grainName); StartNewLine(); var declaringTypes = new Dictionary <string, List <KeyValuePair <string, PropertyInfo> > >(); foreach (var pair in asyncProperties) { var dtName = GetGenericTypeName(pair.Value.DeclaringType, referred, nonamespace); if (!declaringTypes.ContainsKey(dtName)) { declaringTypes.Add(dtName, new List <KeyValuePair <string, PropertyInfo> >()); } var lst = declaringTypes[dtName]; lst.Add(pair); } foreach (var declaringType in declaringTypes) { StartNewLine(); generatedCode.AppendFormat(@"interface {0} with", declaringType.Key); IncreaseIndent(); foreach (var pair in declaringType.Value) { var propertyType = pair.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 initExpr = noCreateNew ? string.Format("Unchecked.defaultof<{0}>", GetGenericTypeName(propertyType, referred, nonamespace)) : string.Format("{0}()", GetGenericTypeName(propertyType, referred, nonamespace)); StartNewLine(); generatedCode.AppendFormat(@"override val {0} = {1} with get,set", pair.Key, initExpr); } DecreaseIndent(); } GenerateSetAll(asyncProperties, referred); GenerateAsDictionary(asyncProperties, referred); GenerateToString(stateClassName, asyncProperties, referred); // Generate the serialization members. StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.CopierMethodAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"static member public _Copier(original:obj) : obj ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"let input = original :?> {0}", stateClassBaseName); StartNewLine(); generatedCode.AppendFormat(@"input.DeepCopy() :> obj"); DecreaseIndent(); StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.SerializerMethodAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"static member public _Serializer(original:obj, stream:global.Orleans.Serialization.BinaryTokenStreamWriter, expected:System.Type) : unit ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"let input = original :?> {0}", stateClassBaseName); StartNewLine(); generatedCode.AppendFormat(@"input.SerializeTo(stream)"); DecreaseIndent(); StartNewLine(); StartNewLine(); generatedCode.AppendFormat(@"[<global.Orleans.CodeGeneration.DeserializerMethodAttribute()>]"); StartNewLine(); generatedCode.AppendFormat(@"static member public _Deserializer(expected:System.Type, stream:global.Orleans.Serialization.BinaryTokenStreamReader) : obj ="); IncreaseIndent(); StartNewLine(); generatedCode.AppendFormat(@"let result = {0}()", stateClassBaseName); StartNewLine(); generatedCode.AppendFormat(@"result.DeserializeFrom(stream)"); StartNewLine(); generatedCode.AppendFormat(@"result :> obj"); DecreaseIndent(); DecreaseIndent(); return(null); }
public CodeTypeParameterCollection(CodeTypeParameterCollection value) {}
/// <summary> /// Generates a wrapper method that takes arguments of the original method. /// </summary> protected override CodeTypeMember GetBasicReferenceMethod(MethodInfo methodInfo, CodeTypeParameterCollection genericTypeParam, bool isObserver) { throw new NotImplementedException("GetBasicReferenceMethod"); }
public void AddRange(CodeTypeParameterCollection value) { }
/// <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); }
internal static CodeMemberMethod GenerateCopier(string name, string typeName, CodeTypeParameterCollection genericTypeParams = null) { var copier = new CodeMemberMethod { Name = name }; copier.Attributes = (copier.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; copier.Attributes = (copier.Attributes & ~MemberAttributes.ScopeMask) | MemberAttributes.Static; copier.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(CopierMethodAttribute), CodeTypeReferenceOptions.GlobalReference))); copier.ReturnType = new CodeTypeReference(typeof(object)); copier.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "original")); copier.Statements.Add(new CodeVariableDeclarationStatement(typeName, "input", new CodeCastExpression(typeName, new CodeArgumentReferenceExpression("original")))); return(copier); }
internal void AddReferenceClass(GrainInterfaceData interfaceData) { bool isObserver = IsObserver(interfaceData.Type); CodeTypeParameterCollection genericTypeParam = interfaceData.GenericTypeParams; // Declare factory class var factoryClass = new CodeTypeDeclaration(interfaceData.FactoryClassBaseName); if (genericTypeParam != null) { factoryClass.TypeParameters.AddRange(genericTypeParam); } factoryClass.IsClass = true; factoryClass.TypeAttributes = interfaceData.Type.IsPublic ? TypeAttributes.Public : TypeAttributes.NotPublic; MarkAsGeneratedCode(factoryClass); AddFactoryMethods(interfaceData, factoryClass); AddCastMethods(interfaceData, true, factoryClass); if (ShouldGenerateObjectRefFactory(interfaceData)) { AddCreateObjectReferenceMethods(interfaceData, factoryClass); } int factoryClassIndex = ReferencedNamespace.Types.Add(factoryClass); var referenceClass = new CodeTypeDeclaration(interfaceData.ReferenceClassBaseName); if (genericTypeParam != null) { referenceClass.TypeParameters.AddRange(genericTypeParam); } referenceClass.IsClass = true; referenceClass.BaseTypes.Add(new CodeTypeReference(typeof(GrainReference), CodeTypeReferenceOptions.GlobalReference)); referenceClass.BaseTypes.Add(new CodeTypeReference(typeof(IAddressable), CodeTypeReferenceOptions.GlobalReference)); var tref = new CodeTypeReference(interfaceData.Type); if (genericTypeParam != null) { foreach (CodeTypeParameter tp in genericTypeParam) { tref.TypeArguments.Add(tp.Name); } } referenceClass.BaseTypes.Add(tref); MarkAsGeneratedCode(referenceClass); referenceClass.TypeAttributes = TypeAttributes.NestedAssembly; referenceClass.CustomAttributes.Add( new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializableAttribute)))); referenceClass.CustomAttributes.Add( new CodeAttributeDeclaration( new CodeTypeReference(typeof(GrainReferenceAttribute), CodeTypeReferenceOptions.GlobalReference), new CodeAttributeArgument( new CodePrimitiveExpression(interfaceData.Type.Namespace + "." + TypeUtils.GetParameterizedTemplateName((interfaceData.Type)))))); var baseReferenceConstructor2 = new CodeConstructor { Attributes = MemberAttributes.FamilyOrAssembly }; baseReferenceConstructor2.Parameters.Add(new CodeParameterDeclarationExpression( new CodeTypeReference(typeof(GrainReference), CodeTypeReferenceOptions.GlobalReference), "reference")); baseReferenceConstructor2.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("reference")); referenceClass.Members.Add(baseReferenceConstructor2); var baseReferenceConstructor3 = new CodeConstructor { Attributes = MemberAttributes.FamilyOrAssembly }; baseReferenceConstructor3.Parameters.Add(new CodeParameterDeclarationExpression("SerializationInfo", "info")); baseReferenceConstructor3.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("info")); baseReferenceConstructor3.Parameters.Add(new CodeParameterDeclarationExpression("StreamingContext", "context")); baseReferenceConstructor3.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("context")); referenceClass.Members.Add(baseReferenceConstructor3); var grainRef = new CodeTypeReference(typeof(GrainReference), CodeTypeReferenceOptions.GlobalReference); var refClassName = FixupTypeName(interfaceData.ReferenceClassName); // Copier, serializer, and deserializer for this type var copier = SerializerGenerationUtilities.GenerateCopier("_Copier", refClassName, genericTypeParam); copier.Statements.Add( new CodeMethodReturnStatement( new CodeCastExpression(refClassName, new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(grainRef), "CopyGrainReference", new CodeVariableReferenceExpression("input"))))); referenceClass.Members.Add(copier); var serializer = SerializerGenerationUtilities.GenerateSerializer("_Serializer", refClassName, genericTypeParam); serializer.Statements.Add( new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(grainRef), "SerializeGrainReference", new CodeVariableReferenceExpression("input"), new CodeArgumentReferenceExpression("stream"), new CodeArgumentReferenceExpression("expected"))); referenceClass.Members.Add(serializer); var deserializer = SerializerGenerationUtilities.GenerateDeserializer("_Deserializer", refClassName, genericTypeParam); deserializer.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(refClassName), "Cast", new CodeCastExpression(grainRef, new CodeMethodInvokeExpression( new CodeTypeReferenceExpression(grainRef), "DeserializeGrainReference", new CodeArgumentReferenceExpression("expected"), new CodeArgumentReferenceExpression("stream")))))); referenceClass.Members.Add(deserializer); // this private class is the "implementation class" for the interface reference type ReferencedNamespace.Types[factoryClassIndex].Members.Add(referenceClass); AddCastMethods(interfaceData, false, referenceClass); var interfaceId = GrainInterfaceData.GetGrainInterfaceId(interfaceData.Type); var interfaceIdMethod = new CodeMemberProperty { Name = "InterfaceId", Type = new CodeTypeReference(typeof(int)), Attributes = MemberAttributes.Family | MemberAttributes.Override, HasSet = false, HasGet = true }; interfaceIdMethod.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(interfaceId))); referenceClass.Members.Add(interfaceIdMethod); var left = new CodeBinaryOperatorExpression( new CodeArgumentReferenceExpression("interfaceId"), CodeBinaryOperatorType.ValueEquality, new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), "InterfaceId")); var interfaceList = GrainInterfaceData.GetRemoteInterfaces(interfaceData.Type); foreach (int iid in interfaceList.Keys) { if (iid == interfaceId) { continue; // already covered the main interfaces } left = new CodeBinaryOperatorExpression( left, CodeBinaryOperatorType.BooleanOr, new CodeBinaryOperatorExpression( new CodeArgumentReferenceExpression("interfaceId"), CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(iid))); } var interfaceIsCompatibleMethod = new CodeMemberMethod { Name = "IsCompatible", ReturnType = new CodeTypeReference(typeof(bool)) }; interfaceIsCompatibleMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "interfaceId")); interfaceIsCompatibleMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; interfaceIsCompatibleMethod.Statements.Add(new CodeMethodReturnStatement(left)); referenceClass.Members.Add(interfaceIsCompatibleMethod); var interfaceNameMethod = new CodeMemberProperty { Name = "InterfaceName", Type = new CodeTypeReference(typeof(string)), Attributes = MemberAttributes.Family | MemberAttributes.Override, HasSet = false, HasGet = true }; interfaceNameMethod.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(FixupTypeName(interfaceData.TypeFullName)))); referenceClass.Members.Add(interfaceNameMethod); var invokerClassName = interfaceData.InvokerClassName; var getMethodNameMethod = new CodeMemberMethod { Name = "GetMethodName", ReturnType = new CodeTypeReference(typeof(string)) }; getMethodNameMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "interfaceId")); getMethodNameMethod.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "methodId")); getMethodNameMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override; var methodInvokerName = string.Format("{0}.GetMethodName", FixupTypeName(invokerClassName)); getMethodNameMethod.Statements.Add( new CodeMethodReturnStatement( new CodeMethodInvokeExpression( null, methodInvokerName, new CodeArgumentReferenceExpression("interfaceId"), new CodeArgumentReferenceExpression("methodId")))); referenceClass.Members.Add(getMethodNameMethod); CodeTypeDeclaration invokerClass = GetInvokerClass(interfaceData, true); invokerClass.TypeAttributes = TypeAttributes.NotPublic; ReferencedNamespace.Types.Add(invokerClass); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Net")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.Serialization")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Runtime.Serialization.Formatters.Binary")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.IO")); ReferencedNamespace.Imports.Add(new CodeNamespaceImport("System.Collections.Generic")); MethodInfo[] methods = GrainInterfaceData.GetMethods(interfaceData.Type); AddMethods(methods, referenceClass, genericTypeParam, isObserver); }
internal static CodeMemberMethod GenerateSerializer(string name, string typeName, CodeTypeParameterCollection genericTypeParams = null) { var serializer = new CodeMemberMethod { Name = name }; serializer.Attributes = (serializer.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; serializer.Attributes = (serializer.Attributes & ~MemberAttributes.ScopeMask) | MemberAttributes.Static; serializer.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(SerializerMethodAttribute), CodeTypeReferenceOptions.GlobalReference))); serializer.ReturnType = new CodeTypeReference(typeof(void)); serializer.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "original")); serializer.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(BinaryTokenStreamWriter), CodeTypeReferenceOptions.GlobalReference), "stream")); serializer.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Type), "expected")); serializer.Statements.Add(new CodeVariableDeclarationStatement(typeName, "input", new CodeCastExpression(typeName, new CodeArgumentReferenceExpression("original")))); return(serializer); }
private void AddMethod(MethodInfo methodInfo, CodeTypeDeclaration referenceClass, CodeTypeParameterCollection genericTypeParam, bool isObserver) { if (methodInfo.IsStatic || IsSpecialEventMethod(methodInfo)) { return; // skip such methods } int methodId = GrainInterfaceData.ComputeMethodId(methodInfo); if (methodIdCollisionDetection.Contains(methodId)) { ReportErrorAndThrow(string.Format("Collision detected for method {0}, declaring type {1}, consider renaming method name", methodInfo.Name, methodInfo.DeclaringType.FullName)); } else { var code = GetBasicReferenceMethod(methodInfo, genericTypeParam, isObserver); referenceClass.Members.Add(code); // method with original argument types methodIdCollisionDetection.Add(methodId); } if (typeof(IAddressable).IsAssignableFrom(methodInfo.ReturnType)) { RecordReferencedNamespaceAndAssembly(methodInfo.ReturnType); } }
internal static CodeMemberMethod GenerateDeserializer(string name, string typeName, CodeTypeParameterCollection genericTypeParams = null) { var deserializer = new CodeMemberMethod { Name = name }; deserializer.Attributes = (deserializer.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; deserializer.Attributes = (deserializer.Attributes & ~MemberAttributes.ScopeMask) | MemberAttributes.Static; deserializer.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(DeserializerMethodAttribute), CodeTypeReferenceOptions.GlobalReference))); deserializer.ReturnType = new CodeTypeReference(typeof(object)); deserializer.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Type), "expected")); deserializer.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(BinaryTokenStreamReader), CodeTypeReferenceOptions.GlobalReference), "stream")); return(deserializer); }
private void ValidateTypeParameters(CodeTypeParameterCollection parameters) { for (int i = 0; i < parameters.Count; i++) { ValidateTypeParameter(parameters[i]); } }
static void PopulateGenericParameters(IGenericParameterProvider publicType, CodeTypeParameterCollection parameters, AttributeFilter attributeFilter, Func <GenericParameter, bool> shouldUseParameter) { foreach (var parameter in publicType.GenericParameters.Where(shouldUseParameter)) { // A little hacky. Means we get "in" and "out" prefixed on any constraints, but it's either that // or add it as a custom attribute var name = parameter.Name; if (parameter.IsCovariant) { name = "out " + name; } if (parameter.IsContravariant) { name = "in " + name; } var attributeCollection = new CodeAttributeDeclarationCollection(); if (parameter.HasCustomAttributes) { PopulateCustomAttributes(parameter, attributeCollection, attributeFilter); } var typeParameter = new CodeTypeParameter(name) { HasConstructorConstraint = parameter.HasDefaultConstructorConstraint && !parameter.HasNotNullableValueTypeConstraint }; typeParameter.CustomAttributes.AddRange(attributeCollection.OfType <CodeAttributeDeclaration>().ToArray()); var nullableConstraint = parameter.GetNullabilityMap().First(); var unmanagedConstraint = parameter.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.Runtime.CompilerServices.IsUnmanagedAttribute"); if (parameter.HasNotNullableValueTypeConstraint) { typeParameter.Constraints.Add(unmanagedConstraint ? " unmanaged" : " struct"); } if (parameter.HasReferenceTypeConstraint) { typeParameter.Constraints.Add(nullableConstraint == true ? " class?" : " class"); } else if (nullableConstraint == false) { typeParameter.Constraints.Add(" notnull"); } using (NullableContext.Push(parameter)) { foreach (var constraint in parameter.Constraints.Where(constraint => !IsSpecialConstraint(constraint))) { // for generic constraints like IEnumerable<T> call to GetElementType() returns TypeReference with Name = !0 var typeReference = constraint.ConstraintType /*.GetElementType()*/.CreateCodeTypeReference(constraint); typeParameter.Constraints.Add(typeReference); } } parameters.Add(typeParameter); } bool IsSpecialConstraint(GenericParameterConstraint constraint) { // struct if (constraint.ConstraintType is TypeReference reference && reference.FullName == "System.ValueType") { return(true); } // unmanaged if (constraint.ConstraintType.IsUnmanaged()) { return(true); } return(false); } }