示例#1
0
        public static Type GenerateInterface(string iName, IPersistentMap attributes, Seqable extends, ISeq methods)
        {
            iName = iName.Replace('-', '_');

            GenContext context;

            if (Compiler.IsCompiling)
            {
                //string path = (string)Compiler.COMPILE_PATH.deref();
                //if (path == null)
                //    throw new Exception("*compile-path* not set");
                //context = new GenContext(iName, ".dll", path, CompilerMode.File);
                context = (GenContext)Compiler.CompilerContextVar.deref();
            }
            else
            {
                // TODO: In CLR4, should create a collectible type?
                context = GenContext.CreateWithExternalAssembly(iName + "_" + RT.nextID(), ".dll", false);
            }

            for (ISeq s = RT.seq(extends); s != null; s = s.next())
            {
                object f    = s.first();
                string name = f as String ?? ((Named)f).getName();

                if (name.Contains("-"))
                {
                    throw new ArgumentException("Interface methods must not contain '-'");
                }
            }


            Type[] interfaceTypes = GenClass.CreateTypeArray(extends?.seq());

            TypeBuilder proxyTB = context.ModuleBuilder.DefineType(
                iName,
                TypeAttributes.Interface | TypeAttributes.Public | TypeAttributes.Abstract,
                null,
                interfaceTypes);

            // Should we associate source file info?
            // See Java committ 8d6fdb, 2015.07.17, related to CLJ-1645
            // TODO: part of check on debug info

            SetCustomAttributes(proxyTB, attributes);

            DefineMethods(proxyTB, methods);

            Type t = proxyTB.CreateType();

            //if ( Compiler.IsCompiling )
            //    context.SaveAssembly();

            Compiler.RegisterDuplicateType(t);

            return(t);
        }
        public static Type GenerateInterface(string iName, IPersistentMap attributes, Seqable extends, ISeq methods)
        {
            iName = iName.Replace('-', '_');

            GenContext context;

            if (Compiler.IsCompiling)
            {
                //string path = (string)Compiler.COMPILE_PATH.deref();
                //if (path == null)
                //    throw new Exception("*compile-path* not set");
                //context = new GenContext(iName, ".dll", path, CompilerMode.File);
                context = (GenContext)Compiler.CompilerContextVar.deref();
            }
            else
            {
                // TODO: In CLR4, should create a collectible type?
                context = GenContext.CreateWithExternalAssembly(iName, ".dll", false);
            }

            Type[] interfaceTypes = GenClass.CreateTypeArray(extends == null ? null : extends.seq());

            TypeBuilder proxyTB = context.ModuleBuilder.DefineType(
                iName,
                TypeAttributes.Interface | TypeAttributes.Public | TypeAttributes.Abstract,
                null,
                interfaceTypes);

            SetCustomAttributes(proxyTB, attributes);

            DefineMethods(proxyTB, methods);

            Type t = proxyTB.CreateType();

            //if ( Compiler.IsCompiling )
            //    context.SaveAssembly();

            Compiler.RegisterDuplicateType(t);

            return(t);
        }
        private static void DefineMethod(TypeBuilder proxyTB, IPersistentVector sig)
        {
            Symbol mname = (Symbol)sig.nth(0);

            Type[] paramTypes = GenClass.CreateTypeArray((ISeq)sig.nth(1));
            Type   retType    = (Type)sig.nth(2);
            ISeq   pmetas     = (ISeq)(sig.count() >= 4 ? sig.nth(3) : null);

            MethodBuilder mb = proxyTB.DefineMethod(mname.Name, MethodAttributes.Abstract | MethodAttributes.Public | MethodAttributes.Virtual, retType, paramTypes);

            SetCustomAttributes(mb, GenInterface.ExtractAttributes(RT.meta(mname)));
            int i = 1;

            for (ISeq s = pmetas; s != null; s = s.next(), i++)
            {
                IPersistentMap meta = GenInterface.ExtractAttributes((IPersistentMap)s.first());
                if (meta != null && meta.count() > 0)
                {
                    ParameterBuilder pb = mb.DefineParameter(i, ParameterAttributes.None, String.Format("p_{0}", i));
                    GenInterface.SetCustomAttributes(pb, meta);
                }
            }
        }