Hello list,

I have almost completed a predicate called ‘jread’ which parses a Java .class 
file into a term that will allow me to create a database of all of the methods, 
fields, superclass and interfaces for that class and ultimately create a 
database for a complete “android.jar” file of any required API level.

I am, for educational purposes and my own learning, trying to build a system 
like Hoogle/Hayoo for Android. I do a lot of Android and I wanted to create a 
sytem I can wire into Emacs/IntelliJ or anything for that matter, a simple HTTP 
server that can supply a list of methods that have a certain type signature 
using a si mple query language.  Searching by types it very very useful when 
using Haskell and I wanted to improve my Prolog so I figured why not do 
something like that in GNU Prolog? I have already started a simple HTTP library 
in pure GNU Prolog as well but this comes first now.

Progress so far is good…if I run it like this from a folder containing the 
unpacked android.jar file...

| ?- jread('javax/net/SocketFactory.class',X).

X = 
javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])]))
 ? 

The place I am at now is decoding the bit flags for the class (and eventually 
the methods etc) into a term.

A typical value would be “1057” decimal, 0x421, this contains the flags:

ACC_PUBLIC      0x0001  Declared public; may be accessed from outside its 
package.
ACC_FINAL       0x0010  Declared final; no subclasses allowed.
ACC_SUPER       0x0020  Treat superclass methods specially when invoked by the 
invokespecial instruction.                                     
ACC_INTERFACE   0x0200  Is an interface, not a class.
ACC_ABSTRACT    0x0400  Declared abstract; must not be instantiated.
ACC_SYNTHETIC   0x1000  Declared synthetic; not present in the source code.
ACC_ANNOTATION  0x2000  Declared as an annotation type.
ACC_ENUM        0x4000  Declared as an enum type.

So you can see that 0x421 means “ACC_PUBLIC, ACC_SUPER and ACC_ABSTRACT”. I 
would like to produce a term something like this:

    access_flags(public,super,abstract)

It’s not that I don’t know how to do it or that I can’t do it but I am not sure 
what is the *most elegant* way to do it in Prolog! Heaven knows I have written 
bit shifting loops to test for flags in a dozen languages but not in Prolog.

So, there’s the challenge, what is the most elegant way to turn a list of bits 
into a list of atom terms. Ideally I would make the list of atoms a parameter 
so that I can reuse it for the other flag based values.

Consider the gauntlet thrown!   In the meantime I am continuing to research the 
possibilities for myself. I will of course put it all on GitHub along with my 
Redis client. I may even create a Redis database with the information!

:)
Sean.

_______________________________________________
Users-prolog mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/users-prolog

Reply via email to