From 7d43d3286a06d86ed65b43eeb9662f3908e72316 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 23 Sep 2026 13:44:32 +0000 Subject: [PATCH] Memoise Decompile(0) on AST nodes Decompile(0) is the form consumers ask for, and they ask repeatedly: a CFLint scan runs every rule over every node and several rules decompile the same node. Instrumented over a 3,002-file scan, 1.25M calls of which 74% of expression calls and 76% of statement calls were repeats. Each one rebuilds the whole subtree's text by concatenation, so the repeats are pure waste. Both abstract CFParsedStatement bases now implement Decompile(int) as a wrapper caching the indent == 0 result, delegating to a new abstract decompileImpl(int) that the 59 concrete nodes override. The public CFStatement / CFScriptStatement interfaces are untouched, so callers see no change. A non-zero indent is only ever reached from a parent already rendering itself, so it is not worth keying on. CFCase and CFCatchStatement implement the interface directly rather than extending a base, so they keep overriding Decompile and get no caching. The cached string is valid only while the node is unchanged. Nothing mutates a node after the visitor finishes building it -- which is before any consumer can hold a reference -- but a setter added later that changes rendering must call invalidateDecompiled(). That contract is recorded at the cache and in CLAUDE.md, because getting it wrong returns stale text rather than failing. Worth ~6% on a large scan and nothing on a small one, where cold DFA construction dominates everything. Reported for what it is: the 74% hit rate is not a 74% saving. Verified: 326 cfparser tests, 675 CFLint tests, and a 3,002-file CFLint scan whose JSON output is byte-identical to baseline (33,468,306 bytes, 48,690 issues both ways). Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01GzpZFd4rnE1Yi2sVHAji35 --- CLAUDE.md | 19 +++++++++++ .../CFAnonymousComponentExpression.java | 2 +- .../CFAnonymousFunctionExpression.java | 2 +- .../parsing/cfscript/CFArrayExpression.java | 2 +- .../cfscript/CFAssignmentExpression.java | 2 +- .../parsing/cfscript/CFBinaryExpression.java | 2 +- .../parsing/cfscript/CFElvisExpression.java | 2 +- .../parsing/cfscript/CFFullVarExpression.java | 2 +- .../cfscript/CFFunctionExpression.java | 2 +- .../cfml/parsing/cfscript/CFIdentifier.java | 2 +- .../cfscript/CFJavaMethodExpression.java | 2 +- .../parsing/cfscript/CFLambdaExpression.java | 2 +- .../java/cfml/parsing/cfscript/CFLiteral.java | 2 +- .../java/cfml/parsing/cfscript/CFMember.java | 2 +- .../cfscript/CFMultipartIdentifier.java | 4 +-- .../parsing/cfscript/CFNestedExpression.java | 2 +- .../parsing/cfscript/CFNewExpression.java | 2 +- .../parsing/cfscript/CFParsedStatement.java | 34 ++++++++++++++++++- .../cfml/parsing/cfscript/CFSliceMember.java | 2 +- .../parsing/cfscript/CFStringExpression.java | 2 +- .../cfscript/CFStructElementExpression.java | 2 +- .../parsing/cfscript/CFStructExpression.java | 2 +- .../parsing/cfscript/CFTernaryExpression.java | 2 +- .../parsing/cfscript/CFUnaryExpression.java | 2 +- .../parsing/cfscript/CFVarDeclExpression.java | 2 +- .../cfscript/script/CFAbortStatement.java | 2 +- .../cfscript/script/CFAdminStatement.java | 2 +- .../cfscript/script/CFBreakStatement.java | 2 +- .../cfscript/script/CFCompDeclStatement.java | 2 +- .../cfscript/script/CFCompoundStatement.java | 2 +- .../cfscript/script/CFContinueStatement.java | 2 +- .../cfscript/script/CFDoWhileStatement.java | 2 +- .../cfscript/script/CFEmptyStatement.java | 2 +- .../cfscript/script/CFExitStatement.java | 2 +- .../script/CFExpressionStatement.java | 2 +- .../cfscript/script/CFForInStatement.java | 2 +- .../cfscript/script/CFForStatement.java | 2 +- .../cfscript/script/CFFuncDeclStatement.java | 2 +- .../cfscript/script/CFIfStatement.java | 2 +- .../cfscript/script/CFImportStatement.java | 2 +- .../cfscript/script/CFIncludeStatement.java | 2 +- .../script/CFInterfaceDeclStatement.java | 4 +-- .../cfscript/script/CFLockStatement.java | 2 +- .../script/CFMLFunctionStatement.java | 2 +- .../cfscript/script/CFParamStatement.java | 2 +- .../cfscript/script/CFParsedStatement.java | 34 ++++++++++++++++++- .../cfscript/script/CFPropertyStatement.java | 2 +- .../cfscript/script/CFReThrowStatement.java | 2 +- .../cfscript/script/CFReturnStatement.java | 2 +- .../script/CFStaticBlockStatement.java | 2 +- .../cfscript/script/CFSwitchStatement.java | 2 +- .../cfscript/script/CFTagStatement.java | 2 +- .../cfscript/script/CFTagThrowStatement.java | 2 +- .../script/CFTemplateBlockStatement.java | 2 +- .../cfscript/script/CFThreadStatement.java | 2 +- .../cfscript/script/CFThrowStatement.java | 2 +- .../script/CFTransactionStatement.java | 2 +- .../cfscript/script/CFTryCatchStatement.java | 2 +- .../cfscript/script/CFWhileStatement.java | 2 +- .../cfscript/script/IncludeStatement.java | 2 +- 60 files changed, 144 insertions(+), 61 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 6ea8bad7..8e24b743 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -129,6 +129,25 @@ empties the cache. Cache hits cost ~7% of a miss (0.002ms vs 0.032ms), worth roughly 30% of expression-parse time on a large file. +### Decompile(0) is memoised — setters must invalidate + +`Decompile(int)` is declared on the `CFStatement` and `CFScriptStatement` interfaces, and both +abstract `CFParsedStatement` bases implement it as a wrapper that caches the `indent == 0` result +and delegates to `decompileImpl(int)`. **Concrete nodes override `decompileImpl`, not `Decompile`.** +A non-zero indent is only reached from a parent already rendering itself, so it is not cached. + +`CFCase` and `CFCatchStatement` implement the interface directly rather than extending a base, so +they still override `Decompile` and get no caching. + +The cached string is valid only while the node is unchanged. Nothing mutates a node after the +visitor finishes building it — which is before any consumer can hold a reference — but **a setter +that changes rendering must call `invalidateDecompiled()`**, or `Decompile(0)` keeps handing back +the text from before the change. `setIsShortHand`, `setStatic`, `setModifier` and +`setMemberOperator` are the kind of setter this applies to. + +Worth roughly 6% of a large CFLint scan (74% of `Decompile(0)` calls were repeats), and nothing on +a small one, where DFA warm-up dominates — see below. + ## Downstream: CFLint `cfmleditor/CFLint` is the main consumer. It declares the cfparser version **twice** — a diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousComponentExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousComponentExpression.java index e446cc12..c6258bb3 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousComponentExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousComponentExpression.java @@ -40,7 +40,7 @@ public CFCompDeclStatement getComponentDeclaration() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { return "new " + componentDeclaration.Decompile(0); } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousFunctionExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousFunctionExpression.java index 12517beb..ed146c57 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousFunctionExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAnonymousFunctionExpression.java @@ -28,7 +28,7 @@ public byte getType() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { return (funcDeclStatement.Decompile(0)); } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFArrayExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFArrayExpression.java index c0dba2ee..207489a1 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFArrayExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFArrayExpression.java @@ -29,7 +29,7 @@ public void addElement(CFExpression _e) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { if (elements.size() > 0) { StringBuilder sb = new StringBuilder(); sb.append('['); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAssignmentExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAssignmentExpression.java index 5b104546..6895ce68 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAssignmentExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFAssignmentExpression.java @@ -105,7 +105,7 @@ public void checkIndirectAssignments(String[] scriptSource) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); if (left != null) { sb.append(left.Decompile(indent)); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFBinaryExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFBinaryExpression.java index 72f023ec..e4623cbd 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFBinaryExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFBinaryExpression.java @@ -43,7 +43,7 @@ public byte getType() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { String endChar = ""; if (_kind == CFSCRIPTLexer.LEFTBRACKET) { endChar = "]"; diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFElvisExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFElvisExpression.java index 1dca6390..e483a0f9 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFElvisExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFElvisExpression.java @@ -12,7 +12,7 @@ public CFElvisExpression(Token t, CFExpression left, CFExpression right) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { return "" + _left.Decompile(indent) + " " + operatorImage + " " + _right.Decompile(indent); } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFullVarExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFullVarExpression.java index b79f8a4f..f2096249 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFullVarExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFullVarExpression.java @@ -65,7 +65,7 @@ public void addMember(CFExpression _right) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); for (CFExpression expression : expressions) { if (sb.length() > 0) { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFunctionExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFunctionExpression.java index 23c3d436..707ebce9 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFunctionExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFFunctionExpression.java @@ -52,7 +52,7 @@ public boolean isUDF() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { String s = nameId == null ? "" : nameId.Decompile(indent); s += "("; diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFIdentifier.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFIdentifier.java index 8f353344..221aa11c 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFIdentifier.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFIdentifier.java @@ -53,7 +53,7 @@ public Token getToken() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { return getFullName(); } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFJavaMethodExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFJavaMethodExpression.java index 69192487..e7072903 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFJavaMethodExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFJavaMethodExpression.java @@ -56,7 +56,7 @@ public void setOnMethodMissing() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append(name.Decompile(indent)); sb.append("("); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLambdaExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLambdaExpression.java index df9a7a66..262e5473 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLambdaExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLambdaExpression.java @@ -57,7 +57,7 @@ public CFExpression getExpressionBody() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { CFFuncDeclStatement declaration = getFuncDeclStatement(); StringBuilder sb = new StringBuilder(); sb.append("("); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLiteral.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLiteral.java index fd9cc1ac..261632a7 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLiteral.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFLiteral.java @@ -60,7 +60,7 @@ public String getStringImage() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { try { if (CFSCRIPTLexer.STRING_LITERAL == kind && val != null) { return "'" + val + "'"; diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMember.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMember.java index ca0d6a98..6e2171dc 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMember.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMember.java @@ -34,7 +34,7 @@ public Token getToken() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { return "[" + expression.Decompile(0) + "]"; } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMultipartIdentifier.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMultipartIdentifier.java index 4430bbf2..e63675f1 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMultipartIdentifier.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFMultipartIdentifier.java @@ -20,9 +20,9 @@ public CFMultipartIdentifier(CFIdentifier... identifiers) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuffer sb = new StringBuffer(); - sb.append(super.Decompile(indent)); + sb.append(super.decompileImpl(indent)); for (int i = 1; i < ids.size(); i++) { sb.append(".").append(ids.get(i).Decompile(0)); } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNestedExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNestedExpression.java index 088a310b..2576b7ea 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNestedExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNestedExpression.java @@ -28,7 +28,7 @@ public byte getType() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append('#'); sb.append(sub.Decompile(0)); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNewExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNewExpression.java index 79320022..e4a7adfc 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNewExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFNewExpression.java @@ -38,7 +38,7 @@ public CFNewExpression(Token _t, CFExpression _component, String _pathPrefix, Ar } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append("new "); if (pathPrefix != null) { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFParsedStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFParsedStatement.java index 6844c7f7..c693cd85 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFParsedStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFParsedStatement.java @@ -52,8 +52,40 @@ public void setToken(Token t) { token = t; } + /** + * Decompile(0) is the form consumers ask for, and they ask repeatedly: a CFLint scan + * runs every rule over every node and several of them decompile the same node, so a + * 3,002-file scan made 1.25M calls of which 74% were repeats. Each one rebuilds the + * whole subtree's text by concatenation, so the repeats are pure waste. Cache that + * one form; a non-zero indent is only ever reached from a parent already rendering + * itself, so it is not worth keying on. + * + * The cached string is only valid while the node is unchanged. Nothing mutates a node + * after the visitor finishes building it, which is before any consumer can hold a + * reference -- but a setter added later that changes rendering must call + * invalidateDecompiled(), or it will hand back the text from before the change. + */ @Override - public abstract String Decompile(int indent); + public String Decompile(int indent) { + if (indent != 0) { + return decompileImpl(indent); + } + String cached = decompiled0; + if (cached == null) { + cached = decompileImpl(0); + decompiled0 = cached; + } + return cached; + } + + /** Drops the cached Decompile(0) text. Call from any setter that changes rendering. */ + protected void invalidateDecompiled() { + decompiled0 = null; + } + + private transient String decompiled0; + + protected abstract String decompileImpl(int indent); @Override public void checkIndirectAssignments(String[] scriptSource) { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFSliceMember.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFSliceMember.java index 1845d402..1bebdb87 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFSliceMember.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFSliceMember.java @@ -47,7 +47,7 @@ public CFExpression getBy() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder("["); sb.append(decompileBound(getFrom())); sb.append(":"); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStringExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStringExpression.java index 220ae0e5..b43d4b88 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStringExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStringExpression.java @@ -23,7 +23,7 @@ public CFStringExpression(Token t) { private static final long serialVersionUID = 233826913909000678L; @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append("'"); for (CFExpression expression : subExpressions) { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructElementExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructElementExpression.java index acde6a58..439a504a 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructElementExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructElementExpression.java @@ -32,7 +32,7 @@ public String toString() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append(key.Decompile(0)); sb.append(':'); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructExpression.java index c4d7b433..bd5ac32f 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFStructExpression.java @@ -46,7 +46,7 @@ public void addElement(CFStructElementExpression _element) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append(ordered ? '[' : '{'); if (elements.isEmpty() && emptyMarker != null) { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFTernaryExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFTernaryExpression.java index 6c58139a..af2fd3c4 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFTernaryExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFTernaryExpression.java @@ -39,7 +39,7 @@ public byte getType() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { // String endChar = ""; // if (_kind == CFSCRIPTLexer.LEFTBRACKET) { // endChar = "]"; diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFUnaryExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFUnaryExpression.java index 28ad1b1d..e0c8bcf4 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFUnaryExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFUnaryExpression.java @@ -46,7 +46,7 @@ public boolean isPrefixop() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); switch (kind) { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFVarDeclExpression.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFVarDeclExpression.java index 254aee1d..ae388bcb 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFVarDeclExpression.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/CFVarDeclExpression.java @@ -42,7 +42,7 @@ public CFVarDeclExpression(Token _t, CFExpression _var, CFExpression _init) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder s = new StringBuilder(Indent(indent)); s.append(staticDecl ? "static " : finalDecl ? "final " : "var "); s.append(var.Decompile(0)); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAbortStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAbortStatement.java index 5e6ffa36..a6cb2bdf 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAbortStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAbortStatement.java @@ -25,7 +25,7 @@ public CFAbortStatement(org.antlr.v4.runtime.Token t, CFExpression _message) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { if (message != null) { return "abort \"" + message + "\""; } else { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAdminStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAdminStatement.java index 66889a88..a6edfbf7 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAdminStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFAdminStatement.java @@ -25,7 +25,7 @@ public CFAdminStatement(org.antlr.v4.runtime.Token t, Map _attributes) } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder("include"); if (hasAttributes()) { DecompileAttributes(sb); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFInterfaceDeclStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFInterfaceDeclStatement.java index 974fac2c..a28ac2b8 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFInterfaceDeclStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFInterfaceDeclStatement.java @@ -18,7 +18,7 @@ public CFInterfaceDeclStatement(Token _t, Map _attr, } @Override - public String Decompile(int indent) { - return super.Decompile(0).replaceFirst("component", "interface"); + protected String decompileImpl(int indent) { + return super.decompileImpl(0).replaceFirst("component", "interface"); } } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFLockStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFLockStatement.java index 83a1752f..edcb149f 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFLockStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFLockStatement.java @@ -44,7 +44,7 @@ public void validate() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { validate(); StringBuilder sb = new StringBuilder(); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFMLFunctionStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFMLFunctionStatement.java index 80e7c281..580eaa68 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFMLFunctionStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFMLFunctionStatement.java @@ -39,7 +39,7 @@ public Token getType() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append(type.getText()); DecompileAttributes(sb); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFParamStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFParamStatement.java index c7cbe9ce..cb33b258 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFParamStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFParamStatement.java @@ -45,7 +45,7 @@ public CFParamStatement(org.antlr.v4.runtime.Token t, Map getAccessTypes() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append(Indent(indent)); sb.append("static {\n"); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFSwitchStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFSwitchStatement.java index c703425c..143bbd6c 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFSwitchStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFSwitchStatement.java @@ -42,7 +42,7 @@ public void checkIndirectAssignments(String[] scriptSource) { } @Override - public String Decompile(int _indent) { + protected String decompileImpl(int _indent) { StringBuilder sb = new StringBuilder(); sb.append("switch ("); sb.append(variable.Decompile(0)); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTagStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTagStatement.java index cc5f88d0..254becbf 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTagStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTagStatement.java @@ -33,7 +33,7 @@ public CFTagStatement(org.antlr.v4.runtime.Token t, Map getExpressions() { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { return FENCE + content + FENCE; } diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThreadStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThreadStatement.java index 492c38f9..481e30f7 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThreadStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThreadStatement.java @@ -44,7 +44,7 @@ public CFThreadStatement(Token _t, Map _attr, CFScri } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append("thread "); DecompileAttributes(sb); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThrowStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThrowStatement.java index 08a5354d..1fd9b4eb 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThrowStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFThrowStatement.java @@ -40,7 +40,7 @@ public CFThrowStatement(org.antlr.v4.runtime.Token t, CFExpression _message) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { if (message != null) { return "throw " + message + ""; } else { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTransactionStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTransactionStatement.java index f25c5873..8e6bf762 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTransactionStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTransactionStatement.java @@ -40,7 +40,7 @@ public CFTransactionStatement(Token _t, Map _attr, C } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append("transaction "); DecompileAttributes(sb); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTryCatchStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTryCatchStatement.java index 1a84cb76..e44d7512 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTryCatchStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFTryCatchStatement.java @@ -69,7 +69,7 @@ public void checkIndirectAssignments(String[] scriptSource) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { validate(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < catchStatements.size(); i++) { diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFWhileStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFWhileStatement.java index a3b0e85e..aba83a8a 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFWhileStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/CFWhileStatement.java @@ -33,7 +33,7 @@ public void checkIndirectAssignments(String[] scriptSource) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { StringBuilder sb = new StringBuilder(); sb.append(Indent(indent)); sb.append("while("); diff --git a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/IncludeStatement.java b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/IncludeStatement.java index a8f71fe9..a6a526d0 100644 --- a/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/IncludeStatement.java +++ b/cfml.parsing/src/main/java/cfml/parsing/cfscript/script/IncludeStatement.java @@ -23,7 +23,7 @@ public IncludeStatement(Token _t, CFExpression _template) { } @Override - public String Decompile(int indent) { + protected String decompileImpl(int indent) { return "include " + template.Decompile(0); }