Package: MultipleWordsWordRule$WordMatch

MultipleWordsWordRule$WordMatch

nameinstructionbranchcomplexitylinemethod
MultipleWordsWordRule.WordMatch(IToken, Integer)
M: 9 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * #%~
3: * org.overture.ide.ui
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.ide.ui.editor.syntax;
23:
24: import org.eclipse.core.runtime.Assert;
25: import org.eclipse.jface.text.rules.ICharacterScanner;
26: import org.eclipse.jface.text.rules.IToken;
27: import org.eclipse.jface.text.rules.IWordDetector;
28: import org.eclipse.jface.text.rules.Token;
29: import org.eclipse.jface.text.rules.WordRule;
30:
31: /**
32: * Rule scanner for multiword words like "is subclass responsibility".
33: *
34: * @author kel
35: */
36: public class MultipleWordsWordRule extends WordRule
37: {
38:         /**
39:          * Used as result for {@link MultipleWordsWordRule#checkMatch(String)} to hold the token and unmatched length
40:          *
41:          * @author kel
42:          */
43:         private static class WordMatch
44:         {
45:                 public final IToken token;
46:                 public final Integer unMatchedLength;
47:
48:                 public WordMatch(IToken token, Integer unMatchedLength)
49:                 {
50:                         this.token = token;
51:                         this.unMatchedLength = unMatchedLength;
52:                 }
53:         }
54:
55:         public MultipleWordsWordRule(IWordDetector detector, IToken defaultToken,
56:                         boolean ignoreCase)
57:         {
58:                 super(detector, defaultToken, ignoreCase);
59:         }
60:
61:         private StringBuffer fBuffer = new StringBuffer();
62:         private boolean fIgnoreCase = false;
63:
64:         @SuppressWarnings("unchecked")
65:         public void addWord(String word, IToken token)
66:         {
67:                 Assert.isNotNull(word);
68:                 Assert.isNotNull(token);
69:
70:                 // If case-insensitive, convert to lower case before adding to the map
71:                 if (fIgnoreCase)
72:                 {
73:                         word = word.toLowerCase();
74:                 }
75:                 fWords.put(word, token);
76:         }
77:
78:         /**
79:          * Calculates the maximum number of parts in the largest word in the rule scanner
80:          *
81:          * @return the largest number of parts. (number of spaces spaced words"
82:          */
83:         private int getMaxPartCount()
84:         {
85:                 int max = 0;
86:                 for (Object k : super.fWords.keySet())
87:                 {
88:                         String key = k.toString();
89:                         int count = key.split("\\s+?").length;
90:                         if (count > max)
91:                         {
92:                                 max = count;
93:                         }
94:                 }
95:                 return max;
96:         }
97:         
98:         int offset = 0;
99:         
100:         private int read(ICharacterScanner scanner){
101:                 offset++;
102:                 return scanner.read();
103:         }
104:         
105:         private void unread(ICharacterScanner scanner){
106:                 offset--;
107:                  scanner.unread();
108:         }
109:         private IToken returnEmpty(IToken token)
110:         {
111:                 if(offset!=0)
112:                 {
113:                         System.out.println("Something is wrong: "+offset);
114:                 }
115:                 return token;
116:         }
117:
118:         /*
119:          * @see IRule#evaluate(ICharacterScanner)
120:          */
121:         public IToken evaluate(ICharacterScanner scanner)
122:         {
123:                 offset = 0;
124:                 int c = read(scanner);
125:                 if (c != ICharacterScanner.EOF && fDetector.isWordStart((char) c))
126:                 {
127:                         if (fColumn == UNDEFINED || fColumn == scanner.getColumn() - 1)
128:                         {
129:                                 fBuffer.setLength(0);
130:                                 fBuffer.append((char) c);
131:
132:                                 for (int i = 0; i < getMaxPartCount(); i++)
133:                                 {
134:                                         // read a word for each part
135:                                         do
136:                                         {
137:                                                 c = read(scanner);
138:                                                 fBuffer.append((char) c);
139:                                                 // System.out.println("Read: '"+c + "' - '"+(char)c+"'");
140:                                         } while (c != ICharacterScanner.EOF && c != ' '
141:                                                         && fDetector.isWordStart((char) c));
142:                                 }
143:
144:                                 // we may have read EOF so unread it
145:                                 popEof(scanner);
146:
147:                                 final char lastChar = fBuffer.charAt(fBuffer.length()-1);
148:                                 if (lastChar==' ' || lastChar=='\t'
149:                                                 || lastChar=='\n' || lastChar=='\r')
150:                                 {
151:                                         unread(scanner);// last space
152:                                         fBuffer.delete(fBuffer.length() - 1, fBuffer.length());
153:                                 }
154:                                 
155:                                 String text = fBuffer.toString().toString().replace('\n', ' ').replace('\r', ' ').replace('\t', ' ');
156:                                 String key = text;// text.substring(0, text.length() - 1);
157:
158:
159:                                 WordMatch match = checkMatch(key);
160:                                 if (match != null)
161:                                 {
162:                                         if (match.unMatchedLength > 0)
163:                                         {
164:                                                 // unread unmatched parts
165:                                                 for (int i = 0; i < match.unMatchedLength; i++)
166:                                                 {
167:                                                         unread(scanner);
168:                                                 }
169:                                         }
170:
171:                                         return match.token;
172:                                 }
173:
174:                                 if (fDefaultToken.isUndefined())
175:                                 {
176:                                         unreadBuffer(scanner);
177:                                 }
178:
179:                                 return returnEmpty(fDefaultToken);
180:
181:                         }
182:                 }
183:
184:                 unread(scanner);
185:                 return returnEmpty(Token.UNDEFINED);
186:         }
187:
188:         private void popEof(ICharacterScanner scanner)
189:         {
190:                 while (fBuffer.length() > 0
191:                                 && fBuffer.charAt(fBuffer.length() - 1) == (char) -1)
192:                 {
193:                         unread(scanner);
194:                         fBuffer.delete(fBuffer.length() - 1, fBuffer.length());
195:                 }
196:         }
197:
198:         /**
199:          * Checks if the scanned multipart word exists in the {@code fWords} maps keys collection os if the prefix exists.
200:          *
201:          * @param key
202:          * @return
203:          */
204:         private WordMatch checkMatch(String key)
205:         {
206:                 String matchString = key;
207:
208:                 while (matchString.indexOf(' ') > -1)
209:                 {
210:                         if (fWords.containsKey(matchString))
211:                         {
212: //                                System.out.println("key '"+key+"' not matched: "+(key.length()
213: //                                                - matchString.length()));
214:                                 return new WordMatch((IToken) fWords.get(matchString), key.length()
215:                                                 - matchString.length());
216:                         }
217:
218:                         matchString = matchString.substring(0, matchString.lastIndexOf(' '));
219:                 }
220:
221:                 return null;
222:         }
223:
224:         protected void unreadBuffer(ICharacterScanner scanner)
225:         {
226: //                System.out.println("Did not match '"+fBuffer+"' " + fBuffer.length());
227:                 for (int i = fBuffer.length() - 1; i >= 0; i--)
228:                 {
229:                         unread(scanner);
230: //                        System.out.println("Unread");
231:                 }
232:         }
233:
234: }