Ejemplo n.º 1
0
    Type complete_singleton_type(singleton_entry entry)
    {
        TypeBuilder type_builder = entry.m_type_builder;
        XSingletonTypeDescription2 xSingletonType = entry.m_xType;
        string sSingletonName = to_cts_name(xSingletonType.getName());

        // Create the private default constructor
        ConstructorBuilder ctor_builder =
            type_builder.DefineConstructor((MethodAttributes.Private |
                                            MethodAttributes.HideBySig |
                                            MethodAttributes.SpecialName |
                                            MethodAttributes.RTSpecialName),
                                           CallingConventions.Standard, null);

        ILGenerator ilGen = ctor_builder.GetILGenerator();
        ilGen.Emit(OpCodes.Ldarg_0); // push this
        ilGen.Emit(OpCodes.Call,
                   type_builder.BaseType.GetConstructor(new Type[0]));
        ilGen.Emit(OpCodes.Ret);

        // obtain the interface which makes up this service, it is the return
        // type of the constructor functions
        XInterfaceTypeDescription2 xIfaceType =
            xSingletonType.getInterface() as XInterfaceTypeDescription2;

        if (xIfaceType == null)
            xIfaceType = resolveInterfaceTypedef(
                xSingletonType.getInterface());
        Type retType = get_type(xIfaceType);

        // Create the ConstructorInfo for a DeploymentException
        Type typeDeploymentExc =
            get_type("unoidl.com.sun.star.uno.DeploymentException", true);

        Type[] typeCtor = new Type[] { typeof(System.String),
                                       typeof(System.Object) };
        ConstructorInfo ctorDeploymentException =
            typeDeploymentExc.GetConstructor(typeCtor);

        // define method
        Type[] typeParameters =
            new Type[] { get_type(
                             "unoidl.com.sun.star.uno.XComponentContext",
                             true) };
        MethodBuilder method_builder = type_builder.DefineMethod(
            "get",
            (MethodAttributes.Public |
             MethodAttributes.HideBySig |
             MethodAttributes.Static),
            retType,
            typeParameters);

        //    method_builder.SetCustomAttribute(get_service_ctor_method_attribute(ctorDes));

        // The first parameter is the XComponentContext, which cannot be
        // obtained using reflection.
        // The context is not part of the idl description
        /* ParameterBuilder param_builder = */ method_builder.DefineParameter(
            1, ParameterAttributes.In, "the_context");

        ilGen = method_builder.GetILGenerator();
        // Define locals
        // Any, returned by XComponentContext.getValueByName
        LocalBuilder local_any = ilGen.DeclareLocal(typeof(uno.Any));

        // Call XContext.getValueByName
        ilGen.Emit(OpCodes.Ldarg_0);
        // build the singleton name: /singleton/unoidl.com.sun.star.XXX
        ilGen.Emit(OpCodes.Ldstr, "/singletons/" + sSingletonName);

        MethodInfo methodGetValueByName =
            get_type("unoidl.com.sun.star.uno.XComponentContext",
                     true).GetMethod("getValueByName");
        ilGen.Emit(OpCodes.Callvirt, methodGetValueByName);
        ilGen.Emit(OpCodes.Stloc_0);

        // Does the returned Any contain a value?
        ilGen.Emit(OpCodes.Ldloca_S, local_any);
        MethodInfo methodHasValue = typeof(uno.Any).GetMethod("hasValue");
        ilGen.Emit(OpCodes.Call, methodHasValue);

        // If not, then throw a DeploymentException
        Label label_singleton_exists = ilGen.DefineLabel();
        ilGen.Emit(OpCodes.Brtrue_S, label_singleton_exists);
        ilGen.Emit(OpCodes.Ldstr,
                   "Component context fails to supply singleton " +
                   sSingletonName + " of type " + retType.FullName + ".");
        ilGen.Emit(OpCodes.Ldarg_0);
        ilGen.Emit(OpCodes.Newobj, ctorDeploymentException);
        ilGen.Emit(OpCodes.Throw);
        ilGen.MarkLabel(label_singleton_exists);

        // Cast the singleton contained in the Any to the expected
        // interface and return it.
        ilGen.Emit(OpCodes.Ldloca_S, local_any);
        ilGen.Emit(OpCodes.Call,
                   typeof(uno.Any).GetProperty("Value").GetGetMethod());
        ilGen.Emit(OpCodes.Castclass, retType);
        ilGen.Emit(OpCodes.Ret);

        // remove from incomplete singletons map
        m_incomplete_singletons.Remove(type_builder.FullName);

        if (Climaker.g_verbose)
        {
            Console.WriteLine("> emitting singleton type {0}",
                              type_builder.FullName);
        }

        return type_builder.CreateType();
    }
Ejemplo n.º 2
0
    Type get_type(XSingletonTypeDescription2 xType)
    {
        if (!xType.isInterfaceBased())
            return null;

        string cts_name = to_cts_name(xType.getName());
        Type ret_type = get_type(cts_name, false /* no exc */);
        if (ret_type != null)
            return ret_type;

        TypeAttributes attr = (TypeAttributes.Public |
                               TypeAttributes.Sealed |
                               TypeAttributes.BeforeFieldInit |
                               TypeAttributes.AnsiClass);

        TypeBuilder type_builder = m_module_builder.DefineType(cts_name, attr);

        // insert to be completed
        singleton_entry entry = new singleton_entry();
        entry.m_xType = xType;
        entry.m_type_builder = type_builder;
        m_incomplete_singletons.Add(cts_name, entry);

        return type_builder;
    }