Пример #1
0
        /// <summary>
        /// Create app widget provider xml file.
        /// </summary>
        private void CreateAppWidgetProviderFile(string tempFolder, int index, CustomAttribute attr)
        {
            var resourceName = AppWidgetProviderResource.GetResourceName(index);
            var path         = Path.Combine(Path.Combine(tempFolder, @"res\xml"), resourceName + ".xml");

            var doc  = new XDocument();
            var root = new XElement("appwidget-provider");

            doc.Add(root);

            root.AddAttrIfNotEmpty("minWidth", Namespace, attr.GetValue <string>("MinWidth"));
            root.AddAttrIfNotEmpty("minHeight", Namespace, attr.GetValue <string>("MinHeight"));
            root.AddAttrIfNotDefault("updatePeriodMillis", Namespace, attr.GetValue <long>("UpdatePeriod"), 0L);
            root.AddAttrIfNotEmpty("previewImage", Namespace, attr.GetValue <string>("PreviewImage"), FormatDrawable);
            root.AddAttrIfNotEmpty("initialLayout", Namespace, attr.GetValue <string>("InitialLayout"), FormatLayout);
            var configureActivityType = attr.GetValue <TypeReference>("ConfigureActivity");

            if (configureActivityType != null)
            {
                var configureActivityTypeDef = configureActivityType.Resolve();
                if (configureActivityTypeDef == null)
                {
                    throw new ArgumentException("Cannot resolve " + configureActivityType.FullName);
                }
                root.AddAttr("configure", Namespace, FormatClassName(XBuilder.AsTypeDefinition(module, configureActivityTypeDef)));
            }
            root.AddAttrIfNotDefault("resizeMode", Namespace, attr.GetValue <int>("ResizeMode"), 0, widgetResizeModesOptions.Format);
            root.AddAttrIfNotDefault("widgetCategory", Namespace, attr.GetValue <int>("Category"), 0, widgetCategoriesOptions.Format);
            root.AddAttrIfNotEmpty("initialKeyguardLayout", Namespace, attr.GetValue <string>("InitialKeyguardLayout"), FormatLayout);

            Directory.CreateDirectory(Path.GetDirectoryName(path));
            doc.Save(path);
        }
Пример #2
0
        /// <summary>
        /// Create all provider elements
        /// </summary>
        private void CreateProvider(XElement manifest)
        {
            // Create services
            foreach (var tuple in FindProviders())
            {
                var type  = tuple.Item1;
                var xType = XBuilder.AsTypeDefinition(module, type);
                var attr  = tuple.Item2;

                var provider = new XElement("provider");
                manifest.Add(provider);

                provider.AddAttr("name", Namespace, FormatClassName(xType));
                var authoritiesArr = (attr != null) ? attr.GetValue <string[]>("Authorities") : null;
                if (authoritiesArr != null && authoritiesArr.Any())
                {
                    //semicolon seperated list
                    provider.AddAttr("authorities", Namespace, string.Join(";", authoritiesArr));
                }
                provider.AddAttrIfFound("enabled", Namespace, attr, "Enabled");
                provider.AddAttrIfFound("exported", Namespace, attr, "Exported");
                provider.AddAttrIfFound("grantUriPermissions", Namespace, attr, "GrantUriPermissions");
                provider.AddAttrIfNotEmpty("icon", Namespace, attr.GetValue <string>("Icon"), FormatDrawable);
                provider.AddAttrIfNotEmpty("label", Namespace, attr.GetValue <string>("Label"), FormatStringOrLiteral);
                provider.AddAttrIfFound("multiprocess", Namespace, attr, "MultiProcess");
                provider.AddAttrIfNotEmpty("permission", Namespace, attr.GetValue <string>("Permission"));
                provider.AddAttrIfNotEmpty("process", Namespace, attr.GetValue <string>("Process"));
                provider.AddAttrIfNotEmpty("readPermission", Namespace, attr.GetValue <string>("ReadPermission"));
                provider.AddAttrIfFound("syncable", Namespace, attr, "Syncable");
                provider.AddAttrIfNotEmpty("writePermission", Namespace, attr.GetValue <string>("WritePermission"));
            }
        }
Пример #3
0
        /// <summary>
        /// Create all service elements
        /// </summary>
        private void CreateService(XElement application)
        {
            // Create services
            foreach (var tuple in FindServices())
            {
                var type  = tuple.Item1;
                var xType = XBuilder.AsTypeDefinition(module, type);
                var attr  = tuple.Item2;

                var service = new XElement("service");
                application.Add(service);

                service.AddAttr("name", Namespace, FormatClassName(xType));
                service.AddAttrIfNotEmpty("label", Namespace, attr.GetValue <string>("Label"), FormatStringOrLiteral);
                service.AddAttrIfNotEmpty("icon", Namespace, attr.GetValue <string>("Icon"), FormatDrawable);
                service.AddAttrIfFound("enabled", Namespace, attr, "Enabled");
                service.AddAttrIfFound("exported", Namespace, attr, "Exporter");
                service.AddAttrIfFound("isolatedProcess", Namespace, attr, "IsolatedProcess");
                service.AddAttrIfNotEmpty("permission", Namespace, attr.GetValue <string>("Permission"));
                service.AddAttrIfNotEmpty("process", Namespace, attr.GetValue <string>("Process"));
                service.AddAttrIfFound("stopWithTask", Namespace, attr, "StopWithTask");

                CreateIntentFilter(service, type, false, false);
                CreateMetaData(service, type);
            }
        }
Пример #4
0
        /// <summary>
        /// Create the application element
        /// </summary>
        private void CreateApplication(Targets target, XElement manifest, string outputFolder)
        {
            // Find application attribute
            var appTuple = FindApplication();
            var attr     = appTuple.Item2;

            var label = attr.GetValue <string>(0, "Label");

            if (string.IsNullOrEmpty(label))
            {
                throw new ArgumentException(string.Format("No Label set in {0}", attr));
            }
            var icon = attr.GetValue <string>("Icon");

            if (string.IsNullOrEmpty(icon))
            {
                // Select icon from activity
                var activityIcons = FindActivities().Select(x => x.Item2.GetValue <string>("Icon")).Where(x => !string.IsNullOrEmpty(x));
                icon = activityIcons.FirstOrDefault();
            }
            // Create application
            var application = new XElement("application");

            manifest.Add(application);
            application.AddAttr("label", Namespace, FormatStringOrLiteral(label));
            if (appTuple.Item1 != null)
            {
                var xType = XBuilder.AsTypeDefinition(module, appTuple.Item1);
                application.AddAttr("name", Namespace, FormatClassName(xType));
            }
            application.AddAttrIfNotEmpty("icon", Namespace, icon, FormatDrawable);
            application.AddAttrIfNotEmpty("theme", Namespace, attr.GetValue <string>("Theme"), FormatStyle);
            application.AddAttrIfNotEmpty("description", Namespace, attr.GetValue <string>("Description"));
            application.AddAttrIfNotEmpty("logo", Namespace, attr.GetValue <string>("Logo"), FormatDrawable);
            application.AddAttrIfNotDefault("debuggable", Namespace, attr.GetValue <bool>("Debuggable", debuggable), false);
            application.AddAttrIfFound("enabled", Namespace, attr, "Enabled");
            application.AddAttrIfNotDefault("persistent", Namespace, attr.GetValue <bool>("Persistent"), false);
            application.AddAttrIfFound("allowTaskReparenting", Namespace, attr, "AllowTaskReparenting");
            application.AddAttrIfNotEmpty("backupAgent", Namespace, attr.GetValue <Type>("BackupAgent"), nsConverter.GetConvertedFullName);
            application.AddAttrIfFound("hardwareAccelerated", Namespace, attr, "HardwareAccelerated");
            application.AddAttrIfFound("killAfterRestore", Namespace, attr, "KillAfterRestore");
            application.AddAttrIfFound("largeHeap", Namespace, attr, "LargeHeap");
            application.AddAttrIfNotEmpty("manageSpaceActivity", Namespace, attr.GetValue <Type>("ManageSpaceActivity"), nsConverter.GetConvertedFullName);
            application.AddAttrIfNotEmpty("process", Namespace, attr.GetValue <string>("Process"));
            application.AddAttrIfFound("restoreAnyVersion", Namespace, attr, "RestoreAnyVersion");
            application.AddAttrIfNotEmpty("taskAffinity", Namespace, attr.GetValue <string>("TaskAffinity"));
            application.AddAttrIfNotDefault("uiOptions", Namespace, attr.GetValue <int>("UIOptions"), 0, uiOptions.Format);

            // Create child elements
            CreateActivity(application);
            CreateService(application);
            CreateReceiver(application);
            CreateAppWidgetProvider(application, outputFolder);
            CreateUsesLibrary(application);
            CreateProvider(application);
            CreateMetaData(application, assembly); // Must be last
        }
Пример #5
0
        /// <summary>
        /// Gets the type of this variable.
        /// </summary>
        protected override TTypeRef GetType <TTypeRef>(ITypeResolver <TTypeRef> typeResolver)
        {
            if ((originalVariable == null) || (originalVariable.VariableType == null))
            {
                return(default(TTypeRef));
            }
            var xVarType = XBuilder.AsTypeReference(Type.Module, originalVariable.VariableType);

            return(typeResolver.GetTypeReference(xVarType));
        }
Пример #6
0
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public virtual void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            // Find xfield
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield      = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);

            // Give warning if static in generic class.
            // This could of cause also be handled automagically be the compiler,
            // with mixture of whats done in the Interlocked converter and whats
            // done in the GenericInstanceConverter.
            if (field.IsStatic && declaringType.IsGenericClass)
            {
                if (!field.HasSuppressMessageAttribute("StaticFieldInGenericType") &&
                    !field.DeclaringType.HasSuppressMessageAttribute("StaticFieldInGenericType"))
                {
                    string msg;
                    if (field.Name.Contains("CachedAnonymousMethodDelegate"))
                    {
                        msg = "The compiler generated a static field '{0}' in generic type '{1}'. This is not supported " +
                              "in Dot42 if the anonymous delegate accesses a generic class parameter. A workaround " +
                              "is to convert the anonymous static delegate to a normal method.\n";
                    }
                    else
                    {
                        msg = "Static field '{0}' in generic type {1}: All generic instances will share " +
                              "the same static field, contrary on how CLR operates. A workaround is to " +
                              "use ConcurrentDictionaries to access the values dependent on the type.\n";
                    }

                    msg += "You can suppress this warning with a [SuppressMessage(\"dot42\"," +
                           " \"StaticFieldInGenericType\")] attribute, either on the field or on the class.";

                    var body = field.DeclaringType.Methods.Select(m => m.Body)
                               .FirstOrDefault(m => m != null &&
                                               m.Instructions.Any(i => i.SequencePoint(m) != null));
                    if (body != null)
                    {
                        var seqPoint = body.Instructions.Select(i => i.SequencePoint(body)).First(i => i != null);
                        DLog.Warning(DContext.CompilerILConverter, seqPoint.Document.Url, seqPoint.StartColumn, seqPoint.StartLine, msg, field.Name, declaringType.FullName);
                    }
                    else
                    {
                        DLog.Warning(DContext.CompilerILConverter, msg, field.Name, declaringType.FullName);
                    }
                }
            }
        }
Пример #7
0
        /// <summary>
        /// Gets a class reference for the given type reference.
        /// </summary>
        internal static TypeReference GetReference(this Mono.Cecil.TypeReference type, DexTargetPackage targetPackage, XModule module)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var xType = XBuilder.AsTypeReference(module, type);

            return(xType.GetReference(targetPackage));
        }
Пример #8
0
        /// <summary>
        /// Gets a Dex method reference for the given type reference.
        /// </summary>
        internal static MethodReference GetReference(this Mono.Cecil.MethodReference method, DexTargetPackage targetPackage, XModule module)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            var xMethod = XBuilder.AsMethodReference(module, method);

            return(xMethod.GetReference(targetPackage));
        }
Пример #9
0
        /// <summary>
        /// Gets a Dex field reference for the given field reference.
        /// </summary>
        internal static FieldReference GetReference(this Mono.Cecil.FieldReference field, DexTargetPackage targetPackage, XModule module)
        {
            if (field == null)
            {
                throw new ArgumentNullException("field");
            }

            var xField = XBuilder.AsFieldReference(module, field);

            return(xField.GetReference(targetPackage));
        }
Пример #10
0
        /// <summary>
        /// Gets a class reference for the given type reference.
        /// </summary>
        internal static TypeReference GetReference(this JvmClassLib.TypeReference type, XTypeUsageFlags usageFlags, DexTargetPackage targetPackage, XModule module)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            var xType = XBuilder.AsTypeReference(module, type, usageFlags);

            return(xType.GetReference(targetPackage));
        }
        /// <summary>
        /// Gets all constructors that have to be wrapped in this class.
        /// </summary>
        protected virtual IEnumerable <XMethodDefinition> GetBaseClassCtors()
        {
            var baseTypeRef = Type.BaseType;
            var baseType    = (baseTypeRef != null) ? baseTypeRef.Resolve() : null;

            if (baseType == null)
            {
                return(Enumerable.Empty <XMethodDefinition>());
            }
            return(baseType.Methods.Where(x => x.IsReachable && !x.IsStatic && x.IsConstructor && !x.IsPrivate)
                   .Select(x => XBuilder.AsMethodDefinition(Compiler.Module, x)));
        }
Пример #12
0
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public void Create(ClassDefinition declaringClass, DexTargetPackage targetPackage)
        {
            // Find xField
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield      = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);
        }
Пример #13
0
        protected override XTypeDefinition CreateXType(XTypeDefinition parentXType)
        {
            var typeDef = (XBuilder.ILTypeDefinition)XBuilder.AsTypeReference(Compiler.Module, Type)
                          .Resolve();

            string name = NameConverter.GetNullableClassName(typeDef.Name);

            XSyntheticTypeFlags xflags = default(XSyntheticTypeFlags);

            return(XSyntheticTypeDefinition.Create(Compiler.Module, parentXType, xflags,
                                                   typeDef.Namespace, name,
                                                   Compiler.Module.TypeSystem.Object,
                                                   string.Join(":", Type.Scope.Name, Type.MetadataToken.ToScopeId(), "Nullable")));
        }
Пример #14
0
        /// <summary>
        /// Create all activity elements
        /// </summary>
        private void CreateActivity(XElement application)
        {
            bool isFirst = true;

            // Create activities
            foreach (var tuple in FindActivities())
            {
                var type  = tuple.Item1;
                var xType = XBuilder.AsTypeDefinition(module, type);
                var attr  = tuple.Item2;

                var activity = new XElement("activity");
                application.Add(activity);

                activity.AddAttr("name", Namespace, FormatClassName(xType));
                activity.AddAttrIfNotEmpty("label", Namespace, attr.GetValue <string>("Label"), FormatStringOrLiteral);
                activity.AddAttrIfNotEmpty("icon", Namespace, attr.GetValue <string>("Icon"), FormatDrawable);
                activity.AddAttrIfFound("allowTaskReparenting", Namespace, attr, "AllowTaskReparenting");
                activity.AddAttrIfFound("alwaysRetainTaskState", Namespace, attr, "AlwaysRetainTaskState");
                activity.AddAttrIfFound("clearTaskOnLaunch", Namespace, attr, "ClearTaskOnLaunch");
                activity.AddAttrIfNotDefault("configChanges", Namespace, attr.GetValue <int>("ConfigChanges"), 0, configChangesOptions.Format);
                activity.AddAttrIfFound("enabled", Namespace, attr, "Enabled");
                activity.AddAttrIfFound("excludeFromRecents", Namespace, attr, "ExcludeFromRecents");
                activity.AddAttrIfFound("exported", Namespace, attr, "Exported");
                activity.AddAttrIfFound("finishOnTaskLaunch", Namespace, attr, "FinishOnTaskLaunch");
                activity.AddAttrIfFound("hardwareAccelerated", Namespace, attr, "HardwareAccelerated");
                activity.AddAttrIfNotDefault("launchMode", Namespace, attr.GetValue <int>("LaunchMode"), 0, launchModesOptions.Format);
                activity.AddAttrIfFound("multiprocess", Namespace, attr, "MultiProcess");
                activity.AddAttrIfFound("noHistory", Namespace, attr, "NoHistory");
                activity.AddAttrIfNotEmpty("parentActivityName", Namespace, attr.GetValue <Type>("ParentActivity"), nsConverter.GetConvertedFullName);
                activity.AddAttrIfNotEmpty("permission", Namespace, attr.GetValue <string>("Permission"));
                activity.AddAttrIfNotEmpty("process", Namespace, attr.GetValue <string>("Process"));
                activity.AddAttrIfNotDefault("screenOrientation", Namespace, attr.GetValue <int>("ScreenOrientation"), 0, screenOrientationsOptions.Format);
                activity.AddAttrIfFound("stateNotNeeded", Namespace, attr, "StateNotNeeded");
                activity.AddAttrIfNotEmpty("taskAffinity", Namespace, attr.GetValue <string>("TaskAffinity"));
                activity.AddAttrIfNotEmpty("theme", Namespace, attr.GetValue <string>("Theme"), FormatStyle);
                activity.AddAttrIfNotDefault("uiOptions", Namespace, attr.GetValue <int>("UIOptions"), 0, uiOptions.Format);
                activity.AddAttrIfNotDefault("windowSoftInputMode", Namespace, attr.GetValue <int>("WindowSoftInputMode"), 0, windowSoftInputModeOptions.Format);

                var visibleInLauncher = isFirst ||
                                        attr.GetValue("VisibleInLauncher", false) ||
                                        attr.GetValue("MainLauncher", false);

                CreateIntentFilter(activity, type, visibleInLauncher, false);
                CreateMetaData(activity, type);

                isFirst = false;
            }
        }
Пример #15
0
        void ConvertParameters(List <ByteCode> body)
        {
            AstVariable thisParameter = null;

            if (methodDef.HasThis)
            {
                TypeReference type = methodDef.DeclaringType;
                thisParameter = new AstILVariable("this", XBuilder.AsTypeReference(module, type.IsValueType ? new ByReferenceType(type) : type), methodDef.Body.ThisParameter);
            }
            foreach (var p in methodDef.Parameters)
            {
                Parameters.Add(new AstILVariable(p.Name, XBuilder.AsTypeReference(module, p.ParameterType), p));
            }
            if (Parameters.Count > 0 && (methodDef.IsSetter || methodDef.IsAddOn || methodDef.IsRemoveOn))
            {
                // last parameter must be 'value', so rename it
                Parameters.Last().Name = "value";
            }
            foreach (ByteCode byteCode in body)
            {
                ParameterDefinition p;
                switch (byteCode.Code)
                {
                case AstCode.__Ldarg:
                    p                = (ParameterDefinition)byteCode.Operand;
                    byteCode.Code    = AstCode.Ldloc;
                    byteCode.Operand = p.Index < 0 ? thisParameter : this.Parameters[p.Index];
                    break;

                case AstCode.__Starg:
                    p                = (ParameterDefinition)byteCode.Operand;
                    byteCode.Code    = AstCode.Stloc;
                    byteCode.Operand = p.Index < 0 ? thisParameter : this.Parameters[p.Index];
                    break;

                case AstCode.__Ldarga:
                    p                = (ParameterDefinition)byteCode.Operand;
                    byteCode.Code    = AstCode.Ldloca;
                    byteCode.Operand = p.Index < 0 ? thisParameter : this.Parameters[p.Index];
                    break;
                }
            }
            if (thisParameter != null)
            {
                this.Parameters.Add(thisParameter);
            }
        }
Пример #16
0
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public void Create(ClassDefinition declaringClass, DexTargetPackage targetPackage)
        {
            // Find xMethod
            xMethod = XBuilder.AsMethodDefinition(compiler.Module, method);

            // Create method definition
            dmethod           = new DexLib.MethodDefinition();
            dmethod.Name      = GetMethodName(method, targetPackage);
            dmethod.MapFileId = compiler.GetNextMapFileId();
            AddMethodToDeclaringClass(declaringClass, dmethod, targetPackage);
            targetPackage.Record(xMethod, dmethod);

            // Set access flags
            SetAccessFlags(dmethod, method);

            // Create prototype
            dmethod.Prototype = PrototypeBuilder.BuildPrototype(compiler, targetPackage, declaringClass, xMethod);
        }
Пример #17
0
        /// <summary>
        /// Create all activity elements
        /// </summary>
        private void CreateAppWidgetProvider(XElement application, string outputFolder)
        {
            //Debugger.Launch();
            // Create activities
            var index = -1;

            foreach (var tuple in FindAppWidgetProviders())
            {
                index++;
                var type  = tuple.Item1;
                var xType = XBuilder.AsTypeDefinition(module, type);
                var attr  = tuple.Item2;

                var receiver = new XElement("receiver");
                application.Add(receiver);

                // receiver attributes
                receiver.AddAttr("name", Namespace, FormatClassName(xType));
                receiver.AddAttrIfNotEmpty("label", Namespace, attr.GetValue <string>("Label"), FormatStringOrLiteral);

                // intent-filter
                CreateIntentFilter(receiver, type, false, true);

                // meta-data
                receiver.Add(new XElement("meta-data",
                                          new XAttribute(XName.Get("name", Namespace), "android.appwidget.provider"),
                                          new XAttribute(XName.Get("resource", Namespace), "@xml/" + AppWidgetProviderResource.GetResourceName(index))));
                CreateMetaData(receiver, type);

                // Create the appwidget-provider xml file
                CreateAppWidgetProviderFile(outputFolder, index, attr);
            }

            // Check that the number of app widgets is correct
            if (index > appWidgetProviderCodeFiles.Count)
            {
                throw new CompilerException("For more AppWidgetProvider attributes than source files with subtype AppWidgetProvider");
            }
        }
Пример #18
0
        /// <summary>
        /// Implement the class now that all classes have been created
        /// </summary>
        protected override void CreateMembers(DexTargetPackage targetPackage)
        {
            // Build ctors
            foreach (var baseCtor in GetBaseClassCtors())
            {
                // Build ctor
                var prototype = PrototypeBuilder.BuildPrototype(Compiler, targetPackage, null, baseCtor);
                var ctor      = new MethodDefinition(Class, "<init>", prototype);
                ctor.AccessFlags = AccessFlags.Public | AccessFlags.Constructor;
                Class.Methods.Add(ctor);
                // Create ctor body
                var ctorBody = CreateCtorBody(prototype);
                targetPackage.Record(new CompiledMethod {
                    DexMethod = ctor, RLBody = ctorBody
                });
            }

            // build original type field
            // Create field definition
            var dfield = new Dot42.DexLib.FieldDefinition();

            dfield.Owner       = Class;
            dfield.Name        = "underlying$";
            dfield.IsSynthetic = true;
            dfield.IsFinal     = true;
            dfield.IsStatic    = true;
            dfield.IsPublic    = true;

            dfield.Type = Compiler.Module.TypeSystem.Type.GetClassReference(targetPackage);

            // not sure if GetClassReference is the best way to go forward here.
            // might depend on the sort order of the class builders.
            var underlyingType = XBuilder.AsTypeReference(Compiler.Module, Type);

            dfield.Value = underlyingType.GetClassReference(targetPackage);

            Class.Fields.Add(dfield);
        }
Пример #19
0
        /// <summary>
        /// Create all receiver elements
        /// </summary>
        private void CreateReceiver(XElement application)
        {
            // Create receivers
            foreach (var tuple in FindReceivers())
            {
                var type  = tuple.Item1;
                var xType = XBuilder.AsTypeDefinition(module, type);
                var attr  = tuple.Item2;

                var receiver = new XElement("receiver");
                application.Add(receiver);

                receiver.AddAttr("name", Namespace, FormatClassName(xType));
                receiver.AddAttrIfNotEmpty("label", Namespace, attr.GetValue <string>("Label"), FormatStringOrLiteral);
                receiver.AddAttrIfNotEmpty("icon", Namespace, attr.GetValue <string>("Icon"), FormatDrawable);
                receiver.AddAttrIfFound("enabled", Namespace, attr, "Enabled");
                receiver.AddAttrIfFound("exported", Namespace, attr, "Exported");
                receiver.AddAttrIfNotEmpty("permission", Namespace, attr.GetValue <string>("Permission"));
                receiver.AddAttrIfNotEmpty("process", Namespace, attr.GetValue <string>("Process"));

                CreateIntentFilter(receiver, type, false, false);
                CreateMetaData(receiver, type);
            }
        }
Пример #20
0
        /// <summary>
        /// Create all annotations for this method
        /// </summary>
        internal virtual void CreateAnnotations(DexTargetPackage targetPackage)
        {
            // Build method annotations
            AttributeAnnotationInstanceBuilder.CreateAttributeAnnotations(compiler, method, dmethod, targetPackage);

            // only add generics annotation for getters or setters or constructors
            if (method.IsGetter)
            {
                // Note that the return type might has been
                // changed above, to compensate for interface
                // inheritance and generic specialization.
                // We need to use the original declaration.
                // TODO: why not get rid of "OriginalReturnType"
                //       and use the IL's return type??
                var returnType = xMethod.OriginalReturnType;
                var xType      = XBuilder.AsTypeReference(compiler.Module, returnType);
                dmethod.AddGenericDefinitionAnnotationIfGeneric(xType, compiler, targetPackage);
            }
            else if (method.IsSetter)
            {
                for (int i = 0; i < xMethod.Parameters.Count; ++i)
                {
                    var dp = dmethod.Prototype.Parameters[i];
                    dp.AddGenericDefinitionAnnotationIfGeneric(xMethod.Parameters[i].ParameterType, compiler,
                                                               targetPackage);
                }
            }
            else if (method.IsConstructor && !method.IsStatic)
            {
                // Add parameter names and original access flags, as these might be important
                // in serialization and/or dependency injection.

                var reflectionInfo = compiler.GetDot42InternalType(InternalConstants.ReflectionInfoAnnotation)
                                     .GetClassReference(targetPackage);
                var annotation = new Annotation {
                    Type = reflectionInfo, Visibility = AnnotationVisibility.Runtime
                };

                bool isPublic = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;

                // Not sure if it makes any sense to remap the access flags.
                bool isProtected = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family ||
                                   (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem ||
                                   (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;

                bool isInternal = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly ||
                                  (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem ||
                                  (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;

                bool isPrivate = (method.OriginalAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;

                // only create accessFlags if they differs from java's
                if (isPublic != dmethod.IsPublic ||
                    isProtected != dmethod.IsProtected ||
                    isPrivate != dmethod.IsPrivate ||
                    isInternal)
                {
                    int accessFlags = 0;
                    if (isPublic)
                    {
                        accessFlags |= 0x01;
                    }
                    if (isProtected)
                    {
                        accessFlags |= 0x02;
                    }
                    if (isPrivate)
                    {
                        accessFlags |= 0x04;
                    }
                    if (isInternal)
                    {
                        accessFlags |= 0x08;
                    }
                    annotation.Arguments.Add(new AnnotationArgument(InternalConstants.ReflectionInfoAccessFlagsField, accessFlags));
                }

                if (method.Parameters.Count > 0)
                {
                    annotation.Arguments.Add(new AnnotationArgument(InternalConstants.ReflectionInfoParameterNamesField,
                                                                    method.Parameters.Select(p => p.Name).ToArray()));
                }

                if (annotation.Arguments.Count > 0)
                {
                    dmethod.Annotations.Add(annotation);
                }

                //for (int i = 0; i < xMethod.Parameters.Count; ++i)
                //{
                //    var dp = dmethod.Prototype.Parameters[i];
                //    dp.AddGenericDefinitionAnnotationIfGeneric(xMethod.Parameters[i].ParameterType, compiler,
                //        targetPackage);
                //}
            }
        }
Пример #21
0
        private static MethodDefinition CreateFactoryMethod(AssemblyCompiler compiler, DexTargetPackage targetPackage, CustomAttribute attribute, AttributeAnnotationMapping mapping)
        {
            var             targetClass      = mapping.AttributeClass; // is this really the right place for the factory methods?
            ISourceLocation seqp             = null;
            var             attributeTypeDef = attribute.AttributeType.Resolve();

            // create method
            string           methodName = CreateAttributeFactoryMethodName(targetClass);
            MethodDefinition method     = new MethodDefinition(targetClass, methodName, new Prototype(mapping.AttributeClass));

            method.AccessFlags = AccessFlags.Public | AccessFlags.Static | AccessFlags.Synthetic;
            targetClass.Methods.Add(method);

            // create method body
            MethodBody body = new MethodBody(null);
            // Allocate attribute
            Register attributeReg = body.AllocateRegister(RCategory.Temp, RType.Object);

            body.Instructions.Add(seqp, RCode.New_instance, mapping.AttributeClass, attributeReg);

            // collect ctor arguments
            List <Register> ctorArgRegs = new List <Register>()
            {
                attributeReg
            };

            foreach (var p in attribute.ConstructorArguments)
            {
                XTypeReference xType     = XBuilder.AsTypeReference(compiler.Module, p.Type);
                Register[]     valueRegs = CreateInitializeValueInstructions(seqp, body, xType, p, compiler, targetPackage);
                ctorArgRegs.AddRange(valueRegs);
            }
            // Invoke ctor
            DexLib.MethodReference dctor = attribute.Constructor.GetReference(targetPackage, compiler.Module);
            body.Instructions.Add(seqp, RCode.Invoke_direct, dctor, ctorArgRegs.ToArray());

            // set field values
            foreach (var p in attribute.Fields)
            {
                var field  = GetField(attributeTypeDef, p.Name);
                var xField = XBuilder.AsFieldReference(compiler.Module, field);

                Register[] valueRegs = CreateInitializeValueInstructions(seqp, body, xField.FieldType, p.Argument, compiler, targetPackage);
                body.Instructions.Add(seqp, xField.FieldType.IPut(), xField.GetReference(targetPackage),
                                      valueRegs[0], attributeReg);
            }

            // set property values
            foreach (var p in attribute.Properties)
            {
                PropertyDefinition property = GetSettableProperty(attributeTypeDef, p.Name);
                XTypeReference     xType    = XBuilder.AsTypeReference(compiler.Module, property.PropertyType);

                Register[]        valueRegs  = CreateInitializeValueInstructions(seqp, body, xType, p.Argument, compiler, targetPackage);
                XMethodDefinition xSetMethod = XBuilder.AsMethodDefinition(compiler.Module, property.SetMethod);
                body.Instructions.Add(seqp, xSetMethod.Invoke(xSetMethod, null),
                                      xSetMethod.GetReference(targetPackage),
                                      new[] { attributeReg }.Concat(valueRegs).ToArray());
            }

            // Return attribute
            body.Instructions.Add(seqp, RCode.Return_object, attributeReg);

            // Register method body
            targetPackage.Record(new CompiledMethod()
            {
                DexMethod = method, RLBody = body
            });

            // Return method
            return(method);
        }
Пример #22
0
 /// <summary>
 /// Make a xtype reference for a java class name.
 /// </summary>
 private XTypeReference AsTypeReference(string className, XTypeUsageFlags usageFlags)
 {
     return(XBuilder.AsTypeReference(module, className, usageFlags));
 }
Пример #23
0
 /// <summary>
 /// Make a .NET type reference for a java type reference.
 /// </summary>
 private XTypeReference AsTypeReference(JvmClassLib.TypeReference javaRef, XTypeUsageFlags usageFlags)
 {
     return(XBuilder.AsTypeReference(module, javaRef, usageFlags));
 }
Пример #24
0
 /// <summary>
 /// Make a .NET type reference for a java class file.
 /// </summary>
 private XTypeReference AsTypeReference(ClassFile classFile, XTypeUsageFlags usageFlags)
 {
     return(XBuilder.AsTypeReference(module, classFile, usageFlags));
 }
Пример #25
0
        /// <summary>
        /// Create a method definition for the builder method that builds a custom attribute from an annotation.
        /// </summary>
        private static MethodDefinition CreateBuildMethod(
            ISourceLocation seqp,
            Mono.Cecil.MethodDefinition ctor,
            List <MethodDefinition> paramGetMethods,
            AssemblyCompiler compiler,
            DexTargetPackage targetPackage,
            ClassDefinition attributeClass,
            AttributeAnnotationInterface mapping)
        {
            // Create method definition
            string           name             = CreateBuildMethodName(attributeClass);
            TypeReference    attributeTypeRef = ctor.DeclaringType.GetReference(targetPackage, compiler.Module);
            MethodDefinition method           = new MethodDefinition(attributeClass, name, new Prototype(attributeTypeRef, new Parameter(mapping.AnnotationInterfaceClass, "ann")));

            method.AccessFlags = AccessFlags.Public | AccessFlags.Static | AccessFlags.Synthetic;
            attributeClass.Methods.Add(method);

            // Create method body
            MethodBody body          = new MethodBody(null);
            Register   annotationReg = body.AllocateRegister(RCategory.Argument, RType.Object);
            //body.Instructions.Add(seqp, RCode.Check_cast, mapping.AnnotationInterfaceClass, annotationReg);

            // Allocate attribute
            Register attributeReg = body.AllocateRegister(RCategory.Temp, RType.Object);

            body.Instructions.Add(seqp, RCode.New_instance, attributeClass, attributeReg);

            // Get ctor arguments
            List <Register> ctorArgRegs = new List <Register>();

            foreach (MethodDefinition p in paramGetMethods)
            {
                TypeReference paramType = p.Prototype.ReturnType;
                Register[]    valueRegs = CreateLoadValueSequence(seqp, body, paramType, annotationReg, p);
                ctorArgRegs.AddRange(valueRegs);
            }

            // Invoke ctor
            DexLib.MethodReference dctor = ctor.GetReference(targetPackage, compiler.Module);
            body.Instructions.Add(seqp, RCode.Invoke_direct, dctor, new[] { attributeReg }.Concat(ctorArgRegs).ToArray());

            // Get field values
            foreach (var fieldMap in mapping.FieldToGetMethodMap)
            {
                Mono.Cecil.FieldDefinition field  = fieldMap.Key;
                MethodDefinition           getter = fieldMap.Value;
                Register[]            valueRegs   = CreateLoadValueSequence(seqp, body, getter.Prototype.ReturnType, annotationReg, getter);
                DexLib.FieldReference dfield      = field.GetReference(targetPackage, compiler.Module);
                XModel.XTypeReference xFieldType  = XBuilder.AsTypeReference(compiler.Module, field.FieldType);
                body.Instructions.Add(seqp, xFieldType.IPut(), dfield, valueRegs[0], attributeReg);
            }

            // Get property values
            foreach (var propertyMap in mapping.PropertyToGetMethodMap)
            {
                PropertyDefinition       property   = propertyMap.Key;
                MethodDefinition         getter     = propertyMap.Value;
                Register[]               valueRegs  = CreateLoadValueSequence(seqp, body, getter.Prototype.ReturnType, annotationReg, getter);
                DexLib.MethodReference   dmethod    = property.SetMethod.GetReference(targetPackage, compiler.Module);
                XModel.XMethodDefinition xSetMethod = XBuilder.AsMethodDefinition(compiler.Module, property.SetMethod);
                body.Instructions.Add(seqp, xSetMethod.Invoke(xSetMethod, null), dmethod, new[] { attributeReg }.Concat(valueRegs).ToArray());
            }

            // Return attribute
            body.Instructions.Add(seqp, RCode.Return_object, attributeReg);

            // Register method body
            targetPackage.Record(new CompiledMethod()
            {
                DexMethod = method, RLBody = body
            });

            // Return method
            return(method);
        }
Пример #26
0
        /// <summary>
        /// Create code to initialize a value from an attribute.
        /// </summary>
        /// <returns>The register(s) holding the value</returns>
        private static Register[] CreateInitializeValueInstructions(ISourceLocation seqp, MethodBody body, XTypeReference targetType, CustomAttributeArgument value, AssemblyCompiler compiler, DexTargetPackage targetPackage)
        {
            List <Register> result = new List <Register>();

            // allocate result, initialize to default value.
            if (targetType.IsWide())
            {
                Tuple <Register, Register> regs = body.AllocateWideRegister(RCategory.Temp);
                //body.Instructions.Add(seqp, RCode.Const_wide, 0, regs.Item1);
                result.Add(regs.Item1);
                result.Add(regs.Item2);
            }
            else if (targetType.IsPrimitive)
            {
                Register reg = body.AllocateRegister(RCategory.Temp, RType.Value);
                //body.Instructions.Add(seqp, RCode.Const, 0, reg);
                result.Add(reg);
            }
            else // object
            {
                Register reg = body.AllocateRegister(RCategory.Temp, RType.Object);
                //body.Instructions.Add(seqp, RCode.Const, 0, reg);
                result.Add(reg);
            }

            // load data

            if (value.Value == null) // must be a reference type
            {
                body.Instructions.Add(seqp, RCode.Const, 0, result[0]);
                body.Instructions.Add(seqp, RCode.Check_cast, targetType.GetReference(targetPackage), result[0]);
                return(result.ToArray());
            }

            var valueType = XBuilder.AsTypeReference(compiler.Module, value.Type);

            if (value.Value is CustomAttributeArgument)
            {
                // this happens if a type conversion is neccessary
                var nestedValue = (CustomAttributeArgument)value.Value;
                valueType = XBuilder.AsTypeReference(compiler.Module, nestedValue.Type);

                var rOrigValue = CreateInitializeValueInstructions(seqp, body, valueType, nestedValue, compiler, targetPackage);

                if (!nestedValue.Type.IsPrimitive)
                {
                    body.Instructions.Add(seqp, RCode.Move_object, result[0], rOrigValue[0]);
                    body.Instructions.Add(seqp, RCode.Check_cast, targetType.GetReference(targetPackage), result[0]);
                }
                else if (!targetType.IsPrimitive)
                {
                    body.Instructions.Add(seqp, RCode.Invoke_static, valueType.GetBoxValueOfMethod(), rOrigValue);
                    body.Instructions.Add(seqp, RCode.Move_result_object, result[0]);
                    body.Instructions.Add(seqp, RCode.Check_cast, targetType.GetReference(targetPackage), result[0]);
                }
                else
                {
                    throw new Exception(string.Format("type converstion in attribute {0}=>{1} not yet supported", valueType.FullName, targetType.FullName));
                }
            }
            else if (valueType.IsArray)
            {
                var array       = (CustomAttributeArgument[])value.Value;
                var elementType = valueType.ElementType;

                Register rIndex = body.AllocateRegister(RCategory.Temp, RType.Value);
                body.Instructions.Add(seqp, RCode.Const, array.Length, rIndex);
                body.Instructions.Add(seqp, RCode.New_array, valueType.GetReference(targetPackage), result[0], rIndex);

                // iterate through each value
                for (int i = 0; i < array.Length; i++)
                {
                    Register rLoaded = CreateInitializeValueInstructions(seqp, body, elementType, array[i], compiler, targetPackage)[0];

                    body.Instructions.Add(seqp, RCode.Const, i, rIndex);
                    body.Instructions.Add(seqp, valueType.APut(), rLoaded, result[0], rIndex);
                }
            }
            else if (targetType.IsEnum())
            {
                var enumClass = (targetType.IsEnum()? targetType:valueType).GetReference(targetPackage);

                Register rEnumClass = body.AllocateRegister(RCategory.Temp, RType.Object);
                body.Instructions.Add(seqp, RCode.Const_class, enumClass, rEnumClass);

                long lVal = Convert.ToInt64(value.Value);
                if (lVal <= int.MaxValue && lVal >= int.MinValue)
                {
                    Register regTmp = body.AllocateRegister(RCategory.Temp, RType.Value);
                    body.Instructions.Add(seqp, RCode.Const, (int)lVal, regTmp);
                    var get = compiler.GetDot42InternalType("Enum").Resolve()
                              .Methods.Single(p => p.Name == "Get" && p.Parameters.Count == 2 && !p.Parameters[1].ParameterType.IsWide())
                              .GetReference(targetPackage);
                    body.Instructions.Add(seqp, RCode.Invoke_static, get, rEnumClass, regTmp);
                    body.Instructions.Add(seqp, targetType.MoveResult(), result[0]);
                }
                else
                {
                    var regTmp = body.AllocateWideRegister(RCategory.Temp);
                    body.Instructions.Add(seqp, RCode.Const, (long)lVal, regTmp.Item1);
                    var get = compiler.GetDot42InternalType("Enum").Resolve()
                              .Methods.Single(p => p.Name == "Get" && p.Parameters.Count == 2 && p.Parameters[1].ParameterType.IsWide())
                              .GetReference(targetPackage);
                    body.Instructions.Add(seqp, RCode.Invoke_static, get, rEnumClass, regTmp.Item1);
                    body.Instructions.Add(seqp, targetType.MoveResult(), result[0]);
                }
                body.Instructions.Add(seqp, RCode.Check_cast, targetType.GetReference(targetPackage), result[0]);
            }
            else if (valueType.IsSystemString())
            {
                body.Instructions.Add(seqp, RCode.Const_string, (string)value.Value, result[0]);
            }
            else if (valueType.IsSystemType())
            {
                var type = XBuilder.AsTypeReference(compiler.Module, (TypeReference)value.Value);
                // TODO: this might not work with typeof(void) on ART runtime.
                body.Instructions.Add(seqp, RCode.Const_class, type.GetReference(targetPackage), result[0]);
            }
            else if (!valueType.IsPrimitive)
            {
                // can this happen?
                throw new Exception("invalid value type in attribute: " + targetType.FullName);
            }
            else
            {
                if (targetType.IsSystemObject())
                {
                    // can this happen? or is this always handled above?

                    // boxing required.
                    var rUnboxed = CreateInitializeValueInstructions(seqp, body, valueType, value, compiler, targetPackage);
                    body.Instructions.Add(seqp, RCode.Invoke_static, valueType.GetBoxValueOfMethod(), rUnboxed);
                    body.Instructions.Add(seqp, RCode.Move_result_object, result[0]);
                }
                else if (targetType.IsDouble())
                {
                    body.Instructions.Add(seqp, RCode.Const_wide, Convert.ToDouble(value.Value), result[0]);
                }
                else if (targetType.IsWide() && valueType.IsUInt64())
                {
                    body.Instructions.Add(seqp, RCode.Const_wide, (long)Convert.ToUInt64(value.Value), result[0]);
                }
                else if (targetType.IsWide())
                {
                    body.Instructions.Add(seqp, RCode.Const_wide, Convert.ToInt64(value.Value), result[0]);
                }
                else if (targetType.IsFloat())
                {
                    body.Instructions.Add(seqp, RCode.Const, Convert.ToSingle(value.Value), result[0]);
                }
                else
                {
                    body.Instructions.Add(seqp, RCode.Const, (int)Convert.ToInt64(value.Value), result[0]);
                }
            }

            return(result.ToArray());
        }
Пример #27
0
            /// <summary>
            /// Convert the given interface method if it has explicit implementations.
            /// </summary>
            private void ConvertInterfaceMethod(TypeDefinition iType, MethodDefinition iMethod)
            {
                var implementations = GetImplementations(iMethod);
                var iMethodIsJavaWithGenericParams = iMethod.IsJavaMethodWithGenericParams();
                var iMethodContainsGenericParams   = iMethod.ContainsGenericParameter;

                if (!iMethodIsJavaWithGenericParams && !iMethodContainsGenericParams && (!implementations.Any(x => x.IsExplicitImplementation())))
                {
                    // There are no explicit implementation.
                    // No need to convert
                    return;
                }

                // Rename method
                string newName;
                bool   createExplicitStubs = true;
                var    oldName             = iMethod.Name;
                var    attr = iMethod.GetDexOrJavaImportAttribute();

                if (attr != null)
                {
                    string className;
                    string memberName;
                    string descriptor;
                    attr.GetDexOrJavaImportNames(iMethod, out memberName, out descriptor, out className);
                    newName = memberName;
                }
                else if ((attr = iMethod.GetDexNameAttribute()) != null)
                {
                    newName             = (string)(attr.ConstructorArguments[0].Value);
                    createExplicitStubs = false;
                }
                else
                {
                    var module = reachableContext.Compiler.Module;
                    var xiType = XBuilder.AsTypeReference(module, iType);
                    newName = methodNames.GetUniqueName(NameConverter.GetConvertedName(xiType) + "_" + iMethod.Name);
                    oldName = newName;
                }
                Rename(iMethod, newName);


                // Update implementations
                foreach (var impl in implementations)
                {
                    if (impl.IsExplicitImplementation())
                    {
                        // Convert to implicit
                        impl.IsPublic = true;

                        // Rename
                        Rename(impl, newName);
                        // Update names of overrides
                        foreach (var @override in impl.Overrides)
                        {
                            @override.Name = newName;
                        }
                    }
                    else if (!(impl.HasDexImportAttribute() || impl.HasJavaImportAttribute()))
                    {
                        // Add stub redirecting explicit implementation to implicit implementation
                        if (createExplicitStubs)
                        {
                            CreateExplicitStub(impl, newName, oldName, iMethod, iMethodIsJavaWithGenericParams /*|| iMethodContainsGenericParams*/);
                        }
                    }
                }
            }
Пример #28
0
 /// <summary>
 /// Make a .NET field reference from a java constant pool method reference.
 /// </summary>
 private XFieldReference AsFieldReference(ConstantPoolFieldRef cpField)
 {
     return(XBuilder.AsFieldReference(module, cpField));
 }
Пример #29
0
 /// <summary>
 /// Make a .NET method reference from a java constant pool method reference.
 /// </summary>
 private XMethodReference AsMethodReference(ConstantPoolMethodRef cpMethod, bool hasThis)
 {
     return(XBuilder.AsMethodReference(module, cpMethod, hasThis));
 }
Пример #30
0
 /// <summary>
 /// Create the XType for this builder.
 /// </summary>
 protected virtual XTypeDefinition CreateXType(XTypeDefinition parentXType)
 {
     return(XBuilder.AsTypeReference(compiler.Module, typeDef).Resolve());
 }