Exemplo n.º 1
0
        public override object VisitMethod_declaration([NotNull] NyaParser.Method_declarationContext context)
        {
            // TODO: Break out constructor logic to new method

            string methodName = context.identifier().GetText();

            MethodDescriptor descriptor = new MethodDescriptor()
            {
                Name    = methodName,
                Context = context
            };

            if (_currentDescriptor != null)
            {
                _currentDescriptor.Methods.Add(descriptor);
            }
            else
            {
                GlobalMethods.Add(descriptor);
            }

            return(descriptor);
        }
Exemplo n.º 2
0
 public override object VisitMethod_declaration([NotNull] NyaParser.Method_declarationContext context)
 {
     return(null);
 }
Exemplo n.º 3
0
        private void BuildMethod(ModuleBuilder moduleBuilder, MethodDescriptor meth, NyaParser.Method_declarationContext context)
        {
            string methodName = context.identifier().GetText();
            bool   bIsEntry   = false;

            meth.IsStatic      = context.IsStatic != null;
            meth.IsConstructor = methodName == "New";

            MethodAttributes methAttrs = MethodAttributes.Private | MethodAttributes.HideBySig;

            if (meth.IsStatic)
            {
                methAttrs |= MethodAttributes.Static;
            }

            if (meth.IsConstructor)
            {
                methodName = meth.IsStatic ? ".cctor" : ".ctor";
                methAttrs |= MethodAttributes.SpecialName;
            }

            meth.IsFinal = true;

            foreach (var attr in context.attributes()?.children?
                     .OfType <NyaParser.AttributeContext>() ?? new NyaParser.AttributeContext[] { })
            {
                string attrName = attr.identifier().GetText();
                switch (attrName)
                {
                case "entry":
                    bIsEntry = true;
                    break;

                case "public":
                    methAttrs ^= MethodAttributes.Private;
                    methAttrs |= MethodAttributes.Public;
                    break;

                case "virtual":
                    methAttrs |= MethodAttributes.Virtual;
                    break;

                case "abstract":
                    methAttrs |= MethodAttributes.Abstract;
                    break;
                }
            }

            var parameters = context.fixed_parameters()?.children?
                             .OfType <NyaParser.Fixed_parameterContext>() ?? new NyaParser.Fixed_parameterContext[] { };

            meth.ParameterTypes = parameters.Select(x => ParseTypeDescriptor(x.type_descriptor())).ToArray();
            Type returnType = ParseTypeDescriptor(context.type_descriptor());

            MethodInfo baseMethod = FindParentDefinition(_currTypeBuilder, methodName, meth.ParameterTypes);

            MethodBuilder methodBuilder;

            if (baseMethod != null)
            {
                if (baseMethod.IsVirtual && !baseMethod.IsFinal)
                {
                    if ((methAttrs & MethodAttributes.Virtual) != MethodAttributes.Virtual)
                    {
                        methAttrs |= MethodAttributes.Final;
                    }
                    methAttrs |= MethodAttributes.Virtual;
                    if (baseMethod.DeclaringType.IsInterface)
                    {
                        methAttrs |= MethodAttributes.NewSlot;
                    }

                    if ((methAttrs & MethodAttributes.Public) != MethodAttributes.Public)
                    {
                        throw new Exception("Oy! This needs to be public!");
                    }
                }
                if (methodName == ".ctor" && !baseMethod.IsPublic)
                {
                    throw new Exception("Oy! The base constructor needs to be public!");
                }
            }

            if (_currTypeBuilder != null)
            {
                methodBuilder = _currTypeBuilder.DefineMethod(methodName, methAttrs, returnType, meth.ParameterTypes);
            }
            else
            {
                methAttrs    |= MethodAttributes.Static;
                methodBuilder = moduleBuilder.DefineGlobalMethod(methodName, methAttrs, returnType, meth.ParameterTypes);
            }

            for (int i = 0; i < parameters.Count(); i++)
            {
                var    param     = parameters.ElementAt(i);
                string paramName = param.identifier().GetText();

                ParameterAttributes pAttrs = ParameterAttributes.None;

                ParameterBuilder pb = methodBuilder.DefineParameter(i + 1, pAttrs, paramName);
                meth.Parameters.Add(pb);

                if (param.Question() != null || param.literal() != null)
                {
                    pb.SetCustomAttribute(
                        new CustomAttributeBuilder(
                            typeof(OptionalAttribute).GetConstructor(new Type[] { }),
                            new object[] { })
                        );

                    if (param.literal() != null)
                    {
                        object o = Visit(param.literal());

                        if (o != null)
                        {
                            pb.SetConstant(o);
                        }
                    }
                }
            }

            if (bIsEntry)
            {
                AssemblyBuilder.SetEntryPoint(methodBuilder, PEFileKinds.ConsoleApplication);
            }

            meth.Builder = methodBuilder;
        }