Context? #1266
Context: #1267 (comment)
Currently, generators Symbol Table uses Java names as the keys:
|
AddType (new SimpleSymbol ("IntPtr.Zero", "void", "void", "V")); |
Keys will be strings such as Java builtin types like boolean and int, and "fully qualified dotted" Java names such as java.lang.Object and android.app.Activity.
There are (at least?) two issues with this setup:
- Nested type semantics
- Potential ambiguity with JNI names
For nested type semantics, consider #1267:
[Register ("com/mypackage/FieldClass")]
public class FieldClass : Java.Lang.Object {
public NestedFieldClass field;
public class NestedFieldClass : Java.Lang.Object {
}
}
The above could be a hand-written C# snippet added to a binding assembly, and then referenced by generator when emitting a new set of bindings.
The (long-standing so not necessarily a "real") concern is that when generator processes the above, the symbol table will have:
- an entry
com.mypackage.FieldClass for FieldClass (as per [Register]), and
- an entry
Com.Mypackage.FieldClass.NestedFieldClass for FieldClass.NestedFieldClass`.
This nested name is wrong; it should instead be one of:
com.mypackage.FieldClass.NestedFieldClass (append nested name to declaring type name), or
- Whatever
jcw-gen would emit for this type, which could be com.mypackage.FieldClass_NestedFieldClass, or something like that. (Requires testing.)
Then there's #1266: somehow -- we're not quite sure we fully understand yet -- JniTypeSignatureAttribute.SimpleReference is being used as a key for the Symbol Table.
Given:
|
[JniTypeSignature ("B", ArrayRank=1, IsKeyword=true, GenerateJavaPeer=false)] |
|
public sealed class JavaSByteArray : JavaPrimitiveArray<SByte> { |
and a Java type:
// Java
public abstract /* partial */ class androidx.work.WorkRequest.Builder<
B extends androidx.work.WorkRequest$Builder<B, ?>,
W extends androidx.work.WorkRequest>
{
public final B setId(java.util.UUID);
}
then the return value of WorkRequest.Builder.setId() is being detected as JavaSByteArray instead of WorkRequest.Builder.
Aside: how?!
|
internal static RegisterAttribute? RegisterFromJniTypeSignatureAttribute (CustomAttribute attr) |
|
{ |
|
// attr.Resolve (); |
|
RegisterAttribute? r = null; |
|
if (attr.ConstructorArguments.Count == 1) |
|
r = new RegisterAttribute ((string) attr.ConstructorArguments [0].Value, attr); |
|
if (r != null) { |
|
var v = attr.Properties.FirstOrDefault (p => p.Name == "GenerateJavaPeer"); |
|
if (v.Name == null) { |
|
r.DoNotGenerateAcw = false; |
|
} else if (v.Name == "GenerateJavaPeer") { |
|
r.DoNotGenerateAcw = !(bool) v.Argument.Value; |
|
} |
|
var isKeyProp = attr.Properties.FirstOrDefault (p => p.Name == "IsKeyword"); |
|
var isKeyword = isKeyProp.Name != null && ((bool) isKeyProp.Argument.Value) == true; |
|
var arrRankProp = attr.Properties.FirstOrDefault (p => p.Name == "ArrayRank"); |
|
if (arrRankProp.Name != null && arrRankProp.Argument.Value is int rank) { |
|
r.Name = new string ('[', rank) + (isKeyword ? r.Name : "L" + r.Name + ";"); |
|
} |
|
} |
|
return r; |
|
} |
certainly looks like [JniTypeSignature("B", ArrayRank=1, IsKeyword=true)] should result in a Register attribute with a name of [B. How/where would this value be "cleaned up"?
The scenario described in #1266 should not happen. An idea to do that would be to alter the symbol table keys to instead be JNI type signatures. B would thus only be "byte", while LB; would be a class B{} in the global package, and Ljava/lang/Object; would be java.lang.Object.
Context? #1266
Context: #1267 (comment)
Currently,
generators Symbol Table uses Java names as the keys:java-interop/tools/generator/Java.Interop.Tools.Generator.ObjectModel/Symbols/SymbolTable.cs
Line 59 in 23e9e04
Keys will be strings such as Java builtin types like
booleanandint, and "fully qualified dotted" Java names such asjava.lang.Objectandandroid.app.Activity.There are (at least?) two issues with this setup:
For nested type semantics, consider #1267:
The above could be a hand-written C# snippet added to a binding assembly, and then referenced by
generatorwhen emitting a new set of bindings.The (long-standing so not necessarily a "real") concern is that when
generatorprocesses the above, the symbol table will have:com.mypackage.FieldClassforFieldClass(as per[Register]), andCom.Mypackage.FieldClass.NestedFieldClassfor FieldClass.NestedFieldClass`.This nested name is wrong; it should instead be one of:
com.mypackage.FieldClass.NestedFieldClass(append nested name to declaring type name), orjcw-genwould emit for this type, which could becom.mypackage.FieldClass_NestedFieldClass, or something like that. (Requires testing.)Then there's #1266: somehow -- we're not quite sure we fully understand yet --
JniTypeSignatureAttribute.SimpleReferenceis being used as a key for the Symbol Table.Given:
java-interop/src/Java.Interop/Java.Interop/JavaPrimitiveArrays.cs
Lines 349 to 350 in 23e9e04
and a Java type:
then the return value of
WorkRequest.Builder.setId()is being detected asJavaSByteArrayinstead ofWorkRequest.Builder.Aside: how?!
java-interop/src/Java.Interop.Tools.JavaCallableWrappers/Java.Interop.Tools.JavaCallableWrappers/CecilExtensions.cs
Lines 75 to 96 in 23e9e04
certainly looks like
[JniTypeSignature("B", ArrayRank=1, IsKeyword=true)]should result in aRegisterattribute with a name of[B. How/where would this value be "cleaned up"?The scenario described in #1266 should not happen. An idea to do that would be to alter the symbol table keys to instead be JNI type signatures.
Bwould thus only be "byte", whileLB;would be aclass B{}in the global package, andLjava/lang/Object;would bejava.lang.Object.