public override void VisitEnumDeclaration(EnumDeclarationSyntax node) { _memberCollector = new EnumMemberValueCollector(); node.Accept(_memberCollector); var enumType = TempLocalVar(node.Identifier.ValueText); var attrs = ModifiersToCecil("TypeAttributes", node.Modifiers, "Private"); var typeDef = CecilDefinitionsFactory.Type(Context, enumType, node.Identifier.ValueText, attrs + " | TypeAttributes.Sealed", Context.TypeResolver.Resolve("System.Enum"), false, Array.Empty <string>()); AddCecilExpressions(typeDef); using (Context.DefinitionVariables.WithCurrent(node.Parent.IsKind(SyntaxKind.CompilationUnit) ? "" : node.Parent.ResolveDeclaringType().Identifier.ValueText, node.Identifier.ValueText, MemberKind.Type, enumType)) { //.class private auto ansi MyEnum //TODO: introduce TypeSystem.CoreLib.Enum/Action/etc... var fieldVar = MethodExtensions.LocalVariableNameFor("valueField", node.Identifier.ValueText); var valueFieldExp = CecilDefinitionsFactory.Field(enumType, fieldVar, "value__", "assembly.MainModule.TypeSystem.Int32", "FieldAttributes.SpecialName | FieldAttributes.RTSpecialName | FieldAttributes.Public"); AddCecilExpressions(valueFieldExp); HandleAttributesInMemberDeclaration(node.AttributeLists, enumType); base.VisitEnumDeclaration(node); } }
private string HandleTypeDeclaration(TypeDeclarationSyntax node, string baseType) { var varName = LocalVariableNameForId(NextLocalVariableTypeId()); var isStructWithNoFields = node.Kind() == SyntaxKind.StructDeclaration && node.Members.Count == 0; var typeDefinitionExp = CecilDefinitionsFactory.Type( Context, varName, node.Identifier.ValueText, TypeModifiersToCecil(node), baseType, isStructWithNoFields, ImplementedInterfacesFor(node.BaseList).Select(i => Context.TypeResolver.Resolve(i)), node.TypeParameterList); AddCecilExpressions(typeDefinitionExp); if (baseType != null) { // we postpone setting the base type because it may depend on generic parameters defined in the class itself (for instance 'class C<T> : Base<T> {}') // and these are introduced by the code in CecilDefinitionsFactory.Type(). WriteCecilExpression(Context, $"{varName}.BaseType = {ProcessBase(node)};"); } EnsureCurrentTypeHasADefaultCtor(node, varName); HandleAttributesInMemberDeclaration(node.AttributeLists, varName); Context.WriteCecilExpression(Environment.NewLine); return(varName); }
public override void VisitDelegateDeclaration(DelegateDeclarationSyntax node) { var typeVar = LocalVariableNameForId(NextLocalVariableTypeId()); var accessibility = ModifiersToCecil("TypeAttributes", node.Modifiers, "Private"); var typeDef = CecilDefinitionsFactory.Type( Context, typeVar, node.Identifier.ValueText, DefaultTypeAttributeFor(node).AppendModifier(accessibility), Context.TypeResolver.Resolve("System.MulticastDelegate"), false, Array.Empty <string>(), node.TypeParameterList, "IsAnsiClass = true"); AddCecilExpressions(typeDef); HandleAttributesInMemberDeclaration(node.AttributeLists, typeVar); using (Context.DefinitionVariables.WithCurrent("", node.Identifier.ValueText, MemberKind.Type, typeVar)) { // Delegate ctor AddCecilExpression(CecilDefinitionsFactory.Constructor(Context, out var ctorLocalVar, node.Identifier.Text, "MethodAttributes.FamANDAssem | MethodAttributes.Family", new[] { "System.Object", "System.IntPtr" }, "IsRuntime = true")); AddCecilExpression($"{ctorLocalVar}.Parameters.Add(new ParameterDefinition({Context.TypeResolver.ResolvePredefinedType("Object")}));"); AddCecilExpression($"{ctorLocalVar}.Parameters.Add(new ParameterDefinition({Context.TypeResolver.ResolvePredefinedType("IntPtr")}));"); AddCecilExpression($"{typeVar}.Methods.Add({ctorLocalVar});"); AddDelegateMethod(typeVar, "Invoke", ResolveType(node.ReturnType), node.ParameterList.Parameters, (methodVar, param) => CecilDefinitionsFactory.Parameter(param, Context.SemanticModel, methodVar, TempLocalVar($"{param.Identifier.ValueText}"), ResolveType(param.Type))); // BeginInvoke() method var beginInvokeMethodVar = TempLocalVar("beginInvoke"); AddCecilExpression( $@"var {beginInvokeMethodVar} = new MethodDefinition(""BeginInvoke"", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, {Context.TypeResolver.Resolve("System.IAsyncResult")}) {{ HasThis = true, IsRuntime = true, }};" ); foreach (var param in node.ParameterList.Parameters) { var paramExps = CecilDefinitionsFactory.Parameter(param, Context.SemanticModel, beginInvokeMethodVar, TempLocalVar($"{param.Identifier.ValueText}"), ResolveType(param.Type)); AddCecilExpressions(paramExps); } AddCecilExpression($"{beginInvokeMethodVar}.Parameters.Add(new ParameterDefinition({Context.TypeResolver.Resolve("System.AsyncCallback")}));"); AddCecilExpression($"{beginInvokeMethodVar}.Parameters.Add(new ParameterDefinition({Context.TypeResolver.ResolvePredefinedType("Object")}));"); AddCecilExpression($"{typeVar}.Methods.Add({beginInvokeMethodVar});"); AddDelegateMethod(typeVar, "EndInvoke", ResolveType(node.ReturnType), node.ParameterList.Parameters, (methodVar, param) => CecilDefinitionsFactory.Parameter(param, Context.SemanticModel, methodVar, TempLocalVar("ar"), Context.TypeResolver.Resolve("System.IAsyncResult"))); base.VisitDelegateDeclaration(node); } void AddDelegateMethod(string typeLocalVar, string methodName, string returnTypeName, in SeparatedSyntaxList <ParameterSyntax> parameters, Func <string, ParameterSyntax, IEnumerable <string> > paramterHandler) { var methodLocalVar = TempLocalVar(methodName.ToLower()); AddCecilExpression( $@"var {methodLocalVar} = new MethodDefinition(""{methodName}"", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, {returnTypeName}) {{ HasThis = true, IsRuntime = true, }};" ); foreach (var param in parameters) { AddCecilExpressions(paramterHandler(methodLocalVar, param)); } AddCecilExpression($"{typeLocalVar}.Methods.Add({methodLocalVar});"); } }