From 5c1fb75e8d43a1841e01f4990fd575d9e4fa1852 Mon Sep 17 00:00:00 2001 From: Markus Scheidgen Date: Thu, 18 Jun 2015 22:40:00 +0200 Subject: [PATCH 1/5] Fixed to support js native methods in inner classes as well. --- .../de/itemis/xtend/auto/gwt/JsNative.xtend | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend index 5219573..1f1cc9d 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend @@ -15,6 +15,7 @@ import org.eclipse.xtend.lib.macro.declaration.MethodDeclaration import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration import org.eclipse.xtend.lib.macro.file.Path +import java.util.List /** * JSNI requires comments containing Java script code, which is not translated by the Xtend compiler. @@ -51,14 +52,22 @@ class JsNativeProcessor extends AbstractMethodProcessor { return method.declaringType.simpleName+"#"+method.simpleName+"("+method.parameters.map[type].join(',')+")" } - override doGenerateCode(MethodDeclaration annotatedMethod, extension CodeGenerationContext context) { - val path = annotatedMethod.declaringType.getTargetPath(context) - val contents = path.contents.toString - val markerStart = contents.indexOf(getUniqueMarkerCode(annotatedMethod)) - val startIndex = contents.substring(0, markerStart).lastIndexOf('{') - val endIndex = contents.substring(markerStart).indexOf('}') + markerStart - val jsCode = annotatedMethod.body.toString.trimTripleQuotes - path.contents = contents.substring(0, startIndex)+"/*-{"+jsCode+"}-*/;"+contents.substring(endIndex+1) + override doGenerateCode(List annotatedMethods, extension CodeGenerationContext context) { + val path = annotatedMethods.findFirst[true].declaringType.getTargetPath(context) + var contents = path.contents.toString + + for(annotatedMethod: annotatedMethods) { + val markerStart = contents.indexOf(getUniqueMarkerCode(annotatedMethod)) + val startIndex = contents.substring(0, markerStart).lastIndexOf('{') + val endIndex = contents.substring(markerStart).indexOf('}') + markerStart + val jsCode = annotatedMethod.body.toString.trimTripleQuotes + contents = contents.substring(0, startIndex)+"/*-{"+jsCode+"}-*/;"+contents.substring(endIndex+1) + } + + path.contents = contents + do { + Thread.sleep(100) + } while (path.contents.toString != contents) } private def String trimTripleQuotes(String s) { @@ -68,6 +77,6 @@ class JsNativeProcessor extends AbstractMethodProcessor { def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { val unit = type.compilationUnit val targetFolder = unit.filePath.targetFolder - return targetFolder.append(type.qualifiedName.replace('.','/')+".java") + return targetFolder.append(unit.sourceTypeDeclarations.findFirst[true].qualifiedName.replace('.','/')+".java") } -} \ No newline at end of file +} From 4ad34d84695dc576a3cba91ece45f57ccba78598 Mon Sep 17 00:00:00 2001 From: Markus Scheidgen Date: Wed, 24 Jun 2015 11:15:30 +0200 Subject: [PATCH 2/5] Added support for inner classes to JsNative; added support for primitive array types in OverlayTypeByExample; added replacement of @ClientBundle.Source to @Source since my gwt (or atleast gwt's eclipse plugins) does not interpret it correctly otherwise. --- .../itemis/xtend/auto/gwt/ClientBundle.xtend | 17 +++++++- .../de/itemis/xtend/auto/gwt/JsNative.xtend | 17 ++++---- .../xtend/auto/gwt/OverlayTypeByExample.xtend | 41 ++++++++++++------- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend b/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend index a3ac05d..1d45514 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend @@ -30,6 +30,9 @@ import org.eclipse.xtend.lib.macro.declaration.MutableAnnotationTarget import org.eclipse.xtend.lib.macro.declaration.MutableInterfaceDeclaration import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration +import org.eclipse.xtend.lib.macro.CodeGenerationParticipant +import org.eclipse.xtend.lib.macro.CodeGenerationContext +import org.eclipse.xtend.lib.macro.file.Path @Target(ElementType.TYPE) annotation CssResource { @@ -47,7 +50,8 @@ annotation ImageResources { annotation ClientBundle { } -class CliendBundleProcessor implements RegisterGlobalsParticipant, TransformationParticipant { +class CliendBundleProcessor implements RegisterGlobalsParticipant, TransformationParticipant, + CodeGenerationParticipant { private static final String INSTANCE = 'INSTANCE' @@ -246,5 +250,16 @@ class CliendBundleProcessor implements RegisterGlobalsParticipant annotatedSourceElements, extension CodeGenerationContext context) { + val path = annotatedSourceElements.get(0).declaringType.getTargetPath(context) + val contents = path.contents.toString.replaceAll("@ClientBundle.Source", "@Source") + path.contents = contents + } + private def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { + val unit = type.compilationUnit + val targetFolder = unit.filePath.targetFolder + return targetFolder.append(unit.sourceTypeDeclarations.findFirst[true].qualifiedName.replace('.','/')+".java") + } } diff --git a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend index 1f1cc9d..8521b58 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend @@ -53,21 +53,20 @@ class JsNativeProcessor extends AbstractMethodProcessor { } override doGenerateCode(List annotatedMethods, extension CodeGenerationContext context) { - val path = annotatedMethods.findFirst[true].declaringType.getTargetPath(context) + val path = annotatedMethods.get(0).declaringType.getTargetPath(context) var contents = path.contents.toString for(annotatedMethod: annotatedMethods) { val markerStart = contents.indexOf(getUniqueMarkerCode(annotatedMethod)) - val startIndex = contents.substring(0, markerStart).lastIndexOf('{') - val endIndex = contents.substring(markerStart).indexOf('}') + markerStart - val jsCode = annotatedMethod.body.toString.trimTripleQuotes - contents = contents.substring(0, startIndex)+"/*-{"+jsCode+"}-*/;"+contents.substring(endIndex+1) + if (markerStart > 0) { + val startIndex = contents.substring(0, markerStart).lastIndexOf('{') + val endIndex = contents.substring(markerStart).indexOf('}') + markerStart + val jsCode = annotatedMethod.body.toString.trimTripleQuotes + contents = contents.substring(0, startIndex)+"/*-{"+jsCode+"}-*/;"+contents.substring(endIndex+1) + } } path.contents = contents - do { - Thread.sleep(100) - } while (path.contents.toString != contents) } private def String trimTripleQuotes(String s) { @@ -77,6 +76,6 @@ class JsNativeProcessor extends AbstractMethodProcessor { def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { val unit = type.compilationUnit val targetFolder = unit.filePath.targetFolder - return targetFolder.append(unit.sourceTypeDeclarations.findFirst[true].qualifiedName.replace('.','/')+".java") + return targetFolder.append(type.qualifiedName.replace('.','/')+".java") } } diff --git a/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend b/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend index 96f59d3..052b873 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend @@ -27,6 +27,9 @@ import org.eclipse.xtend.lib.macro.declaration.TypeReference import org.eclipse.xtend.lib.macro.declaration.Visibility import static extension de.itemis.xtend.auto.gwt.StaticUtils.* +import com.google.gwt.core.client.JsArrayString +import com.google.gwt.core.client.JsArrayBoolean +import com.google.gwt.core.client.JsArrayNumber /** * Allows to implement a GWT OverlayType using a JSON example. @@ -85,7 +88,7 @@ class OverlayTypeByExampleProcessor extends AbstractClassProcessor { } - val PATTERN = Pattern.compile("public final native (.+) get(\\w+)\\(\\);") + val PATTERN = Pattern.compile("public final native (.+) get(\\w+)\\(\\) \\{\\s*(\\w+)\\s*\\}") /** * we add the Java comment containing the javascript code during code generation, since there is no way to add it using the Java model. @@ -95,10 +98,9 @@ class OverlayTypeByExampleProcessor extends AbstractClassProcessor { val targetFile = targetFolder.append(annotatedClass.qualifiedName.replace('.','/')+".java") val contents = targetFile.contents val matcher = PATTERN.matcher(contents) - targetFile.contents = matcher.replaceAll("public final native $1 get$2() /*-{ return this.$2; }-*/;") + targetFile.contents = matcher.replaceAll("public final native $1 get$2() /*-{ return this.$3; }-*/;") } - static class Util { extension TransformationContext ctx @@ -122,6 +124,8 @@ class OverlayTypeByExampleProcessor extends AbstractClassProcessor { native = true final = true returnType = getJavaType(property, classDeclaration) + // save the property key as body for later reference in code generation phase + body = '''«property.key»''' ] } @@ -147,19 +151,26 @@ class OverlayTypeByExampleProcessor extends AbstractClassProcessor { val type = currentContainer.declaredClasses.findFirst[simpleName == simpleTypeName] type.newTypeReference } - JsonPrimitive case element.isString: { - String.newTypeReference - } - JsonPrimitive case element.isBoolean: { - boolean.newTypeReference - } - JsonPrimitive case element.isNumber: { - if (element.asString.indexOf('.') == -1) { - int.newTypeReference + JsonPrimitive: + if (isArray) { + switch (element) { + case element.isString: return JsArrayString.newTypeReference + case element.isBoolean: return JsArrayBoolean.newTypeReference + case element.isNumber: return JsArrayNumber.newTypeReference + } } else { - double.newTypeReference - } - } + switch (element) { + case element.isString: String.newTypeReference + case element.isBoolean: boolean.newTypeReference + case element.isNumber: { + if (element.asString.indexOf('.') == -1) { + int.newTypeReference + } else { + double.newTypeReference + } + } + } + } default : { currentContainer.addError("unknown element "+element) throw new IllegalStateException From 116e3a1099c9e3c41eaaf49b353e4ae2b1436243 Mon Sep 17 00:00:00 2001 From: Markus Scheidgen Date: Wed, 24 Jun 2015 11:49:28 +0200 Subject: [PATCH 3/5] Fixed support for inner classes in JsNative (again). --- src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend index 8521b58..99da9d9 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend @@ -76,6 +76,6 @@ class JsNativeProcessor extends AbstractMethodProcessor { def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { val unit = type.compilationUnit val targetFolder = unit.filePath.targetFolder - return targetFolder.append(type.qualifiedName.replace('.','/')+".java") + return targetFolder.append(unit.sourceTypeDeclarations.findFirst[true].qualifiedName.replace('.','/')+".java") } } From 203e1e1a2ad87a114dce5e074740f054f89a12c4 Mon Sep 17 00:00:00 2001 From: Markus Scheidgen Date: Wed, 24 Jun 2015 14:03:08 +0200 Subject: [PATCH 4/5] Streamlined the solutions in all CodeGenerationParticipants; JsNative now only saves each compilation unit once and can deal with multiple compilation units. --- .../itemis/xtend/auto/gwt/ClientBundle.xtend | 12 ++++--- .../de/itemis/xtend/auto/gwt/JsNative.xtend | 36 ++++++++++++++----- .../xtend/auto/gwt/OverlayTypeByExample.xtend | 13 +++---- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend b/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend index 1d45514..93512ab 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend @@ -20,6 +20,8 @@ import java.lang.annotation.ElementType import java.lang.annotation.Target import java.util.List import org.eclipse.xtend.lib.macro.Active +import org.eclipse.xtend.lib.macro.CodeGenerationContext +import org.eclipse.xtend.lib.macro.CodeGenerationParticipant import org.eclipse.xtend.lib.macro.RegisterGlobalsContext import org.eclipse.xtend.lib.macro.RegisterGlobalsParticipant import org.eclipse.xtend.lib.macro.TransformationContext @@ -30,8 +32,6 @@ import org.eclipse.xtend.lib.macro.declaration.MutableAnnotationTarget import org.eclipse.xtend.lib.macro.declaration.MutableInterfaceDeclaration import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration -import org.eclipse.xtend.lib.macro.CodeGenerationParticipant -import org.eclipse.xtend.lib.macro.CodeGenerationContext import org.eclipse.xtend.lib.macro.file.Path @Target(ElementType.TYPE) @@ -252,9 +252,11 @@ class CliendBundleProcessor implements RegisterGlobalsParticipant annotatedSourceElements, extension CodeGenerationContext context) { - val path = annotatedSourceElements.get(0).declaringType.getTargetPath(context) - val contents = path.contents.toString.replaceAll("@ClientBundle.Source", "@Source") - path.contents = contents + for(annotatedSourceElement: annotatedSourceElements) { + val path = annotatedSourceElement.declaringType.getTargetPath(context) + val newContents = path.contents.toString.replaceAll("@ClientBundle.Source", "@Source") + path.contents = newContents + } } private def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { diff --git a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend index 99da9d9..abfba6b 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend @@ -7,6 +7,8 @@ *******************************************************************************/ package de.itemis.xtend.auto.gwt +import java.util.HashMap +import java.util.List import org.eclipse.xtend.lib.macro.AbstractMethodProcessor import org.eclipse.xtend.lib.macro.Active import org.eclipse.xtend.lib.macro.CodeGenerationContext @@ -15,7 +17,6 @@ import org.eclipse.xtend.lib.macro.declaration.MethodDeclaration import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration import org.eclipse.xtend.lib.macro.file.Path -import java.util.List /** * JSNI requires comments containing Java script code, which is not translated by the Xtend compiler. @@ -53,29 +54,46 @@ class JsNativeProcessor extends AbstractMethodProcessor { } override doGenerateCode(List annotatedMethods, extension CodeGenerationContext context) { - val path = annotatedMethods.get(0).declaringType.getTargetPath(context) - var contents = path.contents.toString - + // When the annotation is used multiple times within a single source xtend compilation + // unit, the methods can end up in several different java compilation units due to + // multiple toplevel types in one xtend file. Furthermore, there can be multiple + // annotated methods per java compilation unit. + // We load change all contents first and later save all compilation units only once. + val javaUnits = new HashMap; for(annotatedMethod: annotatedMethods) { + val path = annotatedMethod.declaringType.getTargetPath(context) + if (javaUnits.get(path) == null) { + javaUnits.put(path, path.contents.toString) + } + var contents = javaUnits.get(path) + val markerStart = contents.indexOf(getUniqueMarkerCode(annotatedMethod)) if (markerStart > 0) { val startIndex = contents.substring(0, markerStart).lastIndexOf('{') val endIndex = contents.substring(markerStart).indexOf('}') + markerStart val jsCode = annotatedMethod.body.toString.trimTripleQuotes - contents = contents.substring(0, startIndex)+"/*-{"+jsCode+"}-*/;"+contents.substring(endIndex+1) + val newContents = contents.substring(0, startIndex)+"/*-{"+jsCode+"}-*/;"+contents.substring(endIndex+1) + + javaUnits.put(path, newContents) } } - - path.contents = contents + for (path: javaUnits.keySet) { + path.contents = javaUnits.get(path) + } } private def String trimTripleQuotes(String s) { s.substring(3, s.length-3) } - def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { + private def TypeDeclaration topLevelType(TypeDeclaration type) { + return if (type.declaringType == null) type else type.declaringType.topLevelType + } + + private def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { + val topLevelType = type.topLevelType val unit = type.compilationUnit val targetFolder = unit.filePath.targetFolder - return targetFolder.append(unit.sourceTypeDeclarations.findFirst[true].qualifiedName.replace('.','/')+".java") + return targetFolder.append(unit.sourceTypeDeclarations.findFirst[sourceType|sourceType==topLevelType].qualifiedName.replace('.','/')+".java") } } diff --git a/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend b/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend index 052b873..a9fea8d 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend @@ -14,6 +14,9 @@ import com.google.gson.JsonParser import com.google.gson.JsonPrimitive import com.google.gwt.core.client.JavaScriptObject import com.google.gwt.core.client.JsArray +import com.google.gwt.core.client.JsArrayBoolean +import com.google.gwt.core.client.JsArrayNumber +import com.google.gwt.core.client.JsArrayString import java.util.Map.Entry import java.util.regex.Pattern import org.eclipse.xtend.lib.macro.AbstractClassProcessor @@ -27,9 +30,6 @@ import org.eclipse.xtend.lib.macro.declaration.TypeReference import org.eclipse.xtend.lib.macro.declaration.Visibility import static extension de.itemis.xtend.auto.gwt.StaticUtils.* -import com.google.gwt.core.client.JsArrayString -import com.google.gwt.core.client.JsArrayBoolean -import com.google.gwt.core.client.JsArrayNumber /** * Allows to implement a GWT OverlayType using a JSON example. @@ -95,10 +95,11 @@ class OverlayTypeByExampleProcessor extends AbstractClassProcessor { */ override doGenerateCode(ClassDeclaration annotatedClass, extension CodeGenerationContext context) { val targetFolder = annotatedClass.compilationUnit.filePath.targetFolder - val targetFile = targetFolder.append(annotatedClass.qualifiedName.replace('.','/')+".java") - val contents = targetFile.contents + val path = targetFolder.append(annotatedClass.qualifiedName.replace('.','/')+".java") + val contents = path.contents val matcher = PATTERN.matcher(contents) - targetFile.contents = matcher.replaceAll("public final native $1 get$2() /*-{ return this.$3; }-*/;") + val newContents = matcher.replaceAll("public final native $1 get$2() /*-{ return this.$3; }-*/;") + path.contents = newContents } static class Util { From a636b6c11d2bd0d9462278c99da9c925a98a57d6 Mon Sep 17 00:00:00 2001 From: Markus Scheidgen Date: Thu, 25 Jun 2015 23:50:38 +0200 Subject: [PATCH 5/5] Removed the bad synchronization hack. Pulled duplicate code into ActiveAnnotationProcessorHelper. --- .../gwt/ActiveAnnotationProcessorHelper.xtend | 18 ++++++++++++++++++ .../itemis/xtend/auto/gwt/ClientBundle.xtend | 9 +-------- .../de/itemis/xtend/auto/gwt/JsNative.xtend | 13 +------------ .../xtend/auto/gwt/OverlayTypeByExample.xtend | 5 +++-- 4 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 src/main/java/de/itemis/xtend/auto/gwt/ActiveAnnotationProcessorHelper.xtend diff --git a/src/main/java/de/itemis/xtend/auto/gwt/ActiveAnnotationProcessorHelper.xtend b/src/main/java/de/itemis/xtend/auto/gwt/ActiveAnnotationProcessorHelper.xtend new file mode 100644 index 0000000..b6e5c7b --- /dev/null +++ b/src/main/java/de/itemis/xtend/auto/gwt/ActiveAnnotationProcessorHelper.xtend @@ -0,0 +1,18 @@ +package de.itemis.xtend.auto.gwt + +import org.eclipse.xtend.lib.macro.CodeGenerationContext +import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration +import org.eclipse.xtend.lib.macro.file.Path + +class ActiveAnnotationProcessorHelper { + private static def TypeDeclaration topLevelType(TypeDeclaration type) { + return if (type.declaringType == null) type else type.declaringType.topLevelType + } + + static def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { + val topLevelType = type.topLevelType + val unit = type.compilationUnit + val targetFolder = unit.filePath.targetFolder + return targetFolder.append(unit.sourceTypeDeclarations.findFirst[sourceType|sourceType==topLevelType].qualifiedName.replace('.','/')+".java") + } +} \ No newline at end of file diff --git a/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend b/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend index 93512ab..c1dbe15 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/ClientBundle.xtend @@ -32,7 +32,6 @@ import org.eclipse.xtend.lib.macro.declaration.MutableAnnotationTarget import org.eclipse.xtend.lib.macro.declaration.MutableInterfaceDeclaration import org.eclipse.xtend.lib.macro.declaration.MutableMethodDeclaration import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration -import org.eclipse.xtend.lib.macro.file.Path @Target(ElementType.TYPE) annotation CssResource { @@ -253,15 +252,9 @@ class CliendBundleProcessor implements RegisterGlobalsParticipant annotatedSourceElements, extension CodeGenerationContext context) { for(annotatedSourceElement: annotatedSourceElements) { - val path = annotatedSourceElement.declaringType.getTargetPath(context) + val path = ActiveAnnotationProcessorHelper::getTargetPath(annotatedSourceElement, context) val newContents = path.contents.toString.replaceAll("@ClientBundle.Source", "@Source") path.contents = newContents } } - - private def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { - val unit = type.compilationUnit - val targetFolder = unit.filePath.targetFolder - return targetFolder.append(unit.sourceTypeDeclarations.findFirst[true].qualifiedName.replace('.','/')+".java") - } } diff --git a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend index abfba6b..ef341a9 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/JsNative.xtend @@ -61,7 +61,7 @@ class JsNativeProcessor extends AbstractMethodProcessor { // We load change all contents first and later save all compilation units only once. val javaUnits = new HashMap; for(annotatedMethod: annotatedMethods) { - val path = annotatedMethod.declaringType.getTargetPath(context) + val path = ActiveAnnotationProcessorHelper::getTargetPath(annotatedMethod.declaringType, context) if (javaUnits.get(path) == null) { javaUnits.put(path, path.contents.toString) } @@ -85,15 +85,4 @@ class JsNativeProcessor extends AbstractMethodProcessor { private def String trimTripleQuotes(String s) { s.substring(3, s.length-3) } - - private def TypeDeclaration topLevelType(TypeDeclaration type) { - return if (type.declaringType == null) type else type.declaringType.topLevelType - } - - private def Path getTargetPath(TypeDeclaration type, extension CodeGenerationContext ctx) { - val topLevelType = type.topLevelType - val unit = type.compilationUnit - val targetFolder = unit.filePath.targetFolder - return targetFolder.append(unit.sourceTypeDeclarations.findFirst[sourceType|sourceType==topLevelType].qualifiedName.replace('.','/')+".java") - } } diff --git a/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend b/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend index a9fea8d..675918e 100644 --- a/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend +++ b/src/main/java/de/itemis/xtend/auto/gwt/OverlayTypeByExample.xtend @@ -26,8 +26,10 @@ import org.eclipse.xtend.lib.macro.RegisterGlobalsContext import org.eclipse.xtend.lib.macro.TransformationContext import org.eclipse.xtend.lib.macro.declaration.ClassDeclaration import org.eclipse.xtend.lib.macro.declaration.MutableClassDeclaration +import org.eclipse.xtend.lib.macro.declaration.TypeDeclaration import org.eclipse.xtend.lib.macro.declaration.TypeReference import org.eclipse.xtend.lib.macro.declaration.Visibility +import org.eclipse.xtend.lib.macro.file.Path import static extension de.itemis.xtend.auto.gwt.StaticUtils.* @@ -94,8 +96,7 @@ class OverlayTypeByExampleProcessor extends AbstractClassProcessor { * we add the Java comment containing the javascript code during code generation, since there is no way to add it using the Java model. */ override doGenerateCode(ClassDeclaration annotatedClass, extension CodeGenerationContext context) { - val targetFolder = annotatedClass.compilationUnit.filePath.targetFolder - val path = targetFolder.append(annotatedClass.qualifiedName.replace('.','/')+".java") + val path = ActiveAnnotationProcessorHelper::getTargetPath(annotatedClass, context) val contents = path.contents val matcher = PATTERN.matcher(contents) val newContents = matcher.replaceAll("public final native $1 get$2() /*-{ return this.$3; }-*/;")