Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 300852
Collapse All | Expand All

(-)src/org/eclipse/wst/jsdt/internal/ui/text/FastJavaPartitionScanner.java (-128 / +78 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2008 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 10-16 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.wst.jsdt.internal.ui.text;
11
package org.eclipse.wst.jsdt.internal.ui.text;
12
12
13
14
import org.eclipse.jface.text.IDocument;
13
import org.eclipse.jface.text.IDocument;
15
import org.eclipse.jface.text.rules.ICharacterScanner;
14
import org.eclipse.jface.text.rules.ICharacterScanner;
16
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
15
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
Lines 18-35 Link Here
18
import org.eclipse.jface.text.rules.Token;
17
import org.eclipse.jface.text.rules.Token;
19
import org.eclipse.wst.jsdt.ui.text.IJavaScriptPartitions;
18
import org.eclipse.wst.jsdt.ui.text.IJavaScriptPartitions;
20
19
21
22
/**
20
/**
23
 * This scanner recognizes the JavaDoc comments, Java multi line comments, Java single line comments,
21
 * This scanner recognizes the JSDoc comments, multi line comments, single line comments,
24
 * Java strings and Java characters.
22
 * strings, characters, and regular expressions.
25
 */
23
 */
26
public class FastJavaPartitionScanner implements IPartitionTokenScanner, IJavaScriptPartitions {
24
public class FastJavaPartitionScanner implements IPartitionTokenScanner, IJavaScriptPartitions {
27
25
28
	// states
26
	// states
29
	private static final int JAVA= 0;
27
	private static final int JAVASCRIPT= 0;
30
	private static final int SINGLE_LINE_COMMENT= 1;
28
	private static final int SINGLE_LINE_COMMENT= 1;
31
	private static final int MULTI_LINE_COMMENT= 2;
29
	private static final int MULTI_LINE_COMMENT= 2;
32
	private static final int JAVADOC= 3;
30
	private static final int JSDOC= 3;
33
	private static final int CHARACTER= 4;
31
	private static final int CHARACTER= 4;
34
	private static final int STRING= 5;
32
	private static final int STRING= 5;
35
	private static final int REGULAR_EXPRESSION = 6;
33
	private static final int REGULAR_EXPRESSION = 6;
Lines 59-69 Link Here
59
	/** The amount of characters already read on first call to nextToken(). */
57
	/** The amount of characters already read on first call to nextToken(). */
60
	private int fPrefixLength;
58
	private int fPrefixLength;
61
59
62
	// emulate JavaPartitionScanner
63
	private boolean fEmulate= false;
64
	private int fJavaOffset;
65
	private int fJavaLength;
66
67
	private final IToken[] fTokens= new IToken[] {
60
	private final IToken[] fTokens= new IToken[] {
68
		new Token(null),
61
		new Token(null),
69
		new Token(JAVA_SINGLE_LINE_COMMENT),
62
		new Token(JAVA_SINGLE_LINE_COMMENT),
Lines 74-120 Link Here
74
		new Token(JAVA_STRING)	// regular expression same as string
67
		new Token(JAVA_STRING)	// regular expression same as string
75
	};
68
	};
76
69
77
	public FastJavaPartitionScanner(boolean emulate) {
78
	    fEmulate= emulate;
79
	}
80
81
	public FastJavaPartitionScanner() {
70
	public FastJavaPartitionScanner() {
82
	    this(false);
71
	    // create the scanner
83
	}
72
	}
84
73
85
	/*
74
	/*
86
	 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
75
	 * @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
87
	 */
76
	 */
88
	public IToken nextToken() {
77
	public IToken nextToken() {
89
90
		// emulate JavaPartitionScanner
91
		if (fEmulate) {
92
			if (fJavaOffset != -1 && fTokenOffset + fTokenLength != fJavaOffset + fJavaLength) {
93
				fTokenOffset += fTokenLength;
94
				return fTokens[JAVA];
95
			} else {
96
				fJavaOffset= -1;
97
				fJavaLength= 0;
98
			}
99
		}
100
101
		fTokenOffset += fTokenLength;
78
		fTokenOffset += fTokenLength;
102
		fTokenLength= fPrefixLength;
79
		fTokenLength= fPrefixLength;
103
80
		
104
		boolean possibleRegExp=false;
81
		int lastNonWhitespaceChar = NONE;
105
		int ch2=-1;
82
		int currentChar = NONE;
106
		int lastch=-1;
83
		
107
		while (true) {
84
		while (true) {
108
			if (!Character.isWhitespace((char)ch2))
85
			if (!Character.isWhitespace((char)currentChar))
109
				lastch=ch2;
86
				lastNonWhitespaceChar = currentChar;
110
			final int ch= fScanner.read();
87
			
111
		    ch2=ch;
88
			// read in the next char
89
			currentChar= fScanner.read();
90
112
			// characters
91
			// characters
113
	 		switch (ch) {
92
	 		switch (currentChar) {
114
	 		case ICharacterScanner.EOF:
93
	 		case ICharacterScanner.EOF:
115
		 		if (fTokenLength > 0) {
94
		 		if (fTokenLength > 0) {
116
		 			fLast= NONE; // ignore last
95
		 			fLast= NONE; // ignore last
117
		 			return preFix(fState, JAVA, NONE, 0);
96
		 			return preFix(fState, JAVASCRIPT, NONE, 0);
118
97
119
		 		} else {
98
		 		} else {
120
		 			fLast= NONE;
99
		 			fLast= NONE;
Lines 123-136 Link Here
123
		 		}
102
		 		}
124
103
125
	 		case '\r':
104
	 		case '\r':
126
	 			// emulate JavaPartitionScanner
105
	 			if (fLast != CARRIAGE_RETURN) {
127
	 			if (!fEmulate && fLast != CARRIAGE_RETURN) {
128
						fLast= CARRIAGE_RETURN;
106
						fLast= CARRIAGE_RETURN;
129
						fTokenLength++;
107
						fTokenLength++;
130
	 					continue;
108
	 					continue;
131
109
132
	 			} else {
110
	 			} else {
133
134
					switch (fState) {
111
					switch (fState) {
135
					case SINGLE_LINE_COMMENT:
112
					case SINGLE_LINE_COMMENT:
136
					case CHARACTER:
113
					case CHARACTER:
Lines 138-155 Link Here
138
					case REGULAR_EXPRESSION:
115
					case REGULAR_EXPRESSION:
139
						if (fTokenLength > 0) {
116
						if (fTokenLength > 0) {
140
							IToken token= fTokens[fState];
117
							IToken token= fTokens[fState];
118
				 			
119
							fLast= CARRIAGE_RETURN;
120
							fPrefixLength= 1;
141
121
142
				 			// emulate JavaPartitionScanner
122
							fState= JAVASCRIPT;
143
							if (fEmulate) {
144
								fTokenLength++;
145
								fLast= NONE;
146
								fPrefixLength= 0;
147
							} else {
148
								fLast= CARRIAGE_RETURN;
149
								fPrefixLength= 1;
150
							}
151
152
							fState= JAVA;
153
							return token;
123
							return token;
154
124
155
						} else {
125
						} else {
Lines 169-186 Link Here
169
				case CHARACTER:
139
				case CHARACTER:
170
				case REGULAR_EXPRESSION:
140
				case REGULAR_EXPRESSION:
171
				case STRING:
141
				case STRING:
172
					// assert(fTokenLength > 0);
173
					return postFix(fState);
142
					return postFix(fState);
174
143
175
				default:
144
				default:
176
					consume();
145
					consume();
177
					continue;
146
					continue;
178
				}
147
				}
179
180
				
181
				
148
				
182
			default:
149
			default:
183
				if (!fEmulate && fLast == CARRIAGE_RETURN) {
150
				if (fLast == CARRIAGE_RETURN) {
184
					switch (fState) {
151
					switch (fState) {
185
					case SINGLE_LINE_COMMENT:
152
					case SINGLE_LINE_COMMENT:
186
					case REGULAR_EXPRESSION:
153
					case REGULAR_EXPRESSION:
Lines 189-203 Link Here
189
156
190
						int last;
157
						int last;
191
						int newState;
158
						int newState;
192
						switch (ch) {
159
						switch (currentChar) {
193
						case '/':
160
						case '/':
194
							last= SLASH;
161
							last= SLASH;
195
							newState= JAVA;
162
							newState= JAVASCRIPT;
196
							break;
163
							break;
197
164
198
						case '*':
165
						case '*':
199
							last= STAR;
166
							last= STAR;
200
							newState= JAVA;
167
							newState= JAVASCRIPT;
201
							break;
168
							break;
202
169
203
						case '\'':
170
						case '\'':
Lines 212-228 Link Here
212
179
213
						case '\r':
180
						case '\r':
214
							last= CARRIAGE_RETURN;
181
							last= CARRIAGE_RETURN;
215
							newState= JAVA;
182
							newState= JAVASCRIPT;
216
							break;
183
							break;
217
184
218
						case '\\':
185
						case '\\':
219
							last= BACKSLASH;
186
							last= BACKSLASH;
220
							newState= JAVA;
187
							newState= JAVASCRIPT;
221
							break;
188
							break;
222
189
223
						default:
190
						default:
224
							last= NONE;
191
							last= NONE;
225
							newState= JAVA;
192
							newState= JAVASCRIPT;
226
							break;
193
							break;
227
						}
194
						}
228
195
Lines 237-257 Link Here
237
204
238
			// states
205
			// states
239
	 		switch (fState) {
206
	 		switch (fState) {
240
	 		case JAVA:
207
	 		case JAVASCRIPT:
241
				switch (ch) {
208
				switch (currentChar) {
242
				case '/':
209
				case '/':
243
					if (fLast == SLASH) {
210
					if (fLast == SLASH) {
244
						if (fTokenLength - getLastLength(fLast) > 0) {
211
						if (fTokenLength - getLastLength(fLast) > 0) {
245
							return preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
212
							return preFix(JAVASCRIPT, SINGLE_LINE_COMMENT, NONE, 2);
246
						} else {
213
						} else {
247
							preFix(JAVA, SINGLE_LINE_COMMENT, NONE, 2);
214
							preFix(JAVASCRIPT, SINGLE_LINE_COMMENT, NONE, 2);
248
							fTokenOffset += fTokenLength;
215
							fTokenOffset += fTokenLength;
249
							fTokenLength= fPrefixLength;
216
							fTokenLength= fPrefixLength;
250
							break;
217
							break;
251
						}
218
						}
252
219
253
					} else {
220
					} else {
254
						switch (lastch)	//possible chars before regexp 
221
						switch (lastNonWhitespaceChar)	//possible chars before regexp 
255
						{
222
						{
256
						case '(':
223
						case '(':
257
						case ',':
224
						case ',':
Lines 263-279 Link Here
263
						case '?':
230
						case '?':
264
						case '{':
231
						case '{':
265
						case '}':
232
						case '}':
266
							//check if regexp
233
							int tempChar = fScanner.read();
267
							possibleRegExp=true;
234
							fScanner.unread();
268
							fLast= NONE; // ignore fLast
235
							switch(tempChar) {
269
							if (fTokenLength > 0)
236
							case '/':
270
								return preFix(JAVA, REGULAR_EXPRESSION, NONE, 1);
237
							case '*':
271
							else {
272
								preFix(JAVA, REGULAR_EXPRESSION, NONE, 1);
273
								fTokenOffset += fTokenLength;
274
								fTokenLength= fPrefixLength;
275
								break;
238
								break;
239
							default:
240
								//check if regexp
241
								fLast= NONE; // ignore fLast
242
								if (fTokenLength > 0)
243
									return preFix(JAVASCRIPT, REGULAR_EXPRESSION, NONE, 1);
244
								else {
245
									preFix(JAVASCRIPT, REGULAR_EXPRESSION, NONE, 1);
246
									fTokenOffset += fTokenLength;
247
									fTokenLength= fPrefixLength;
248
									break;
249
								}
276
							}
250
							}
251
							
277
						}
252
						}
278
						fTokenLength++;
253
						fTokenLength++;
279
						fLast= SLASH;
254
						fLast= SLASH;
Lines 283-291 Link Here
283
				case '*':
258
				case '*':
284
					if (fLast == SLASH) {
259
					if (fLast == SLASH) {
285
						if (fTokenLength - getLastLength(fLast) > 0)
260
						if (fTokenLength - getLastLength(fLast) > 0)
286
							return preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
261
							return preFix(JAVASCRIPT, MULTI_LINE_COMMENT, SLASH_STAR, 2);
287
						else {
262
						else {
288
							preFix(JAVA, MULTI_LINE_COMMENT, SLASH_STAR, 2);
263
							preFix(JAVASCRIPT, MULTI_LINE_COMMENT, SLASH_STAR, 2);
289
							fTokenOffset += fTokenLength;
264
							fTokenOffset += fTokenLength;
290
							fTokenLength= fPrefixLength;
265
							fTokenLength= fPrefixLength;
291
							break;
266
							break;
Lines 299-307 Link Here
299
				case '\'':
274
				case '\'':
300
					fLast= NONE; // ignore fLast
275
					fLast= NONE; // ignore fLast
301
					if (fTokenLength > 0)
276
					if (fTokenLength > 0)
302
						return preFix(JAVA, CHARACTER, NONE, 1);
277
						return preFix(JAVASCRIPT, CHARACTER, NONE, 1);
303
					else {
278
					else {
304
						preFix(JAVA, CHARACTER, NONE, 1);
279
						preFix(JAVASCRIPT, CHARACTER, NONE, 1);
305
						fTokenOffset += fTokenLength;
280
						fTokenOffset += fTokenLength;
306
						fTokenLength= fPrefixLength;
281
						fTokenLength= fPrefixLength;
307
						break;
282
						break;
Lines 310-318 Link Here
310
				case '"':
285
				case '"':
311
					fLast= NONE; // ignore fLast
286
					fLast= NONE; // ignore fLast
312
					if (fTokenLength > 0)
287
					if (fTokenLength > 0)
313
						return preFix(JAVA, STRING, NONE, 1);
288
						return preFix(JAVASCRIPT, STRING, NONE, 1);
314
					else {
289
					else {
315
						preFix(JAVA, STRING, NONE, 1);
290
						preFix(JAVASCRIPT, STRING, NONE, 1);
316
						fTokenOffset += fTokenLength;
291
						fTokenOffset += fTokenLength;
317
						fTokenLength= fPrefixLength;
292
						fTokenLength= fPrefixLength;
318
						break;
293
						break;
Lines 328-342 Link Here
328
				consume();
303
				consume();
329
				break;
304
				break;
330
305
331
	 		case JAVADOC:
306
	 		case JSDOC:
332
				switch (ch) {
307
				switch (currentChar) {
333
				case '/':
308
				case '/':
334
					switch (fLast) {
309
					switch (fLast) {
335
					case SLASH_STAR_STAR:
310
					case SLASH_STAR_STAR:
336
						return postFix(MULTI_LINE_COMMENT);
311
						return postFix(MULTI_LINE_COMMENT);
337
312
338
					case STAR:
313
					case STAR:
339
						return postFix(JAVADOC);
314
						return postFix(JSDOC);
340
315
341
					default:
316
					default:
342
						consume();
317
						consume();
Lines 356-367 Link Here
356
				break;
331
				break;
357
332
358
	 		case MULTI_LINE_COMMENT:
333
	 		case MULTI_LINE_COMMENT:
359
				switch (ch) {
334
				switch (currentChar) {
360
				case '*':
335
				case '*':
361
					if (fLast == SLASH_STAR) {
336
					if (fLast == SLASH_STAR) {
362
						fLast= SLASH_STAR_STAR;
337
						fLast= SLASH_STAR_STAR;
363
						fTokenLength++;
338
						fTokenLength++;
364
						fState= JAVADOC;
339
						fState= JSDOC;
365
					} else {
340
					} else {
366
						fTokenLength++;
341
						fTokenLength++;
367
						fLast= STAR;
342
						fLast= STAR;
Lines 383-389 Link Here
383
				break;
358
				break;
384
359
385
	 		case STRING:
360
	 		case STRING:
386
	 			switch (ch) {
361
	 			switch (currentChar) {
387
	 			case '\\':
362
	 			case '\\':
388
					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
363
					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
389
					fTokenLength++;
364
					fTokenLength++;
Lines 405-411 Link Here
405
	 			break;
380
	 			break;
406
381
407
	 		case REGULAR_EXPRESSION:
382
	 		case REGULAR_EXPRESSION:
408
	 			switch (ch) {
383
	 			switch (currentChar) {
409
384
410
				case '\\':
385
				case '\\':
411
					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
386
					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
Lines 444-450 Link Here
444
	 			break;
419
	 			break;
445
420
446
	 		case CHARACTER:
421
	 		case CHARACTER:
447
	 			switch (ch) {
422
	 			switch (currentChar) {
448
				case '\\':
423
				case '\\':
449
					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
424
					fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
450
					fTokenLength++;
425
					fTokenLength++;
Lines 498-534 Link Here
498
	private final IToken postFix(int state) {
473
	private final IToken postFix(int state) {
499
		fTokenLength++;
474
		fTokenLength++;
500
		fLast= NONE;
475
		fLast= NONE;
501
		fState= JAVA;
476
		fState= JAVASCRIPT;
502
		fPrefixLength= 0;
477
		fPrefixLength= 0;
503
		return fTokens[state];
478
		return fTokens[state];
504
	}
479
	}
505
480
506
	private final IToken preFix(int state, int newState, int last, int prefixLength) {
481
	private final IToken preFix(int state, int newState, int last, int prefixLength) {
507
		// emulate JavaPartitionScanner
482
		fTokenLength -= getLastLength(fLast);
508
		if (fEmulate && state == JAVA && (fTokenLength - getLastLength(fLast) > 0)) {
483
		fLast= last;
509
			fTokenLength -= getLastLength(fLast);
484
		fPrefixLength= prefixLength;
510
			fJavaOffset= fTokenOffset;
485
		IToken token= fTokens[state];
511
			fJavaLength= fTokenLength;
486
		fState= newState;
512
			fTokenLength= 1;
487
		return token;
513
			fState= newState;
514
			fPrefixLength= prefixLength;
515
			fLast= last;
516
			return fTokens[state];
517
518
		} else {
519
			fTokenLength -= getLastLength(fLast);
520
			fLast= last;
521
			fPrefixLength= prefixLength;
522
			IToken token= fTokens[state];
523
			fState= newState;
524
			return token;
525
		}
526
	}
488
	}
527
489
528
	private static int getState(String contentType) {
490
	private static int getState(String contentType) {
529
491
530
		if (contentType == null)
492
		if (contentType == null)
531
			return JAVA;
493
			return JAVASCRIPT;
532
494
533
		else if (contentType.equals(JAVA_SINGLE_LINE_COMMENT))
495
		else if (contentType.equals(JAVA_SINGLE_LINE_COMMENT))
534
			return SINGLE_LINE_COMMENT;
496
			return SINGLE_LINE_COMMENT;
Lines 537-543 Link Here
537
			return MULTI_LINE_COMMENT;
499
			return MULTI_LINE_COMMENT;
538
500
539
		else if (contentType.equals(JAVA_DOC))
501
		else if (contentType.equals(JAVA_DOC))
540
			return JAVADOC;
502
			return JSDOC;
541
503
542
		else if (contentType.equals(JAVA_STRING))
504
		else if (contentType.equals(JAVA_STRING))
543
			return STRING;
505
			return STRING;
Lines 546-552 Link Here
546
			return CHARACTER;
508
			return CHARACTER;
547
509
548
		else
510
		else
549
			return JAVA;
511
			return JAVASCRIPT;
550
	}
512
	}
551
513
552
	/*
514
	/*
Lines 562-577 Link Here
562
524
563
		if (offset == partitionOffset) {
525
		if (offset == partitionOffset) {
564
			// restart at beginning of partition
526
			// restart at beginning of partition
565
			fState= JAVA;
527
			fState= JAVASCRIPT;
566
		} else {
528
		} else {
567
			fState= getState(contentType);
529
			fState= getState(contentType);
568
		}
530
		}
569
570
		// emulate JavaPartitionScanner
571
		if (fEmulate) {
572
			fJavaOffset= -1;
573
			fJavaLength= 0;
574
		}
575
	}
531
	}
576
532
577
	/*
533
	/*
Lines 584-596 Link Here
584
		fTokenLength= 0;
540
		fTokenLength= 0;
585
		fPrefixLength= 0;
541
		fPrefixLength= 0;
586
		fLast= NONE;
542
		fLast= NONE;
587
		fState= JAVA;
543
		fState= JAVASCRIPT;
588
589
		// emulate JavaPartitionScanner
590
		if (fEmulate) {
591
			fJavaOffset= -1;
592
			fJavaLength= 0;
593
		}
594
	}
544
	}
595
545
596
	/*
546
	/*

Return to bug 300852