Skip to content

Commit 1d4bf6e

Browse files
committed
LDEV-5895 AST include java function source
1 parent bf982cb commit 1d4bf6e

5 files changed

Lines changed: 37 additions & 11 deletions

File tree

core/src/main/java/lucee/transformer/bytecode/statement/TagIsland.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void dump(Struct sct) {
5050
stmt.dump(stmtSct);
5151
bodyArr.appendEL(stmtSct);
5252
}
53-
sct.setEL("body", bodyArr);
53+
sct.setEL(KeyConstants._body, bodyArr);
5454
}
5555

5656
// Body interface methods - delegate to inner body

core/src/main/java/lucee/transformer/bytecode/statement/udf/Function.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ public abstract class Function extends StatementBaseNoFinal implements Opcodes,
153153
Literal cachedWithin;
154154
int modifier;
155155
protected JavaFunction jf;
156+
protected String rawJavaSource; // raw Java source for AST round-tripping
156157
// private final Root root;
157158
protected int index = -1;
158159

@@ -614,6 +615,10 @@ public void setJavaFunction(JavaFunction jf) {
614615
this.jf = jf;
615616
}
616617

618+
public void setRawJavaSource(String rawJavaSource) {
619+
this.rawJavaSource = rawJavaSource;
620+
}
621+
617622
public void setIndex(int index) {
618623
this.index = index;
619624
}
@@ -733,6 +738,10 @@ public void dump(Struct sct, String type) {
733738
if (body != null) {
734739
Struct s = new StructImpl(Struct.TYPE_LINKED);
735740
body.dump(s);
741+
// For Java functions, include raw Java source for round-tripping
742+
if (rawJavaSource != null) {
743+
s.setEL(KeyConstants._raw, rawJavaSource);
744+
}
736745
sct.setEL(KeyConstants._body, s);
737746
}
738747
}

core/src/main/java/lucee/transformer/cfml/expression/AbstrCFMLExprTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,7 @@ private FunctionMember getFunctionMember(Data data, final ExprString name, boole
18651865
arg = it.next();
18661866
// Skip hidden args (internal metadata like __filename, __mapping) in ast mode only
18671867
if (data.ast && arg.isHidden()) continue;
1868-
if (arg.getDefaultValue() != null)bif.addArgument(new NamedArgumentImpl(data.factory.createLitString(arg.getName()),
1868+
if (arg.getDefaultValue() != null) bif.addArgument(new NamedArgumentImpl(data.factory.createLitString(arg.getName()),
18691869
data.factory.createLitString(arg.getDefaultValue()), arg.getTypeAsString(), false));
18701870
}
18711871
}

core/src/main/java/lucee/transformer/cfml/script/AbstrCFMLScriptTransformer.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,8 +1217,8 @@ protected final Function closurePart(Data data, String id, int access, int modif
12171217

12181218
// TODO cachedwithin
12191219

1220-
func.setJavaFunction(java(data, body, id, access, modifier, hint, args, attrs, rtnType, output, bufferOutput, displayName, description, returnFormat, secureJson,
1221-
verifyClient, localMode));
1220+
java(data, func, body, id, access, modifier, hint, args, attrs, rtnType, output, bufferOutput, displayName, description, returnFormat, secureJson,
1221+
verifyClient, localMode);
12221222
}
12231223
else {
12241224
func.register(data.page);
@@ -1261,7 +1261,7 @@ private Attribute[] remove(Attribute[] attrs, String name) {
12611261
return list.toArray(new Attribute[list.size()]);
12621262
}
12631263

1264-
private JavaFunction java(Data data, Body body, String functionName, int access, int modifier, String hint, ArrayList<Argument> args, Attribute[] attrs, String rtnType,
1264+
private void java(Data data, Function func, Body body, String functionName, int access, int modifier, String hint, ArrayList<Argument> args, Attribute[] attrs, String rtnType,
12651265
Boolean output, Boolean bufferOutput, String displayName, String description, int returnFormat, Boolean secureJson, Boolean verifyClient, int localMode)
12661266
throws TemplateException {
12671267

@@ -1286,22 +1286,25 @@ private JavaFunction java(Data data, Body body, String functionName, int access,
12861286
SourceCode sc = data.srcCode;
12871287
Position start = sc.getPosition();
12881288
findTheEnd(data, start.line);
1289+
Position end = sc.getPosition();
1290+
String javaCode = sc.substring(start.pos, end.pos - start.pos);
12891291

1290-
// In AST mode without PageSource, we can't compile - just return null
1292+
// Always store raw Java source for AST round-tripping
1293+
func.setRawJavaSource(javaCode);
1294+
1295+
// In AST mode without PageSource, we can't compile - just store raw source
12911296
// The function body has already been parsed past by findTheEnd
12921297
if (ps == null) {
1293-
return null;
1298+
return;
12941299
}
1295-
1296-
Position end = sc.getPosition();
1297-
String javaCode = sc.substring(start.pos, end.pos - start.pos);
12981300
try {
12991301
String id = data.page.registerJavaFunctionName(functionName);
13001302
lucee.commons.lang.compiler.SourceCode _sc = fd.createSourceCode(ps, javaCode, id, functionName, access, modifier, hint, args, output, bufferOutput, displayName,
13011303
description, returnFormat, secureJson, verifyClient, localMode);
13021304
JavaFunction jf = new JavaFunction(ps, _sc, CompilerFactory.getInstance().compile((ConfigPro) data.config, _sc));
13031305

1304-
return jf;
1306+
func.setJavaFunction(jf);
1307+
return;
13051308
}
13061309
catch (JavaCompilerException e) {
13071310
Throwable cause = e.getCause();

test/tickets/LDEV5985.cfc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,20 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="ast" {
2828
expect( funcDecl.type ).toBe( "FunctionDeclaration" );
2929
});
3030

31+
it( "should preserve raw Java source in AST body for round-tripping", function() {
32+
var code = fileRead( variables.testDir & "javaFunction.cfm" );
33+
var ast = astFromString( code );
34+
35+
// Find the function declaration
36+
var funcDecl = findNodeByType( ast, "FunctionDeclaration" );
37+
expect( isNull( funcDecl ) ).toBeFalse( "FunctionDeclaration should be present" );
38+
39+
// The body should contain the raw Java source for round-tripping
40+
expect( funcDecl ).toHaveKey( "body" );
41+
expect( funcDecl.body ).toHaveKey( "raw" );
42+
expect( funcDecl.body.raw ).toInclude( "return i*2" );
43+
});
44+
3145
});
3246

3347
}

0 commit comments

Comments
 (0)