@@ -22,24 +22,45 @@ import org.utplsql.sqldev.model.parser.Unit
22
22
23
23
class UtplsqlParser {
24
24
private String plsql
25
- private String plsqlWithoutComments
25
+ private String plsqlReduced
26
26
private ArrayList<PlsqlObject > objects = new ArrayList<PlsqlObject >
27
27
private ArrayList<Unit > units = new ArrayList<Unit >
28
28
29
29
new (String plsql) {
30
- this . plsql = plsql
31
- setPlsqlWithoutComments
30
+ setPlsql( plsql)
31
+ setPlsqlReduced
32
32
populateObjects
33
33
populateUnits
34
34
}
35
35
36
36
/**
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.
39
41
*/
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 () {
41
62
val sb = new StringBuffer
42
- val p = Pattern . compile(" (/\\ *(.|[\\ r \\ n])*?\\ */)|(--. *\\ r? \\ n)" )
63
+ val p = Pattern . compile(" (/\\ *(.|[\\ n])*?\\ */)|(--[^ \\ n] *\\ n)|('([^']|[ \\ n])*?' )" )
43
64
val m = p. matcher(plsql)
44
65
var pos = 0
45
66
while (m. find) {
@@ -59,12 +80,12 @@ class UtplsqlParser {
59
80
if (plsql. length > pos) {
60
81
sb. append(plsql. substring(pos, plsql. length))
61
82
}
62
- plsqlWithoutComments = sb. toString
83
+ plsqlReduced = sb. toString
63
84
}
64
85
65
86
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 )
68
89
while (m. find) {
69
90
val o = new PlsqlObject
70
91
o. name = m. group(6 )
@@ -73,8 +94,8 @@ class UtplsqlParser {
73
94
}
74
95
}
75
96
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 )
78
99
while (m. find) {
79
100
val u = new Unit
80
101
u. name = m. group(4 )
@@ -104,7 +125,7 @@ class UtplsqlParser {
104
125
}
105
126
106
127
private def fixName (String name ) {
107
- return name. replace(" \" " , " " ). replace( " ; " , " " )
128
+ return name. replace(" \" " , " " )
108
129
}
109
130
110
131
def getObjects () {
0 commit comments