### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java,v retrieving revision 1.1 diff -u -r1.1 CharOperationTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java 25 Nov 2005 17:26:24 -0000 1.1 +++ src/org/eclipse/jdt/core/tests/compiler/regression/CharOperationTest.java 14 Feb 2006 00:12:16 -0000 @@ -11,6 +11,7 @@ package org.eclipse.jdt.core.tests.compiler.regression; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; import junit.framework.Test; @@ -77,4 +78,51 @@ public static Class testClass() { return CharOperationTest.class; } + +public void testCamel() { + String[][] MATCHES = { + {"TZ","TimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TiZ","TimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TiZon","TimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TZon","TimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TZone","TimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TimeZone","TimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TimeZ","TimeZ"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TZ","TimeZ"}, //$NON-NLS-1$//$NON-NLS-2$ + {"T","TimeZ"}, //$NON-NLS-1$//$NON-NLS-2$ + {"T","TimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"TZ","TZ"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aT","aTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aTi","aTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aTiZ","aTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aTZ","aTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aT","artTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aTi","artTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aTiZ","artTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + {"aTZ","artTimeZone"}, //$NON-NLS-1$//$NON-NLS-2$ + }; + + for (int i = 0; i reject - return false; - } else { - // pattern char == name char (uppercase) - iName++; - iPattern++; - continue nextPatternChar; - } - } - if (iPattern == patternEnd) return true; - if (iName == nameEnd) return false; - continue nextPatternChar; - } + + int iPattern = patternStart; + int iName = nameStart; + + while (true) { - // check trailing part in case sensitive way - while (iPattern < patternEnd && iName < nameEnd) { - if (pattern[iPattern] != name[iName]) { - return false; - } iPattern++; iName++; + + if (iPattern == patternEnd) { + // We have exhausted pattern, so it's a match + return true; + } + + if (iName == nameEnd){ + // We have exhausted name (and not pattern), so it's not a match + return false; + } + + patternChar = pattern[iPattern]; + + // For as long as we're exactly matching, bring it on + if (patternChar == name[iName]) + continue; + + if ( + (patternChar < ScannerHelper.MAX_OBVIOUS + && + ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar] != ScannerHelper.C_UPPER_LETTER) + || + (Character.isJavaIdentifierPart(patternChar) + && + !Character.isUpperCase(patternChar)) + ) { + // patternChar is lowercase, and it does not match name, so it's not a match + return false; + } + + // patternChar is uppercase, so let's find the next uppercase in name + while (true) { + if (iName == nameEnd){ + // We have exhausted name (and not pattern), so it's not a match + return false; + } + + nameChar = name[iName]; + + if ( + (nameChar < ScannerHelper.MAX_OBVIOUS + && + ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar] != ScannerHelper.C_UPPER_LETTER) + || + (Character.isJavaIdentifierPart(nameChar) + && + !Character.isUpperCase(nameChar)) + ) { + // nameChar is lowercase + iName++; + } else { + // nameChar is uppercase... + if (patternChar != nameChar) + //.. and it does not match patternChar, so it's not a match + return false; + + //.. and it matched patternChar. Back to the big loop + break; + } + } + + // At this point, either name has been exhausted, or it is at an uppercase letter. + // Since pattern is also at an + } - return iPattern == patternEnd; } /**