Skip to content

Commit a75c0ca

Browse files
committed
com.alibaba.qlexpress4.Express4RunnerTest#scripTimeoutTest unit test with timeout
1 parent 10a13c1 commit a75c0ca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+4617
-3731
lines changed

src/main/java/com/alibaba/qlexpress4/Express4Runner.java

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -229,21 +229,23 @@ public Set<String> getOutVarNames(String script) {
229229
VariableDetector.Context context;
230230
try {
231231
context = variableDetector.detect(programNode);
232-
} catch (Exception e) {
232+
}
233+
catch (Exception e) {
233234
throw new RuntimeException("Failed to detect variables", e);
234235
}
235-
236+
236237
// Get all variable reads (external variables are those that are read but not declared)
237238
Set<String> allVars = context.getAllVariableNames();
238-
239+
239240
// Remove declared variables (local variables)
240-
for (com.alibaba.qlexpress4.parser.visitor.VariableDetector.VariableDeclaration decl : context.getVariableDeclarations()) {
241+
for (com.alibaba.qlexpress4.parser.visitor.VariableDetector.VariableDeclaration decl : context
242+
.getVariableDeclarations()) {
241243
allVars.remove(decl.getVariableName());
242244
}
243-
245+
244246
return allVars;
245247
}
246-
248+
247249
/**
248250
* Get external variable attribute access paths referenced by the script.
249251
*
@@ -256,15 +258,17 @@ public Set<List<String>> getOutVarAttrs(String script) {
256258
VariableDetector.Context context;
257259
try {
258260
context = variableDetector.detect(programNode);
259-
} catch (Exception e) {
261+
}
262+
catch (Exception e) {
260263
throw new RuntimeException("Failed to detect variable attributes", e);
261264
}
262-
265+
263266
// Convert variable accesses to attribute paths
264267
// Note: This is a simplified implementation - the original implementation
265268
// handles complex cases like field access chains
266269
Set<List<String>> outVarAttrs = new java.util.HashSet<>();
267-
for (com.alibaba.qlexpress4.parser.visitor.VariableDetector.VariableAccess access : context.getVariableReads()) {
270+
for (com.alibaba.qlexpress4.parser.visitor.VariableDetector.VariableAccess access : context
271+
.getVariableReads()) {
268272
if (access.getType() == com.alibaba.qlexpress4.parser.visitor.VariableDetector.VariableAccessType.READ) {
269273
List<String> path = new java.util.ArrayList<>();
270274
path.add(access.getVariableName());
@@ -273,7 +277,7 @@ public Set<List<String>> getOutVarAttrs(String script) {
273277
}
274278
return outVarAttrs;
275279
}
276-
280+
277281
/**
278282
* Get external functions (those that must be provided via context) referenced by the script.
279283
*
@@ -286,17 +290,19 @@ public Set<String> getOutFunctions(String script) {
286290
List<com.alibaba.qlexpress4.parser.visitor.FunctionExtractor.FunctionCall> functionCalls;
287291
try {
288292
functionCalls = functionExtractor.extract(programNode);
289-
} catch (Exception e) {
293+
}
294+
catch (Exception e) {
290295
throw new RuntimeException("Failed to extract functions", e);
291296
}
292-
297+
293298
// Filter for direct calls (external functions)
294299
return functionCalls.stream()
295-
.filter(fc -> fc.getType() == com.alibaba.qlexpress4.parser.visitor.FunctionExtractor.FunctionCallType.DIRECT_CALL)
296-
.map(com.alibaba.qlexpress4.parser.visitor.FunctionExtractor.FunctionCall::getName)
297-
.collect(Collectors.toSet());
300+
.filter(fc -> fc
301+
.getType() == com.alibaba.qlexpress4.parser.visitor.FunctionExtractor.FunctionCallType.DIRECT_CALL)
302+
.map(com.alibaba.qlexpress4.parser.visitor.FunctionExtractor.FunctionCall::getName)
303+
.collect(Collectors.toSet());
298304
}
299-
305+
300306
/**
301307
* Get the expression trace trees for the script without executing it.
302308
*
@@ -307,8 +313,9 @@ public List<TracePointTree> getExpressionTracePoints(String script) {
307313
ProgramNode programNode = parseToSyntaxTree(script);
308314
TraceGenerator traceGenerator = new TraceGenerator();
309315
try {
310-
((com.alibaba.qlexpress4.parser.ast.ASTNode) programNode).accept(traceGenerator, null);
311-
} catch (Exception e) {
316+
((com.alibaba.qlexpress4.parser.ast.ASTNode)programNode).accept(traceGenerator, null);
317+
}
318+
catch (Exception e) {
312319
throw new RuntimeException("Failed to generate trace points", e);
313320
}
314321
return traceGenerator.getTracePoints();
@@ -335,13 +342,14 @@ public void addOrReplaceMacro(String name, String macroScript) {
335342

336343
private MacroDefine parseMacroDefine(String name, String macroScript) {
337344
ProgramNode macroProgram = parseToSyntaxTree(macroScript);
338-
345+
339346
try {
340347
// Compile the macro using the new AST compiler
341-
QLambdaDefinitionInner macroLambdaDef = (QLambdaDefinitionInner) ASTCompiler.compile(macroProgram, operatorManager);
348+
QLambdaDefinitionInner macroLambdaDef =
349+
(QLambdaDefinitionInner)ASTCompiler.compile(macroProgram, operatorManager);
342350
QLInstruction[] macroInstructionsArray = macroLambdaDef.getInstructions();
343351
List<QLInstruction> macroInstructions = java.util.Arrays.asList(macroInstructionsArray);
344-
352+
345353
// Determine if the last statement is an expression
346354
// The new AST's ProgramNode has a list of statements
347355
boolean lastStmtExpress = false;
@@ -351,9 +359,10 @@ private MacroDefine parseMacroDefine(String name, String macroScript) {
351359
// Check if the last statement is an expression (implements ExpressionNode)
352360
lastStmtExpress = lastStmt instanceof com.alibaba.qlexpress4.parser.ast.ExpressionNode;
353361
}
354-
362+
355363
return new MacroDefine(macroInstructions, lastStmtExpress);
356-
} catch (Exception e) {
364+
}
365+
catch (Exception e) {
357366
throw new RuntimeException("Failed to parse macro definition: " + name, e);
358367
}
359368
}
@@ -564,7 +573,8 @@ public Object invoke(Object obj, Object[] args)
564573
});
565574
}
566575

567-
public ProgramNode parseToSyntaxTree(String script) throws QLSyntaxException {
576+
public ProgramNode parseToSyntaxTree(String script)
577+
throws QLSyntaxException {
568578
try {
569579
return SyntaxTreeFactory.buildTree(script,
570580
operatorManager,
@@ -575,32 +585,32 @@ public ProgramNode parseToSyntaxTree(String script) throws QLSyntaxException {
575585
initOptions.getSelectorStart(),
576586
initOptions.getSelectorEnd(),
577587
initOptions.isStrictNewLines());
578-
} catch (com.alibaba.qlexpress4.parser.parser.QLexpressParser.ParseException e) {
588+
}
589+
catch (com.alibaba.qlexpress4.parser.parser.QLexpressParser.ParseException e) {
579590
// Convert ParseException to QLSyntaxException
580591
// position is -1 (unknown) since ParseException doesn't provide character offset
581-
throw QLException.reportScannerErr(
582-
script,
592+
throw QLException.reportScannerErr(script,
583593
-1,
584594
e.getLine(),
585595
e.getColumn(),
586-
"", // lexeme is not available from ParseException
596+
"", // lexeme is not available from ParseException
587597
QLErrorCodes.SYNTAX_ERROR.name(),
588598
e.getMessage());
589599
}
590600
}
591-
601+
592602
public void check(String script, CheckOptions checkOptions)
593603
throws QLSyntaxException {
594604
// 1. Parse syntax tree (reuse existing parseToSyntaxTree logic)
595605
ProgramNode programNode = parseToSyntaxTree(script);
596-
606+
597607
// 2. Create ScriptChecker and pass validation configuration and script content
598608
ScriptChecker scriptChecker = new ScriptChecker(checkOptions, script);
599-
609+
600610
// 3. Traverse syntax tree and perform operator validation during traversal
601611
scriptChecker.check(programNode);
602612
}
603-
613+
604614
public void check(String script)
605615
throws QLSyntaxException {
606616
check(script, CheckOptions.DEFAULT_OPTIONS);
@@ -645,7 +655,7 @@ public QCompileCache parseToDefinitionWithCache(String script) {
645655
public Value loadField(Object object, String fieldName) {
646656
return reflectLoader.loadField(object, fieldName, true, PureErrReporter.INSTANCE);
647657
}
648-
658+
649659
/**
650660
* Clear the compilation cache.
651661
* This method clears the cache that stores compiled scripts for performance optimization.
@@ -672,20 +682,23 @@ private Future<QCompileCache> getParseFuture(String script) {
672682

673683
private QCompileCache parseDefinition(String script) {
674684
ProgramNode programNode = parseToSyntaxTree(script);
675-
685+
676686
try {
677687
if (initOptions.isTraceExpression()) {
678688
// Compile with trace points
679689
ASTCompiler.CompilationResult result = ASTCompiler.compileWithTrace(programNode, operatorManager);
680690
return new QCompileCache(result.getLambdaDefinition(), result.getTracePoints());
681-
} else {
691+
}
692+
else {
682693
// Compile without trace points
683-
QLambdaDefinitionInner qLambdaDefinition = (QLambdaDefinitionInner) ASTCompiler.compile(programNode, operatorManager);
694+
QLambdaDefinitionInner qLambdaDefinition =
695+
(QLambdaDefinitionInner)ASTCompiler.compile(programNode, operatorManager);
684696
return new QCompileCache(qLambdaDefinition, Collections.emptyList());
685697
}
686-
} catch (Exception e) {
698+
}
699+
catch (Exception e) {
687700
if (e instanceof QLSyntaxException) {
688-
throw (QLSyntaxException) e;
701+
throw (QLSyntaxException)e;
689702
}
690703
throw new RuntimeException("Compilation failed", e);
691704
}

src/main/java/com/alibaba/qlexpress4/parser/ASTCompiler.java

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
* @author QLExpress Team
3232
*/
3333
public class ASTCompiler {
34-
34+
3535
private ASTCompiler() {
3636
// Static utility class
3737
}
38-
38+
3939
/**
4040
* Compiles a ProgramNode to a QLambdaDefinition.
4141
* <p>
@@ -48,30 +48,30 @@ private ASTCompiler() {
4848
* @throws Exception if compilation fails
4949
*/
5050
public static QLambdaDefinition compile(ProgramNode programNode, OperatorManager operatorManager)
51-
throws Exception {
51+
throws Exception {
5252
if (programNode == null) {
5353
throw new IllegalArgumentException("programNode cannot be null");
5454
}
5555
if (operatorManager == null) {
5656
throw new IllegalArgumentException("operatorManager cannot be null");
5757
}
58-
58+
5959
// Create instruction generator
6060
InstructionGenerator generator = new InstructionGenerator(operatorManager);
61-
61+
6262
// Generate instructions from AST
63-
GenerationResult result = ((ASTNode) programNode).accept(generator, new GenerationContext());
64-
63+
GenerationResult result = ((ASTNode)programNode).accept(generator, new GenerationContext());
64+
6565
// Extract instructions
6666
List<QLInstruction> instructions = result.getInstructions();
67-
67+
6868
// Calculate max stack size
6969
int maxStackSize = calculateMaxStackSize(instructions);
70-
70+
7171
// Create main lambda definition
7272
return new QLambdaDefinitionInner("main", instructions, Collections.emptyList(), maxStackSize);
7373
}
74-
74+
7575
/**
7676
* Compiles a ProgramNode to a QLambdaDefinition with trace points.
7777
* <p>
@@ -83,25 +83,24 @@ public static QLambdaDefinition compile(ProgramNode programNode, OperatorManager
8383
* @return A CompilationResult containing the lambda definition and trace points
8484
* @throws Exception if compilation fails
8585
*/
86-
public static CompilationResult compileWithTrace(ProgramNode programNode,
87-
OperatorManager operatorManager)
88-
throws Exception {
86+
public static CompilationResult compileWithTrace(ProgramNode programNode, OperatorManager operatorManager)
87+
throws Exception {
8988
if (programNode == null) {
9089
throw new IllegalArgumentException("programNode cannot be null");
9190
}
9291
if (operatorManager == null) {
9392
throw new IllegalArgumentException("operatorManager cannot be null");
9493
}
95-
94+
9695
// Compile to lambda definition
9796
QLambdaDefinition lambdaDefinition = compile(programNode, operatorManager);
98-
97+
9998
// Generate trace points
10099
List<TracePointTree> tracePoints = generateTracePoints(programNode);
101-
100+
102101
return new CompilationResult(lambdaDefinition, tracePoints);
103102
}
104-
103+
105104
/**
106105
* Generates execution trace points from a ProgramNode.
107106
*
@@ -112,19 +111,20 @@ public static List<TracePointTree> generateTracePoints(ProgramNode programNode)
112111
if (programNode == null) {
113112
throw new IllegalArgumentException("programNode cannot be null");
114113
}
115-
114+
116115
TraceGenerator traceGenerator = new TraceGenerator();
117116
try {
118-
((ASTNode) programNode).accept(traceGenerator, null);
119-
} catch (Exception e) {
117+
((ASTNode)programNode).accept(traceGenerator, null);
118+
}
119+
catch (Exception e) {
120120
// Trace generation should not fail compilation
121121
// Return empty list on error
122122
return Collections.emptyList();
123123
}
124-
124+
125125
return traceGenerator.getTracePoints();
126126
}
127-
127+
128128
/**
129129
* Calculates the maximum stack size needed for a list of instructions.
130130
* <p>
@@ -139,7 +139,7 @@ private static int calculateMaxStackSize(List<QLInstruction> instructions) {
139139
// This matches the heuristic used in the original QvmInstructionVisitor
140140
return Math.max(10, instructions.size() / 2 + 5);
141141
}
142-
142+
143143
/**
144144
* Compilation result containing both the lambda definition and trace points.
145145
* <p>
@@ -148,18 +148,18 @@ private static int calculateMaxStackSize(List<QLInstruction> instructions) {
148148
*/
149149
public static class CompilationResult {
150150
private final QLambdaDefinition lambdaDefinition;
151+
151152
private final List<TracePointTree> tracePoints;
152-
153-
public CompilationResult(QLambdaDefinition lambdaDefinition,
154-
List<TracePointTree> tracePoints) {
153+
154+
public CompilationResult(QLambdaDefinition lambdaDefinition, List<TracePointTree> tracePoints) {
155155
this.lambdaDefinition = lambdaDefinition;
156156
this.tracePoints = tracePoints;
157157
}
158-
158+
159159
public QLambdaDefinition getLambdaDefinition() {
160160
return lambdaDefinition;
161161
}
162-
162+
163163
public List<TracePointTree> getTracePoints() {
164164
return tracePoints;
165165
}

0 commit comments

Comments
 (0)