diff --git a/tool/src/org/antlr/v4/codegen/Target.java b/tool/src/org/antlr/v4/codegen/Target.java index 618d891a21..2f6b6f522d 100644 --- a/tool/src/org/antlr/v4/codegen/Target.java +++ b/tool/src/org/antlr/v4/codegen/Target.java @@ -18,12 +18,7 @@ import org.antlr.v4.tool.Grammar; import org.antlr.v4.tool.Rule; import org.antlr.v4.tool.ast.GrammarAST; -import org.stringtemplate.v4.NumberRenderer; -import org.stringtemplate.v4.ST; -import org.stringtemplate.v4.STErrorListener; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.STGroupFile; -import org.stringtemplate.v4.StringRenderer; +import org.stringtemplate.v4.*; import org.stringtemplate.v4.misc.STMessage; import java.util.HashMap; @@ -32,8 +27,9 @@ /** */ public abstract class Target { + private final static Map languageTemplates = new HashMap<>(); + protected final CodeGenerator gen; - private STGroup templates; protected static final Map defaultCharValueEscape; static { @@ -92,14 +88,22 @@ public String getVersion() { } public STGroup getTemplates() { + String language = getLanguage(); + STGroup templates = languageTemplates.get(language); + if (templates == null) { - String version = getVersion(); - if ( version==null || - !RuntimeMetaData.getMajorMinorVersion(version).equals(RuntimeMetaData.getMajorMinorVersion(Tool.VERSION))) - { - gen.tool.errMgr.toolError(ErrorType.INCOMPATIBLE_TOOL_AND_TEMPLATES, version, Tool.VERSION, getLanguage()); + synchronized (languageTemplates) { + templates = languageTemplates.get(language); + if (templates == null) { + String version = getVersion(); + if (version == null || + !RuntimeMetaData.getMajorMinorVersion(version).equals(RuntimeMetaData.getMajorMinorVersion(Tool.VERSION))) { + gen.tool.errMgr.toolError(ErrorType.INCOMPATIBLE_TOOL_AND_TEMPLATES, version, Tool.VERSION, language); + } + templates = loadTemplates(); + languageTemplates.put(language, templates); + } } - templates = loadTemplates(); } return templates; diff --git a/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java b/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java index 3d15c1cb14..c6212df68f 100644 --- a/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/CSharpTarget.java @@ -136,41 +136,6 @@ protected String escapeWord(String word) { return "@" + word; } - @Override - protected STGroup loadTemplates() { - // override the superclass behavior to put all C# templates in the same folder - STGroup result = new STGroupFile(CodeGenerator.TEMPLATE_ROOT+"/CSharp/"+ getLanguage()+STGroup.GROUP_FILE_EXTENSION); - result.registerRenderer(Integer.class, new NumberRenderer()); - result.registerRenderer(String.class, new StringRenderer()); - result.setListener(new STErrorListener() { - @Override - public void compileTimeError(STMessage msg) { - reportError(msg); - } - - @Override - public void runTimeError(STMessage msg) { - reportError(msg); - } - - @Override - public void IOError(STMessage msg) { - reportError(msg); - } - - @Override - public void internalError(STMessage msg) { - reportError(msg); - } - - private void reportError(STMessage msg) { - getCodeGenerator().tool.errMgr.toolError(ErrorType.STRING_TEMPLATE_WARNING, msg.cause, msg.toString()); - } - }); - - return result; - } - @Override public boolean isATNSerializedAsInts() { return true; diff --git a/tool/src/org/antlr/v4/codegen/target/CppTarget.java b/tool/src/org/antlr/v4/codegen/target/CppTarget.java index d5cc5fff57..f8fc4d2702 100644 --- a/tool/src/org/antlr/v4/codegen/target/CppTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/CppTarget.java @@ -8,14 +8,7 @@ import org.antlr.v4.codegen.CodeGenerator; import org.antlr.v4.codegen.Target; -import org.antlr.v4.tool.ErrorType; -import org.stringtemplate.v4.NumberRenderer; import org.stringtemplate.v4.ST; -import org.stringtemplate.v4.STErrorListener; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.StringRenderer; -import org.stringtemplate.v4.misc.STMessage; - import java.util.*; public class CppTarget extends Target { @@ -124,38 +117,4 @@ public String getBaseVisitorFileName(boolean header) { String listenerName = gen.g.name + "BaseVisitor"; return listenerName+extST.render(); } - - @Override - protected STGroup loadTemplates() { - STGroup result = super.loadTemplates(); - result.registerRenderer(Integer.class, new NumberRenderer()); - result.registerRenderer(String.class, new StringRenderer()); - result.setListener(new STErrorListener() { - @Override - public void compileTimeError(STMessage msg) { - reportError(msg); - } - - @Override - public void runTimeError(STMessage msg) { - reportError(msg); - } - - @Override - public void IOError(STMessage msg) { - reportError(msg); - } - - @Override - public void internalError(STMessage msg) { - reportError(msg); - } - - private void reportError(STMessage msg) { - getCodeGenerator().tool.errMgr.toolError(ErrorType.STRING_TEMPLATE_WARNING, msg.cause, msg.toString()); - } - }); - - return result; - } } diff --git a/tool/src/org/antlr/v4/codegen/target/DartTarget.java b/tool/src/org/antlr/v4/codegen/target/DartTarget.java index 64dc2ee3b5..30e1209f63 100644 --- a/tool/src/org/antlr/v4/codegen/target/DartTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/DartTarget.java @@ -8,18 +8,13 @@ import org.antlr.v4.codegen.CodeGenerator; import org.antlr.v4.codegen.Target; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.StringRenderer; import java.util.*; public class DartTarget extends Target { protected static final Map targetCharValueEscape; static { - HashMap map = new HashMap<>(); - for (Map.Entry entry : defaultCharValueEscape.entrySet()) { - map.put(entry.getKey(), entry.getValue()); - } + HashMap map = new HashMap<>(defaultCharValueEscape); addEscapedChar(map, '$'); targetCharValueEscape = map; } @@ -63,14 +58,6 @@ public Set getReservedWords() { return reservedWords; } - @Override - protected STGroup loadTemplates() { - STGroup result = super.loadTemplates(); - result.registerRenderer(String.class, new StringRenderer(), true); - - return result; - } - @Override public boolean isATNSerializedAsInts() { return true; diff --git a/tool/src/org/antlr/v4/codegen/target/GoTarget.java b/tool/src/org/antlr/v4/codegen/target/GoTarget.java index 21eb79fc4d..672507883b 100644 --- a/tool/src/org/antlr/v4/codegen/target/GoTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/GoTarget.java @@ -99,13 +99,6 @@ public int getInlineTestSetWordSize() { return 32; } - @Override - protected STGroup loadTemplates() { - STGroup result = super.loadTemplates(); - result.registerRenderer(String.class, new JavaStringRenderer(), true); - return result; - } - public String getRecognizerFileName(boolean header) { CodeGenerator gen = getCodeGenerator(); Grammar g = gen.g; @@ -164,17 +157,4 @@ public String getBaseVisitorFileName(boolean header) { assert g.name != null; return g.name.toLowerCase()+"_base_visitor.go"; } - - protected static class JavaStringRenderer extends StringRenderer { - @Override - public String toString(Object o, String formatString, Locale locale) { - - if ("java-escape".equals(formatString)) { - // 5C is the hex code for the \ itself - return ((String)o).replace("\\u", "\\u005Cu"); - } - - return super.toString(o, formatString, locale); - } - } } diff --git a/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java b/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java index d199f3ed5f..ae30501414 100644 --- a/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java @@ -8,13 +8,9 @@ import org.antlr.v4.codegen.CodeGenerator; import org.antlr.v4.codegen.Target; -import org.antlr.v4.tool.ast.GrammarAST; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.StringRenderer; import java.util.Arrays; import java.util.HashSet; -import java.util.Locale; import java.util.Set; public class JavaScriptTarget extends Target { @@ -56,27 +52,6 @@ public int getInlineTestSetWordSize() { return 32; } - @Override - protected STGroup loadTemplates() { - STGroup result = super.loadTemplates(); - result.registerRenderer(String.class, new JavaStringRenderer(), true); - return result; - } - - protected static class JavaStringRenderer extends StringRenderer { - - @Override - public String toString(Object o, String formatString, Locale locale) { - if ("java-escape".equals(formatString)) { - // 5C is the hex code for the \ itself - return ((String)o).replace("\\u", "\\u005Cu"); - } - - return super.toString(o, formatString, locale); - } - - } - @Override public boolean wantsBaseListener() { return false; diff --git a/tool/src/org/antlr/v4/codegen/target/JavaTarget.java b/tool/src/org/antlr/v4/codegen/target/JavaTarget.java index 869c98e445..4b1a12b7c7 100644 --- a/tool/src/org/antlr/v4/codegen/target/JavaTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/JavaTarget.java @@ -49,31 +49,6 @@ public int getSerializedATNSegmentLimit() { return 65535 / 3; } - @Override - protected STGroup loadTemplates() { - STGroup result = targetTemplates.get(); - if (result == null) { - result = super.loadTemplates(); - result.registerRenderer(String.class, new JavaStringRenderer(), true); - targetTemplates.set(result); - } - - return result; - } - - protected static class JavaStringRenderer extends StringRenderer { - - @Override - public String toString(Object o, String formatString, Locale locale) { - if ("java-escape".equals(formatString)) { - // 5C is the hex code for the \ itself - return ((String)o).replace("\\u", "\\u005Cu"); - } - - return super.toString(o, formatString, locale); - } - } - @Override public boolean isATNSerializedAsInts() { return false; diff --git a/tool/src/org/antlr/v4/codegen/target/PHPTarget.java b/tool/src/org/antlr/v4/codegen/target/PHPTarget.java index b8c362f2f6..4f9188df3b 100644 --- a/tool/src/org/antlr/v4/codegen/target/PHPTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/PHPTarget.java @@ -8,8 +8,6 @@ import org.antlr.v4.codegen.CodeGenerator; import org.antlr.v4.codegen.Target; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.StringRenderer; import java.util.*; @@ -73,14 +71,6 @@ protected Set getReservedWords() { return reservedWords; } - @Override - protected STGroup loadTemplates() { - STGroup result = super.loadTemplates(); - result.registerRenderer(String.class, new StringRenderer(), true); - - return result; - } - @Override public boolean supportsOverloadedMethods() { return false; diff --git a/tool/src/org/antlr/v4/codegen/target/Python2Target.java b/tool/src/org/antlr/v4/codegen/target/Python2Target.java index 6f4ac59041..9efa20f448 100644 --- a/tool/src/org/antlr/v4/codegen/target/Python2Target.java +++ b/tool/src/org/antlr/v4/codegen/target/Python2Target.java @@ -8,8 +8,6 @@ import org.antlr.v4.codegen.CodeGenerator; import org.antlr.v4.codegen.Target; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.StringRenderer; import java.util.*; @@ -76,21 +74,6 @@ protected Set getReservedWords() { return reservedWords; } - @Override - protected STGroup loadTemplates() { - STGroup result = super.loadTemplates(); - result.registerRenderer(String.class, new PythonStringRenderer(), true); - return result; - } - - protected static class PythonStringRenderer extends StringRenderer { - - @Override - public String toString(Object o, String formatString, Locale locale) { - return super.toString(o, formatString, locale); - } - } - @Override public boolean wantsBaseListener() { return false; diff --git a/tool/src/org/antlr/v4/codegen/target/Python3Target.java b/tool/src/org/antlr/v4/codegen/target/Python3Target.java index c4684cc68b..768dbc1ef7 100644 --- a/tool/src/org/antlr/v4/codegen/target/Python3Target.java +++ b/tool/src/org/antlr/v4/codegen/target/Python3Target.java @@ -8,8 +8,6 @@ import org.antlr.v4.codegen.CodeGenerator; import org.antlr.v4.codegen.Target; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.StringRenderer; import java.util.*; @@ -75,21 +73,6 @@ protected Set getReservedWords() { return reservedWords; } - @Override - protected STGroup loadTemplates() { - STGroup result = super.loadTemplates(); - result.registerRenderer(String.class, new PythonStringRenderer(), true); - return result; - } - - protected static class PythonStringRenderer extends StringRenderer { - - @Override - public String toString(Object o, String formatString, Locale locale) { - return super.toString(o, formatString, locale); - } - } - @Override public boolean wantsBaseListener() { return false; diff --git a/tool/src/org/antlr/v4/codegen/target/SwiftTarget.java b/tool/src/org/antlr/v4/codegen/target/SwiftTarget.java index aee548b335..320bc786df 100644 --- a/tool/src/org/antlr/v4/codegen/target/SwiftTarget.java +++ b/tool/src/org/antlr/v4/codegen/target/SwiftTarget.java @@ -10,22 +10,14 @@ import org.antlr.v4.codegen.Target; import org.antlr.v4.tool.Grammar; import org.stringtemplate.v4.ST; -import org.stringtemplate.v4.STGroup; -import org.stringtemplate.v4.StringRenderer; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; -import java.util.Locale; import java.util.Map; import java.util.Set; public class SwiftTarget extends Target { - /** - * The Swift target can cache the code generation templates. - */ - private static final ThreadLocal targetTemplates = new ThreadLocal<>(); - protected static final Map targetCharValueEscape; static { // https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html @@ -78,30 +70,6 @@ protected void genFile(Grammar g, ST outputFileST, String fileName) { super.genFile(g,outputFileST,fileName); } - @Override - protected STGroup loadTemplates() { - STGroup result = targetTemplates.get(); - if (result == null) { - result = super.loadTemplates(); - result.registerRenderer(String.class, new SwiftStringRenderer(), true); - targetTemplates.set(result); - } - - return result; - } - - protected static class SwiftStringRenderer extends StringRenderer { - @Override - public String toString(Object o, String formatString, Locale locale) { - if ("java-escape".equals(formatString)) { - // 5C is the hex code for the \ itself - return ((String)o).replace("\\u", "\\u005Cu"); - } - - return super.toString(o, formatString, locale); - } - } - @Override public boolean isATNSerializedAsInts() { return true;