예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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});");
            }
        }