You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/10/18 23:23:06 UTC
[sling-org-apache-sling-scripting-sightly-compiler-java] 50/50:
SLING-7205 - Generate import statements for data-sly-use Java use objects
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-compiler-java.git
commit cd39d0a5e2b2f685c793931b7e09b262de7fd19e
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Wed Oct 18 16:00:09 2017 +0000
SLING-7205 - Generate import statements for data-sly-use Java use objects
* added support for generating the import statements for fully qualified Java
class names passed as identifiers to data-sly-resource; use objects stored in the
repository are ignored
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1812544 13f79535-47bb-0310-9956-ffa450edef68
---
pom.xml | 1 +
.../java/compiler/JavaClassBackendCompiler.java | 18 ++++++++++-
.../sightly/java/compiler/JavaImportsAnalyzer.java | 37 ++++++++++++++++++++++
.../sightly/java/compiler/impl/CodeGenVisitor.java | 4 +--
.../java/compiler/impl/JavaClassTemplate.java | 10 ++++--
.../scripting/sightly/java/compiler/impl/Type.java | 31 ++++++++++++------
.../sightly/java/compiler/impl/TypeInference.java | 30 ++++++++++++++----
.../sightly/java/compiler/impl/UnitBuilder.java | 17 ++++++++--
.../java/compiler/impl/VariableDescriptor.java | 2 +-
.../sightly/java/compiler/package-info.java | 2 +-
.../resources/templates/compiled_unit_template.txt | 2 ++
.../java/JavaClassBackendCompilerTest.java | 12 +++++++
src/test/resources/imports.html | 22 +++++++++++++
.../resources/imports.html.java} | 19 ++++++++---
14 files changed, 176 insertions(+), 31 deletions(-)
diff --git a/pom.xml b/pom.xml
index b891e9d..51b6c0a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -49,6 +49,7 @@
<properties>
<jacoco.maven.plugin.version>0.7.9</jacoco.maven.plugin.version>
+ <sling.java.version>8</sling.java.version>
</properties>
<!-- ======================================================================= -->
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaClassBackendCompiler.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaClassBackendCompiler.java
index 87e9655..8069cb0 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaClassBackendCompiler.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaClassBackendCompiler.java
@@ -38,7 +38,8 @@ public final class JavaClassBackendCompiler implements BackendCompiler {
private static final String mainTemplate;
private static final String childTemplate;
- private UnitBuilder unitBuilder = new UnitBuilder();
+ private UnitBuilder unitBuilder;
+ private final JavaImportsAnalyzer JAVA_IMPORTS_ANALYZER;
static {
try {
@@ -50,6 +51,14 @@ public final class JavaClassBackendCompiler implements BackendCompiler {
}
}
+ public JavaClassBackendCompiler() {
+ this(new JavaImportsAnalyzer() {});
+ }
+
+ public JavaClassBackendCompiler(JavaImportsAnalyzer javaImportsAnalyzer) {
+ JAVA_IMPORTS_ANALYZER = javaImportsAnalyzer;
+ unitBuilder = new UnitBuilder(JAVA_IMPORTS_ANALYZER);
+ }
@Override
public void handle(CommandStream stream) {
@@ -76,6 +85,13 @@ public final class JavaClassBackendCompiler implements BackendCompiler {
JavaClassTemplate mainTemplate = newMainTemplate();
mainTemplate.setPackageName(classInfo.getPackageName());
mainTemplate.setClassName(classInfo.getSimpleClassName());
+ StringBuilder imports = new StringBuilder();
+ for (String importClass : unitBuilder.getImports()) {
+ if (JAVA_IMPORTS_ANALYZER.allowImport(importClass)) {
+ imports.append("import ").append(importClass).append(";").append(System.lineSeparator());
+ }
+ }
+ mainTemplate.setImports(imports.toString());
processCompilationResult(compilationOutput, mainTemplate);
return mainTemplate.toString();
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaImportsAnalyzer.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaImportsAnalyzer.java
new file mode 100644
index 0000000..23a94e4
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/JavaImportsAnalyzer.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ ******************************************************************************/
+package org.apache.sling.scripting.sightly.java.compiler;
+
+/**
+ * The {@code JavaImportsAnalyzer} allows checking imports in generated HTL Java classes, in order to optimise dependencies.
+ */
+public interface JavaImportsAnalyzer {
+
+ /**
+ * Analyses the provided {@code importedClass} and decides if this class should be an explicit import or not in the generated HTL
+ * Java class.
+ *
+ * @param importedClass the import to analyse
+ * @return {@code true} if the import should be declared, {@code false} otherwise
+ */
+ default boolean allowImport(String importedClass) {
+ return true;
+ }
+
+}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/CodeGenVisitor.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/CodeGenVisitor.java
index a619ff6..629f9ac 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/CodeGenVisitor.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/CodeGenVisitor.java
@@ -117,7 +117,7 @@ public class CodeGenVisitor implements CommandVisitor {
@Override
public void visit(VariableBinding.Start variableBinding) {
source.startBlock();
- TypeInfo typeInfo = TypeInference.inferTypes(variableBinding.getExpression(), analyzer);
+ TypeInfo typeInfo = TypeInference.inferTypes(variableBinding.getExpression(), analyzer, unitBuilder.getImports());
Type type = typeInfo.typeOf(variableBinding.getExpression());
String properName = declare(variableBinding.getVariableName(), type);
source.beginAssignment(properName, type.getNativeClass());
@@ -142,7 +142,7 @@ public class CodeGenVisitor implements CommandVisitor {
@Override
public void visit(VariableBinding.Global globalAssignment) {
- TypeInfo typeInfo = TypeInference.inferTypes(globalAssignment.getExpression(), analyzer);
+ TypeInfo typeInfo = TypeInference.inferTypes(globalAssignment.getExpression(), analyzer, unitBuilder.getImports());
VariableDescriptor descriptor = analyzer.declareGlobal(globalAssignment.getVariableName());
String name = descriptor.getAssignedName();
source.append(name).assign();
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaClassTemplate.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaClassTemplate.java
index 34be88b..85a0236 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaClassTemplate.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/JavaClassTemplate.java
@@ -23,10 +23,10 @@ public class JavaClassTemplate {
private String classTemplate;
-
- private static final String MAIN_BODY = "MainBody";
- private static final String CLASS_NAME = "ClassName";
private static final String PACKAGE_NAME = "PackageName";
+ private static final String IMPORTS = "Imports";
+ private static final String CLASS_NAME = "ClassName";
+ private static final String MAIN_BODY = "MainBody";
private static final String TEMPLATE_INIT = "SubTemplateMapInit";
private static final String NAME = "Name";
@@ -52,6 +52,10 @@ public class JavaClassTemplate {
setPart(PACKAGE_NAME, name);
}
+ public void setImports(String imports) {
+ setPart(IMPORTS, imports);
+ }
+
@Override
public String toString() {
return insertPart(TEMPLATE_INIT, classTemplate, templateInitBuilder.toString());
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/Type.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/Type.java
index e73d5e5..187c650 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/Type.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/Type.java
@@ -20,27 +20,38 @@ package org.apache.sling.scripting.sightly.java.compiler.impl;
/**
* Type inferred for an expression
*/
-public enum Type {
- UNKNOWN("Object", false),
- STRING("String", false),
- LONG("long", true),
- DOUBLE("double", true),
- BOOLEAN("boolean", true),
- MAP("java.util.Map", false);
-
- private final String nativeClass;
+public class Type {
+
+ public static final Type UNKNOWN = new Type("Object", false, null);
+ public static final Type STRING = new Type("String", false, null);
+ public static final Type LONG = new Type("long", true, 0);
+ public static final Type DOUBLE = new Type("double", true, 0.0d);
+ public static final Type BOOLEAN = new Type("boolean", true, false);
+ public static final Type MAP = new Type("java.util.Map", false, null);
+
+ private String nativeClass;
private final boolean isPrimitive;
+ private final Object defaultValue;
- Type(String nativeClass, boolean isPrimitive) {
+ private Type(String nativeClass, boolean isPrimitive, Object defaultValue) {
this.nativeClass = nativeClass;
this.isPrimitive = isPrimitive;
+ this.defaultValue = defaultValue;
}
public String getNativeClass() {
return nativeClass;
}
+ public Object getDefaultValue() {
+ return defaultValue;
+ }
+
public boolean isPrimitive() {
return isPrimitive;
}
+
+ public static Type dynamic(String type) {
+ return new Type(type, false, null);
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/TypeInference.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/TypeInference.java
index 39377b8..6511de3 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/TypeInference.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/TypeInference.java
@@ -19,10 +19,10 @@ package org.apache.sling.scripting.sightly.java.compiler.impl;
import java.util.IdentityHashMap;
import java.util.Map;
+import java.util.Set;
+import java.util.regex.Pattern;
-import org.apache.sling.scripting.sightly.java.compiler.impl.operator.BinaryOpGen;
-import org.apache.sling.scripting.sightly.java.compiler.impl.operator.Operators;
-import org.apache.sling.scripting.sightly.java.compiler.impl.operator.UnaryOpGen;
+import org.apache.sling.scripting.sightly.compiler.RuntimeFunction;
import org.apache.sling.scripting.sightly.compiler.expression.ExpressionNode;
import org.apache.sling.scripting.sightly.compiler.expression.NodeVisitor;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.ArrayLiteral;
@@ -37,6 +37,9 @@ import org.apache.sling.scripting.sightly.compiler.expression.nodes.RuntimeCall;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.StringConstant;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.TernaryOperator;
import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperation;
+import org.apache.sling.scripting.sightly.java.compiler.impl.operator.BinaryOpGen;
+import org.apache.sling.scripting.sightly.java.compiler.impl.operator.Operators;
+import org.apache.sling.scripting.sightly.java.compiler.impl.operator.UnaryOpGen;
/**
* Expression translator which uses type information
@@ -44,17 +47,20 @@ import org.apache.sling.scripting.sightly.compiler.expression.nodes.UnaryOperati
public final class TypeInference implements NodeVisitor<Type> {
private final VariableAnalyzer analyzer;
- private final Map<ExpressionNode, Type> inferMap = new IdentityHashMap<ExpressionNode, Type>();
+ private final Map<ExpressionNode, Type> inferMap = new IdentityHashMap<>();
+ private final Set<String> imports;
+ private static final Pattern FQCN_PATTERN = Pattern.compile("([[\\p{L}&&[^\\p{Lu}]]_$][\\p{L}\\p{N}_$]*\\.)+[\\p{Lu}_$][\\p{L}\\p{N}_$]*");
- public static TypeInfo inferTypes(ExpressionNode node, VariableAnalyzer analyzer) {
- TypeInference typeInference = new TypeInference(analyzer);
+ public static TypeInfo inferTypes(ExpressionNode node, VariableAnalyzer analyzer, Set<String> imports) {
+ TypeInference typeInference = new TypeInference(analyzer, imports);
typeInference.infer(node);
return new TypeInfo(typeInference.inferMap);
}
- private TypeInference(VariableAnalyzer analyzer) {
+ private TypeInference(VariableAnalyzer analyzer, Set<String> imports) {
this.analyzer = analyzer;
+ this.imports = imports;
}
@@ -128,6 +134,16 @@ public final class TypeInference implements NodeVisitor<Type> {
@Override
public Type evaluate(RuntimeCall runtimeCall) {
inferAll(runtimeCall.getArguments());
+ if (runtimeCall.getFunctionName().equals(RuntimeFunction.USE)) {
+ ExpressionNode identifier = runtimeCall.getArguments().get(0);
+ if (identifier instanceof StringConstant) {
+ String objectType = ((StringConstant) identifier).getText();
+ if (FQCN_PATTERN.matcher(objectType).matches()) {
+ imports.add(objectType);
+ return Type.dynamic(objectType);
+ }
+ }
+ }
return Type.UNKNOWN;
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/UnitBuilder.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/UnitBuilder.java
index 990bf8c..3a7678c 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/UnitBuilder.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/UnitBuilder.java
@@ -19,10 +19,12 @@ package org.apache.sling.scripting.sightly.java.compiler.impl;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.sling.scripting.sightly.java.compiler.CompilationOutput;
+import org.apache.sling.scripting.sightly.java.compiler.JavaImportsAnalyzer;
/**
* Builder for compiled sources
@@ -32,9 +34,12 @@ public class UnitBuilder {
private final JavaSource source = new JavaSource();
private final Set<String> parameters;
private final Map<String, UnitBuilder> subTemplates = new HashMap<String, UnitBuilder>();
+ private Set<String> imports = new HashSet<>();
+ private JavaImportsAnalyzer javaImportsAnalyzer;
- public UnitBuilder() {
- this(Collections.<String>emptySet());
+ public UnitBuilder(JavaImportsAnalyzer javaImportsAnalyzer) {
+ this(Collections.emptySet());
+ this.javaImportsAnalyzer = javaImportsAnalyzer;
}
public UnitBuilder(Set<String> parameters) {
@@ -62,4 +67,12 @@ public class UnitBuilder {
}
return new CompilationOutputImpl(source.toString(), map);
}
+
+ public JavaImportsAnalyzer getJavaImportsAnalyzer() {
+ return javaImportsAnalyzer;
+ }
+
+ public Set<String> getImports() {
+ return imports;
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableDescriptor.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableDescriptor.java
index 51193d6..800a5bd 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableDescriptor.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/impl/VariableDescriptor.java
@@ -78,7 +78,7 @@ public class VariableDescriptor {
}
/**
- * Get the inferred type fot this variable
+ * Get the inferred type for this variable
* @return - the class of the variable
*/
public Type getType() {
diff --git a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java
index 4502fd2..45ddcbe 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/java/compiler/package-info.java
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
-@Version("1.1.0")
+@Version("1.2.0")
package org.apache.sling.scripting.sightly.java.compiler;
import org.osgi.annotation.versioning.Version;
diff --git a/src/main/resources/templates/compiled_unit_template.txt b/src/main/resources/templates/compiled_unit_template.txt
index a327d6a..3ce6585 100644
--- a/src/main/resources/templates/compiled_unit_template.txt
+++ b/src/main/resources/templates/compiled_unit_template.txt
@@ -25,6 +25,8 @@ import javax.script.Bindings;
import org.apache.sling.scripting.sightly.java.compiler.RenderUnit;
import org.apache.sling.scripting.sightly.render.RenderContext;
+##Imports##
+
public final class ##ClassName## extends RenderUnit {
@Override
diff --git a/src/test/java/org/apache/sling/scripting/sightly/compiler/java/JavaClassBackendCompilerTest.java b/src/test/java/org/apache/sling/scripting/sightly/compiler/java/JavaClassBackendCompilerTest.java
index 3dd3c8c..924e519 100644
--- a/src/test/java/org/apache/sling/scripting/sightly/compiler/java/JavaClassBackendCompilerTest.java
+++ b/src/test/java/org/apache/sling/scripting/sightly/compiler/java/JavaClassBackendCompilerTest.java
@@ -93,6 +93,18 @@ public class JavaClassBackendCompilerTest {
assertEquals(expectedOutput, writer.toString());
}
+ @Test
+ public void generateImportStatements() throws Exception {
+ CompilationUnit compilationUnit = TestUtils.readScriptFromClasspath("/imports.html");
+ JavaClassBackendCompiler backendCompiler = new JavaClassBackendCompiler();
+ SightlyCompiler sightlyCompiler = new SightlyCompiler();
+ sightlyCompiler.compile(compilationUnit, backendCompiler);
+ ClassInfo classInfo = buildClassInfo("imports");
+ String source = backendCompiler.build(classInfo);
+ String expectedJavaOutput = IOUtils.toString(this.getClass().getResourceAsStream("/imports.html.java"), "UTF-8");
+ assertEquals(expectedJavaOutput, source);
+ }
+
private ClassInfo buildClassInfo(final String info) {
return new ClassInfo() {
@Override
diff --git a/src/test/resources/imports.html b/src/test/resources/imports.html
new file mode 100644
index 0000000..82d1905
--- /dev/null
+++ b/src/test/resources/imports.html
@@ -0,0 +1,22 @@
+<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
+<div data-sly-use.slingSettings="org.apache.sling.settings.SlingSettingsService"
+ data-sly-use.js="script.js"
+ data-sly-use.pojo="Pojo"
+></div>
diff --git a/src/main/resources/templates/compiled_unit_template.txt b/src/test/resources/imports.html.java
similarity index 77%
copy from src/main/resources/templates/compiled_unit_template.txt
copy to src/test/resources/imports.html.java
index a327d6a..f80f7db 100644
--- a/src/main/resources/templates/compiled_unit_template.txt
+++ b/src/test/resources/imports.html.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
******************************************************************************/
-package ##PackageName##;
+package org.apache.sling.scripting.sightly.compiler.java;
import java.io.PrintWriter;
import java.util.Collection;
@@ -25,7 +25,10 @@ import javax.script.Bindings;
import org.apache.sling.scripting.sightly.java.compiler.RenderUnit;
import org.apache.sling.scripting.sightly.render.RenderContext;
-public final class ##ClassName## extends RenderUnit {
+import org.apache.sling.settings.SlingSettingsService;
+
+
+public final class Test_imports extends RenderUnit {
@Override
protected final void render(PrintWriter out,
@@ -34,7 +37,15 @@ public final class ##ClassName## extends RenderUnit {
RenderContext renderContext) {
// Main Template Body -----------------------------------------------------------------------------
-##MainBody##
+Object _global_slingsettings = null;
+Object _global_js = null;
+Object _global_pojo = null;
+out.write("\n");
+_global_slingsettings = renderContext.call("use", "org.apache.sling.settings.SlingSettingsService", obj());
+_global_js = renderContext.call("use", "script.js", obj());
+_global_pojo = renderContext.call("use", "Pojo", obj());
+out.write("<div></div>\n");
+
// End Of Main Template Body ----------------------------------------------------------------------
}
@@ -44,7 +55,7 @@ public final class ##ClassName## extends RenderUnit {
{
//Sub-Templates Initialization --------------------------------------------------------------------
-##SubTemplateMapInit##
+
//End of Sub-Templates Initialization -------------------------------------------------------------
}
--
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.