@@ -22,24 +22,45 @@ import org.utplsql.sqldev.model.parser.Unit
2222
2323class UtplsqlParser {
2424 private String plsql
25- private String plsqlWithoutComments
25+ private String plsqlReduced
2626 private ArrayList<PlsqlObject > objects = new ArrayList<PlsqlObject >
2727 private ArrayList<Unit > units = new ArrayList<Unit >
2828
2929 new (String plsql) {
30- this . plsql = plsql
31- setPlsqlWithoutComments
30+ setPlsql( plsql)
31+ setPlsqlReduced
3232 populateObjects
3333 populateUnits
3434 }
3535
3636 /**
37- * replace multi-line and single-line PL/SQL comments with space
38- * to simplify and improve performance of subsequent regex expressions
37+ * JTextComponents uses one position for EOL (end-of-line),
38+ * even on Windows platforms were it is two characters (CR/LF).
39+ * To simplify position calculations and subsequent regular expressions
40+ * all new lines are replaced with LF on Windows platforms.
3941 */
40- private def setPlsqlWithoutComments () {
42+ private def setPlsql (String plsql ) {
43+ val lineSep = System . getProperty(" line.separator" )
44+ if (lineSep. length > 0 ) {
45+ // replace CR/LF with LF on Windows platforms
46+ this . plsql = plsql. replace(lineSep, " \n " )
47+ } else {
48+ this . plsql = plsql
49+ }
50+ }
51+
52+ /**
53+ * replace the following expressions with space to simplify
54+ * and improve performance of subsequent regular expressions:
55+ * - multi-line PL/SQL comments
56+ * - single-line PL/SQL comments
57+ * - string literals
58+ * the result is not valid PL/SQL anymore, but good enough
59+ * to find PL/SQL objects and units
60+ */
61+ private def setPlsqlReduced () {
4162 val sb = new StringBuffer
42- val p = Pattern . compile(" (/\\ *(.|[\\ r \\ n])*?\\ */)|(--. *\\ r? \\ n)" )
63+ val p = Pattern . compile(" (/\\ *(.|[\\ n])*?\\ */)|(--[^ \\ n] *\\ n)|('([^']|[ \\ n])*?' )" )
4364 val m = p. matcher(plsql)
4465 var pos = 0
4566 while (m. find) {
@@ -59,12 +80,12 @@ class UtplsqlParser {
5980 if (plsql. length > pos) {
6081 sb. append(plsql. substring(pos, plsql. length))
6182 }
62- plsqlWithoutComments = sb. toString
83+ plsqlReduced = sb. toString
6384 }
6485
6586 private def populateObjects () {
66- val p = Pattern . compile(" (?i)(\\ s*)(create(\\ s+or\\ s+replace)?\\ s+(package|type)\\ s+(body\\ s+)?)(.+? )(\\ s+)" )
67- val m = p. matcher(plsqlWithoutComments )
87+ val p = Pattern . compile(" (?i)(\\ s*)(create(\\ s+or\\ s+replace)?\\ s+(package|type)\\ s+(body\\ s+)?)([^ \\ s]+ )(\\ s+)" )
88+ val m = p. matcher(plsqlReduced )
6889 while (m. find) {
6990 val o = new PlsqlObject
7091 o. name = m. group(6 )
@@ -73,8 +94,8 @@ class UtplsqlParser {
7394 }
7495 }
7596 private def populateUnits () {
76- val p = Pattern . compile(" (?i)(\\ s*)(function|procedure)(\\ s+)(.+?)( \\ s+)" )
77- val m = p. matcher(plsqlWithoutComments )
97+ val p = Pattern . compile(" (?i)(\\ s*)(function|procedure)(\\ s+)([^ \\ s\\ (;] +)" )
98+ val m = p. matcher(plsqlReduced )
7899 while (m. find) {
79100 val u = new Unit
80101 u. name = m. group(4 )
@@ -104,7 +125,7 @@ class UtplsqlParser {
104125 }
105126
106127 private def fixName (String name ) {
107- return name. replace(" \" " , " " ). replace( " ; " , " " )
128+ return name. replace(" \" " , " " )
108129 }
109130
110131 def getObjects () {
0 commit comments