Skip to content

generator Symbol Table semantics #1268

Open
@jonpryor

Description

@jonpryor

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:

  1. Nested type semantics
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementProposed change to current functionalitygeneratorIssues binding a Java library (generator, class-parse, etc.)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions