protected override void EmitField(Field field) { if (field.Scope == "protected") { return; } bool hasValue = !string.IsNullOrEmpty(field.Value); if (!hasValue) { WriteLine("internal static global::MonoJavaBridge.FieldId _{0}{1};", field.Name.Replace("@", ""), myMemberCounter++); } Write(field.Scope); if (field.Static) { Write("static"); } Write("{0}{1}", ObjectModel.IsSystemType(field.Type) ? string.Empty : "global::", field.Type); Write(field.Name, false); WriteLine(); WriteLine("{"); myIndent++; WriteLine("get"); WriteLine("{"); if (hasValue) { myIndent++; string val = field.Value; val = val.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n"); if (field.Type == "java.lang.String") { Write("return \"{0}\"", false, val); } else if (field.Type == "char") { val = val.Replace("'", "\\'"); // there's a weird compile error happening here due to unicode chars or something... if (field.Name == "HEX_INPUT" || field.Name == "PICKER_DIALOG_INPUT") { val = "0"; } Write("return '{0}'", false, val); } else { Write("return {0}", false, field.Value); } if (field.Type == "long") { Write("L", false); } else if (field.Type == "float") { Write("f", false); } WriteLine(";"); myIndent--; } else { myIndent++; WriteLine("return default({0}{1});", ObjectModel.IsSystemType(field.Type) ? string.Empty : "global::", field.Type); myIndent--; } WriteLine("}"); if (!field.IsReadOnly) { WriteLine("set"); WriteLine("{"); WriteLine("}"); } myIndent--; WriteLine("}"); }
protected override void EmitMethod(Method method) { if (method.IsSynthetic) { return; } if (method.IsOverride && !method.IsConstructor && !method.Abstract && !method.Static) { Type parent = method.Type.ParentType; string sig = method.ToSignatureString(); while (parent != null) { if (myJniTypes.ContainsKey(parent.Name) && parent.Methods.Dictionary.ContainsKey(sig)) { var jniType = myJniTypes[parent.Name]; // see if the method exists to override try { if (jniType.GetMethod(method.Name) == null) { return; } } catch (AmbiguousMatchException) { } } parent = parent.ParentType; } } //if (method.PropertyType != null && method.Name.StartsWith("set")) // return; string methodId = null; if (!method.Type.IsInterface) { string signature = GetMethodSignature(method); if (method.Name.LastIndexOf('.') == -1) { methodId = method.Name; } else { methodId = method.Name.Substring(method.Name.LastIndexOf('.') + 1); } string methodIdLookup = methodId; methodId = string.Format("_{0}{1}", methodId.Replace("@", ""), myMemberCounter++); string initJni = string.Format("global::{0}.{1} = @__env.Get{4}MethodIDNoThrow(global::{0}.staticClass, \"{2}\", \"{3}\");", method.Type.Name, methodId, method.IsConstructor ? "<init>" : methodIdLookup, signature, method.Static ? "Static" : string.Empty); myInitJni.Add(initJni); WriteLine("internal static global::MonoJavaBridge.MethodId {0};", methodId); //WriteLine("[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]"); Write(method.Scope); if (method.Abstract) { Write("abstract"); } else { if (method.Static) { Write("static"); } else if (!method.IsConstructor) { if (method.IsOverride) { if (method.IsSealed) { Write("sealed"); } Write("override"); } else if (!method.Type.IsSealed && method.Scope != string.Empty) { Write("virtual"); } } //Write("extern"); } } // TODO: Reflect on the jni4net type, and see if the method exists or not. // This is a hack to prevent some compiler warnings. if (method.IsNew && (method.Name != "clone" || !myJniTypes.ContainsKey(method.Type.Parent))) { Write("new"); } if (method.Return != null) { Write("{0}{1}", ObjectModel.IsSystemType(method.Return) ? string.Empty : "global::", method.Return); } Write(method.Name, false); Write("(", false); //WriteDelimited(method.Parameters, (v, i) => string.Format("{0} arg{1}", v == "java.lang.CharSequence" && !method.Name.Contains('.') ? "string" : v, i), ","); WriteDelimited(method.Parameters, (v, i) => string.Format("{0} arg{1}", v, i), ","); if (method.Type.IsInterface || method.Abstract || method.Scope == "internal") { WriteLine(");"); } else { Write(")"); if (method.IsConstructor) { Write(" : base(global::MonoJavaBridge.JNIEnv.ThreadEnv)"); } WriteLine(); WriteLine("{"); myIndent++; // TODO: Remove this if statement when array returns are properly supported WriteLine("global::MonoJavaBridge.JNIEnv @__env = global::MonoJavaBridge.JNIEnv.ThreadEnv;"); var statement = GetMethodStatement(method); StringBuilder parBuilder = new StringBuilder(); if (method.Static || method.IsConstructor) { parBuilder.AppendFormat("{0}.staticClass, ", method.Type.Name); } else { parBuilder.Append("this.JvmHandle, "); } parBuilder.AppendFormat("global::{0}.{1}", method.Type.Name, methodId); //if (method.IsConstructor) // parBuilder.Append(", this"); bool hasCharSequenceArgument = false; for (int i = 0; i < method.Parameters.Count; i++) { parBuilder.Append(", "); var parType = method.ParameterTypes[i]; var par = method.Parameters[i]; if (par == "java.lang.CharSequence") { hasCharSequenceArgument = true; } parBuilder.Append("global::MonoJavaBridge.JavaBridge."); parBuilder.Append(string.Format(GetParameterStatement(parType, par), "arg" + i)); } if (method.Static || method.IsConstructor) { WriteLine(statement, method.Static ? "Static" : string.Empty, parBuilder); if (method.IsConstructor) { WriteLine("Init(@__env, handle);"); } } else { WriteLine("if (!IsClrObject)", method.Type.Name); myIndent++; WriteLine(statement, string.Empty, parBuilder); myIndent--; WriteLine("else"); myIndent++; WriteLine(statement, "NonVirtual", string.Format(parBuilder.ToString().Replace("this.JvmHandle, ", "this.JvmHandle, global::{0}.staticClass, "), method.Type.Name)); myIndent--; } myIndent--; WriteLine("}"); if (hasCharSequenceArgument && !method.IsConstructor && method.Scope == "public" && !method.Static) { var em = method; //myExtensionMethods.Add(method); Write("public {0} {1}(", false, em.Return, em.Name); //Write("this global::{0} __this", false, em.Type.Name); WriteDelimited(em.Parameters, (v, i) => string.Format("{0} arg{1}", v == "java.lang.CharSequence" ? "string" : v, i), ","); WriteLine(")"); WriteLine("{"); myIndent++; if (em.Return != "void") { Write("return"); } Write("{0}(", false, em.Name); WriteDelimited(em.Parameters, (v, i) => string.Format("{0}arg{1}", v == "java.lang.CharSequence" ? "(global::java.lang.CharSequence)(global::java.lang.String)" : string.Empty, i), ","); WriteLine(");"); myIndent--; WriteLine("}"); } } }
protected virtual void Prepare(ObjectModel model) { }