import RegExpParser from './regEx/RegExParser' ; import DocFormater from './docFormater' ; import './definition' ; interface PLSQLInfos { packageName : string ; spec ? : PLSQLSymbol ; body ? : PLSQLSymbol ; } interface PLSQLRange { start : number ; end : number ; } export default class PlSqlParser { public static initParser ( symbolsComment ? ) { this . getParser ( ) . initParser ( symbolsComment ) ; } public static parseFile ( fileName , content ) { const root = this . getParser ( ) . getSymbols ( content ) ; if ( root ) root . fileName = fileName ; return root ; } public static parseParams ( symbol ) { return this . getParser ( ) . parseParams ( symbol ) ; } public static findSymbolByNameOffset ( symbols , name , offset = 0 , recursive = true ) { const lower = name . toLowerCase ( ) ; return this . findSymbol ( symbols , symbol => ( symbol . name . toLowerCase ( ) === lower && symbol . offset >= offset ) , recursive ) ; } public static findSymbolNearOffset ( symbols , offset , recursive = true ) { let nearSymbol ; this . findSymbol ( symbols , ( symbol ) => { const result = ( symbol . offset > offset ) ; if ( ! result ) nearSymbol = symbol ; return result ; } , recursive ) ; return nearSymbol ; } public static findSymbolByNameKind ( symbols , name , kind , recursive = true ) { const lower = name . toLowerCase ( ) , kindArray = Array . isArray ( kind ) ? kind : [ kind ] ; return this . findSymbol ( symbols , symbol => ( symbol . name . toLowerCase ( ) === lower && kindArray . includes ( symbol . kind ) ) , recursive ) ; } public static getSymbolsDeclaration ( root ) { const allSymbols = [ ] ; this . forEachSymbol ( root . symbols , symbol => { if ( ! [ PLSQLSymbolKind . function , PLSQLSymbolKind . procedure , PLSQLSymbolKind . packageBody , PLSQLSymbolKind . packageSpec ] . includes ( symbol . kind ) ) allSymbols . push ( symbol ) ; } ) ; return allSymbols ; } public static switchSymbol ( symbol ) { let kind ; if ( symbol . kind === PLSQLSymbolKind . packageSpec ) kind = PLSQLSymbolKind . packageBody ; else if ( symbol . kind === PLSQLSymbolKind . packageBody ) kind = PLSQLSymbolKind . packageSpec ; else return symbol ; return this . findSymbolByNameKind ( symbol . root . symbols , symbol . name , kind , false ) ; } public static switchSymbolKind ( symbolKind ) { if ( symbolKind === PLSQLSymbolKind . functionSpec ) return PLSQLSymbolKind . function ; else if ( symbolKind === PLSQLSymbolKind . function ) return PLSQLSymbolKind . functionSpec ; else if ( symbolKind === PLSQLSymbolKind . procedureSpec ) return PLSQLSymbolKind . procedure ; else if ( symbolKind === PLSQLSymbolKind . procedure ) return PLSQLSymbolKind . procedureSpec ; else if ( symbolKind === PLSQLSymbolKind . packageSpec ) return PLSQLSymbolKind . packageBody ; else if ( symbolKind === PLSQLSymbolKind . packageBody ) return PLSQLSymbolKind . packageSpec ; else return symbolKind ; } public static isSymbolSpec ( symbol ) { return [ PLSQLSymbolKind . packageSpec , PLSQLSymbolKind . procedureSpec , PLSQLSymbolKind . functionSpec ] . includes ( symbol . kind ) ; } public static getSymbols ( fileName , content ) { return this . getSymbolsFromRoot ( this . parseFile ( fileName , content ) ) ; } public static getSymbolsFromRoot ( root ) { const allSymbols = [ ] ; this . forEachSymbol ( root . symbols , symbol => { allSymbols . push ( symbol ) ; } ) ; return allSymbols ; } public static getSymbolFileName ( symbol ) { while ( symbol . parent ) symbol = symbol . parent ; return symbol . root . fileName ; } public static formatSymbolDocumentation ( symbol , useJSDoc ) { if ( symbol . documentation && ! symbol . formatedDoc ) { symbol . formatedDoc = { text : DocFormater . format ( symbol . documentation , useJSDoc ) , isMarkdown : useJSDoc } ; } } private static forEachSymbol ( symbols , fn ) { if ( symbols ) symbols . forEach ( symbol => { fn . apply ( this , [ symbol ] ) ; this . forEachSymbol ( symbol . symbols , fn ) ; } ) ; } private static findSymbol ( symbols , fn , recursive = true ) { if ( ! symbols ) return ; let result ; for ( let symbol of symbols ) { if ( fn . apply ( this , [ symbol ] ) ) return symbol ; if ( recursive ) { result = this . findSymbol ( symbol . symbols , fn ) ; if ( result ) return result ; } } } private static getParser ( ) { return RegExpParser ; } }