01: package gnu.kawa.functions;
02:
03: import gnu.bytecode.*;
04: import gnu.mapping.*;
05: import gnu.expr.*;
06:
07: /** Special procedure to get the Class of the current module.
08: * Since "current module" is defined by lexical scope,
09: * this isn't a first-class procedure - it has to be inlined.
10: */
11:
12: public class GetModuleClass extends Procedure0 implements Inlineable {
13: public static final GetModuleClass getModuleClass = new GetModuleClass();
14:
15: public Object apply0() {
16: throw new Error("get-module-class must be inlined");
17: }
18:
19: public void compile(ApplyExp exp, Compilation comp, Target target) {
20: comp.loadClassRef(comp.mainClass);
21: target
22: .compileFromStack(comp, ClassType
23: .make("java.lang.Class"));
24: }
25:
26: public gnu.bytecode.Type getReturnType(Expression[] args) {
27: return ClassType.make("java.lang.Class");
28: }
29:
30: private static String CLASS_RESOURCE_NAME = "$class_resource_URI$";
31:
32: /** Return an expression that evaluates to a module-relative URI.
33: * This has the Kawa-specific URI scheme "class-resource:" and an
34: * assocatied ClassLoader (using a WekaHashMap). It used to reference
35: * resources located using the compiled class's ClassLoader. */
36: public static Expression getModuleClassURI(Compilation comp) {
37: Declaration decl = comp.mainLambda.lookup(CLASS_RESOURCE_NAME);
38: if (decl == null) {
39: comp.mustCompileHere();
40: decl = new Declaration(CLASS_RESOURCE_NAME);
41: decl.setFlag(Declaration.IS_CONSTANT
42: | Declaration.STATIC_SPECIFIED);
43: Method maker = ClassType.make("gnu.text.URLPath")
44: .getDeclaredMethod("classResourcePath", 1);
45: Expression clas = new ApplyExp(
46: gnu.kawa.functions.GetModuleClass.getModuleClass,
47: Expression.noExpressions);
48: decl
49: .setValue(new ApplyExp(maker,
50: new Expression[] { clas }));
51: comp.mainLambda.add(null, decl);
52: }
53: return new ReferenceExp(decl);
54: }
55: }
|