8000 Handle leading comments · marcusgram/utPLSQL-SQLDeveloper@018df7b · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 018df7b

Browse files
Handle leading comments
1 parent 243dc17 commit 018df7b

File tree

3 files changed

+94
-19
lines changed

3 files changed

+94
-19
lines changed

sqldev/src/main/java/org/utplsql/sqldev/editor/menu/UtplsqlEditorController.xtend

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class UtplsqlEditorController implements Controller {
4545
val component = view.defaultFocusComponent
4646
if (component instanceof JEditorPane) {
4747
val parser = new UtplsqlParser(component.text)
48-
if (!parser.getUtPlsqlCall(component.caretPosition).empty) {
48+
if (!parser.getPathAt(component.caretPosition).empty) {
4949
action.enabled = true
5050
}
5151
}
@@ -64,7 +64,7 @@ class UtplsqlEditorController implements Controller {
6464
val parser = new UtplsqlParser(component.text)
6565
val position = component.caretPosition
6666
// TODO: open new worksheet and call utPLSQL
67-
logger.fine('''Cursor is at «position». Calling «parser.getUtPlsqlCall(position)»''')
67+
logger.fine('''Cursor is at «position». Calling «parser.getPathAt(position)»''')
6868
}
6969
}
7070
logger.fine ("utPLSQL test started successfully.")

sqldev/src/main/java/org/utplsql/sqldev/parser/UtplsqlParser.xtend

Lines changed: 67 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,65 @@ package org.utplsql.sqldev.parser
1616

1717
import java.util.ArrayList
1818
import java.util.regex.Pattern
19-
import org.utplsql.sqldev.model.parser.Unit
19+
import javax.swing.text.JTextComponent
2020
import org.utplsql.sqldev.model.parser.PlsqlObject
21+
import org.utplsql.sqldev.model.parser.Unit
2122

2223
class UtplsqlParser {
2324
private String plsql
25+
private String plsqlWithoutComments
2426
private ArrayList<PlsqlObject> objects = new ArrayList<PlsqlObject>
2527
private ArrayList<Unit> units = new ArrayList<Unit>
2628

2729
new(String plsql) {
2830
this.plsql = plsql
31+
setPlsqlWithoutComments
2932
populateObjects
3033
populateUnits
3134
}
3235

33-
private def populateObjects() {
34-
val p = Pattern.compile("(?i)(\\s*)(create(\\s+or\\s+replace)?\\s+(package|type)\\s+(body\\s+)?)(.*?)(\\s+)", Pattern.DOTALL)
36+
/**
37+
* replace multi-line and single-line PL/SQL comments with space
38+
* to simplify and improve performance of subsequent regex expressions
39+
*/
40+
private def setPlsqlWithoutComments() {
41+
val sb = new StringBuffer
42+
val p = Pattern.compile("(/\\*(.|[\\r\\n])*?\\*/)|(--.*\\r?\\n)")
3543
val m = p.matcher(plsql)
44+
var pos = 0
45+
while (m.find) {
46+
if (pos < m.start) {
47+
sb.append(plsql.substring(pos, m.start))
48+
}
49+
for (var i=m.start; i<m.end; i++) {
50+
val c = plsql.substring(i, i+1)
51+
if (c == "\n" || c == "\r") {
52+
sb.append(c)
53+
} else {
54+
sb.append(" ")
55+
}
56+
}
57+
pos = m.end
58+
}
59+
if (plsql.length > pos) {
60+
sb.append(plsql.substring(pos, plsql.length))
61+
}
62+
plsqlWithoutComments=sb.toString
63+
}
64+
65+
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)
3668
while (m.find) {
3769
val o = new PlsqlObject
3870
o.name = m.group(6)
3971
o.position = m.start
4072
objects.add(o)
4173
}
4274
}
43-
4475
private def populateUnits() {
45-
val p = Pattern.compile("(?i)(\\s*)(function|procedure)(\\s+)(.*?)(\\s+)", Pattern.DOTALL)
46-
val m = p.matcher(plsql)
76+
val p = Pattern.compile("(?i)(\\s*)(function|procedure)(\\s+)(.+?)(\\s+)")
77+
val m = p.matcher(plsqlWithoutComments)
4778
while (m.find) {
4879
val u = new Unit
4980
u.name = m.group(4)
@@ -55,7 +86,7 @@ class UtplsqlParser {
5586
private def getObjectNameAt(int position) {
5687
var name = ""
5788
for (o : objects) {
58-
if (o.position < position) {
89+
if (o.position <= position) {
5990
name = o.name
6091
}
6192
}
@@ -84,17 +115,43 @@ class UtplsqlParser {
84115
return units
85116
}
86117

87-
def getUtPlsqlCall(int position) {
118+
/**
119+
* gets the utPLSQL path based on the current editor position
120+
*
121+
* @param position the absolute position as used in {@link JTextComponent#getCaretPosition()}
122+
* @return the utPLSQL path
123+
*/
124+
def getPathAt(int position) {
88125
var objectName = getObjectNameAt(position)
89126
if (!objectName.empty) {
90127
var unitName = getUnitNameAt(position)
91128
if (unitName.empty) {
92-
return '''ut.run('«objectName.removeQuotes»');'''
129+
return objectName.removeQuotes
93130
} else {
94-
return '''ut.run('«objectName.removeQuotes».«unitName.removeQuotes»');'''
131+
return '''«objectName.removeQuotes».«unitName.removeQuotes»'''
95132
}
96133
}
97134
return ""
98135
}
136+
137+
/**
138+
* gets the utPLSQL path based on the current editor position
139+
*
140+
* @param line the line as used in SQL Developer, starting with 1
141+
* @param column the column as used in SQL Developer, starting with 1
142+
* @return the utPLSQL path
143+
*/
144+
def getPathAt(int line, int column) {
145+
var lines=0
146+
for (var i=0; i<plsql.length; i++) {
147+
if (plsql.substring(i,i+1) == "\n") {
148+
lines++
149+
if (lines == line - 1) {
150+
return getPathAt(i + column)
151+
}
152+
}
153+
}
154+
throw new RuntimeException('''Line «line» not found.''')
155+
}
99156

100157
}

sqldev/src/test/java/org/utplsql/sqldev/preferences/tests/UtplsqlParserTest.xtend

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,17 @@ class UtplsqlParserTest {
2424
@Test
2525
def testPackage() {
2626
val plsql = '''
27-
--
27+
PROMPT
28+
PROMPT Install utPLSQL test package
29+
PROMPT
30+
31+
/*
32+
* some comment
33+
*/
34+
-- %suite
35+
-- %rollback(manual)
2836
CREATE OR REPLACE PACKAGE pkg IS
37+
-- %test
2938
PROCEDURE p (in_p1 INTEGER);
3039
FUNCTION f (in_p1 INTEGER) RETURN INTEGER;
3140
END pkg;
@@ -37,6 +46,12 @@ class UtplsqlParserTest {
3746
BEGIN
3847
NULL;
3948
END p;
49+
50+
/* comment 1 */
51+
-- comment 2
52+
/* comment 3 */
53+
-- comment 4
54+
4055
FUNCTION "F" (in_p1 INTEGER) RETURN INTEGER IS
4156
BEGIN
4257
RETURN 1;
@@ -60,11 +75,14 @@ class UtplsqlParserTest {
6075
Assert.assertTrue(units.get(0).position < units.get(1).position)
6176
Assert.assertTrue(units.get(1).position < units.get(2).position)
6277
Assert.assertTrue(units.get(2).position < units.get(3).position)
63-
Assert.assertEquals("", parser.getUtPlsqlCall(0))
64-
Assert.assertEquals("ut.run('pkg');", parser.getUtPlsqlCall(4))
65-
Assert.assertEquals("ut.run('pkg.p');", parser.getUtPlsqlCall(66))
66-
Assert.assertEquals("ut.run('pkg.f');", parser.getUtPlsqlCall(67))
67-
Assert.assertEquals('''ut.run('SCOTT.PKG.P');'''.toString, parser.getUtPlsqlCall(185))
68-
Assert.assertEquals('''ut.run('SCOTT.PKG.F');'''.toString, parser.getUtPlsqlCall(260))
78+
Assert.assertEquals("", parser.getPathAt(0))
79+
Assert.assertEquals("", parser.getPathAt(3,6))
80+
Assert.assertEquals("pkg", parser.getPathAt(4,1))
81+
Assert.assertEquals("pkg.p", parser.getPathAt(10,33))
82+
Assert.assertEquals("pkg.f", parser.getPathAt(13,1))
83+
Assert.assertEquals("SCOTT.PKG.P", parser.getPathAt(19,1))
84+
Assert.assertEquals("SCOTT.PKG.P", parser.getPathAt(22,9))
85+
Assert.assertEquals("SCOTT.PKG.F", parser.getPathAt(22,10))
86+
Assert.assertEquals("SCOTT.PKG.F", parser.getPathAt(29,1))
6987
}
7088
}

0 commit comments

Comments
 (0)
0