java-gobject-introspection r168 - in trunk: . src src/org/gnome/gir/compiler src/org/gnome/gir/repository



Author: walters
Date: Fri Jan 30 05:35:25 2009
New Revision: 168
URL: http://svn.gnome.org/viewvc/java-gobject-introspection?rev=168&view=rev

Log:
Some initial work on documentation generator

Added:
   trunk/src/jgir-docgen.in
   trunk/src/org/gnome/gir/compiler/DocFactory.java
Modified:
   trunk/src/org/gnome/gir/compiler/CodeFactory.java
   trunk/src/org/gnome/gir/repository/Repository.java
   trunk/wscript

Added: trunk/src/jgir-docgen.in
==============================================================================
--- (empty file)
+++ trunk/src/jgir-docgen.in	Fri Jan 30 05:35:25 2009
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+import os,sys,subprocess
+
+classpath="@CLASSPATH@"
+# Just put this one in the env
+os.environ['TYPELIBDIR'] = "@TYPELIBDIR@"
+os.environ['GIRDIR'] = "@GIRDIR@"
+java_opts=os.environ.get('JAVA_OPTS', None)
+if java_opts:
+    java_opts = java_opts.split(' ')
+else:
+    java_opts = []
+args = ['java']
+args.extend(java_opts)
+args.extend(['-cp', classpath, 'org.gnome.gir.compiler.DocFactory'])
+args.extend(sys.argv[1:])
+subprocess.check_call(args,
+                      stdout=sys.stdout,
+                      stderr=sys.stderr,
+                      close_fds=True)

Modified: trunk/src/org/gnome/gir/compiler/CodeFactory.java
==============================================================================
--- trunk/src/org/gnome/gir/compiler/CodeFactory.java	(original)
+++ trunk/src/org/gnome/gir/compiler/CodeFactory.java	Fri Jan 30 05:35:25 2009
@@ -2311,11 +2311,11 @@
 		return new File(typelibPath.getParent(), String.format("%s-%s.jar", namespace, version));
 	}
 
-	private static boolean namespaceIsExcluded(String namespace) {
+	public static boolean namespaceIsExcluded(String namespace) {
 		return namespace.equals("GLib") || namespace.equals("GObject");
 	}
 
-	private static File getTypelibDir() {
+	public static File getTypelibDir() {
 		return new File(System.getenv("TYPELIBDIR"));
 	}
 
@@ -2330,7 +2330,7 @@
 		verifyJarFiles(Arrays.asList(jars));
 	}
 
-	private static final class NsVer {
+	public static final class NsVer {
 		public String namespace;
 		public String version;
 

Added: trunk/src/org/gnome/gir/compiler/DocFactory.java
==============================================================================
--- (empty file)
+++ trunk/src/org/gnome/gir/compiler/DocFactory.java	Fri Jan 30 05:35:25 2009
@@ -0,0 +1,336 @@
+package org.gnome.gir.compiler;
+
+import gobject.runtime.GErrorException;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+import java.util.logging.StreamHandler;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.gnome.gir.repository.Repository;
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.Attribute;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+public class DocFactory {
+
+	static final Logger logger = Logger.getLogger("org.gnome.gir.Compiler");
+	static {
+		logger.addHandler(new StreamHandler(System.err, new Formatter() {
+			@Override
+			public String format(LogRecord record) {
+				return String.format("%s%n", record.getMessage());
+			}
+		}));
+		logger.setUseParentHandlers(false);
+	}
+
+	private final Repository repo;
+
+	private DocFactory(Repository repo) {
+		this.repo = repo;
+	}
+	
+	public static String join(String sep, List<String> components) {
+		StringBuilder builder = new StringBuilder();
+		int size = components.size();
+		for (int i = 0; i < size; i++) {
+			String component = components.get(i);
+			boolean isLast = i == size-1;
+			builder.append(component);
+			if (!isLast)
+				builder.append(sep);
+		}
+		return builder.toString();
+	}	
+	
+    private static String strAccess(final int access) {
+    	List<String> modifiers = new ArrayList<String>();
+	    if ((access & Opcodes.ACC_PUBLIC) != 0) {
+			modifiers.add("public");
+		}
+		if ((access & Opcodes.ACC_PRIVATE) != 0) {
+			modifiers.add("private");
+		}
+		if ((access & Opcodes.ACC_PROTECTED) != 0) {
+			modifiers.add("protected");
+		}
+		if ((access & Opcodes.ACC_FINAL) != 0) {
+			modifiers.add("final");
+		}
+		if ((access & Opcodes.ACC_STATIC) != 0) {
+			modifiers.add("static");
+		}
+		if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) {
+			modifiers.add("synchronized");
+		}
+		if ((access & Opcodes.ACC_VOLATILE) != 0) {
+			modifiers.add("volatile");
+		}
+		if ((access & Opcodes.ACC_TRANSIENT) != 0) {
+			modifiers.add("transient");
+		}
+		if ((access & Opcodes.ACC_NATIVE) != 0) {
+			modifiers.add("native");
+		}
+		if ((access & Opcodes.ACC_ABSTRACT) != 0 && 
+		    (access & Opcodes.ACC_INTERFACE) == 0) {
+			modifiers.add("abstract");
+		}
+	    return join(" ", modifiers);
+    }
+ 
+    private class ClassJavafier implements ClassVisitor {
+    	Writer out;
+    	String clsName;
+    	
+		public ClassJavafier(Writer out) {
+			this.out = out;
+		}
+
+		@Override
+		public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+			clsName = name;
+			try {
+				out.write(strAccess(access));
+				if ((access & Opcodes.ACC_INTERFACE) != 0)
+					out.write(" interface ");
+				else if ((access & Opcodes.ACC_ENUM) != 0)
+					out.write(" enum ");
+				else
+					out.write(" class ");
+				String iname = stripInternals(name);
+				int innerIdx = iname.indexOf('$');
+				if (innerIdx > 0)
+					iname = iname.substring(innerIdx + 1);
+				out.write(iname);
+				out.write(" extends ");
+				out.write(replaceInternals(superName));
+				if (interfaces != null && interfaces.length > 0) {
+					out.write(" implements ");
+					List<String> ifaces = new ArrayList<String>();
+					for (String iface : Arrays.asList(interfaces)) {
+						ifaces.add(replaceInternals(iface));
+					}
+					out.write(join(",", ifaces));
+				}
+				out.write(" {\n");
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+
+		@Override
+		public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) {
+			return null;
+		}
+
+		@Override
+		public void visitAttribute(Attribute arg0) {
+		}
+
+		@Override
+		public void visitEnd() {			
+		}
+		
+		public void close() {
+    		try {
+				out.write("\n}\n\n");
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}			
+		}
+
+		@Override
+		public FieldVisitor visitField(int arg0, String arg1, String arg2, String arg3, Object arg4) {
+			return null;
+		}
+
+		@Override
+		public void visitInnerClass(String arg0, String arg1, String arg2, int arg3) {
+		}
+
+		@Override
+		public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
+			if (name.equals("<clinit>"))
+				return null;
+			Type[] args = Type.getArgumentTypes(descriptor);
+			Type retType = Type.getReturnType(descriptor);
+			try {
+				out.write(strAccess(access));			
+				out.write(" " + toJava(retType));
+				if (name.equals("<init>"))
+					name = clsName; 
+				out.write(" " + name + " (");
+				
+				for (int i = 0; i < args.length; i++) {
+					out.write(toJava(args[i]));
+					if (i < args.length - 1)
+						out.write(", ");
+				}
+				out.write(");\n\n");
+			} catch (IOException e) {
+				throw new RuntimeException(e);
+			}
+			return null;
+		}
+
+		@Override
+		public void visitOuterClass(String arg0, String arg1, String arg2) {
+		}
+
+		@Override
+		public void visitSource(String arg0, String arg1) {
+		}
+    }
+
+    private static final String toJava(Type type) {
+    	switch (type.getSort()) {
+    	case Type.OBJECT:
+    		return replaceInternals(type.getInternalName());
+    	case Type.ARRAY:
+    		return toJava(type.getElementType()) + "[]";
+    	case Type.BYTE:
+    		return "byte";
+    	case Type.SHORT:
+    		return "short";
+    	case Type.CHAR:
+    		return "char";
+    	case Type.INT:
+    		return "int";
+    	case Type.LONG:
+    		return "long";
+    	case Type.VOID:
+    		return "void";
+    	case Type.BOOLEAN:
+    		return "boolean";
+    	case Type.FLOAT:
+    		return "float";
+    	case Type.DOUBLE:
+    		return "double";
+    	default:
+    		throw new RuntimeException("" + type);
+    	}
+    }
+    
+    private static final String stripInternals(String path) {
+    	int idx = path.lastIndexOf('/');
+    	return path.substring(idx+1);
+    }
+    
+    private static final String replaceInternals(String path) {
+    	return path.replace('/', '.');
+    }
+	
+	private void generateOne(File jarpath, File girpath, File outpath) throws Exception {
+		repo.hashCode();
+		ZipFile zf = new ZipFile(jarpath);
+		
+		List<? extends ZipEntry> entries = Collections.list(zf.entries());
+		
+		for (ZipEntry entry : entries) {
+			String name = stripInternals(entry.getName().replace(".class", ""));
+			if (name.contains("$"))
+				continue;
+			
+			File javaOutPath = new File(outpath, entry.getName().replace(".class", ".java"));
+			javaOutPath.getParentFile().mkdirs();
+
+			Writer javaOut = new BufferedWriter(new FileWriter(javaOutPath));
+			
+			InputStream is = zf.getInputStream(entry);
+			ClassReader cv = new ClassReader(is);			
+
+			ClassJavafier visitor = new ClassJavafier(javaOut);
+
+			cv.accept(visitor, 0);
+			
+			String innerPrefix = name + "$";
+			/* Load its inner classes */
+			for (ZipEntry subEntry : entries) {
+				String innerName = stripInternals(subEntry.getName().replace(".class", ""));
+				if (!innerName.startsWith(innerPrefix))
+					continue;
+				
+				InputStream innerInput = zf.getInputStream(subEntry);
+				ClassReader innerCv = new ClassReader(innerInput);			
+
+				ClassJavafier innerVisitor = new ClassJavafier(javaOut);
+				innerCv.accept(innerVisitor, 0);
+				innerVisitor.close();
+			}
+			
+			visitor.close();
+			
+			javaOut.close();
+			logger.info("Wrote " + javaOutPath);
+		}
+	}
+	
+	public static void generate(File girpath, File outpath) throws Exception {
+		String base = girpath.getName();
+
+		CodeFactory.NsVer nsver = CodeFactory.NsVer.parse(base);
+		if (CodeFactory.namespaceIsExcluded(nsver.namespace))
+			return;
+		
+		Repository repo = new Repository();
+		try {
+			repo.require(nsver.namespace, nsver.version);
+		} catch (GErrorException e) {
+			logger.log(Level.WARNING, "Failed to load namespace " + nsver.namespace, e);
+			return;
+		}
+		
+		File jarpath = CodeFactory.getJarPath(repo, nsver.namespace);
+		
+		DocFactory factory = new DocFactory(repo);
+
+		factory.generateOne(jarpath, girpath, outpath);
+	}
+	
+	private static File getGirDir() {
+		return new File(System.getenv("GIRDIR"));
+	}	
+
+	public static void generateAll(File outpath) throws Exception {
+		File[] girs = getGirDir().listFiles(new FilenameFilter() {
+			@Override
+			public boolean accept(File dir, String name) {
+				return name.endsWith(".gir");
+			}
+		});
+
+		for (File gir : girs) {
+			generate(gir, outpath);
+		}
+	}
+
+	public static void main(String[] args) throws Exception {
+		if (args[0].equals("--compileall"))
+			generateAll(new File(args[1]));
+		else if (args[0].endsWith(".gir")) {
+			File gir = new File(args[0]);
+			generate(gir, new File(args[1]));
+		}
+	}
+}

Modified: trunk/src/org/gnome/gir/repository/Repository.java
==============================================================================
--- trunk/src/org/gnome/gir/repository/Repository.java	(original)
+++ trunk/src/org/gnome/gir/repository/Repository.java	Fri Jan 30 05:35:25 2009
@@ -12,6 +12,10 @@
 
 public class Repository extends GObject {
 
+	static {
+		GlibRuntime.init();		
+	}
+	
 	public Repository(Initializer init) {
 		super(init);
 	}
@@ -87,7 +91,6 @@
 	}
 	
 	public static synchronized Repository getDefault() {
-		GlibRuntime.init();
 		return (Repository) NativeObject.Internals.objectFor(getNativeLibrary().g_irepository_get_default(),
 									  Repository.class, false, false);
 	}

Modified: trunk/wscript
==============================================================================
--- trunk/wscript	(original)
+++ trunk/wscript	Fri Jan 30 05:35:25 2009
@@ -1,7 +1,7 @@
 #! /usr/bin/env python
 # -*- coding: utf-8; indent-tabs-mode: nil; python-indent: 2 -*-
 
-import os
+import os, glob, shutil
 
 import Task,TaskGen,Node
 from TaskGen import *
@@ -64,6 +64,7 @@
 
   conf.check_cfg(package='gobject-introspection-1.0', uselib_store='GI', args="--cflags --libs", mandatory=True)
   conf.get_pkgconfig_var('gobject-introspection-1.0', 'typelibdir')
+  conf.get_pkgconfig_var('gobject-introspection-1.0', 'girdir')
 
   asm_deps = ['asm', 'asm-util', 'asm-tree', 'asm-commons', 'asm-analysis']
   for dep in asm_deps:
@@ -75,9 +76,11 @@
 
 def build(bld):
   jsrc = bld.new_task_gen(features='java',
+                          name='jsrc',
                           install_path = '${PREFIX}/share/java',
                           source_root = 'src',
                           jarname = 'jgir.jar')
+  bld.install_files('${PREFIX}/share/java', 'jgir.jar')
 
   full_cp = bld.env['CLASSPATH'] + ':' + bld.env['PREFIX'] + '/share/java/jgir.jar'
   compscript = bld.new_task_gen('subst')
@@ -86,7 +89,7 @@
   compscript.source = 'src/jgir-compile-all.in'
   compscript.target = 'jgir-compile-all'
   compscript.dict = {'CLASSPATH': full_cp, 'PREFIX': bld.env['PREFIX'],
-                     'TYPELIBDIR': bld.env['typelibdir']}
+                     'TYPELIBDIR': bld.env['typelibdir'], 'GIRDIR': bld.env['girdir']}
 
   compscript = bld.new_task_gen('subst')
   compscript.install_path = "${PREFIX}/bin"
@@ -94,6 +97,21 @@
   compscript.source = 'src/jgir-compile.in'
   compscript.target = 'jgir-compile'
   compscript.dict = {'CLASSPATH': full_cp, 'TYPELIBDIR': bld.env['typelibdir']}
+  
+  compscript = bld.new_task_gen('subst')
+  compscript.install_path = "${PREFIX}/bin"
+  compscript.chmod = 0755
+  compscript.source = 'src/jgir-docgen.in'
+  compscript.target = 'jgir-docgen'
+  compscript.dict = {'CLASSPATH': full_cp, 'PREFIX': bld.env['PREFIX'],
+                     'TYPELIBDIR': bld.env['typelibdir'], 'GIRDIR': bld.env['girdir']}  
+
+  #openjdkdir = glob.glob('/usr/share/javadoc/java-1.6*openjdk/api')[0]
+  #jnadir = glob.glob('/usr/share/javadoc/jna-*')[0]
+  #bld.new_task_gen(name='javadoc',
+  #                 sources = jsrc.
+  #                 rule='javadoc -d javadoc -sourcepath ../src -classpath ' + bld.env['CLASSPATH'] + ':.' \
+  #                       + ' -link ' + openjdkdir + ' -link ' + jnadir + ' gobject.runtime')
 
   #libinvoke = bld.new_task_gen('cc', 'shlib')
   #libinvoke.packages = ['gobject-introspection-1.0']
@@ -109,4 +127,13 @@
   #testinvoke.unit_test = 1
 
 def shutdown():
-  pass
+#  if Options.is_install:
+#    destdir = Build.bld.get_install_path('${PREFIX}/share/javadoc')
+#    try:
+#      os.makedirs(destdir)
+#    except OSError, e:
+#      pass
+#    target = os.path.join(destdir, 'jgir')
+#    shutil.rmtree(target)
+#    print "Installing javadoc to " + target
+#    shutil.copytree('build/javadoc', target)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]