1.1 --- a/geo/src/main/java/org/apidesign/html/geo/impl/GeoProcessor.java Thu Jul 25 16:54:49 2013 +0200
1.2 +++ b/geo/src/main/java/org/apidesign/html/geo/impl/GeoProcessor.java Mon Jul 29 16:06:51 2013 +0200
1.3 @@ -22,6 +22,7 @@
1.4
1.5 import java.io.IOException;
1.6 import java.io.Writer;
1.7 +import java.util.List;
1.8 import java.util.Locale;
1.9 import java.util.Set;
1.10 import java.util.logging.Level;
1.11 @@ -38,6 +39,7 @@
1.12 import javax.lang.model.element.Modifier;
1.13 import javax.lang.model.element.PackageElement;
1.14 import javax.lang.model.element.TypeElement;
1.15 +import javax.lang.model.element.VariableElement;
1.16 import javax.lang.model.type.TypeMirror;
1.17 import javax.tools.Diagnostic;
1.18 import javax.tools.JavaFileObject;
1.19 @@ -85,8 +87,9 @@
1.20 return false;
1.21 }
1.22 TypeMirror positionClass = processingEnv.getElementUtils().getTypeElement(Position.class.getName()).asType();
1.23 - if (me.getParameters().size() != 1 || !me.getParameters().get(0).asType().equals(positionClass)) {
1.24 - error("Method annotated by @OnLocation needs to have one net.java.html.geo.Position argument!", e);
1.25 + final List<? extends VariableElement> params = me.getParameters();
1.26 + if (params.size() < 1 || !params.get(0).asType().equals(positionClass)) {
1.27 + error("Method annotated by @OnLocation first argument must be net.java.html.geo.Position!", e);
1.28 return false;
1.29 }
1.30 String className = ol.className();
1.31 @@ -104,17 +107,32 @@
1.32 final String pkg = pe.getQualifiedName().toString();
1.33 final String fqn = pkg + "." + className;
1.34 final boolean isStatic = me.getModifiers().contains(Modifier.STATIC);
1.35 + String sep;
1.36 try {
1.37 JavaFileObject fo = processingEnv.getFiler().createSourceFile(fqn, e);
1.38 Writer w = fo.openWriter();
1.39 w.append("package ").append(pkg).append(";\n");
1.40 w.append("class ").append(className).append(" extends net.java.html.geo.Position.Handle {\n");
1.41 - w.append(" private ").append(te.getSimpleName()).append(" i;\n");
1.42 + if (!isStatic) {
1.43 + w.append(" private final ").append(te.getSimpleName()).append(" $i;\n");
1.44 + }
1.45 + for (int i = 1; i < params.size(); i++) {
1.46 + final VariableElement p = params.get(i);
1.47 + w.append(" private final ").append(p.asType().toString()).append(" ").append(p.getSimpleName()).append(";\n");
1.48 + }
1.49 w.append(" private ").append(className).append("(boolean oneTime");
1.50 w.append(", ").append(te.getSimpleName()).append(" i");
1.51 + for (int i = 1; i < params.size(); i++) {
1.52 + final VariableElement p = params.get(i);
1.53 + w.append(", ").append(p.asType().toString()).append(" ").append(p.getSimpleName());
1.54 + }
1.55 w.append(") {\n super(oneTime);\n");
1.56 if (!isStatic) {
1.57 - w.append(" this.i = i;\n");
1.58 + w.append(" this.$i = i;\n");
1.59 + }
1.60 + for (int i = 1; i < params.size(); i++) {
1.61 + final VariableElement p = params.get(i);
1.62 + w.append(" this.").append(p.getSimpleName()).append(" = ").append(p.getSimpleName()).append(";\n");
1.63 }
1.64 w.append("}\n");
1.65 w.append(" static net.java.html.geo.Position.Handle createQuery(");
1.66 @@ -122,15 +140,39 @@
1.67 if (!isStatic) {
1.68 w.append(te.getSimpleName()).append(" instance");
1.69 inst = "instance";
1.70 + sep = ", ";
1.71 } else {
1.72 inst = "null";
1.73 + sep = "";
1.74 }
1.75 - w.append(") { return new ").append(className).append("(true, ").append(inst).append("); }\n");
1.76 + for (int i = 1; i < params.size(); i++) {
1.77 + final VariableElement p = params.get(i);
1.78 + w.append(sep).append(p.asType().toString()).append(" ").append(p.getSimpleName());
1.79 + sep = ", ";
1.80 + }
1.81 + w.append(") { return new ").append(className).append("(true, ").append(inst);
1.82 + for (int i = 1; i < params.size(); i++) {
1.83 + final VariableElement p = params.get(i);
1.84 + w.append(", ").append(p.getSimpleName());
1.85 + }
1.86 + w.append("); }\n");
1.87 w.append(" static net.java.html.geo.Position.Handle createWatch(");
1.88 if (!isStatic) {
1.89 w.append(te.getSimpleName()).append(" instance");
1.90 + sep = ", ";
1.91 + } else {
1.92 + sep = "";
1.93 }
1.94 - w.append(") { return new ").append(className).append("(false, ").append(inst).append("); }\n");
1.95 + for (int i = 1; i < params.size(); i++) {
1.96 + final VariableElement p = params.get(i);
1.97 + w.append(sep).append(p.asType().toString()).append(" ").append(p.getSimpleName());
1.98 + }
1.99 + w.append(") { return new ").append(className).append("(false, ").append(inst);
1.100 + for (int i = 1; i < params.size(); i++) {
1.101 + final VariableElement p = params.get(i);
1.102 + w.append(", ").append(p.getSimpleName());
1.103 + }
1.104 + w.append("); }\n");
1.105 w.append(" @Override protected void onError(Exception t) throws Throwable {\n");
1.106 if (ol.onError().isEmpty()) {
1.107 w.append(" t.printStackTrace();");
1.108 @@ -141,18 +183,28 @@
1.109 if (isStatic) {
1.110 w.append(" ").append(te.getSimpleName()).append(".");
1.111 } else {
1.112 - w.append(" i.");
1.113 + w.append(" $i.");
1.114 }
1.115 - w.append(ol.onError()).append("(t);\n");
1.116 + w.append(ol.onError()).append("(t");
1.117 + for (int i = 1; i < params.size(); i++) {
1.118 + final VariableElement p = params.get(i);
1.119 + w.append(", ").append(p.getSimpleName());
1.120 + }
1.121 + w.append(");\n");
1.122 }
1.123 w.append(" }\n");
1.124 w.append(" @Override protected void onLocation(net.java.html.geo.Position p) throws Throwable {\n");
1.125 if (isStatic) {
1.126 w.append(" ").append(te.getSimpleName()).append(".");
1.127 } else {
1.128 - w.append(" i.");
1.129 + w.append(" $i.");
1.130 }
1.131 - w.append(me.getSimpleName()).append("(p);\n");
1.132 + w.append(me.getSimpleName()).append("(p");
1.133 + for (int i = 1; i < params.size(); i++) {
1.134 + final VariableElement p = params.get(i);
1.135 + w.append(", ").append(p.getSimpleName());
1.136 + }
1.137 + w.append(");\n");
1.138 w.append(" }\n");
1.139 w.append("}\n");
1.140 w.close();
1.141 @@ -165,9 +217,9 @@
1.142 return true;
1.143 }
1.144
1.145 - private boolean findOnError(Element errElem, TypeElement te, String name, boolean onlyStatic) {
1.146 + private boolean findOnError(ExecutableElement errElem, TypeElement te, String name, boolean onlyStatic) {
1.147 String err = null;
1.148 - for (Element e : te.getEnclosedElements()) {
1.149 + METHODS: for (Element e : te.getEnclosedElements()) {
1.150 if (e.getKind() != ElementKind.METHOD) {
1.151 continue;
1.152 }
1.153 @@ -175,19 +227,35 @@
1.154 continue;
1.155 }
1.156 if (onlyStatic && !e.getModifiers().contains(Modifier.STATIC)) {
1.157 - errElem = e;
1.158 + errElem = (ExecutableElement) e;
1.159 err = "Would have to be static";
1.160 continue;
1.161 }
1.162 ExecutableElement ee = (ExecutableElement) e;
1.163 TypeMirror excType = processingEnv.getElementUtils().getTypeElement(Exception.class.getName()).asType();
1.164 - if (ee.getParameters().size() != 1 ||
1.165 + final List<? extends VariableElement> params = ee.getParameters();
1.166 + if (params.size() < 1 ||
1.167 !processingEnv.getTypeUtils().isAssignable(excType, ee.getParameters().get(0).asType())
1.168 ) {
1.169 - errElem = e;
1.170 - err = "Error method needs to take one Exception argument";
1.171 + errElem = (ExecutableElement) e;
1.172 + err = "Error method first argument needs to be Exception";
1.173 continue;
1.174 }
1.175 + final List<? extends Element> origParams = errElem.getParameters();
1.176 + if (params.size() != origParams.size()) {
1.177 + errElem = (ExecutableElement) e;
1.178 + err = "Error method must have the same parameters as @OnLocation one";
1.179 + continue;
1.180 + }
1.181 + for (int i = 1; i < origParams.size(); i++) {
1.182 + final TypeMirror t1 = params.get(i).asType();
1.183 + final TypeMirror t2 = origParams.get(i).asType();
1.184 + if (!processingEnv.getTypeUtils().isSameType(t1, t2)) {
1.185 + errElem = (ExecutableElement) e;
1.186 + err = "Error method must have the same parameters as @OnLocation one";
1.187 + continue METHODS;
1.188 + }
1.189 + }
1.190 return true;
1.191 }
1.192 if (err == null) {
2.1 --- a/geo/src/test/java/net/java/html/geo/OnLocationTest.java Thu Jul 25 16:54:49 2013 +0200
2.2 +++ b/geo/src/test/java/net/java/html/geo/OnLocationTest.java Mon Jul 29 16:06:51 2013 +0200
2.3 @@ -104,4 +104,12 @@
2.4 if (h.isSupported()) h.start();
2.5 h.stop();
2.6 }
2.7 +
2.8 + @OnLocation(onError = "errParam") void withParam(Position pos, int param) {
2.9 + instCnt = param;
2.10 + }
2.11 +
2.12 + void errParam(Exception ex, int param) {
2.13 + instCnt = param;
2.14 + }
2.15 }
3.1 --- a/geo/src/test/java/org/apidesign/html/geo/impl/GeoProcessorTest.java Thu Jul 25 16:54:49 2013 +0200
3.2 +++ b/geo/src/test/java/org/apidesign/html/geo/impl/GeoProcessorTest.java Mon Jul 29 16:06:51 2013 +0200
3.3 @@ -40,7 +40,7 @@
3.4 + "}\n"
3.5 );
3.6 res.assertErrors();
3.7 - res.assertError("one net.java.html.geo.Position argument");
3.8 + res.assertError("first argument must be net.java.html.geo.Position");
3.9 }
3.10
3.11 @Test public void onLocationMethodCannotBePrivate() throws IOException {
3.12 @@ -86,7 +86,7 @@
3.13 + "}\n"
3.14 );
3.15 res.assertErrors();
3.16 - res.assertError("take one Exception arg");
3.17 + res.assertError("Error method first argument needs to be Exception");
3.18 }
3.19
3.20 }