From 3978f22a96c1d0243ab9da85e42d75358a4136ce Mon Sep 17 00:00:00 2001
From: Sven Gestegard Robertz <sven.robertz@cs.lth.se>
Date: Tue, 11 Nov 2014 11:46:44 +0100
Subject: [PATCH] cherry-pick fde3673cc

---
 compiler/DeclNames.jrag    |   7 ++
 compiler/Java_CodeGen.jrag | 129 ++++++++++++++++++++++++++++++++-----
 examples/simple/simple.lc  |   9 +++
 lib/java/Makefile          |   1 +
 4 files changed, 129 insertions(+), 17 deletions(-)

diff --git a/compiler/DeclNames.jrag b/compiler/DeclNames.jrag
index 4e58087..042739b 100644
--- a/compiler/DeclNames.jrag
+++ b/compiler/DeclNames.jrag
@@ -4,4 +4,11 @@ aspect DeclNames {
 
 	inh String Field.declName();
 	eq StructType.getField(int i).declName() = declName();
+    
+        //TODO: aspect should be renamed to parent-something
+
+        inh Decl Type.parentDecl();
+        inh Decl Field.parentDecl();
+        eq Decl.getType().parentDecl() = this;
+        eq StructType.getField(int i).parentDecl() = parentDecl();
 }
diff --git a/compiler/Java_CodeGen.jrag b/compiler/Java_CodeGen.jrag
index c21260b..61e95c3 100644
--- a/compiler/Java_CodeGen.jrag
+++ b/compiler/Java_CodeGen.jrag
@@ -206,6 +206,21 @@ aspect Java_CodeGen {
 
   public void Program.J_gen(PrintStream ps, String pack, int version) throws IOException {
     Java_env env;
+/*
+    // Registration class
+    env = new Java_env(version, ps);
+    if (pack != null && pack.length() > 0) {
+      env.println("package " + pack + ";");
+    }
+    env.println("public class LabCommRegister {");
+    env.println();
+    env.indent();
+    Java_emitTypeRegister(env);
+    env.unindent();
+    env.println();
+    env.println("}");
+//    env.close();
+*/
     env = new Java_env(version, ps);
     for (int i = 0; i < getNumDecl(); i++) {
       Decl d = getDecl(i);
@@ -221,6 +236,21 @@ aspect Java_CodeGen {
 
   public void Program.J_gen(String dir, String pack, int version) throws IOException {
     Java_env env;
+/*
+    // Registration class
+    env = new Java_env(version, new File(dir, "LabCommRegister.java"));
+    if (pack != null && pack.length() > 0) {
+      env.println("package " + pack + ";");
+    }
+    env.println("public class LabCommRegister {");
+    env.println();
+    env.indent();
+    Java_emitTypeRegister(env);
+    env.unindent();
+    env.println();
+    env.println("}");
+    env.close();
+*/
     for (int i = 0; i < getNumDecl(); i++) {
       Decl d = getDecl(i);
       try {
@@ -256,6 +286,57 @@ aspect Java_CodeGen {
       }
     }
   }
+
+}
+
+aspect Java_Register {
+
+  public void Program.Java_emitTypeRegister(Java_env env) {
+    
+    env.println("static void register(Encoder e) {");
+    env.indent();
+    for (int i = 0; i < getNumDecl(); i++) {
+      getDecl(i).Java_emitTypeRegister(env);
+    }
+    env.unindent();
+    env.println("}");
+
+
+  }
+
+  public void Decl.Java_emitTypeRegister(Java_env env) {
+    throw new Error(this.getClass().getName() + 
+		    ".Java_emitTypeRegister(Java_env env)" + 
+		    " not declared");
+  }
+
+  public void SampleDecl.Java_emitTypeRegister(Java_env env) {
+    env.println(getName() + ".register(e);");
+  }
+
+  public void TypeDecl.Java_emitTypeRegister(Java_env env) {
+    // TODO
+    env.println("//TODO    " + getName() + ".register(e);");
+  }
+
+}
+aspect User_Types {
+  syn String Type.getTypeName();
+  eq Type.getTypeName() = getClass().getName();
+  eq PrimType.getTypeName() = getName();
+  eq UserType.getTypeName() = getName();
+
+  syn boolean Type.isUserType();
+  eq Type.isUserType() = false;
+  eq UserType.isUserType() = true;
+
+ 
+  coll Set<Decl> Decl.references() [new HashSet<Decl>()] with add;
+
+  Field contributes ((UserType)getType()).decl()   
+  when parentDecl() != null && getType().isUserType()
+  to Decl.references() 
+  for parentDecl();
 }
 
 aspect Java_Class {
@@ -267,46 +348,46 @@ aspect Java_Class {
   }
 
   public void TypeDecl.Java_emitClass(Java_env env, String pack) {
-    if (getType().Java_needInstance()) {
       // Hackish prettyprint preamble
       env.println("/* ");
       pp(env.getPrintStream());
+    if( !references().isEmpty() ) {
+        Iterator<Decl> it = references().iterator();
+        while(it.hasNext()) {
+          Decl t = it.next();
+          env.println(" //Depends on "+t.getName() + " (" + t +") " );
+        }
+    } else {
+        env.println(" //no more deps ");
+    }
       env.println("*/");
 
       if (pack != null && pack.length() > 0) {
         env.println("package " + pack + ";");
       }
 
+    env.println("import se.lth.control.labcomm"+env.verStr+".SampleType;");
+    if (getType().Java_needInstance()) {
       env.println("import java.io.IOException;");
-      env.println("import se.lth.control.labcomm"+env.verStr+".SampleType;");
       env.println("import se.lth.control.labcomm"+env.verStr+".Encoder;");
       env.println("import se.lth.control.labcomm"+env.verStr+".Decoder;");
       env.println();
+    }
+      //For types not needing an instance, currently just an empty class is generated
+
       env.println("public class " + getName() + " implements SampleType {");
       env.println();
+
+    if (getType().Java_needInstance()) {
       env.indent();
       getType().Java_emitInstance(env);
       Java_emitEncoder(env);
       Java_emitDecoder(env);
+    }
       env.unindent();
       env.println("}");
-    }
   }
 
-//  TODO: ?
-//  Code snippet for making samples of user types extend their type 
-//  currently commented out. Is this a good idea?
-//
-//  syn String Type.getTypeName();
-//  eq Type.getTypeName() = getClass().getName();
-//  eq PrimType.getTypeName() = getName();
-//  eq UserType.getTypeName() = getName();
-
-//  syn boolean Type.isUserType();
-//  eq Type.isUserType() = false;
-//  eq UserType.isUserType() = true;
-//
-// plus use some lines down
 
   public void SampleDecl.Java_emitClass(Java_env env, String pack) {
     env.println("/* ");
@@ -325,6 +406,10 @@ aspect Java_Class {
     env.println("import se.lth.control.labcomm"+env.verStr+".Sample;");
     env.println();
     env.print("public class " + getName());
+//  TODO: ?
+//  Code for making samples of user types extend their type 
+//  currently commented out. Is this a good idea or not?
+//
 //    if(getType().isUserType()) {
 //        env.print(" extends "+getType().getTypeName());
 //    }
@@ -350,6 +435,16 @@ aspect Java_Class {
 
     env.println("public static void register(Encoder e) throws IOException {");
     env.indent();
+
+    if( !references().isEmpty() ) {
+        Iterator<Decl> it = references().iterator();
+        while(it.hasNext()) {
+          Decl t = it.next();
+          env.println(" //Depends on "+t.getName() + " (" + t +") " );
+        }
+    } else {
+        env.println(" //no more deps ");
+    }
     env.println("e.register(new Dispatcher());");
     env.unindent();
     env.println("}");
diff --git a/examples/simple/simple.lc b/examples/simple/simple.lc
index f25295d..1330369 100644
--- a/examples/simple/simple.lc
+++ b/examples/simple/simple.lc
@@ -6,6 +6,15 @@ typedef struct {
 sample TwoInts theTwoInts;
 sample TwoInts anotherTwoInts;
 
+typedef int AnInt;
+
+sample AnInt theInt;
+
+sample struct {
+  TwoInts ti1;
+  TwoInts ti2;
+} twoTwoInts;
+
 sample struct {
   int x;
   string s;
diff --git a/lib/java/Makefile b/lib/java/Makefile
index 58ee268..68e4cae 100644
--- a/lib/java/Makefile
+++ b/lib/java/Makefile
@@ -9,6 +9,7 @@ MODULES=Constant \
 	Sample \
 	SampleDispatcher \
 	SampleHandler \
+	Type \
 	SampleType \
 	Writer \
 	WriterWrapper
-- 
GitLab