
org.jamon.codegen.ProxyGenerator Maven / Gradle / Ivy
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.jamon.codegen;
import java.io.OutputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.jamon.compiler.ParserErrorImpl;
import org.jamon.compiler.ParserErrorsImpl;
import org.jamon.node.LocationImpl;
public class ProxyGenerator extends AbstractSourceGenerator {
public ProxyGenerator(TemplateDescriber describer, TemplateUnit templateUnit) {
super(describer, templateUnit);
}
@Override
public void generateSource(OutputStream out) throws java.io.IOException {
writer = new CodeWriter(out, templateUnit.getEncoding());
generateHeader();
generatePrologue();
generateImports();
generateAnnotations();
generateDeclaration();
generateConstructors();
generateIntf();
generateImplData();
if (templateUnit.getJamonContextType() != null) {
generateJamonContextSetter();
}
generateOptionalArgs();
generateFragmentInterfaces(false);
if (templateUnit.isReplacing()) {
generateReplacementConstructor();
}
if (!templateUnit.isParent()) {
generateConstructImplReflective();
generateConstructImplDirect();
generateMakeRenderer();
generateRender();
generateRenderNoFlush();
}
if (templateUnit.isParent()) {
generateParentRendererClass();
}
if (templateUnit.hasParentPath() && !templateUnit.isParent()) {
generateMakeParentRenderer();
}
generateEpilogue();
writer.finish();
}
private void generateImports() {
templateUnit.printImports(writer);
}
private String getClassName() {
return PathUtils.getIntfClassName(templateUnit.getName());
}
private String getPackageName() {
return PathUtils.getIntfPackageName(templateUnit.getName());
}
private void generateHeader() {
writer.println("// Autogenerated Jamon proxy");
writer.println("// "
+ describer.getExternalIdentifier(templateUnit.getName()).replace('\\', '/'));
writer.println();
}
private void generatePrologue() {
String pkgName = getPackageName();
if (pkgName.length() > 0) {
writer.println("package " + pkgName + ";");
writer.println();
}
}
private void generateConstructors() {
writer.println();
writer.println("public " + getClassName() + "(" + ClassNames.TEMPLATE_MANAGER + " p_manager)");
writer.openBlock();
writer.println(" super(p_manager);");
writer.closeBlock();
writer.println();
// We require a pass-through constructor for child templates and for replacement templates,
// meaning that every proxy needs one.
writer.println("protected " + getClassName() + "(String p_path)");
writer.openBlock();
writer.println("super(p_path);");
writer.closeBlock();
writer.println();
if (!templateUnit.isParent()) {
writer.println("public " + getClassName() + "()");
writer.openBlock();
writer.println(" super(\"" + templateUnit.getName() + "\");");
writer.closeBlock();
writer.println();
}
}
private void generateFragmentInterfaces(boolean inner) {
for (FragmentArgument farg : templateUnit.getDeclaredFragmentArgs()) {
farg.getFragmentUnit().printInterface(writer, "public", !inner);
writer.println();
}
writer.println();
}
private void generateReplacementConstructor() {
writer.println();
writer.print(
"public static class ReplacementConstructor implements "
+ ClassNames.REPLACEMENT_CONSTRUCTOR + " ");
writer.openBlock();
if (templateUnit.getGenericParams().getCount() > 0) {
writer.print("@SuppressWarnings(\"rawtypes\") ");
}
writer.print("@Override public " + ClassNames.TEMPLATE + " makeReplacement() ");
writer.openBlock();
writer.println("return new " + getClassName() + "();");
writer.closeBlock();
writer.closeBlock();
}
private void generateAnnotations() {
if (templateUnit.isReplaceable()) {
writer.println("@" + ClassNames.REPLACEABLE);
}
if (templateUnit.isReplacing()) {
writer.print("@" + ClassNames.REPLACES);
writer.openList("(", true);
writer.printListElement("replacedProxy = " + getReplacedProxyClassName() + ".class");
writer.printListElement("replacementConstructor = " + getClassName()
+ ".ReplacementConstructor.class");
writer.closeList();
writer.println();
}
writer.print("@" + ClassNames.TEMPLATE_ANNOTATION);
writer.openList("(", true);
writer.printListElement("signature = \"" + templateUnit.getSignature() + "\"");
if (templateUnit.getGenericParams().getCount() > 0) {
writer.printListElement("genericsCount = " + templateUnit.getGenericParams().getCount());
}
if (templateUnit.getInheritanceDepth() > 0) {
writer.printListElement("inheritanceDepth = " + templateUnit.getInheritanceDepth());
}
if (templateUnit.getJamonContextType() != null) {
writer.printListElement("jamonContextType = \"" + templateUnit.getJamonContextType() + "\"");
}
if (templateUnit.isReplaceable()) {
writer.printListElement("replaceable = true");
}
generateArguments(templateUnit);
generateMethodAnnotations();
generateAbstractMethodAnnotations();
writer.closeList(")");
writer.println();
}
private void generateMethodAnnotations() {
if (!templateUnit.getSignatureMethodUnits().isEmpty()) {
writer.printListElement("methods = ");
writer.openList("{", true);
for (MethodUnit methodUnit : templateUnit.getSignatureMethodUnits()) {
writer.printListElement("@" + ClassNames.METHOD_ANNOTATION);
writer.openList("(", true);
writer.printListElement("name = \"" + methodUnit.getName() + "\"");
generateArguments(methodUnit);
writer.closeList(")");
}
writer.closeList("}");
}
}
private void generateAbstractMethodAnnotations() {
if (!templateUnit.getAbstractMethodNames().isEmpty()) {
writer.printListElement("abstractMethodNames = ");
writer.openList("{", false);
for (String methodName : templateUnit.getAbstractMethodNames()) {
writer.printListElement("\"" + methodName + "\"");
}
writer.closeList("}");
}
}
private void generateArguments(Unit p_unit) {
generateArgumentAnnotations("requiredArguments", p_unit.getSignatureRequiredArgs());
generateArgumentAnnotations("optionalArguments", p_unit.getSignatureOptionalArgs());
generateFragmentAnnotations(p_unit.getFragmentArgs());
}
private void generateFragmentAnnotations(Collection fargs) {
if (!fargs.isEmpty()) {
writer.printListElement("fragmentArguments = ");
writer.openList("{", true);
for (FragmentArgument farg : fargs) {
writer.printListElement("@" + ClassNames.FRAGMENT_ANNOTATION);
writer.openList("(", true);
writer.printListElement("name = \"" + farg.getName() + "\"");
generateArgumentAnnotations("requiredArguments", farg.getFragmentUnit().getRequiredArgs());
generateArgumentAnnotations("optionalArguments", farg.getFragmentUnit().getOptionalArgs());
writer.closeList(")");
}
writer.closeList("}");
}
}
private void generateArgumentAnnotations(
String label, Collection extends AbstractArgument> args) {
if (!args.isEmpty()) {
writer.printListElement(label + " = ");
writer.openList("{", true);
for (AbstractArgument argument : args) {
writer.printListElement(
"@" + ClassNames.ARGUMENT_ANNOTATION + "(name = \""
+ argument.getName() + "\", type = \"" + argument.getType() + "\")");
}
writer.closeList("}");
}
}
private void generateDeclaration() {
generateCustomAnnotations(templateUnit.getAnnotations(), AnnotationType.PROXY);
writer.print("public ");
if (templateUnit.isParent()) {
writer.print("abstract ");
}
writer.println("class " + getClassName()
+ templateUnit.getGenericParams().generateGenericsDeclaration());
writer.println(" extends " + templateUnit.getProxyParentClass());
templateUnit.printInterfaces(writer);
writer.openBlock();
}
private void generateConstructImplReflective() {
writer.println();
writer.println("@Override");
writer.print("public " + ClassNames.BASE_TEMPLATE + " constructImpl" + "(Class extends "
+ ClassNames.BASE_TEMPLATE + "> p_class)");
writer.openBlock();
writer.println("try");
writer.openBlock();
writer.println("return p_class");
writer.indent();
writer.println(".getConstructor(new Class [] { " + ClassNames.TEMPLATE_MANAGER + ".class"
+ ", ImplData.class })");
writer.println(".newInstance(new Object [] { getTemplateManager(), getImplData()});");
writer.outdent();
writer.closeBlock();
writer.println("catch (RuntimeException e)");
writer.openBlock();
writer.println("throw e;");
writer.closeBlock();
writer.println("catch (Exception e)");
writer.openBlock();
writer.println("throw new RuntimeException(e);");
writer.closeBlock();
writer.closeBlock();
}
private void generateConstructImplDirect() {
writer.println();
writer.println("@Override");
writer.print("protected " + ClassNames.BASE_TEMPLATE + " constructImpl()");
writer.openBlock();
writer.println("return new " + PathUtils.getImplClassName(templateUnit.getName())
+ genericParamsList() + "(getTemplateManager(), getImplData());");
writer.closeBlock();
}
private void generateRender() {
writer.print((templateUnit.isParent()
? "protected"
: "public") + " void render");
writer.openList();
writer.printListElement(ArgNames.WRITER_DECL);
templateUnit.printRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.println(" throws " + ClassNames.IOEXCEPTION);
writer.openBlock();
writer.print("renderNoFlush");
writer.openList();
writer.printListElement(ArgNames.WRITER);
templateUnit.printRenderArgs(writer);
writer.closeList();
writer.println(";");
writer.println(ArgNames.WRITER + ".flush();");
writer.closeBlock();
}
private void generateRenderNoFlush() {
writer.print(
(templateUnit.isParent() ? "protected" : "public")
+ " void renderNoFlush");
writer.openList();
writer.printListElement(ArgNames.WRITER_DECL);
templateUnit.printRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.println(" throws " + ClassNames.IOEXCEPTION);
writer.openBlock();
if (!templateUnit.getRenderArgs().isEmpty()) {
writer.println("ImplData" + genericParamsList() + " implData = getImplData();");
for (AbstractArgument arg : templateUnit.getRenderArgs()) {
writer.println("implData." + arg.getSetterName() + "(" + arg.getName() + ");");
}
}
if (templateUnit.getGenericParams().getCount() > 0) {
writer.print("@SuppressWarnings(\"unchecked\") ");
}
writer.print("Intf" + genericParamsList() + " instance = (Intf" + genericParamsList()
+ ") getTemplateManager().constructImpl(this");
if (templateUnit.getJamonContextType() != null) {
writer.print(", getImplData().getJamonContext()");
}
writer.println(");");
writer.println("instance.renderNoFlush(" + ArgNames.WRITER + ");");
writer.println("reset();");
writer.closeBlock();
writer.println();
}
private void generateMakeRenderer() {
writer.print("public " + ClassNames.RENDERER + " makeRenderer");
writer.openList();
templateUnit.printRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.openBlock();
writer.print("return new " + ClassNames.ABSTRACT_RENDERER + "() ");
writer.openBlock();
writer.println("@Override");
writer.println("public void renderTo(" + ArgNames.WRITER_DECL + ")");
writer.println(" throws " + ClassNames.IOEXCEPTION);
writer.openBlock();
writer.print("render");
writer.openList();
writer.printListElement(ArgNames.WRITER);
templateUnit.printRenderArgs(writer);
writer.closeList();
writer.println(";");
writer.closeBlock();
writer.closeBlock(";");
writer.closeBlock();
writer.println();
}
private void generateImplData() throws ParserErrorsImpl {
writer.println("public static class ImplData"
+ templateUnit.getGenericParams().generateGenericsDeclaration());
writer.print(" extends ");
writer.println(implDataAncestor());
if (templateUnit.isReplacing()) {
writer.print(" implements ");
writer.print(ClassNames.IMPL_DATA_COMPATIBLE);
writer.println("<" + getReplacedImplDataClassName() + ">");
}
writer.openBlock();
if (templateUnit.isReplacing()) {
generatePopulateFrom();
}
if (templateUnit.isOriginatingJamonContext()) {
writer.println("private " + templateUnit.getJamonContextType() + " m_jamonContext;");
writer.println("public " + templateUnit.getJamonContextType() + " getJamonContext()");
writer.openBlock();
writer.println("return m_jamonContext;");
writer.closeBlock();
writer.println("public void setJamonContext(" + templateUnit.getJamonContextType()
+ " p_jamonContext)");
writer.openBlock();
writer.println("m_jamonContext = p_jamonContext;");
writer.closeBlock();
}
for (AbstractArgument arg : templateUnit.getDeclaredArgs()) {
arg.generateImplDataCode(writer);
}
writer.closeBlock();
if (!templateUnit.isParent()) {
writer.println("@Override");
writer.println("protected " + ClassNames.TEMPLATE + ".ImplData" + " makeImplData()");
writer.openBlock();
writer.println("return new ImplData" + genericParamsList() + "();");
writer.closeBlock();
}
// Only generate the getImplData method if we're actually going to use it.
if (!templateUnit.isParent() || !templateUnit.getSignatureOptionalArgs().isEmpty()
|| templateUnit.getJamonContextType() != null) {
generateGetImplData();
}
}
/**
* Generate a method to cast getImplData() to the ImplData class defined in this Proxy file.
*/
private void generateGetImplData() {
if (templateUnit.getGenericParams().getCount() > 0) {
writer.print("@SuppressWarnings(\"unchecked\") ");
}
writer.println("@Override public ImplData" + genericParamsList() + " getImplData()");
writer.openBlock();
writer.println("return (ImplData" + genericParamsList() + ") super.getImplData();");
writer.closeBlock();
}
/**
* Generate the populateFrom method, which is used in replacement templates to populate the
* template's ImplData instance with an instance of ImplData for the replaced template.
* @throws ParserErrorsImpl
*/
private void generatePopulateFrom() throws ParserErrorsImpl {
for (FragmentArgument farg : templateUnit.getFragmentArgs()) {
generateFragmentDelegator(farg);
}
writer.print(
"@Override public void populateFrom(" + getReplacedImplDataClassName() + " implData) ");
writer.openBlock();
TemplateDescription replacedTemplateDescription = templateUnit.getReplacedTemplateDescription();
for (RequiredArgument arg : templateUnit.getSignatureRequiredArgs()) {
writer.println(arg.getSetterName() + "(implData." + arg.getGetterName() + "());");
}
Set replacedTemplateOptionalArgNames = getOptionalArgNames(replacedTemplateDescription);
for (OptionalArgument arg : replacedTemplateDescription.getOptionalArgs()) {
writer.printLocation(arg.getLocation());
if (replacedTemplateOptionalArgNames.contains(arg.getName())) {
writer.println("if(implData." + arg.getIsNotDefaultName() + "()) {");
writer.println(" " + arg.getSetterName() + "(implData." + arg.getGetterName() + "());");
writer.println("}");
}
else {
writer.println(arg.getSetterName() + "(implData." + arg.getGetterName() + "());");
}
}
if (templateUnit.getJamonContextType() != null) {
if (replacedTemplateDescription.getJamonContextType() == null) {
throw new ParserErrorsImpl(new ParserErrorImpl(
templateTopLocation(),
"Replaced component does not have a jamonContext, but replacing component has a " +
"jamonContext of type " + templateUnit.getJamonContextType()));
}
else {
writer.printLocation(templateTopLocation());
writer.println("setJamonContext(implData.getJamonContext());");
}
}
for (FragmentArgument farg : templateUnit.getFragmentArgs()) {
writer.printLocation(farg.getLocation());
writer.println(
farg.getSetterName() + "(new " + getFragmentDelegatorName(farg)
+ genericParamsList() + "(implData." + farg.getGetterName() + "()));");
}
writer.closeBlock();
}
/**
* Create a class to delegate from a fragment satisfying the interface for the replaced template
* to a fragment satisfying the corresponding interface in this template.
*
* @param farg the fragment argument to create a delegator for.
*/
private void generateFragmentDelegator(FragmentArgument farg) {
String fragmentInterfaceName = "Fragment_" + farg.getName() + genericParamsList();
// FIXME - use farg.getFragmentUnit.getFullyQualifiedType
String replacedFragmentInterfaceName =
getReplacedProxyClassName() + "." + fragmentInterfaceName;
FragmentUnit fragmentUnit = farg.getFragmentUnit();
// name the fragment being converted "_frag_" to avoid name clashes with the parameters
// passed to the fragment.
writer.print(
"private static class " + getFragmentDelegatorName(farg)
+ templateUnit.getGenericParams().generateGenericsDeclaration() + " implements "
+ fragmentInterfaceName);
writer.openBlock();
writer.println("private final " + replacedFragmentInterfaceName + " frag;");
writer.println();
writer.print(
"public " + getFragmentDelegatorName(farg) + "(" + replacedFragmentInterfaceName + " frag)");
writer.openBlock();
writer.println("this.frag = frag;");
writer.closeBlock();
writer.println();
writer.print("@Override public void renderNoFlush");
writer.openList();
writer.printListElement(ArgNames.WRITER_DECL);
fragmentUnit.printRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.println(" throws java.io.IOException");
writer.openBlock();
writer.print("this.frag.renderNoFlush");
writer.openList();
writer.printListElement(ArgNames.WRITER);
fragmentUnit.printRenderArgs(writer);
writer.closeList();
writer.println(";");
writer.closeBlock();
writer.print("@Override public " + ClassNames.RENDERER + " makeRenderer");
writer.openList();
fragmentUnit.printRenderArgsDecl(writer);
writer.closeList();
writer.openBlock();
writer.print("return this.frag.makeRenderer");
writer.openList();
fragmentUnit.printRenderArgs(writer);
writer.closeList();
writer.println(";");
writer.closeBlock();
writer.closeBlock();
writer.println();
}
private String getFragmentDelegatorName(FragmentArgument farg) {
return "Fragment_" + farg.getName() + "_Delegator";
}
private String getReplacedImplDataClassName() {
return getReplacedProxyClassName() + ".ImplData" + genericParamsList();
}
private String getReplacedIntfClassName() {
return getReplacedProxyClassName() + ".Intf" + genericParamsList();
}
private String getReplacedProxyClassName() {
return PathUtils.getFullyQualifiedIntfClassName(templateUnit.getReplacedTemplatePath());
}
private static Set getOptionalArgNames(TemplateDescription replacedTemplateDescription) {
Set replacedTemplateOptionalArgNames = new HashSet();
for (OptionalArgument arg : replacedTemplateDescription.getOptionalArgs()) {
replacedTemplateOptionalArgNames.add(arg.getName());
}
return replacedTemplateOptionalArgNames;
}
private String implDataAncestor() {
return templateUnit.hasParentPath()
? PathUtils.getFullyQualifiedIntfClassName(templateUnit.getParentPath()) + ".ImplData"
: ClassNames.IMPL_DATA;
}
private void generateJamonContextSetter() {
writer.println();
if (!templateUnit.isOriginatingJamonContext()) {
writer.print("@Override ");
}
writer.print("public ");
printFullProxyType();
writer.println(" setJamonContext(" + templateUnit.getJamonContextType() + " p_jamonContext)");
writer.openBlock();
writer.println("getImplData().setJamonContext(p_jamonContext);");
writer.println("return this;");
writer.closeBlock();
}
private void generateOptionalArgs() {
for (OptionalArgument arg : templateUnit.getDeclaredOptionalArgs()) {
writer.println();
writer.println("protected " + arg.getType() + " " + arg.getName() + ";");
writer.print("public final ");
printFullProxyType();
writer.println(" " + arg.getSetterName() + "(" + arg.getType() + " p_" + arg.getName() + ")");
writer.openBlock();
writer.println("(" + "getImplData()" + ")." + arg.getSetterName() + "(p_" + arg.getName()
+ ");");
writer.println("return this;");
writer.closeBlock();
}
}
private void printFullProxyType() {
String pkgName = getPackageName();
if (pkgName.length() > 0) {
writer.print(pkgName + ".");
}
writer.print(getClassName());
writer.print(genericParamsList());
}
private void generateIntf() {
writer.println("public interface Intf"
+ templateUnit.getGenericParams().generateGenericsDeclaration());
writer.print(" extends ");
writer.openList("", false);
if (templateUnit.hasParentPath()) {
writer.printListElement(
PathUtils.getFullyQualifiedIntfClassName(templateUnit.getParentPath()) + ".Intf");
}
if (templateUnit.isReplacing()) {
writer.printListElement(getReplacedIntfClassName());
}
if (!templateUnit.hasParentPath() && !templateUnit.isReplacing()) {
writer.printListElement(ClassNames.TEMPLATE_INTF);
}
writer.closeList("");
writer.println();
writer.openBlock();
generateFragmentInterfaces(true);
if (!templateUnit.isParent()) {
if (templateUnit.isReplacing()) {
writer.print("@Override ");
}
writer.println(
"void renderNoFlush(" + ArgNames.WRITER_DECL + ") throws " + ClassNames.IOEXCEPTION + ";");
writer.println();
}
writer.closeBlock();
}
private void generateParentRendererClass() {
writer.println("public abstract class ParentRenderer");
writer.openBlock();
writer.println("protected ParentRenderer() {}");
for (OptionalArgument arg : templateUnit.getSignatureOptionalArgs()) {
writer.println();
String name = arg.getName();
writer.print("public final ParentRenderer ");
writer.println(arg.getSetterName() + "(" + arg.getType() + " p_" + name + ")");
writer.openBlock();
writer.println(getClassName() + ".this." + arg.getSetterName() + "(" + "p_" + name + ");");
writer.println("return this;");
writer.closeBlock();
}
if (templateUnit.getJamonContextType() != null) {
writer.print(
"public final ParentRenderer setJamonContext("
+ templateUnit.getJamonContextType() + " p_jamonContext)");
writer.openBlock();
writer.println(getClassName() + ".this.setJamonContext(p_jamonContext);");
writer.println("return this;");
writer.closeBlock();
}
if (!templateUnit.hasParentPath()) {
writer.print("public void render");
writer.openList();
writer.printListElement(ArgNames.WRITER_DECL);
templateUnit.printDeclaredRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.print(" throws " + ClassNames.IOEXCEPTION);
writer.openBlock();
writer.print("renderNoFlush");
writer.openList();
writer.printListElement(ArgNames.WRITER);
templateUnit.printDeclaredRenderArgs(writer);
writer.closeList();
writer.println(";");
writer.println(ArgNames.WRITER + ".flush();");
writer.closeBlock();
writer.print("public void renderNoFlush");
writer.openList();
writer.printListElement(ArgNames.WRITER_DECL);
templateUnit.printDeclaredRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.print(" throws " + ClassNames.IOEXCEPTION);
writer.openBlock();
writer.print("renderChild");
writer.openList();
writer.printListElement(ArgNames.WRITER);
templateUnit.printDeclaredRenderArgs(writer);
writer.closeList();
writer.println(";");
writer.closeBlock();
generateMakeRenderer();
}
else {
generateMakeParentRenderer();
}
writer.print("protected abstract void renderChild");
writer.openList();
writer.printListElement(ArgNames.WRITER_DECL);
templateUnit.printRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.println(" throws " + ClassNames.IOEXCEPTION + ";");
writer.closeBlock();
}
private void generateMakeParentRenderer() {
String parentRendererClass =
PathUtils.getFullyQualifiedIntfClassName(templateUnit.getParentPath()) + ".ParentRenderer";
writer.print("public " + parentRendererClass + " makeParentRenderer");
writer.openList();
templateUnit.printDeclaredRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.openBlock();
writer.print("return new " + parentRendererClass + "() ");
writer.openBlock();
writer.print("@Override protected void renderChild");
writer.openList();
writer.printListElement(ArgNames.WRITER_DECL);
templateUnit.printParentRenderArgsDecl(writer);
writer.closeList();
writer.println();
writer.println(" throws " + ClassNames.IOEXCEPTION);
writer.openBlock();
writer.print(PathUtils.getFullyQualifiedIntfClassName(getClassName()));
if (templateUnit.isParent()) {
writer.print(".ParentRenderer.this.renderChild");
}
else {
writer.print(".this.renderNoFlush");
}
writer.openList();
writer.printListElement(ArgNames.WRITER);
templateUnit.printRenderArgs(writer);
writer.closeList();
writer.println(";");
writer.closeBlock();
writer.closeBlock(";");
writer.closeBlock();
}
private void generateEpilogue() {
writer.println();
writer.closeBlock();
}
private String genericParamsList() {
return templateUnit.getGenericParams().generateGenericParamsList();
}
/**
* @return a location representing the top of the template. Useful for constructs which don't
* relate to any specific point in the template.
*/
private LocationImpl templateTopLocation() {
return new LocationImpl(describer.getTemplateLocation(templateUnit.getName()), 1, 1);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy