diff options
author | Tor Norbye <tnorbye@google.com> | 2013-11-06 07:39:10 -0800 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2013-11-06 07:39:10 -0800 |
commit | 7f79b92786647257a2ef98edbe913d184dde53fc (patch) | |
tree | 5d6087739e835e07617e1290f47d2bec11b6af0b /eclipse | |
parent | 67b0445de97b5442313f06653b137b409660422a (diff) | |
download | sdk-7f79b92786647257a2ef98edbe913d184dde53fc.zip sdk-7f79b92786647257a2ef98edbe913d184dde53fc.tar.gz sdk-7f79b92786647257a2ef98edbe913d184dde53fc.tar.bz2 |
53653: Eclipse: 100% CPU usage in ADT pattern matching code
Change-Id: I8ffcbecd6db644e9a199bd38da1df2aa12cae0a5
Diffstat (limited to 'eclipse')
2 files changed, 43 insertions, 19 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java index 91c4049..1df2e4d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/Hyperlinks.java @@ -162,7 +162,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Pattern; /** * Class containing hyperlink resolvers for XML and Java files to jump to associated @@ -184,10 +183,36 @@ public class Hyperlinks { // for the various inner classes that are actual hyperlink resolvers. } - /** Regular expression matching a FQCN for a view class */ + /** + * Returns whether a string represents a valid fully qualified name for a view class. + * Does not check for existence. + */ @VisibleForTesting - /* package */ static final Pattern CLASS_PATTERN = Pattern.compile( - "(([a-zA-Z_\\$][a-zA-Z0-9_\\$]*)+\\.)+[a-zA-Z_\\$][a-zA-Z0-9_\\$]*"); //$NON-NLS-1$ + static boolean isViewClassName(String name) { + int length = name.length(); + if (length < 2 || name.indexOf('.') == -1) { + return false; + } + + boolean lastWasDot = true; + for (int i = 0; i < length; i++) { + char c = name.charAt(i); + if (lastWasDot) { + if (!Character.isJavaIdentifierStart(c)) { + return false; + } + lastWasDot = false; + } else { + if (c == '.') { + lastWasDot = true; + } else if (!Character.isJavaIdentifierPart(c)) { + return false; + } + } + } + + return !lastWasDot; + } /** Determines whether the given attribute <b>name</b> is linkable */ private static boolean isAttributeNameLink(XmlContext context) { @@ -368,7 +393,7 @@ public class Hyperlinks { // If the element looks like a fully qualified class name (e.g. it's a custom view // element) offer it as a link String tag = context.getElement().getTagName(); - return (tag.indexOf('.') != -1 && CLASS_PATTERN.matcher(tag).matches()); + return isViewClassName(tag); } /** Returns the FQCN for a class declaration at the given context */ diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java index cb83947..20aae84 100644 --- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java +++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/editors/HyperlinksTest.java @@ -54,23 +54,22 @@ public class HyperlinksTest extends AdtProjectTest { } public void testFqnRegexp() throws Exception { - assertTrue(Hyperlinks.CLASS_PATTERN.matcher("com.android.Foo").matches()); - assertTrue(Hyperlinks.CLASS_PATTERN.matcher("com.android.pk_g.Foo_Bar1"). - matches()); - assertTrue(Hyperlinks.CLASS_PATTERN.matcher("com.android.Foo$Inner").matches()); + assertTrue(Hyperlinks.isViewClassName("com.android.Foo")); + assertTrue(Hyperlinks.isViewClassName("com.android.pk_g.Foo_Bar1")); + assertTrue(Hyperlinks.isViewClassName("com.android.Foo$Inner")); // Should we allow non-standard packages and class names? // For now, we're allowing it -- see how this works out in practice. - //assertFalse(XmlHyperlinkResolver.CLASS_PATTERN.matcher("Foo.bar").matches()); - assertTrue(Hyperlinks.CLASS_PATTERN.matcher("Foo.bar").matches()); - - assertFalse(Hyperlinks.CLASS_PATTERN.matcher("LinearLayout").matches()); - assertFalse(Hyperlinks.CLASS_PATTERN.matcher(".").matches()); - assertFalse(Hyperlinks.CLASS_PATTERN.matcher(".F").matches()); - assertFalse(Hyperlinks.CLASS_PATTERN.matcher("f.").matches()); - assertFalse(Hyperlinks.CLASS_PATTERN.matcher("Foo").matches()); - assertFalse(Hyperlinks.CLASS_PATTERN.matcher("com.android.1Foo").matches()); - assertFalse(Hyperlinks.CLASS_PATTERN.matcher("1com.Foo").matches()); + //assertFalse(XmlHyperlinkResolver.isViewClassName("Foo.bar")); + assertTrue(Hyperlinks.isViewClassName("Foo.bar")); + + assertFalse(Hyperlinks.isViewClassName("LinearLayout")); + assertFalse(Hyperlinks.isViewClassName(".")); + assertFalse(Hyperlinks.isViewClassName(".F")); + assertFalse(Hyperlinks.isViewClassName("f.")); + assertFalse(Hyperlinks.isViewClassName("Foo")); + assertFalse(Hyperlinks.isViewClassName("com.android.1Foo")); + assertFalse(Hyperlinks.isViewClassName("1com.Foo")); } public void testNavigate1() throws Exception { |