View | Details | Raw Unified | Return to bug 130390 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java (+48 lines)
Lines 11-16 Link Here
11
package org.eclipse.jdt.core.tests.compiler.regression;
11
package org.eclipse.jdt.core.tests.compiler.regression;
12
12
13
import org.eclipse.jdt.core.compiler.CharOperation;
13
import org.eclipse.jdt.core.compiler.CharOperation;
14
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
14
15
15
import junit.framework.Test;
16
import junit.framework.Test;
16
17
Lines 77-80 Link Here
77
public static Class testClass() {
78
public static Class testClass() {
78
	return CharOperationTest.class;
79
	return CharOperationTest.class;
79
}
80
}
81
82
public void testCamel() {
83
    String[][] MATCHES = {
84
            {"TZ","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
85
            {"TiZ","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
86
            {"TiZon","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
87
            {"TZon","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
88
            {"TZone","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
89
            {"TimeZone","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
90
            {"TimeZ","TimeZ"},  //$NON-NLS-1$//$NON-NLS-2$
91
            {"TZ","TimeZ"},  //$NON-NLS-1$//$NON-NLS-2$
92
            {"T","TimeZ"},  //$NON-NLS-1$//$NON-NLS-2$
93
            {"T","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
94
            {"TZ","TZ"},  //$NON-NLS-1$//$NON-NLS-2$
95
            {"aT","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
96
            {"aTi","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
97
            {"aTiZ","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
98
            {"aTZ","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
99
            {"aT","artTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
100
            {"aTi","artTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
101
            {"aTiZ","artTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
102
            {"aTZ","artTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
103
    };
104
    
105
    for (int i = 0; i<MATCHES.length ; i++) {
106
        String[] match = MATCHES[i];
107
        assertTrue (match[0] + ":" + match[1], CharOperation.camelCaseMatch(match[0].toCharArray(), match[1].toCharArray())); //$NON-NLS-1$
108
    }
109
    
110
    String[][] MIS_MATCHES = {
111
            {"TZ","Timezone"},  //$NON-NLS-1$//$NON-NLS-2$
112
            {"aTZ","TimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
113
            {"aTZ","TZ"},  //$NON-NLS-1$//$NON-NLS-2$
114
            {"arT","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
115
            {"arTi","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
116
            {"arTiZ","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
117
            {"arTZ","aTimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
118
            {"aT","atimeZone"},  //$NON-NLS-1$//$NON-NLS-2$
119
    };
120
    
121
    for (int i = 0; i<MIS_MATCHES.length ; i++) {
122
        String[] match = MIS_MATCHES[i];
123
        assertFalse (match[0] + ":" + match[1], CharOperation.camelCaseMatch(match[0].toCharArray(), match[1].toCharArray())); //$NON-NLS-1$
124
    }
125
    
126
}
127
80
}
128
}
(-)compiler/org/eclipse/jdt/core/compiler/CharOperation.java (-54 / +69 lines)
Lines 284-347 Link Here
284
		return false;
284
		return false;
285
	}
285
	}
286
	char patternChar, nameChar;
286
	char patternChar, nameChar;
287
	int iPattern = patternStart+1;
287
	
288
	int iName = nameStart+1;
288
	int iPattern = patternStart;
289
	nextPatternChar: while (iPattern < patternEnd) {
289
	int iName = nameStart;
290
		// check patternChar, keep camelCasing only if uppercase
290
	
291
		if ((patternChar = pattern[iPattern]) < ScannerHelper.MAX_OBVIOUS) {
291
	while (true) {
292
			switch (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar]) {
293
				case ScannerHelper.C_UPPER_LETTER :
294
					// still uppercase
295
					break;
296
				default:
297
					// end of camelCase part of pattern
298
					break nextPatternChar;
299
			}
300
		} else if (Character.isJavaIdentifierPart(patternChar) 
301
						&& !Character.isUpperCase(patternChar)) {
302
			// end of camelCase part of pattern
303
			break nextPatternChar;
304
		}
305
		nextNameChar: while (iName < nameEnd) {
306
			if ((nameChar = name[iName]) != patternChar) {
307
				if (nameChar < ScannerHelper.MAX_OBVIOUS) {
308
					switch (ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar]) {
309
						case ScannerHelper.C_LOWER_LETTER :
310
						case ScannerHelper.C_IDENT_PART :
311
						case ScannerHelper.C_DIGIT :
312
							// lowercase/digit char is ignored
313
							iName++;
314
							continue nextNameChar;
315
					}
316
				} else if (Character.isJavaIdentifierPart(nameChar) 
317
								&& !Character.isUpperCase(nameChar)) {
318
					// lowercase name char is ignored
319
					iName++;
320
					continue nextNameChar;
321
				}
322
				// mismatch, either uppercase in name or non case char ('/' etc)--> reject
323
				return false;
324
			} else {
325
				// pattern char == name char (uppercase)
326
				iName++;
327
				iPattern++;
328
				continue nextPatternChar;
329
			}	
330
		}
331
		if (iPattern == patternEnd) return true;
332
		if (iName == nameEnd) return false;
333
		continue nextPatternChar;
334
	}
335
		
292
		
336
	// check trailing part in case sensitive way
337
	while (iPattern < patternEnd && iName < nameEnd) {
338
		if (pattern[iPattern] != name[iName]) {
339
			return false;
340
		}
341
		iPattern++;
293
		iPattern++;
342
		iName++;
294
		iName++;
295
		
296
		if (iPattern == patternEnd) {
297
			// We have exhausted pattern, so it's a match
298
			return true;
299
		}
300
		
301
		if (iName == nameEnd){
302
			// We have exhausted name (and not pattern), so it's not a match 
303
			return false;
304
		}
305
		
306
		patternChar = pattern[iPattern];
307
		
308
		// For as long as we're exactly matching, bring it on
309
		if (patternChar == name[iName])
310
			continue;
311
		        
312
		if ( 
313
              (patternChar < ScannerHelper.MAX_OBVIOUS 
314
			    && 
315
              ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar] != ScannerHelper.C_UPPER_LETTER)
316
			||
317
              (Character.isJavaIdentifierPart(patternChar)
318
                &&
319
              !Character.isUpperCase(patternChar))
320
		) {
321
			// patternChar is lowercase, and it does not match name, so it's not a match
322
			return false;
323
		}
324
		
325
		// patternChar is uppercase, so let's find the next uppercase in name
326
		while (true) {
327
			if (iName == nameEnd){
328
            //	We have exhausted name (and not pattern), so it's not a match
329
				return false;
330
			}
331
			
332
			nameChar = name[iName];
333
		         
334
			if ( 
335
		              (nameChar < ScannerHelper.MAX_OBVIOUS 
336
					    && 
337
		              ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar] != ScannerHelper.C_UPPER_LETTER)
338
					||
339
		              (Character.isJavaIdentifierPart(nameChar)
340
		                &&
341
		              !Character.isUpperCase(nameChar))
342
				) {
343
				// nameChar is lowercase    
344
				iName++;
345
			} else {
346
				// nameChar is uppercase... 
347
				if (patternChar != nameChar)
348
					//.. and it does not match patternChar, so it's not a match
349
					return false;
350
				
351
				//.. and it matched patternChar. Back to the big loop
352
				break;
353
			}
354
		}
355
		
356
		// At this point, either name has been exhausted, or it is at an uppercase letter.
357
		// Since pattern is also at an 
358
			
343
	}
359
	}
344
	return iPattern == patternEnd;
345
}	
360
}	
346
361
347
/**
362
/**

Return to bug 130390