001package gudusoft.gsqlparser.ir.builder.oracle; 002 003import gudusoft.gsqlparser.TCustomSqlStatement; 004import gudusoft.gsqlparser.TStatementList; 005import gudusoft.gsqlparser.analyzer.v2.AnalyzerV2Config; 006import gudusoft.gsqlparser.ir.bound.BoundProgram; 007import gudusoft.gsqlparser.ir.bound.BoundScope; 008import gudusoft.gsqlparser.ir.bound.EScopeKind; 009import gudusoft.gsqlparser.ir.builder.IBoundIRBuilder; 010 011/** 012 * Oracle PL/SQL implementation of {@link IBoundIRBuilder}. 013 * <p> 014 * Orchestrates three internal phases: 015 * <ol> 016 * <li>Create global scope, iterate statements</li> 017 * <li>Run {@link PlsqlSymbolCollector} (visitor) to extract routines, variables, cursors, calls</li> 018 * <li>Run {@link RoutineRefResolver} to match {@code BoundRoutineRef} to {@code BoundRoutineSymbol}</li> 019 * </ol> 020 * <p> 021 * Leverages TSQLResolver2's already-populated results (auto-invoked by {@code parse()}) 022 * for table/column resolution, and supplements with PL/SQL-specific symbol extraction. 023 */ 024public class OracleBoundIRBuilder implements IBoundIRBuilder { 025 026 @Override 027 public BoundProgram build(TStatementList stmts, AnalyzerV2Config config) { 028 BoundProgram program = new BoundProgram(); 029 030 // Phase 1: Create global scope 031 BoundScope globalScope = new BoundScope(EScopeKind.GLOBAL, null, null); 032 program.addScope(globalScope); 033 034 if (stmts == null || stmts.size() == 0) { 035 return program; 036 } 037 038 // Phase 2: Walk AST with PlsqlSymbolCollector 039 PlsqlSymbolCollector collector = new PlsqlSymbolCollector(program, globalScope, config); 040 for (int i = 0; i < stmts.size(); i++) { 041 TCustomSqlStatement stmt = stmts.get(i); 042 if (stmt != null) { 043 stmt.acceptChildren(collector); 044 } 045 } 046 047 // Phase 3: Resolve routine references 048 RoutineRefResolver.resolve(program); 049 050 return program; 051 } 052}