diff options
author | Thomas Wolf | 2020-05-22 11:53:36 +0000 |
---|---|---|
committer | Alexander Kurtakov | 2020-07-01 20:06:04 +0000 |
commit | 2c0dcf62f0676116ee51753cf60e8f38cd105d99 (patch) | |
tree | 96ef883f08223d7f9f4b88948427a53144f81827 | |
parent | a373993f5fd26cec102fe67dce28a4359bd366a0 (diff) | |
download | rt.equinox.bundles-2c0dcf62f0676116ee51753cf60e8f38cd105d99.tar.gz rt.equinox.bundles-2c0dcf62f0676116ee51753cf60e8f38cd105d99.tar.xz rt.equinox.bundles-2c0dcf62f0676116ee51753cf60e8f38cd105d99.zip |
Bug 563485 - Add StringMatcher.usePrefixMatch()Y20200704-1200Y20200703-0300I20200707-0600I20200706-2300I20200706-1800I20200706-0600I20200705-1800I20200705-0710I20200705-0600I20200704-1800I20200704-0600I20200703-1800I20200702-2150I20200702-1800I20200701-2350I20200701-2210I20200701-1800
Add a method to make the StringMatcher match on prefixes. Internally
this just switches on wildcard matching and sets fHasTrailingStar to
true. Because the pattern has already been parsed in the constructor,
this gives an easy way to specify prefix matching for non-wildcard
patterns without needing to escape potential wildcards in the pattern:
StringMatcher m = new StringMatcher("foo*bar", false, true);
m.usePrefixMatch();
This matcher will match any text starting with "foo*bar" (with a
literal '*'), but not, for instance, "foobazbar".
Change-Id: I525fbc1d42b16d661988655c8438894f8d6739e8
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
6 files changed, 199 insertions, 12 deletions
diff --git a/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF index c5b6a6e2c..54044befd 100644 --- a/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.common.tests/META-INF/MANIFEST.MF @@ -7,7 +7,7 @@ Automatic-Module-Name: org.eclipse.equinox.common.tests Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Require-Bundle: org.junit, - org.eclipse.equinox.common;bundle-version="3.12.0", + org.eclipse.equinox.common;bundle-version="3.13.0", org.eclipse.core.tests.harness;bundle-version="3.11.400", org.eclipse.equinox.registry;bundle-version="3.8.200" Import-Package: org.eclipse.osgi.service.localization, diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherOtherTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherOtherTest.java new file mode 100644 index 000000000..d4dc5ad38 --- /dev/null +++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherOtherTest.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.equinox.common.tests.text; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.core.text.StringMatcher; +import org.junit.Test; + +public class StringMatcherOtherTest { + + @Test + public void testEmptyNoWildcard() { + StringMatcher m = new StringMatcher("", false, true); + assertTrue(m.match("")); + assertFalse(m.match("foo")); + assertFalse(m.match("foo bar")); + } + + @Test + public void testEmptyWildcard() { + StringMatcher m = new StringMatcher("", false, false); + assertTrue(m.match("")); + assertFalse(m.match("foo")); + assertFalse(m.match("foo bar")); + } +} diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherPrefixTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherPrefixTest.java new file mode 100644 index 000000000..89d39c466 --- /dev/null +++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherPrefixTest.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.equinox.common.tests.text; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.core.text.StringMatcher; +import org.junit.Test; + +public class StringMatcherPrefixTest { + + @Test + public void testNoPrefix() { + StringMatcher m = new StringMatcher("foo", false, true); + assertTrue(m.match("foo")); + assertFalse(m.match("foobar")); + assertFalse(m.match("foo bar")); + assertFalse(m.match("bar foo")); + assertFalse(m.match("bar foo bar")); + } + + @Test + public void testEmptyNoWildcard() { + StringMatcher m = new StringMatcher("", false, true); + m.usePrefixMatch(); + assertTrue(m.match("")); + assertFalse(m.match("foo")); + assertFalse(m.match("foo bar")); + } + + @Test + public void testEmptyWildcard() { + StringMatcher m = new StringMatcher("", false, false); + m.usePrefixMatch(); + assertTrue(m.match("")); + assertTrue(m.match("foo")); + assertTrue(m.match("foo bar")); + } + + @Test + public void testPrefixNoWildcards() { + StringMatcher m = new StringMatcher("foo", false, true); + m.usePrefixMatch(); + assertTrue(m.match("foo")); + assertTrue(m.match("foobar")); + assertTrue(m.match("foo bar")); + assertFalse(m.match("bar foo")); + assertFalse(m.match("bar foo bar")); + } + + @Test + public void testPrefixWildcards() { + StringMatcher m = new StringMatcher("f?o", false, false); + m.usePrefixMatch(); + assertTrue(m.match("foo")); + assertTrue(m.match("foobar")); + assertTrue(m.match("foo bar")); + assertFalse(m.match("bar foo")); + assertFalse(m.match("bar foo bar")); + } + + @Test + public void testPrefixWildcardsOffSingle() { + StringMatcher m = new StringMatcher("f?o", false, true); + m.usePrefixMatch(); + assertFalse(m.match("foo")); + assertTrue(m.match("f?o")); + assertFalse(m.match("foobar")); + assertTrue(m.match("f?obar")); + assertTrue(m.match("f?o bar")); + assertFalse(m.match("bar f?o")); + assertFalse(m.match("bar f?o bar")); + } + + @Test + public void testPrefixWildcardsOffMulti() { + StringMatcher m = new StringMatcher("foo*bar", false, true); + m.usePrefixMatch(); + assertFalse(m.match("foobar")); + assertFalse(m.match("foobazbar")); + assertTrue(m.match("foo*bar")); + assertFalse(m.match("foobarbaz")); + assertTrue(m.match("foo*barbaz")); + assertFalse(m.match("bar foo*bar")); + assertFalse(m.match("bar foo*barbaz")); + } +} diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java index dc4074354..7e9f54690 100644 --- a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java +++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/text/StringMatcherTests.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (C) 2020, Thomas Wolf <thomas.wolf@paranor.ch> and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ package org.eclipse.equinox.common.tests.text; import org.junit.runner.RunWith; @@ -6,9 +16,11 @@ import org.junit.runners.Suite.SuiteClasses; @RunWith(Suite.class) @SuiteClasses({ - StringMatcherFindTest.class, - StringMatcherPlainTest.class, - StringMatcherWildcardTest.class + StringMatcherFindTest.class, + StringMatcherPlainTest.class, + StringMatcherWildcardTest.class, + StringMatcherPrefixTest.class, + StringMatcherOtherTest.class }) public class StringMatcherTests { // empty diff --git a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF index 0f35a0805..fb17d96df 100644 --- a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF @@ -15,7 +15,7 @@ Export-Package: org.eclipse.core.internal.boot;x-friends:="org.eclipse.core.reso org.eclipse.core.filesystem, org.eclipse.equinox.security", org.eclipse.core.runtime;common=split;version="3.6.0";mandatory:=common, - org.eclipse.core.text;version="3.12.0", + org.eclipse.core.text;version="3.13.0", org.eclipse.equinox.events;version="1.0.0" Bundle-Vendor: %providerName Bundle-Activator: org.eclipse.core.internal.runtime.Activator diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java index 5183ff9db..b4a3371f7 100644 --- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java +++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/text/StringMatcher.java @@ -27,17 +27,17 @@ public final class StringMatcher { private final int fLength; // pattern length - private final boolean fIgnoreWildCards; - private final boolean fIgnoreCase; + private boolean fIgnoreWildCards; + private boolean fHasLeadingStar; private boolean fHasTrailingStar; private String fSegments[]; // the given pattern is split into * separated segments - /* Boundary value beyond which we don't need to search in the text. */ + /* Minimum length required for a match: shorter texts cannot possibly match. */ private int fBound = 0; private static final char fSingleWildCard = '\u0000'; @@ -116,21 +116,28 @@ public final class StringMatcher { * StringMatcher constructor takes in a String object that is a simple pattern. * The pattern may contain '*' for 0 and many characters and '?' for exactly one * character. - * + * <p> * Literal '*' and '?' characters must be escaped in the pattern e.g., "\*" * means literal "*", etc. - * + * </p> + * <p> * The escape character '\' is an escape only if followed by '*', '?', or '\'. * All other occurrences are taken literally. - * + * </p> + * <p> * If invoking the StringMatcher with string literals in Java, don't forget * escape characters are represented by "\\". + * </p> + * <p + * An empty pattern matches only an empty text, unless {@link #usePrefixMatch()} + * is used, in which case it always matches. + * </p> * * @param pattern the pattern to match text against, must not be {@code null} * @param ignoreCase if true, case is ignored * @param ignoreWildCards if true, wild cards and their escape sequences are * ignored (everything is taken literally). - * @throws IllegalArgumentException if {@code pattern == null} + * @throws IllegalArgumentException if {@code pattern == null} */ public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) { if (pattern == null) { @@ -149,6 +156,23 @@ public final class StringMatcher { } /** + * Configures this {@link StringMatcher} to also match on prefix-only matches. + * <p> + * If the matcher was created with {@code ignoreWildCards == true}, any wildcard + * characters in the pattern will still be matched literally. + * </p> + * <p> + * If the pattern is empty, it will match any text. + * </p> + * + * @since 3.13 + */ + public void usePrefixMatch() { + fIgnoreWildCards = false; + fHasTrailingStar = true; + } + + /** * Finds the first occurrence of the pattern between {@code start} (inclusive) * and {@code end} (exclusive). * <p> @@ -485,4 +509,23 @@ public final class StringMatcher { } return true; } + + @Override + public String toString() { + String flags = ""; //$NON-NLS-1$ + if (fIgnoreCase) { + flags += 'i'; + } + if (fHasTrailingStar) { + flags += 't'; + } + if (!fIgnoreWildCards) { + flags += '*'; + } + String result = '[' + fPattern; + if (!flags.isEmpty()) { + result += '/' + flags; + } + return result + ']'; + } } |