add tool-template and generatedcode-runtime version compatibility check. Target authors add a VERSION template and supply a RuntimeMetaData.checkVersion() method.
This commit is contained in:
parent
3111db7a76
commit
a3d4ba53a3
|
@ -29,13 +29,7 @@
|
|||
*/
|
||||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNDeserializationOptions;
|
||||
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||
import org.antlr.v4.runtime.atn.ATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.ATNState;
|
||||
import org.antlr.v4.runtime.atn.ParserATNSimulator;
|
||||
import org.antlr.v4.runtime.atn.RuleTransition;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.IntegerStack;
|
||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
||||
|
@ -48,11 +42,7 @@ import org.antlr.v4.runtime.tree.TerminalNode;
|
|||
import org.antlr.v4.runtime.tree.pattern.ParseTreePattern;
|
||||
import org.antlr.v4.runtime.tree.pattern.ParseTreePatternMatcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.*;
|
||||
|
||||
/** This is all the parsing support code essentially; most of it is error recovery stuff. */
|
||||
public abstract class Parser extends Recognizer<Token, ParserATNSimulator> {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.antlr.v4.runtime;
|
||||
|
||||
public class RuntimeMetaData {
|
||||
/** Must match version of tool that generated recognizers */
|
||||
public static final String VERSION = "4.2"; // use just "x.y" and don't include bug fix release number
|
||||
|
||||
/** As parser or lexer class is loaded, it checks that the version used to generate the code
|
||||
* is compatible with the runtime version. ANTLR tool generates recognizers with a hardcoded string created by
|
||||
* the tool during code gen. That version is passed to checkVersion().
|
||||
*/
|
||||
public static void checkVersion(String toolVersion) {
|
||||
if ( !VERSION.equals(toolVersion) ) {
|
||||
System.err.println("ANTLR runtime and generated code versions disagree: "+VERSION+"!="+toolVersion);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -28,6 +28,14 @@
|
|||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/** ANTLR tool checks output templates are compatible with tool code generation.
|
||||
* For now, a simple string match used on x.y of x.y.z scheme.
|
||||
* Must match Tool.VERSION during load to templates.
|
||||
*
|
||||
* REQUIRED.
|
||||
*/
|
||||
VERSION() ::= "4.2" // use just "x.y" and don't include bug fix release number
|
||||
|
||||
javaTypeInitMap ::= [
|
||||
"int":"0",
|
||||
"long":"0",
|
||||
|
@ -214,6 +222,8 @@ Parser(parser, funcs, atn, sempredFuncs, superClass) ::= <<
|
|||
Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= <<
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class <parser.name> extends <superClass> {
|
||||
static { RuntimeMetaData.checkVersion("<file.ANTLRVersion>"); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
|
@ -848,6 +858,7 @@ import org.antlr.v4.runtime.misc.*;
|
|||
Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= <<
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class <lexer.name> extends <superClass> {
|
||||
static { RuntimeMetaData.checkVersion("<lexerFile.ANTLRVersion>"); }
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
|
|
|
@ -30,67 +30,31 @@
|
|||
|
||||
package org.antlr.v4;
|
||||
|
||||
import org.antlr.runtime.ANTLRFileStream;
|
||||
import org.antlr.runtime.ANTLRStringStream;
|
||||
import org.antlr.runtime.CharStream;
|
||||
import org.antlr.runtime.CommonTokenStream;
|
||||
import org.antlr.runtime.ParserRuleReturnScope;
|
||||
import org.antlr.runtime.RecognitionException;
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.v4.analysis.AnalysisPipeline;
|
||||
import org.antlr.v4.automata.ATNFactory;
|
||||
import org.antlr.v4.automata.LexerATNFactory;
|
||||
import org.antlr.v4.automata.ParserATNFactory;
|
||||
import org.antlr.v4.codegen.CodeGenPipeline;
|
||||
import org.antlr.v4.misc.Graph;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||
import org.antlr.v4.parse.GrammarTreeVisitor;
|
||||
import org.antlr.v4.parse.ToolANTLRLexer;
|
||||
import org.antlr.v4.parse.ToolANTLRParser;
|
||||
import org.antlr.v4.parse.v3TreeGrammarException;
|
||||
import org.antlr.v4.parse.*;
|
||||
import org.antlr.v4.runtime.misc.LogManager;
|
||||
import org.antlr.v4.runtime.misc.Nullable;
|
||||
import org.antlr.v4.semantics.SemanticPipeline;
|
||||
import org.antlr.v4.tool.ANTLRMessage;
|
||||
import org.antlr.v4.tool.ANTLRToolListener;
|
||||
import org.antlr.v4.tool.BuildDependencyGenerator;
|
||||
import org.antlr.v4.tool.DOTGenerator;
|
||||
import org.antlr.v4.tool.DefaultToolListener;
|
||||
import org.antlr.v4.tool.ErrorManager;
|
||||
import org.antlr.v4.tool.ErrorType;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.GrammarTransformPipeline;
|
||||
import org.antlr.v4.tool.LexerGrammar;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
import org.antlr.v4.tool.ast.ActionAST;
|
||||
import org.antlr.v4.tool.ast.GrammarAST;
|
||||
import org.antlr.v4.tool.ast.GrammarASTErrorNode;
|
||||
import org.antlr.v4.tool.ast.GrammarRootAST;
|
||||
import org.antlr.v4.tool.ast.RuleAST;
|
||||
import org.antlr.v4.tool.ast.TerminalAST;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ast.*;
|
||||
import org.stringtemplate.v4.STGroup;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
public class Tool {
|
||||
public static final String VERSION;
|
||||
static {
|
||||
String version = Tool.class.getPackage().getImplementationVersion();
|
||||
VERSION = version != null ? version : "4.x";
|
||||
VERSION = version != null ? version : "4.2";
|
||||
}
|
||||
|
||||
public static final String GRAMMAR_EXTENSION = ".g4";
|
||||
|
|
|
@ -88,7 +88,12 @@ public class CodeGenerator {
|
|||
}
|
||||
|
||||
public STGroup getTemplates() {
|
||||
return getTarget().getTemplates();
|
||||
STGroup templates = getTarget().getTemplates();
|
||||
ST version = templates.getInstanceOf("VERSION");
|
||||
if ( version==null || !version.render().equals(Tool.VERSION) ) {
|
||||
tool.errMgr.toolError(ErrorType.INCOMPATIBLE_TOOL_AND_TEMPLATES, version, Tool.VERSION, language);
|
||||
}
|
||||
return templates;
|
||||
}
|
||||
|
||||
protected void loadLanguageTarget(String language) {
|
||||
|
|
|
@ -169,6 +169,12 @@ public enum ErrorType {
|
|||
* no mapping to template name for output model class '<em>class</em>'</p>
|
||||
*/
|
||||
NO_MODEL_TO_TEMPLATE_MAPPING(34, "no mapping to template name for output model class '<arg>'", ErrorSeverity.ERROR),
|
||||
/**
|
||||
* Compiler Error 35.
|
||||
*
|
||||
* <p>templates and tool aren't compatible</p>
|
||||
*/
|
||||
INCOMPATIBLE_TOOL_AND_TEMPLATES(35, "<arg3> code generation templates and tool versions disagree: <arg> != <arg2>", ErrorSeverity.ERROR),
|
||||
|
||||
/*
|
||||
* Grammar errors
|
||||
|
@ -694,7 +700,7 @@ public enum ErrorType {
|
|||
* <p>Some lexer commands require an argument.</p>
|
||||
*
|
||||
* <p>The following rule produces this error.</p>
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
* X : 'foo' -> type(Foo); // ok
|
||||
* Y : 'foo' -> type; // error 150 (the type command requires an argument)
|
||||
|
|
Loading…
Reference in New Issue