Commit a3444899 authored by Daniel Bluhm's avatar Daniel Bluhm

Merge branch 'next' into annotation-extraction

parents cc7b0c47 3bca337c
......@@ -8,6 +8,9 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.11</maven.compiler.source>
<maven.compiler.target>1.11</maven.compiler.target>
<maven.compiler.release>1.11</maven.compiler.release>
</properties>
<build>
......@@ -108,11 +111,16 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.cosium.logging</groupId>
<artifactId>annotation-processor-logger</artifactId>
<version>1.0</version>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.velocity.tools</groupId>
<artifactId>velocity-tools-generic</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
<parent>
......
......@@ -15,9 +15,9 @@ import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.tools.ToolContext;
import org.apache.velocity.tools.ToolManager;
/**
* Abstract base class for classes that render a Java Source file through
......@@ -27,7 +27,50 @@ import org.apache.velocity.context.Context;
*/
public abstract class VelocitySourceWriter implements FileWriter {
/**
* Tool configuration file.
*/
private static final String TOOL_CONFIG = "tools.xml";
/**
* Velocity Engine.
*/
private static VelocityEngine engine = configureVelocityEngine();
/**
* Velocity Tools.
*/
private static ToolManager tools = configureTools();
/**
* Set up the velocity engine with properties.
* @return initialized VelocityEngine
*/
private static VelocityEngine configureVelocityEngine() {
VelocityEngine engine = new VelocityEngine();
engine.init(VelocityProperties.get());
return engine;
}
/**
* Set up the velocity tool manager.
* @return
*/
private static ToolManager configureTools() {
// autoConfigure = false, includeDefaults = true
ToolManager tools = new ToolManager(false, true);
tools.configure(TOOL_CONFIG);
return tools;
}
/**
* Template for writing. Should be filled by concrete classes.
*/
protected String template;
/**
* Context for template. Should be filled by concrete classes.
*/
protected Map<String, Object> context;
public VelocitySourceWriter() {
......@@ -40,13 +83,17 @@ public abstract class VelocitySourceWriter implements FileWriter {
* @param writer to which the java source will be written
*/
public void write(Writer writer) {
// Make sure Velocity is initialized. Subsequent calls are harmless.
Velocity.init(VelocityProperties.get());
if (template == null || template.isEmpty()) {
throw new IllegalStateException("template must be set by concrete VelocitySourceWriter.");
}
// Make velocity context from generic map context.
Context velocityContext = new VelocityContext(context);
// Make tool context (subclass of velocity context) from generic map
// context. This places all tools into the template context.
ToolContext velocityContext = tools.createContext();
// Put all our values into the template context.
velocityContext.putAll(context);
// Write template from context.
Velocity.mergeTemplate(template, "UTF-8", velocityContext, writer);
engine.mergeTemplate(template, "UTF-8", velocityContext, writer);
}
}
}
\ No newline at end of file
......@@ -62,7 +62,7 @@ public class ${class} implements ${interface}, Serializable {
#foreach($field in $fields)
#fielddoc
#nonnull($tab, $newline)
#nonnull($tab, $esc.newline)
#if(!${field.Getter} || ${field.VarNameDifferent})
@Getter(AccessLevel.NONE)
#end
......@@ -176,7 +176,7 @@ public class ${class} implements ${interface}, Serializable {
retval =
#@settab(6)
#foreach($field in ${fields.Match})#@nonewline
${field.VarName}Match#if($foreach.hasNext) &&#if($foreach.count % 3 == 0)$newline#else #end#end
${field.VarName}Match#if($foreach.hasNext) &&#if($foreach.count % 3 == 0)$esc.newline#else #end#end
#end#end;
#end
}
......
......@@ -10,14 +10,12 @@
## Use as a block macro to set the tab index of all lines in body.
#macro(settab $num)
#set($tab = " ")
#set($newline = "
")
#if($num == 0)
#set($shift = "")
#else
#set($shift = "#foreach($i in [1..$num])$tab#end")
#end
#noop$shift$bodyContent.toString().replace("$tab", "").replace("$newline", "$newline$shift").trim()
#noop$shift$bodyContent.toString().replace("$tab", "").replace("$esc.newline", "$esc.newline$shift").trim()
#end
## Use as a block macro to remove the first newline in the body.
......@@ -62,12 +60,10 @@
## Get field doc comment
#macro(fielddoc)
#set($tab = " ")
#set($newline = "
")
#if(${field.DocString})
#@settab(1)
/**
* $field.DocString.trim().replace("$newline", "$newline$tab *")
* $field.DocString.trim().replace("$esc.newline", "$esc.newline$tab *")
*/
#end
#end
......
<?xml version="1.0" encoding="windows-1252"?>
<!--
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.
-->
<tools>
<data type="number" key="TOOLS_VERSION" value="3.0-SNAPSHOT"/>
<data type="boolean" key="GENERIC_TOOLS_AVAILABLE" value="true"/>
<toolbox scope="application">
<tool class="org.apache.velocity.tools.generic.ClassTool" value="classtool"/>
<tool class="org.apache.velocity.tools.generic.CollectionTool"/>
<tool class="org.apache.velocity.tools.generic.ComparisonDateTool"/>
<tool class="org.apache.velocity.tools.generic.DisplayTool"/>
<tool class="org.apache.velocity.tools.generic.EscapeTool"/>
<tool class="org.apache.velocity.tools.generic.FieldTool"/>
<tool class="org.apache.velocity.tools.generic.LogTool"/>
<tool class="org.apache.velocity.tools.generic.MathTool"/>
<tool class="org.apache.velocity.tools.generic.NumberTool"/>
<tool class="org.apache.velocity.tools.generic.ResourceTool"/>
<!-- include deprecated tools, which will only be instanciated on demand -->
<tool class="org.apache.velocity.tools.generic.AlternatorTool"/>
<tool class="org.apache.velocity.tools.generic.ConversionTool"/>
<tool class="org.apache.velocity.tools.generic.SortTool"/>
</toolbox>
<toolbox scope="request">
<tool class="org.apache.velocity.tools.generic.ContextTool"/>
<tool class="org.apache.velocity.tools.generic.ImportTool"/>
<tool class="org.apache.velocity.tools.generic.JsonTool"/>
<tool class="org.apache.velocity.tools.generic.LinkTool"/>
<tool class="org.apache.velocity.tools.generic.LoopTool"/>
<tool class="org.apache.velocity.tools.generic.RenderTool"/>
<tool class="org.apache.velocity.tools.generic.XmlTool"/>
<!--
This is not useful in its default form.
But, if it were, it'd be request-scoped.
<tool class="org.apache.velocity.tools.generic.ValueParser"/>
-->
</toolbox>
</tools>
\ No newline at end of file
......@@ -13,12 +13,12 @@ package org.eclipse.ice.tests.dev.annotations.processors;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import javax.annotation.processing.Processor;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import org.eclipse.ice.dev.annotations.processors.DataElementProcessor;
import com.google.testing.compile.Compilation;
import static com.google.testing.compile.Compiler.*;
......@@ -29,14 +29,7 @@ import static com.google.testing.compile.Compiler.*;
*/
public class DataElementAnnotationTestHelper {
private boolean showDiagnostics = false;
public DataElementAnnotationTestHelper() {
String show = System.getenv("SHOW_DIAGNOSTICS");
if (show != null && show.equals("true")) {
this.showDiagnostics = true;
}
}
public DataElementAnnotationTestHelper() { }
/**
* Retrieve an instance of Lombok's Annotation Processor.
......@@ -64,18 +57,6 @@ public class DataElementAnnotationTestHelper {
return p;
}
private void printDiagnostics(Compilation compilation) {
for (Diagnostic<? extends JavaFileObject> diag :
compilation.diagnostics()
) {
System.err.println(String.format(
"[%s]: %s",
diag.getKind().toString(),
diag.getMessage(Locale.ENGLISH)
));
}
}
/**
* Compile the sources with needed processors.
* @param sources to compile
......@@ -85,11 +66,8 @@ public class DataElementAnnotationTestHelper {
Compilation compilation = javac()
.withProcessors(
getLombokAnnotationProcessor(),
new LoggingDataElementProcessor()
new DataElementProcessor()
).compile(sources);
if (showDiagnostics) {
printDiagnostics(compilation);
}
return compilation;
}
}
......@@ -13,14 +13,15 @@ package org.eclipse.ice.tests.dev.annotations.processors;
import static com.google.testing.compile.CompilationSubject.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Locale;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.testing.compile.Compilation;
......@@ -61,6 +62,11 @@ class DataElementProcessorTest {
*/
private static final String IMPLEMENTATION = "TestImplementation";
/**
* Logger.
*/
private static final Logger logger = LoggerFactory.getLogger(DataElementProcessorTest.class);
/**
* Enumeration of inputs used in testing.
* @author Daniel Bluhm
......@@ -142,6 +148,17 @@ class DataElementProcessorTest {
return PARENT + this.filename;
}
}
/**
* Assert that the compilation succeeded and log any warnings.
* @param compilation to check.
*/
private static void assertSucceededAndLogWarnings(Compilation compilation) {
assertThat(compilation).succeeded();
for (Diagnostic<?> warning : compilation.warnings()) {
logger.warn(warning.getMessage(Locale.ENGLISH));
}
}
/**
......@@ -230,7 +247,7 @@ class DataElementProcessorTest {
@Test
void testNoDataFieldsSucceeds() {
Compilation compilation = helper.compile(Inputs.NO_DATAFIELDS.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertDefaultsPresent(compilation);
}
......@@ -241,7 +258,7 @@ class DataElementProcessorTest {
@Test
void testWithSingleDataFieldSucceeds() {
Compilation compilation = helper.compile(Inputs.SINGLE.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.SINGLE_INT.get());
assertImplementationMatches(compilation, Patterns.SINGLE_IMPL.get());
......@@ -253,7 +270,7 @@ class DataElementProcessorTest {
@Test
void testWithManyDataFieldsSucceeds() {
Compilation compilation = helper.compile(Inputs.MANY.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.MANY_INT.get());
assertImplementationMatches(compilation, Patterns.MANY_IMPL.get());
......@@ -265,7 +282,7 @@ class DataElementProcessorTest {
@Test
void testSingleNonPrimitiveDataFieldSucceeds() {
Compilation compilation = helper.compile(Inputs.SINGLE_NON_PRIMITIVE.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.SINGLE_NON_PRIMITIVE_INT.get());
assertImplementationMatches(compilation, Patterns.SINGLE_NON_PRIMITIVE_IMPL.get());
......@@ -277,7 +294,7 @@ class DataElementProcessorTest {
@Test
void testManyNonPrimitiveDataFieldSucceeds() {
Compilation compilation = helper.compile(Inputs.MANY_NON_PRIMITIVE.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertDefaultsPresent(compilation);
assertInterfaceMatches(compilation, Patterns.MANY_NON_PRIMITIVE_INT.get());
assertImplementationMatches(compilation, Patterns.MANY_NON_PRIMITIVE_IMPL.get());
......@@ -310,7 +327,7 @@ class DataElementProcessorTest {
@Test
void testDocStringsPreserved() {
Compilation compilation = helper.compile(Inputs.SINGLE.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertThat(compilation).generatedSourceFile(IMPLEMENTATION)
.contentsAsUtf8String()
.contains("* A UNIQUE STRING IN THE DOC STRING.");
......@@ -326,7 +343,7 @@ class DataElementProcessorTest {
@Test
void testAccessibilityPreserved() {
Compilation compilation = helper.compile(Inputs.ACCESSIBILITY_PRESERVED.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertImplementationMatches(compilation, Patterns.ACCESSIBILITY_PRESERVED.get());
}
......@@ -359,7 +376,7 @@ class DataElementProcessorTest {
@Test
void testDataFieldGetterOption() {
Compilation compilation = helper.compile(Inputs.DATAFIELD_GETTER.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertThat(compilation)
.generatedSourceFile(INTERFACE)
.hasSourceEquivalentTo(Patterns.DATAFIELD_GETTER_INT.get());
......@@ -371,7 +388,7 @@ class DataElementProcessorTest {
@Test
void testDataFieldSetterOption() {
Compilation compilation = helper.compile(Inputs.DATAFIELD_SETTER.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertThat(compilation)
.generatedSourceFile(INTERFACE)
.hasSourceEquivalentTo(Patterns.DATAFIELD_SETTER_INT.get());
......@@ -383,7 +400,7 @@ class DataElementProcessorTest {
@Test
void testDataFieldMatchOption() {
Compilation compilation = helper.compile(Inputs.DATAFIELD_MATCH.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertThat(compilation)
.generatedSourceFile(IMPLEMENTATION)
.contentsAsUtf8String()
......@@ -400,7 +417,7 @@ class DataElementProcessorTest {
@Test
void testDataFieldDefaultNonString() {
Compilation compilation = helper.compile(Inputs.DEFAULT_NON_STRING.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertImplementationMatches(
compilation,
Patterns.DEFAULT_NON_STRING_IMPL.get()
......@@ -413,7 +430,7 @@ class DataElementProcessorTest {
@Test
void testDataFieldDefaultString() {
Compilation compilation = helper.compile(Inputs.DEFAULT_STRING.get());
assertThat(compilation).succeededWithoutWarnings();
assertSucceededAndLogWarnings(compilation);
assertImplementationMatches(
compilation,
Patterns.DEFAULT_STRING_IMPL.get()
......
/*******************************************************************************
* Copyright (c) 2020- UT-Battelle, LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Daniel Bluhm - Initial implementation
*******************************************************************************/
package org.eclipse.ice.tests.dev.annotations.processors;
import java.util.Set;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import org.eclipse.ice.dev.annotations.processors.DataElementProcessor;
import com.cosium.logging.annotation_processor.AbstractLoggingProcessor;
/**
* Wrapper around DataElementProcessor used to catch warnings that would
* normally be missed.
* @author Daniel Bluhm
*/
@SupportedAnnotationTypes({
"org.eclipse.ice.dev.annotations.DataElement",
"org.eclipse.ice.dev.annotations.DataField",
"org.eclipse.ice.dev.annotations.DataField.Default",
"org.eclipse.ice.dev.annotations.Persisted"
})
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class LoggingDataElementProcessor extends AbstractLoggingProcessor {
/**
* Wrapped processor.
*/
private DataElementProcessor wrappedProcessor = new DataElementProcessor();
@Override
public void init(final ProcessingEnvironment env) {
wrappedProcessor.init(env);
super.init(env);
}
@Override
protected boolean doProcess(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return wrappedProcessor.process(annotations, roundEnv);
}
}
\ No newline at end of file
# SLF4J's SimpleLogger configuration file
# Simple implementation of Logger that sends all enabled log messages, for all
# defined loggers, to System.err.
# Default logging detail level for all instances of SimpleLogger.
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, defaults to "info".
org.slf4j.simpleLogger.defaultLogLevel=info
# Logging detail level for a SimpleLogger instance named "xxxxx".
# Must be one of ("trace", "debug", "info", "warn", or "error").
# If not specified, the default logging detail level is used.
#org.slf4j.simpleLogger.log.xxxxx=
# Set to true if you want the current date and time to be included in output
# messages. Default is false, and will output the number of milliseconds elapsed
# since startup.
#org.slf4j.simpleLogger.showDateTime=false
# The date and time format to be used in the output messages. The pattern
# describing the date and time format is the same that is used in
# java.text.SimpleDateFormat. If the format is not specified or is invalid, the
# default format is used.
# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
# Set to true if you want to output the current thread name.
# Defaults to true.
#org.slf4j.simpleLogger.showThreadName=true
# Set to true if you want the Logger instance name to be included in output
# messages. Defaults to true.
#org.slf4j.simpleLogger.showLogName=true
# Set to true if you want the last component of the name to be included in
# output messages. Defaults to false.
#org.slf4j.simpleLogger.showShortLogName=false
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment