redcar-javamateview 0.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +34 -0
- data/README +58 -0
- data/Rakefile +94 -0
- data/lib/javamateview.rb +41 -0
- data/lib/javamateview/example.rb +334 -0
- data/lib/javamateview/jar/java-mateview.jar +0 -0
- data/lib/javamateview/jcodings.jar +0 -0
- data/lib/javamateview/jdom.jar +0 -0
- data/lib/javamateview/joni.jar +0 -0
- data/spec/onig/match_spec.rb +50 -0
- data/spec/parsing/dynamic_parsing_spec.rb +172 -0
- data/spec/parsing/static_parsing_spec.rb +476 -0
- data/spec/spec_helper.rb +33 -0
- data/src/com/redcareditor/mate/Bundle.java +81 -0
- data/src/com/redcareditor/mate/DoublePattern.java +89 -0
- data/src/com/redcareditor/mate/Grammar.java +129 -0
- data/src/com/redcareditor/mate/IAnnotationAreaListener.java +7 -0
- data/src/com/redcareditor/mate/IGrammarListener.java +5 -0
- data/src/com/redcareditor/mate/IncludePattern.java +10 -0
- data/src/com/redcareditor/mate/LineNumberRulerColumn.java +922 -0
- data/src/com/redcareditor/mate/Marker.java +22 -0
- data/src/com/redcareditor/mate/MateText.java +697 -0
- data/src/com/redcareditor/mate/ParseThunk.java +71 -0
- data/src/com/redcareditor/mate/Parser.java +627 -0
- data/src/com/redcareditor/mate/ParserScheduler.java +237 -0
- data/src/com/redcareditor/mate/Pattern.java +152 -0
- data/src/com/redcareditor/mate/RangeSet.java +91 -0
- data/src/com/redcareditor/mate/Scanner.java +178 -0
- data/src/com/redcareditor/mate/Scope.java +534 -0
- data/src/com/redcareditor/mate/ScopeMatcher.java +162 -0
- data/src/com/redcareditor/mate/SharedTextColors.java +110 -0
- data/src/com/redcareditor/mate/SinglePattern.java +20 -0
- data/src/com/redcareditor/mate/WhitespaceCharacterPainter.java +395 -0
- data/src/com/redcareditor/mate/colouring/Colourer.java +16 -0
- data/src/com/redcareditor/mate/colouring/swt/MarginPaintListener.java +62 -0
- data/src/com/redcareditor/mate/colouring/swt/SwtColourer.java +501 -0
- data/src/com/redcareditor/mate/document/MateDocument.java +15 -0
- data/src/com/redcareditor/mate/document/MateTextFactory.java +9 -0
- data/src/com/redcareditor/mate/document/MateTextLocation.java +8 -0
- data/src/com/redcareditor/mate/document/MateTextLocationComparator.java +17 -0
- data/src/com/redcareditor/mate/document/MateTextRange.java +18 -0
- data/src/com/redcareditor/mate/document/swt/SwtMateDocument.java +143 -0
- data/src/com/redcareditor/mate/document/swt/SwtMateTextLocation.java +88 -0
- data/src/com/redcareditor/mate/document/swt/SwtMateTextRange.java +92 -0
- data/src/com/redcareditor/mate/document/swt/SwtScopePositionUpdater.java +90 -0
- data/src/com/redcareditor/mate/undo/MateTextUndoManager.java +11 -0
- data/src/com/redcareditor/mate/undo/swt/SwtMateTextUndoManager.java +166 -0
- data/src/com/redcareditor/onig/Match.java +212 -0
- data/src/com/redcareditor/onig/NullMatch.java +57 -0
- data/src/com/redcareditor/onig/NullRx.java +29 -0
- data/src/com/redcareditor/onig/Range.java +45 -0
- data/src/com/redcareditor/onig/Rx.java +167 -0
- data/src/com/redcareditor/plist/Dict.java +119 -0
- data/src/com/redcareditor/plist/PlistNode.java +52 -0
- data/src/com/redcareditor/plist/PlistPropertyLoader.java +44 -0
- data/src/com/redcareditor/theme/ScopeSelector.java +39 -0
- data/src/com/redcareditor/theme/Theme.java +122 -0
- data/src/com/redcareditor/theme/ThemeManager.java +41 -0
- data/src/com/redcareditor/theme/ThemeSetting.java +78 -0
- data/src/com/redcareditor/util/FileUtility.java +64 -0
- data/src/com/redcareditor/util/SingleLineFormatter.java +11 -0
- data/src/com/redcareditor/util/swt/ColourUtil.java +56 -0
- data/src/ruby/java-mateview.rb +68 -0
- data/test/com/redcareditor/mate/BundleTest.java +33 -0
- data/test/com/redcareditor/mate/EmptyRangeSetTest.java +27 -0
- data/test/com/redcareditor/mate/FilledRangeSetTest.java +82 -0
- data/test/com/redcareditor/mate/GrammarTest.java +158 -0
- data/test/com/redcareditor/mate/MateTextTest.java +35 -0
- data/test/com/redcareditor/mate/ScopeMatcherMatchingTest.java +55 -0
- data/test/com/redcareditor/mate/ScopeMatcherRankingTest.java +40 -0
- data/test/com/redcareditor/onig/RxTest.java +54 -0
- data/test/com/redcareditor/plist/DictTest.java +33 -0
- data/test/com/redcareditor/theme/RailsCastThemeTest.java +37 -0
- data/test/com/redcareditor/theme/ScopeSelectorTest.java +38 -0
- data/test/com/redcareditor/theme/ThemeManagerTest.java +29 -0
- data/test/com/redcareditor/util/swt/ColourUtilTest.java +17 -0
- metadata +142 -0
@@ -0,0 +1,178 @@
|
|
1
|
+
package com.redcareditor.mate;
|
2
|
+
|
3
|
+
import java.util.ArrayList;
|
4
|
+
import java.util.Iterator;
|
5
|
+
import java.util.logging.Logger;
|
6
|
+
import java.util.logging.Handler;
|
7
|
+
import java.util.logging.ConsoleHandler;
|
8
|
+
import java.util.logging.Level;
|
9
|
+
|
10
|
+
import com.redcareditor.onig.Match;
|
11
|
+
import com.redcareditor.onig.Rx;
|
12
|
+
|
13
|
+
public class Scanner implements Iterable<Marker> {
|
14
|
+
public static int MAX_LINE_LENGTH = 500;
|
15
|
+
private Scope currentScope;
|
16
|
+
public int position;
|
17
|
+
public String line;
|
18
|
+
public int lineLength;
|
19
|
+
public int lineIx;
|
20
|
+
public Logger logger;
|
21
|
+
|
22
|
+
public void setCurrentScope(Scope scope) {
|
23
|
+
this.currentScope = scope;
|
24
|
+
}
|
25
|
+
|
26
|
+
public Scope getCurrentScope() {
|
27
|
+
return this.currentScope;
|
28
|
+
}
|
29
|
+
|
30
|
+
public Scanner(Scope startScope, String line, int lineIx) {
|
31
|
+
this.currentScope = startScope;
|
32
|
+
this.line = line;
|
33
|
+
this.lineIx = lineIx;
|
34
|
+
this.lineLength = line.getBytes().length;
|
35
|
+
this.position = 0;
|
36
|
+
logger = Logger.getLogger("JMV.Scanner");
|
37
|
+
logger.setUseParentHandlers(false);
|
38
|
+
for (Handler h : logger.getHandlers()) {
|
39
|
+
logger.removeHandler(h);
|
40
|
+
}
|
41
|
+
logger.addHandler(MateText.consoleHandler());
|
42
|
+
}
|
43
|
+
|
44
|
+
public Match scanForMatch(int from, Pattern p) {
|
45
|
+
int maxLength = Math.min(MAX_LINE_LENGTH, this.lineLength);
|
46
|
+
Match match = null;
|
47
|
+
if (p instanceof SinglePattern) {
|
48
|
+
SinglePattern sp = (SinglePattern) p;
|
49
|
+
if (sp.match.regex != null) {
|
50
|
+
match = sp.match.search(this.line, from, maxLength);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
else if (p instanceof DoublePattern) {
|
54
|
+
if (((DoublePattern) p).begin.regex != null) {
|
55
|
+
match = ((DoublePattern) p).begin.search(this.line, from, maxLength);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
return match;
|
59
|
+
}
|
60
|
+
|
61
|
+
public Marker findNextMarker() {
|
62
|
+
if (position >= this.lineLength)
|
63
|
+
return null;
|
64
|
+
//logger.info(String.format("scanning: '%s' from %d to %d [%d] (current_scope is %s)", this.line.replaceAll("\n", ""), this.position, this.lineLength, this.line.length(), currentScope.name));
|
65
|
+
if (position > MAX_LINE_LENGTH)
|
66
|
+
return null;
|
67
|
+
Marker bestMarker = null;
|
68
|
+
int newLength;
|
69
|
+
boolean isCloseMatch = false;
|
70
|
+
Rx closingRegex = currentScope.closingRegex;
|
71
|
+
if (closingRegex != null && closingRegex.usable()) {
|
72
|
+
//logger.info(String.format("closing regex: '%s'", closingRegex.pattern));
|
73
|
+
Match match = closingRegex.search(this.line, this.position, this.lineLength);
|
74
|
+
if (match != null &&
|
75
|
+
!(match.getCapture(0).start == currentScope.getStart().getLineOffset() &&
|
76
|
+
currentScope.getStart().getLine() == this.lineIx)
|
77
|
+
) {
|
78
|
+
//logger.info(String.format("closing match: %s (%d-%d)", this.currentScope.name, match.getCapture(0).start, match.getCapture(0).end));
|
79
|
+
Marker newMarker = new Marker();
|
80
|
+
newMarker.pattern = this.currentScope.pattern;
|
81
|
+
newMarker.match = match;
|
82
|
+
newMarker.from = match.getCapture(0).start;
|
83
|
+
newMarker.isCloseScope = true;
|
84
|
+
bestMarker = newMarker;
|
85
|
+
isCloseMatch = true;
|
86
|
+
} else {
|
87
|
+
// logger.info(String.format("no close match"));
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
//logger.info(String.format(" scanning for %d patterns", ((DoublePattern) currentScope.pattern).patterns.size()));
|
92
|
+
if (currentScope.pattern instanceof SinglePattern)
|
93
|
+
return null;
|
94
|
+
|
95
|
+
DoublePattern dp = (DoublePattern) (currentScope.pattern);
|
96
|
+
dp.replaceGrammarIncludes();
|
97
|
+
|
98
|
+
Marker newMarker = scanLine(dp);
|
99
|
+
if (newMarker != null) {
|
100
|
+
bestMarker = newMarker.bestOf(bestMarker);
|
101
|
+
}
|
102
|
+
return bestMarker;
|
103
|
+
}
|
104
|
+
|
105
|
+
// public ArrayList<Marker> allDoublesOnLine(DoublePattern dp) {
|
106
|
+
// ArrayList<Marker> doubleMarkers = new ArrayList<Marker>();
|
107
|
+
// for (Pattern p : dp.patterns) {
|
108
|
+
// if (p.disabled) continue;
|
109
|
+
// Match match = scanForMatch(position, p);
|
110
|
+
// if (match != null) {
|
111
|
+
// Marker newMarker = markerFromMatch(p, match);
|
112
|
+
// if (newMarker != null) {
|
113
|
+
// doubleMarkers.add(newMarker);
|
114
|
+
// }
|
115
|
+
// }
|
116
|
+
// }
|
117
|
+
// return doubleMarkers;
|
118
|
+
// }
|
119
|
+
|
120
|
+
public Marker scanLine(DoublePattern dp) {
|
121
|
+
Marker bestMarker = null;
|
122
|
+
for (Pattern p : dp.patterns) {
|
123
|
+
// System.out.printf(" scanning for %s (%s)\n", p.name, p.disabled);
|
124
|
+
if (p.disabled) continue;
|
125
|
+
Match match = scanForMatch(position, p);
|
126
|
+
if (match != null) {
|
127
|
+
Marker newMarker = markerFromMatch(p, match);
|
128
|
+
if (newMarker != null) {
|
129
|
+
bestMarker = newMarker.bestOf(bestMarker);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
return bestMarker;
|
134
|
+
}
|
135
|
+
|
136
|
+
public Marker markerFromMatch(Pattern p, Match match) {
|
137
|
+
Marker newMarker = new Marker();
|
138
|
+
newMarker.pattern = p;
|
139
|
+
newMarker.match = match;
|
140
|
+
try {
|
141
|
+
newMarker.from = match.getCapture(0).start;
|
142
|
+
}
|
143
|
+
catch (ArrayIndexOutOfBoundsException e) {
|
144
|
+
System.out.printf("*** Warning ArrayIndexOutOfBoundsException pattern: %s, line:'%s'\n", p.name, line);
|
145
|
+
e.printStackTrace();
|
146
|
+
return null;
|
147
|
+
}
|
148
|
+
newMarker.isCloseScope = false;
|
149
|
+
return newMarker;
|
150
|
+
}
|
151
|
+
|
152
|
+
public Iterator<Marker> iterator() {
|
153
|
+
return new ScannerIterator(this);
|
154
|
+
}
|
155
|
+
|
156
|
+
// TODO: implement this class for real
|
157
|
+
public class ScannerIterator implements Iterator<Marker> {
|
158
|
+
private Scanner scanner;
|
159
|
+
private Marker nextMarker;
|
160
|
+
|
161
|
+
public ScannerIterator(Scanner scanner) {
|
162
|
+
this.scanner = scanner;
|
163
|
+
}
|
164
|
+
|
165
|
+
public boolean hasNext() {
|
166
|
+
nextMarker = scanner.findNextMarker();
|
167
|
+
return (nextMarker != null);
|
168
|
+
}
|
169
|
+
|
170
|
+
public Marker next() {
|
171
|
+
return nextMarker;
|
172
|
+
}
|
173
|
+
|
174
|
+
public void remove() {
|
175
|
+
nextMarker = null;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
@@ -0,0 +1,534 @@
|
|
1
|
+
|
2
|
+
package com.redcareditor.mate;
|
3
|
+
|
4
|
+
import java.util.List;
|
5
|
+
import java.util.ArrayList;
|
6
|
+
|
7
|
+
import com.redcareditor.mate.document.MateDocument;
|
8
|
+
import com.redcareditor.mate.document.MateTextLocation;
|
9
|
+
import com.redcareditor.mate.document.swt.SwtMateTextLocation;
|
10
|
+
import com.redcareditor.mate.document.MateTextRange;
|
11
|
+
import com.redcareditor.onig.Match;
|
12
|
+
import com.redcareditor.onig.Rx;
|
13
|
+
import com.redcareditor.theme.ThemeSetting;
|
14
|
+
|
15
|
+
public class Scope implements Comparable<Scope>{
|
16
|
+
private MateText mateText;
|
17
|
+
|
18
|
+
private MateDocument document;
|
19
|
+
|
20
|
+
private MateTextRange range;
|
21
|
+
private MateTextRange innerRange;
|
22
|
+
|
23
|
+
public String name;
|
24
|
+
public Pattern pattern;
|
25
|
+
|
26
|
+
public boolean isOpen;
|
27
|
+
public boolean isCapture;
|
28
|
+
public boolean isCloseCapture;
|
29
|
+
|
30
|
+
public Match openMatch;
|
31
|
+
public Match closeMatch;
|
32
|
+
|
33
|
+
public Rx closingRegex;
|
34
|
+
public String beginMatchString;
|
35
|
+
public String endMatchString;
|
36
|
+
|
37
|
+
public Scope parent;
|
38
|
+
public ArrayList<Scope> children;
|
39
|
+
|
40
|
+
public String bgColour;
|
41
|
+
public String fgColour;
|
42
|
+
|
43
|
+
StringBuilder prettyString;
|
44
|
+
int indent;
|
45
|
+
|
46
|
+
public ThemeSetting themeSetting;
|
47
|
+
|
48
|
+
public Scope(MateText mt, String name) {
|
49
|
+
this.mateText = mt;
|
50
|
+
this.name = name;
|
51
|
+
this.children = new ArrayList<Scope>();
|
52
|
+
this.document = mt.getMateDocument();
|
53
|
+
|
54
|
+
this.range = document.getTextRange();
|
55
|
+
this.innerRange = document.getTextRange();
|
56
|
+
}
|
57
|
+
|
58
|
+
public void setMateText(MateText mateText) {
|
59
|
+
this.mateText = mateText;
|
60
|
+
this.document = mateText.getMateDocument();
|
61
|
+
this.range.setDocument(this.document);
|
62
|
+
if (this.innerRange != null) {
|
63
|
+
this.innerRange.setDocument(this.document);
|
64
|
+
}
|
65
|
+
|
66
|
+
for (Scope child : children)
|
67
|
+
child.setMateText(mateText);
|
68
|
+
}
|
69
|
+
|
70
|
+
static public Scope findContainingScopeOld(ArrayList<Scope> scopes, MateTextLocation location) {
|
71
|
+
for (Scope child : scopes) {
|
72
|
+
if (child.contains(location)) {
|
73
|
+
return child;
|
74
|
+
}
|
75
|
+
}
|
76
|
+
return null;
|
77
|
+
}
|
78
|
+
|
79
|
+
static int indexOfEarliestAfter(ArrayList<Scope> scopes, int offset) {
|
80
|
+
if (offset == 0) {
|
81
|
+
if (scopes.size() > 0)
|
82
|
+
return 0;
|
83
|
+
else
|
84
|
+
return -1;
|
85
|
+
}
|
86
|
+
int ix = indexOfLatestBefore(scopes, offset - 1);
|
87
|
+
int c = ix + 1;
|
88
|
+
if (c == scopes.size())
|
89
|
+
return -1;
|
90
|
+
return c;
|
91
|
+
}
|
92
|
+
|
93
|
+
static int indexOfLatestBefore(ArrayList<Scope> scopes, int offset) {
|
94
|
+
int high = scopes.size(), low = -1, probe, probeStart;
|
95
|
+
if (high == 0)
|
96
|
+
return -1;
|
97
|
+
int bestProbe = 0;
|
98
|
+
int bestStart = ((SwtMateTextLocation) scopes.get(0).getStart()).offset;
|
99
|
+
if (bestStart > offset)
|
100
|
+
return -1;
|
101
|
+
Scope scope;
|
102
|
+
while (high - low > 1) {
|
103
|
+
probe = (low + high) >>> 1;
|
104
|
+
scope = scopes.get(probe);
|
105
|
+
probeStart = ((SwtMateTextLocation) scope.getStart()).offset;
|
106
|
+
//System.out.printf("low: %d high: %d diff: %d probe: %d value: %d\n", low, high, high - low, probe, probeStart);
|
107
|
+
if (probeStart <= offset) {
|
108
|
+
low = probe;
|
109
|
+
bestStart = probeStart;
|
110
|
+
bestProbe = probe;
|
111
|
+
}
|
112
|
+
else {
|
113
|
+
high = probe;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
if (bestStart <= offset)
|
117
|
+
return bestProbe;
|
118
|
+
else
|
119
|
+
return -1;
|
120
|
+
}
|
121
|
+
|
122
|
+
static public Scope findContainingScopeNew(ArrayList<Scope> scopes, int offset) {
|
123
|
+
//System.out.printf("findContainingScopeNew(offset: %d)\n", offset);
|
124
|
+
int ix = indexOfLatestBefore(scopes, offset);
|
125
|
+
if (ix == -1)
|
126
|
+
return null;
|
127
|
+
Scope scope = scopes.get(ix);
|
128
|
+
int scopeStart = ((SwtMateTextLocation) scope.getStart()).offset;
|
129
|
+
if (scopeStart <= offset) {
|
130
|
+
int scopeEnd = ((SwtMateTextLocation) scope.getEnd()).offset;
|
131
|
+
if (scopeEnd > offset) {
|
132
|
+
return scope;
|
133
|
+
}
|
134
|
+
}
|
135
|
+
return null;
|
136
|
+
}
|
137
|
+
|
138
|
+
public Scope scopeAt(int line, int lineOffset) {
|
139
|
+
MateTextLocation location = document.getTextLocation(line, lineOffset);
|
140
|
+
Scope r = null;
|
141
|
+
if (getStart().compareTo(location) <= 0 || parent == null) {
|
142
|
+
if (isOpen || getEnd().compareTo(location) >= 0) {
|
143
|
+
Scope containingChildNew = Scope.findContainingScopeNew(children, ((SwtMateTextLocation) location).offset);
|
144
|
+
//Scope containingChildOld = Scope.findContainingScopeOld(children, location);
|
145
|
+
//if (containingChildNew != containingChildOld) {
|
146
|
+
// System.out.printf("scopeAt(%d, %d)\n", line, lineOffset);
|
147
|
+
// System.out.printf("containingChild differs %s -> %s\n",
|
148
|
+
// (containingChildOld == null ? "none" : containingChildOld.name),
|
149
|
+
// (containingChildNew == null ? "none" : containingChildNew.name)
|
150
|
+
// );
|
151
|
+
// System.out.printf(pretty(2));
|
152
|
+
//}
|
153
|
+
if (containingChildNew != null)
|
154
|
+
r = containingChildNew.scopeAt(line, lineOffset);
|
155
|
+
else
|
156
|
+
r = this;
|
157
|
+
}
|
158
|
+
}
|
159
|
+
return r;
|
160
|
+
}
|
161
|
+
|
162
|
+
public void clearFrom(int offset) {
|
163
|
+
//System.out.printf("clearFrom(%d) children: %d\n", offset, children.size());
|
164
|
+
int ix = indexOfLatestBefore(children, offset);
|
165
|
+
//System.out.printf(" ix: %d\n", ix);
|
166
|
+
if (ix == -1)
|
167
|
+
return;
|
168
|
+
Scope scope = children.get(ix);
|
169
|
+
int scopeStart = scope.getStart().getOffset();
|
170
|
+
//System.out.printf(" scopeStart: %d\n", scopeStart);
|
171
|
+
if (scopeStart < offset) {
|
172
|
+
ix = ix + 1;
|
173
|
+
int scopeEnd = scope.getEnd().getOffset();
|
174
|
+
if (scopeEnd > offset)
|
175
|
+
scope.clearFrom(offset);
|
176
|
+
}
|
177
|
+
if (ix <= children.size() - 1) {
|
178
|
+
//System.out.printf(" range: %d - %d\n", ix, children.size());
|
179
|
+
((List<Scope>) children).subList(ix, children.size()).clear();
|
180
|
+
}
|
181
|
+
if (getEnd().getOffset() > offset) {
|
182
|
+
removeEnd();
|
183
|
+
isOpen = true;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
public int compareTo(Scope o) {
|
188
|
+
if(getStart().compareTo(o.getStart()) == 0){
|
189
|
+
return getEnd().compareTo(o.getEnd());
|
190
|
+
}
|
191
|
+
return getStart().compareTo(o.getStart());
|
192
|
+
}
|
193
|
+
|
194
|
+
public Scope containingDoubleScope(int lineIx) {
|
195
|
+
Scope scope = this;
|
196
|
+
while ((scope.pattern instanceof SinglePattern ||
|
197
|
+
scope.isCapture ||
|
198
|
+
(scope.getStart().getLine() == lineIx && scope.getStart().getLineOffset() == 0)) &&
|
199
|
+
scope.parent != null) {
|
200
|
+
scope = scope.parent;
|
201
|
+
}
|
202
|
+
return scope;
|
203
|
+
}
|
204
|
+
|
205
|
+
public boolean surfaceIdenticalTo(Scope other) {
|
206
|
+
if (surfaceIdenticalToModuloEnding(other) &&
|
207
|
+
getEnd().equals(other.getEnd()) &&
|
208
|
+
getInnerEnd().equals(other.getInnerEnd()) &&
|
209
|
+
beginMatchString.equals(other.beginMatchString)) {
|
210
|
+
return true;
|
211
|
+
}
|
212
|
+
return false;
|
213
|
+
}
|
214
|
+
|
215
|
+
public boolean surfaceIdenticalToModuloEnding(Scope other) {
|
216
|
+
//System.out.printf("name: %s; other.name: %s\n", name, other.name);
|
217
|
+
//if (getStart() == null) {
|
218
|
+
// System.out.printf("getStart() is null");
|
219
|
+
//}
|
220
|
+
if (
|
221
|
+
( (name == null && other.name == null) || (name != null && name.equals(other.name)) ) &&
|
222
|
+
pattern == other.pattern &&
|
223
|
+
getStart().equals(other.getStart()) &&
|
224
|
+
getInnerStart().equals(other.getInnerStart()) &&
|
225
|
+
beginMatchString.equals(other.beginMatchString)) {
|
226
|
+
return true;
|
227
|
+
}
|
228
|
+
return false;
|
229
|
+
}
|
230
|
+
|
231
|
+
public ArrayList<Scope> scopesOnLine(int lineIx) {
|
232
|
+
ArrayList<Scope> scopes = new ArrayList<Scope>();
|
233
|
+
if (getStart().getLine() <= lineIx && getEnd().getLine() >= lineIx)
|
234
|
+
scopes.add(this);
|
235
|
+
childScopesOnLine(lineIx, scopes);
|
236
|
+
return scopes;
|
237
|
+
}
|
238
|
+
|
239
|
+
public void childScopesOnLine(int lineIx, ArrayList<Scope> scopes) {
|
240
|
+
for (Scope child : children) {
|
241
|
+
if (child.getStart().getLine() <= lineIx && child.getEnd().getLine() >= lineIx) {
|
242
|
+
scopes.add(child);
|
243
|
+
child.childScopesOnLine(lineIx, scopes);
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
public ArrayList<Scope> scopesBetween(int startOffset, int endOffset) {
|
249
|
+
ArrayList<Scope> scopes = new ArrayList<Scope>();
|
250
|
+
if (getStart().getOffset() < endOffset && getEnd().getOffset() >= startOffset)
|
251
|
+
scopes.add(this);
|
252
|
+
childScopesBetween(startOffset, endOffset, scopes);
|
253
|
+
return scopes;
|
254
|
+
}
|
255
|
+
|
256
|
+
public void childScopesBetween(int startOffset, int endOffset, ArrayList<Scope> scopes) {
|
257
|
+
for (Scope child : children) {
|
258
|
+
if (child.getStart().getOffset() < endOffset && child.getEnd().getOffset() >= startOffset) {
|
259
|
+
scopes.add(child);
|
260
|
+
child.childScopesBetween(startOffset, endOffset, scopes);
|
261
|
+
}
|
262
|
+
}
|
263
|
+
}
|
264
|
+
|
265
|
+
public boolean overlapsWith(Scope other) {
|
266
|
+
// sd1 +---
|
267
|
+
// sd2 +---
|
268
|
+
if (getStart().compareTo(other.getStart()) >= 0) {
|
269
|
+
if (getStart().compareTo(other.getEnd()) < 0) {
|
270
|
+
return true;
|
271
|
+
}
|
272
|
+
return false;
|
273
|
+
}
|
274
|
+
|
275
|
+
// sd1 +---
|
276
|
+
// sd2 +---
|
277
|
+
if (getEnd().compareTo(other.getStart()) > 0) {
|
278
|
+
return true;
|
279
|
+
}
|
280
|
+
return false;
|
281
|
+
}
|
282
|
+
|
283
|
+
public void addChild(Scope newChild) {
|
284
|
+
if (children.size() == 0){
|
285
|
+
children.add(newChild);
|
286
|
+
return;
|
287
|
+
}
|
288
|
+
|
289
|
+
int newChildStartOffset = newChild.getStart().getOffset();
|
290
|
+
|
291
|
+
if (children.get(0).getStart().getOffset() > newChildStartOffset){
|
292
|
+
children.add(0, newChild);
|
293
|
+
return;
|
294
|
+
}
|
295
|
+
|
296
|
+
int insertIx = 0;
|
297
|
+
int ix = 1;
|
298
|
+
Scope lastChild = children.get(children.size() - 1);
|
299
|
+
|
300
|
+
if (lastChild.getStart().getOffset() <= newChildStartOffset) {
|
301
|
+
insertIx = children.size();
|
302
|
+
}
|
303
|
+
else {
|
304
|
+
for (Scope child : children) {
|
305
|
+
if (child.getStart().getOffset() <= newChildStartOffset) {
|
306
|
+
insertIx = ix;
|
307
|
+
}
|
308
|
+
ix++;
|
309
|
+
}
|
310
|
+
}
|
311
|
+
children.add(insertIx, newChild);
|
312
|
+
}
|
313
|
+
|
314
|
+
public void removeChild(Scope child) {
|
315
|
+
children.remove(child);
|
316
|
+
}
|
317
|
+
|
318
|
+
public Scope firstChildAfter(MateTextLocation location) {
|
319
|
+
if (children.size() == 0)
|
320
|
+
return null;
|
321
|
+
|
322
|
+
int offset = location.getOffset();
|
323
|
+
int ix = indexOfEarliestAfter(children, offset);
|
324
|
+
Scope r = null;
|
325
|
+
if (ix == -1) {
|
326
|
+
return null;
|
327
|
+
}
|
328
|
+
else {
|
329
|
+
return children.get(ix);
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
public void printScopeRanges(String title, ArrayList<Scope> scopes) {
|
334
|
+
System.out.printf("%s: ", title);
|
335
|
+
for (Scope s : scopes) {
|
336
|
+
System.out.printf("%d-%d, ", s.getStart().getOffset(), s.getEnd().getOffset());
|
337
|
+
}
|
338
|
+
System.out.printf("\n");
|
339
|
+
}
|
340
|
+
|
341
|
+
public ArrayList<Scope> deleteAnyBetweenNotIn(int startOffset, int endOffset, ArrayList<Scope> scopes) {
|
342
|
+
//System.out.printf("deleteAnyBetweenNotIn(%d, %d)\n", startOffset, endOffset);
|
343
|
+
//printScopeRanges(" children", children);
|
344
|
+
//printScopeRanges(" safe", scopes);
|
345
|
+
ArrayList<Scope> removedScopes = new ArrayList<Scope>();
|
346
|
+
int ix, childStart;
|
347
|
+
|
348
|
+
int ixEnd = indexOfLatestBefore(children, endOffset);
|
349
|
+
if (ixEnd == -1)
|
350
|
+
return removedScopes;
|
351
|
+
int ixStart = indexOfEarliestAfter(children, startOffset);
|
352
|
+
if (ixStart == -1)
|
353
|
+
ix = 0;
|
354
|
+
else
|
355
|
+
ix = ixStart;
|
356
|
+
//System.out.printf(" start: %d, end: %d\n", ixStart, ixEnd);
|
357
|
+
while (ix <= ixEnd) {
|
358
|
+
Scope child = children.get(ix);
|
359
|
+
childStart = child.getStart().getOffset();
|
360
|
+
//System.out.printf(" checking: %d-%d\n", child.getStart().getOffset(), child.getEnd().getOffset());
|
361
|
+
if (childStart >= startOffset && childStart < endOffset && !scopes.contains(child)) {
|
362
|
+
removedScopes.add(child);
|
363
|
+
}
|
364
|
+
ix++;
|
365
|
+
}
|
366
|
+
children.removeAll(removedScopes);
|
367
|
+
//printScopeRanges(" removedScopes", removedScopes);
|
368
|
+
return removedScopes;
|
369
|
+
}
|
370
|
+
|
371
|
+
public void setStartPos(int line, int lineOffset, boolean hasLeftGravity) {
|
372
|
+
MateTextLocation start = document.getTextLocation(line, lineOffset);
|
373
|
+
this.range.setStart(start);
|
374
|
+
document.addTextLocation("scopes", start);
|
375
|
+
}
|
376
|
+
|
377
|
+
public void setInnerStartPos(int line, int lineOffset, boolean hasLeftGravity) {
|
378
|
+
MateTextLocation innerStart = document.getTextLocation(line, lineOffset);
|
379
|
+
this.innerRange.setStart(innerStart);
|
380
|
+
document.addTextLocation("scopes", innerStart);
|
381
|
+
}
|
382
|
+
|
383
|
+
public void setInnerEndPos(int line, int lineOffset, boolean c) {
|
384
|
+
MateTextLocation innerEnd = document.getTextLocation(line, lineOffset);
|
385
|
+
this.innerRange.setEnd(innerEnd);
|
386
|
+
document.addTextLocation("scopes", innerEnd);
|
387
|
+
}
|
388
|
+
|
389
|
+
public void setEndPos(int line, int lineOffset, boolean c) {
|
390
|
+
MateTextLocation end = document.getTextLocation(line, lineOffset);
|
391
|
+
this.range.setEnd(end);
|
392
|
+
document.addTextLocation("scopes", end);
|
393
|
+
}
|
394
|
+
|
395
|
+
public void removeEnd() {
|
396
|
+
this.range.clearEnd();
|
397
|
+
this.innerRange.clearEnd();
|
398
|
+
}
|
399
|
+
|
400
|
+
public int getLength(){
|
401
|
+
return range.getLength();
|
402
|
+
}
|
403
|
+
|
404
|
+
public MateTextLocation getStart() {
|
405
|
+
return range.getStart();
|
406
|
+
}
|
407
|
+
|
408
|
+
public MateTextLocation getEnd(){
|
409
|
+
return range.getEnd();
|
410
|
+
}
|
411
|
+
|
412
|
+
public MateTextLocation getInnerStart(){
|
413
|
+
return innerRange.getStart();
|
414
|
+
}
|
415
|
+
|
416
|
+
public MateTextLocation getInnerEnd(){
|
417
|
+
return innerRange.getEnd();
|
418
|
+
}
|
419
|
+
|
420
|
+
public boolean contains(MateTextLocation location){
|
421
|
+
return range.conatains(location);
|
422
|
+
}
|
423
|
+
|
424
|
+
public String hierarchyNames(boolean inner) {
|
425
|
+
String selfName;
|
426
|
+
// stdout.printf("'%s'.hierarchy_names(%s)\n", name, inner ? "true" : "false");
|
427
|
+
if (pattern instanceof DoublePattern &&
|
428
|
+
((DoublePattern) pattern).contentName != null &&
|
429
|
+
inner) {
|
430
|
+
selfName = name + " " + ((DoublePattern) pattern).contentName;
|
431
|
+
}
|
432
|
+
else {
|
433
|
+
selfName = name;
|
434
|
+
}
|
435
|
+
if (parent != null) {
|
436
|
+
boolean next_inner;
|
437
|
+
if (isCapture)
|
438
|
+
next_inner = false;
|
439
|
+
else
|
440
|
+
next_inner = true;
|
441
|
+
return parent.hierarchyNames(next_inner) + " " + selfName;
|
442
|
+
}
|
443
|
+
else {
|
444
|
+
return selfName;
|
445
|
+
}
|
446
|
+
}
|
447
|
+
|
448
|
+
public String pretty(int indent) {
|
449
|
+
prettyString = new StringBuilder("");
|
450
|
+
this.indent = indent;
|
451
|
+
for (int i = 0; i < indent; i++)
|
452
|
+
prettyString.append(" ");
|
453
|
+
if (this.isCapture)
|
454
|
+
prettyString.append("c");
|
455
|
+
else
|
456
|
+
prettyString.append("+");
|
457
|
+
|
458
|
+
if (this.name != null)
|
459
|
+
prettyString.append(" " + this.name);
|
460
|
+
else
|
461
|
+
prettyString.append(" " + "[noname]");
|
462
|
+
|
463
|
+
if (this.pattern instanceof DoublePattern &&
|
464
|
+
this.isCapture == false &&
|
465
|
+
((DoublePattern) this.pattern).contentName != null)
|
466
|
+
prettyString.append(" " + ((DoublePattern) this.pattern).contentName);
|
467
|
+
prettyString.append(" (");
|
468
|
+
prettyString.append(String.format(
|
469
|
+
"%d,%d",
|
470
|
+
getStart().getLine(),
|
471
|
+
getStart().getLineOffset()));
|
472
|
+
// prettyString.append(getStart().getOffset());
|
473
|
+
prettyString.append(")-(");
|
474
|
+
prettyString.append(String.format(
|
475
|
+
"%d,%d",
|
476
|
+
getEnd().getLine(),
|
477
|
+
getEnd().getLineOffset()));
|
478
|
+
// prettyString.append(getEnd().getOffset());
|
479
|
+
prettyString.append(")");
|
480
|
+
prettyString.append((isOpen ? " open" : " closed"));
|
481
|
+
prettyString.append("\n");
|
482
|
+
|
483
|
+
this.indent += 1;
|
484
|
+
for (Scope child : this.children) {
|
485
|
+
prettyString.append(child.pretty(this.indent));
|
486
|
+
}
|
487
|
+
|
488
|
+
return prettyString.toString();
|
489
|
+
}
|
490
|
+
|
491
|
+
|
492
|
+
public String nearestBackgroundColour() {
|
493
|
+
if (parent != null) {
|
494
|
+
return parent.nearestBackgroundColour1();
|
495
|
+
}
|
496
|
+
return null;
|
497
|
+
}
|
498
|
+
|
499
|
+
public String nearestBackgroundColour1() {
|
500
|
+
if (bgColour != null)
|
501
|
+
return bgColour;
|
502
|
+
if (parent != null) {
|
503
|
+
return parent.nearestBackgroundColour1();
|
504
|
+
}
|
505
|
+
return null;
|
506
|
+
}
|
507
|
+
|
508
|
+
public String nearestForegroundColour() {
|
509
|
+
if (parent != null) {
|
510
|
+
return parent.nearestForegroundColour1();
|
511
|
+
}
|
512
|
+
return null;
|
513
|
+
}
|
514
|
+
|
515
|
+
public String nearestForegroundColour1() {
|
516
|
+
if (fgColour != null)
|
517
|
+
return fgColour;
|
518
|
+
if (parent != null) {
|
519
|
+
return parent.nearestForegroundColour1();
|
520
|
+
}
|
521
|
+
return null;
|
522
|
+
}
|
523
|
+
|
524
|
+
public int countDescendants() {
|
525
|
+
int i = children.size();
|
526
|
+
for (Scope child : children) {
|
527
|
+
i += child.countDescendants();
|
528
|
+
}
|
529
|
+
return i;
|
530
|
+
}
|
531
|
+
}
|
532
|
+
|
533
|
+
|
534
|
+
|