diff options
author | fingerl | 2017-08-08 15:51:48 +0000 |
---|---|---|
committer | fingerl | 2017-08-15 11:41:24 +0000 |
commit | f002b3af5b2e8c8d256615df1f5ab37dd11312f6 (patch) | |
tree | 43ec69fb97c602fff89ee69048dee11c8c28922d | |
parent | 6332700c91974929c72b945b8dc2b34deb378a21 (diff) | |
download | eclipse.platform.text-f002b3af5b2e8c8d256615df1f5ab37dd11312f6.tar.gz eclipse.platform.text-f002b3af5b2e8c8d256615df1f5ab37dd11312f6.tar.xz eclipse.platform.text-f002b3af5b2e8c8d256615df1f5ab37dd11312f6.zip |
Bug 109481 - [find/replace] replace doesn't work when using a regex withI20170821-2000I20170820-2000I20170819-1500I20170818-2000I20170818-0100I20170818-0040I20170817-2140I20170817-2000I20170816-2000I20170815-2000
a lookahead or boundary matchers
Fixes the bug for the File-Search case (comment 6).
Change-Id: Ia9f22deae6922cf1e5d76a8ec74a280889934b8f
Signed-off-by: fingerl <imelflorianingerl@gmail.com>
3 files changed, 69 insertions, 13 deletions
diff --git a/org.eclipse.search.tests/META-INF/MANIFEST.MF b/org.eclipse.search.tests/META-INF/MANIFEST.MF index cd25df38dd6..0a2795f9882 100644 --- a/org.eclipse.search.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.search.tests/META-INF/MANIFEST.MF @@ -18,7 +18,8 @@ Require-Bundle: org.junit;bundle-version="4.12.0", org.eclipse.ui.workbench.texteditor;bundle-version="[3.5.0,4.0.0)", org.eclipse.jface.text;bundle-version="[3.5.0,4.0.0)", - org.eclipse.ui.editors;bundle-version="[3.5.0,4.0.0)" + org.eclipse.ui.editors;bundle-version="[3.5.0,4.0.0)", + org.eclipse.ltk.core.refactoring;bundle-version="[3.5.0,4.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Eclipse-BundleShape: dir diff --git a/org.eclipse.search.tests/src/org/eclipse/search/tests/filesearch/FileSearchTests.java b/org.eclipse.search.tests/src/org/eclipse/search/tests/filesearch/FileSearchTests.java index 4496d61fb60..675013fbb19 100644 --- a/org.eclipse.search.tests/src/org/eclipse/search/tests/filesearch/FileSearchTests.java +++ b/org.eclipse.search.tests/src/org/eclipse/search/tests/filesearch/FileSearchTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,13 +9,16 @@ * IBM Corporation - initial API and implementation * Christian Walther (Indel AG) - Bug 399094, 402009: Add whole word option to file search * Terry Parker <tparker@google.com> (Google Inc.) - Bug 441016 - Speed up text search by parallelizing it using JobGroups + * Florian Ingerl <imelflorianingerl@gmail.com> - Bug 109481 - [find/replace] replace doesn't work when using a regex with a lookahead or boundary matchers *******************************************************************************/ package org.eclipse.search.tests.filesearch; import static org.junit.Assert.assertEquals; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Scanner; import java.util.regex.Pattern; import org.junit.After; @@ -24,6 +27,8 @@ import org.junit.ClassRule; import org.junit.Test; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -38,10 +43,15 @@ import org.eclipse.search.core.text.TextSearchRequestor; import org.eclipse.search.core.text.TextSearchScope; import org.eclipse.search.internal.core.text.PatternConstructor; import org.eclipse.search.internal.ui.SearchPlugin; +import org.eclipse.search.internal.ui.text.FileSearchQuery; +import org.eclipse.search.internal.ui.text.FileSearchResult; +import org.eclipse.search.internal.ui.text.ReplaceRefactoring; import org.eclipse.search.tests.ResourceHelper; import org.eclipse.search.tests.SearchTestPlugin; import org.eclipse.search.ui.text.FileTextSearchScope; +import org.eclipse.ltk.core.refactoring.Change; + public class FileSearchTests { private static class TestResult { @@ -523,5 +533,50 @@ public class FileSearchTests { assertEquals("Number of results in file", expectedCount, k); } + @Test + public void testReplaceWithLookarounds() throws CoreException, IOException { + IFolder folder= ResourceHelper.createFolder(fProject.getFolder("folder1")); + IFile file1= ResourceHelper.createFile(folder, "file1.txt", "1<2<3<4"); + IFile file2= ResourceHelper.createFile(folder, "file2.txt", "4<5<6<7"); + + FileSearchResult searchResult= performSearch(new String[] { "*.txt" }, "(?<=(\\d)\\<)\\d(?=\\<(\\d))"); + performReplace(searchResult, "$0=($1+$2)/2"); + + assertFileContent(file1, "1<2=(1+3)/2<3=(2+4)/2<4"); + assertFileContent(file2, "4<5=(4+6)/2<6=(5+7)/2<7"); + } + + @Test + public void testReplaceRetainCase() throws CoreException, IOException { + IFolder folder= ResourceHelper.createFolder(fProject.getFolder("folder1")); + IFile file1= ResourceHelper.createFile(folder, "file1.txt", "FOO"); + + FileSearchResult searchResult= performSearch(new String[] { "*.txt" }, "FOO"); + performReplace(searchResult, "xyz\\Cbar\\Cfar"); + + assertFileContent(file1, "xyzBARFAR"); + } + + private FileSearchResult performSearch(String[] fileNamePatterns, String pattern) { + FileTextSearchScope scope= FileTextSearchScope.newSearchScope(new IResource[] { fProject }, fileNamePatterns, false); + FileSearchQuery query= new FileSearchQuery(pattern, true, true, scope); + query.run(null); + return (FileSearchResult) query.getSearchResult(); + } + private void performReplace(FileSearchResult searchResult, String replacementText) throws OperationCanceledException, CoreException { + ReplaceRefactoring refactoring= new ReplaceRefactoring(searchResult, null); + refactoring.setReplaceString(replacementText); + refactoring.checkInitialConditions(null); + refactoring.checkFinalConditions(null); + Change change= refactoring.createChange(null); + change.perform(new NullProgressMonitor()); + } + + private void assertFileContent(IFile file, String expected) throws CoreException { + try (Scanner scanner= new Scanner(file.getContents())) { + scanner.useDelimiter("\\A"); + assertEquals(expected, scanner.next()); + } + } } diff --git a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceRefactoring.java b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceRefactoring.java index 6ae6d9da17a..496fb8a45ba 100644 --- a/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceRefactoring.java +++ b/org.eclipse.search/search/org/eclipse/search/internal/ui/text/ReplaceRefactoring.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2015 IBM Corporation and others. + * Copyright (c) 2007, 2017 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Florian Ingerl <imelflorianingerl@gmail.com> - Bug 109481 - [find/replace] replace doesn't work when using a regex with a lookahead or boundary matchers *******************************************************************************/ package org.eclipse.search.internal.ui.text; @@ -437,7 +438,9 @@ public class ReplaceRefactoring extends Refactoring { continue; } - String replacementString= computeReplacementString(pattern, originalText, fReplaceString, lineDelimiter); + String replacementString= PatternConstructor.interpretReplaceEscapes(fReplaceString, originalText, + lineDelimiter); + replacementString= computeReplacementString(pattern, document, offset, replacementString); if (replacementString == null) { resultingStatus.addError(Messages.format(SearchMessages.ReplaceRefactoring_error_match_content_changed, file.getName())); continue; @@ -467,21 +470,18 @@ public class ReplaceRefactoring extends Refactoring { return PatternConstructor.createPattern(query.getSearchString(), true, true, query.isCaseSensitive(), false); } - private String computeReplacementString(Pattern pattern, String originalText, String replacementText, String lineDelimiter) throws PatternSyntaxException { + private String computeReplacementString(Pattern pattern, IDocument document, int offset, String replacementText) + throws PatternSyntaxException { if (pattern != null) { try { - replacementText= PatternConstructor.interpretReplaceEscapes(replacementText, originalText, lineDelimiter); - - Matcher matcher= pattern.matcher(originalText); - StringBuffer sb = new StringBuffer(); - matcher.reset(); - if (matcher.find()) { + Matcher matcher= pattern.matcher(document.get()); + if (matcher.find(offset)) { + StringBuffer sb= new StringBuffer(); matcher.appendReplacement(sb, replacementText); + return sb.substring(offset); } else { return null; } - matcher.appendTail(sb); - return sb.toString(); } catch (IndexOutOfBoundsException ex) { throw new PatternSyntaxException(ex.getLocalizedMessage(), replacementText, -1); } |