sandbox/old-modules/transformer/src/org/netbeans/modules/jackpot30/transformers/TransformationHintProviderImpl.java
1.1 --- a/sandbox/old-modules/transformer/src/org/netbeans/modules/jackpot30/transformers/TransformationHintProviderImpl.java Mon Dec 19 11:37:36 2016 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,508 +0,0 @@
1.4 -/*
1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6 - *
1.7 - * Copyright 2008-2009 Sun Microsystems, Inc. All rights reserved.
1.8 - *
1.9 - * The contents of this file are subject to the terms of either the GNU
1.10 - * General Public License Version 2 only ("GPL") or the Common
1.11 - * Development and Distribution License("CDDL") (collectively, the
1.12 - * "License"). You may not use this file except in compliance with the
1.13 - * License. You can obtain a copy of the License at
1.14 - * http://www.netbeans.org/cddl-gplv2.html
1.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
1.16 - * specific language governing permissions and limitations under the
1.17 - * License. When distributing the software, include this License Header
1.18 - * Notice in each file and include the License file at
1.19 - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
1.20 - * particular file as subject to the "Classpath" exception as provided
1.21 - * by Sun in the GPL Version 2 section of the License file that
1.22 - * accompanied this code. If applicable, add the following below the
1.23 - * License Header, with the fields enclosed by brackets [] replaced bysanno
1.24 - * your own identifying information:
1.25 - * "Portions Copyrighted [year] [name of copyright owner]"
1.26 - *
1.27 - * If you wish your version of this file to be governed by only the CDDL
1.28 - * or only the GPL Version 2, indicate your decision by adding
1.29 - * "[Contributor] elects to include this software in this distribution
1.30 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
1.31 - * single choice of license, a recipient has the option to distribute
1.32 - * your version of this file under either the CDDL, the GPL Version 2 or
1.33 - * to extend the choice of license to its licensees as provided above.
1.34 - * However, if you add GPL Version 2 code and therefore, elected the GPL
1.35 - * Version 2 license, then the option applies only if the new code is
1.36 - * made subject to such option by the copyright holder.
1.37 - *
1.38 - * Contributor(s):
1.39 - *
1.40 - * Portions Copyrighted 2008-2009 Sun Microsystems, Inc.
1.41 - */
1.42 -
1.43 -package org.netbeans.modules.jackpot30.transformers;
1.44 -
1.45 -import org.netbeans.modules.java.hints.jackpot.spi.Trigger.PatternDescription;
1.46 -import org.netbeans.modules.java.hints.spi.AbstractHint.HintSeverity;
1.47 -import org.netbeans.modules.java.hints.jackpot.spi.support.ErrorDescriptionFactory;
1.48 -import org.netbeans.modules.java.hints.jackpot.spi.ElementBasedHintProvider;
1.49 -import org.netbeans.modules.java.hints.jackpot.spi.HintContext;
1.50 -import org.netbeans.modules.java.hints.jackpot.spi.HintDescription;
1.51 -import org.netbeans.modules.java.hints.jackpot.spi.HintDescription.Worker;
1.52 -import org.netbeans.modules.java.hints.jackpot.spi.HintDescriptionFactory;
1.53 -import org.netbeans.modules.java.hints.jackpot.spi.HintMetadata;
1.54 -import org.netbeans.modules.java.hints.jackpot.spi.JavaFix;
1.55 -import com.sun.source.tree.Tree;
1.56 -import com.sun.source.util.SourcePositions;
1.57 -import com.sun.source.util.TreePath;
1.58 -import java.io.File;
1.59 -import java.io.IOException;
1.60 -import java.net.URL;
1.61 -import java.util.Collection;
1.62 -import java.util.Collections;
1.63 -import java.util.EnumSet;
1.64 -import java.util.HashMap;
1.65 -import java.util.HashSet;
1.66 -import java.util.LinkedList;
1.67 -import java.util.List;
1.68 -import java.util.Map;
1.69 -import java.util.Map.Entry;
1.70 -import java.util.Set;
1.71 -import java.util.concurrent.atomic.AtomicBoolean;
1.72 -import java.util.regex.Matcher;
1.73 -import javax.lang.model.element.AnnotationMirror;
1.74 -import javax.lang.model.element.AnnotationValue;
1.75 -import javax.lang.model.element.Element;
1.76 -import javax.lang.model.element.ElementKind;
1.77 -import javax.lang.model.element.ExecutableElement;
1.78 -import javax.lang.model.element.Modifier;
1.79 -import javax.lang.model.element.PackageElement;
1.80 -import javax.lang.model.element.TypeElement;
1.81 -import javax.lang.model.type.DeclaredType;
1.82 -import javax.lang.model.type.TypeMirror;
1.83 -import javax.lang.model.util.ElementFilter;
1.84 -import org.netbeans.api.java.classpath.ClassPath;
1.85 -import org.netbeans.api.java.source.ClasspathInfo;
1.86 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
1.87 -import org.netbeans.api.java.source.CompilationController;
1.88 -import org.netbeans.api.java.source.CompilationInfo;
1.89 -import org.netbeans.api.java.source.ElementHandle;
1.90 -import org.netbeans.api.java.source.JavaSource;
1.91 -import org.netbeans.api.java.source.Task;
1.92 -import org.netbeans.api.java.source.TypeMirrorHandle;
1.93 -import org.netbeans.api.java.source.support.CancellableTreePathScanner;
1.94 -import org.netbeans.spi.editor.hints.ErrorDescription;
1.95 -import org.netbeans.spi.editor.hints.Fix;
1.96 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
1.97 -import org.openide.filesystems.FileUtil;
1.98 -import org.openide.modules.InstalledFileLocator;
1.99 -import org.openide.util.Exceptions;
1.100 -
1.101 -import org.openide.util.lookup.ServiceProvider;
1.102 -import static org.netbeans.modules.jackpot30.transformers.Annotations.*;
1.103 -
1.104 -/**
1.105 - *
1.106 - * @author Jan Lahoda
1.107 - */
1.108 -@ServiceProvider(service=ElementBasedHintProvider.class)
1.109 -public class TransformationHintProviderImpl implements ElementBasedHintProvider {
1.110 -
1.111 - private JavaSource prepareJavaSource(CompilationInfo info) {
1.112 - ClasspathInfo currentCP = info.getClasspathInfo();
1.113 - ClassPath overlayCompileCP = prepareOverlayCompileCP();
1.114 - ClassPath extendedCompileCP = ClassPathSupport.createProxyClassPath(overlayCompileCP, currentCP.getClassPath(PathKind.COMPILE));
1.115 - ClassPath overlayBootCP = prepareOverlayBootCP();
1.116 - ClassPath extendedBootCP = ClassPathSupport.createProxyClassPath(overlayBootCP, currentCP.getClassPath(PathKind.BOOT));
1.117 - ClasspathInfo extendedCPInfo = ClasspathInfo.create(extendedBootCP, extendedCompileCP, currentCP.getClassPath(PathKind.SOURCE));
1.118 -
1.119 - return JavaSource.create(extendedCPInfo);
1.120 - }
1.121 -
1.122 - public Collection<? extends HintDescription> computeHints(final CompilationInfo info) {
1.123 - final List<HintDescription> hints = new LinkedList<HintDescription>();
1.124 -
1.125 - if (ANNOTATIONS_JAR != null && (JDK_OVERLAY_JAR != null || NB_OVERLAY_JAR != null)) {
1.126 - try {
1.127 - prepareJavaSource(info).runUserActionTask(new Task<CompilationController>() {
1.128 - public void run(final CompilationController overlayInfo) throws Exception {
1.129 - List<HintDescription> w = doComputeHints(info, overlayInfo);
1.130 -
1.131 - if (w != null) {
1.132 - hints.addAll(w);
1.133 - }
1.134 - }
1.135 - }, true);
1.136 - } catch (IOException ex) {
1.137 - Exceptions.printStackTrace(ex);
1.138 - }
1.139 - } else {
1.140 - List<HintDescription> w = doComputeHints(info, null);
1.141 -
1.142 - if (w != null) {
1.143 - hints.addAll(w);
1.144 - }
1.145 - }
1.146 -
1.147 - return hints;
1.148 - }
1.149 -
1.150 - private static final Set<ElementKind> KINDS_FOR_ELEMENT_HANDLE = EnumSet.of(
1.151 - ElementKind.PACKAGE, ElementKind.CLASS, ElementKind.INTERFACE, ElementKind.ENUM,
1.152 - ElementKind.ANNOTATION_TYPE, ElementKind.METHOD, ElementKind.CONSTRUCTOR,
1.153 - ElementKind.INSTANCE_INIT, ElementKind.STATIC_INIT, ElementKind.FIELD,
1.154 - ElementKind.ENUM_CONSTANT);
1.155 -
1.156 - private List<HintDescription> doComputeHints(CompilationInfo info,
1.157 - CompilationInfo overlayInfo) {
1.158 -
1.159 - FindAnnotation ann = new FindAnnotation(info, overlayInfo, /*XXX*/new AtomicBoolean());
1.160 -
1.161 - ann.scan(info.getCompilationUnit(), null);
1.162 -
1.163 - return ann.hints;
1.164 - }
1.165 -
1.166 - private final class FindAnnotation extends CancellableTreePathScanner<Void, Void> {
1.167 -
1.168 - private final CompilationInfo info;
1.169 - private final CompilationInfo overlayInfo;
1.170 - private final List<HintDescription> hints = new LinkedList<HintDescription>();
1.171 -
1.172 - public FindAnnotation(CompilationInfo info, CompilationInfo overlayInfo, AtomicBoolean cancel) {
1.173 - super(cancel);
1.174 - this.info = info;
1.175 - this.overlayInfo = overlayInfo;
1.176 - }
1.177 -
1.178 - private final Set<Element> handledElements = new HashSet<Element>();
1.179 -
1.180 - private void handleElementImpl(Element el) {
1.181 - if (!handledElements.add(el)) return ;
1.182 -
1.183 - List<HintDescription> currentHints = processAnnotations(el, el.getEnclosingElement(), info, info);
1.184 -
1.185 - if (overlayInfo != null && currentHints.isEmpty() && KINDS_FOR_ELEMENT_HANDLE.contains(el.getKind())) {
1.186 - Element overlay = ElementHandle.create(el).resolve(overlayInfo);
1.187 -
1.188 - if (overlay != null) {
1.189 - currentHints = processAnnotations(overlay, overlay.getEnclosingElement(), info, overlayInfo);
1.190 - }
1.191 - }
1.192 -
1.193 - this.hints.addAll(currentHints);
1.194 - }
1.195 -
1.196 - private void handleElement(Element el) {
1.197 - PackageElement p = info.getElements().getPackageOf(el);
1.198 -
1.199 - while (p != el) {
1.200 - handleElementImpl(el);
1.201 - el = el.getEnclosingElement();
1.202 - }
1.203 -
1.204 - handleElementImpl(p);
1.205 - }
1.206 -
1.207 - @Override
1.208 - public Void scan(Tree tree, Void p) {
1.209 - if (tree == null) return null;
1.210 -
1.211 - TreePath tp = new TreePath(getCurrentPath(), tree);
1.212 - Element el = info.getTrees().getElement(tp);
1.213 -
1.214 - if (el != null) {
1.215 - handleElement(el);
1.216 - }
1.217 -
1.218 - return super.scan(tree, p);
1.219 - }
1.220 - }
1.221 -
1.222 - private static final class WorkerImpl implements Worker {
1.223 -
1.224 - private final String displayName;
1.225 - private final List<FixDescription> fixDescriptions;
1.226 -
1.227 - public WorkerImpl(String displayName, List<FixDescription> fixDescriptions) {
1.228 - this.displayName = displayName;
1.229 - this.fixDescriptions = fixDescriptions;
1.230 - }
1.231 -
1.232 - public Collection<? extends ErrorDescription> createErrors(HintContext ctx) {
1.233 - //XXX: antipatterns not supported by the current infrastructure
1.234 -// TreePath tp = treePath;
1.235 -//
1.236 -// while (tp != null) {
1.237 -// if (!pd.getPattern().checkAntipatterns(tp)) {
1.238 -// return null;
1.239 -// }
1.240 -//
1.241 -// tp = tp.getParentPath();
1.242 -// }
1.243 -
1.244 - List<Fix> fixes = new LinkedList<Fix>();
1.245 -
1.246 - for (FixDescription d : fixDescriptions) {
1.247 - String dn = d.getDisplayName();
1.248 -
1.249 - if (dn.length() == 0) {
1.250 - dn = defaultFixDisplayName(ctx.getInfo(), ctx.getVariables(), d);
1.251 - }
1.252 -
1.253 - fixes.add(JavaFix.rewriteFix(ctx.getInfo(), dn, ctx.getPath(), d.getPattern(), ctx.getVariables(), ctx.getMultiVariables(), ctx.getVariableNames(), Collections.<String, TypeMirror>emptyMap()/*XXX: pd.pattern.getConstraints()*/));
1.254 - }
1.255 -
1.256 - return Collections.singletonList(ErrorDescriptionFactory.forName(ctx, ctx.getPath(), displayName, fixes.toArray(new Fix[0])));
1.257 - }
1.258 - }
1.259 -
1.260 - private static <T> T findValue(AnnotationMirror m, String name, Class<T> clazz) {
1.261 - for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e : m.getElementValues().entrySet()) {
1.262 - if (name.equals(e.getKey().getSimpleName().toString())) {
1.263 - return clazz.cast(e.getValue().getValue());
1.264 - }
1.265 - }
1.266 -
1.267 - TypeElement te = (TypeElement) m.getAnnotationType().asElement();
1.268 -
1.269 - for (ExecutableElement ee : ElementFilter.methodsIn(te.getEnclosedElements())) {
1.270 - if (name.equals(ee.getSimpleName().toString())) {
1.271 - if (ee.getDefaultValue() == null) {
1.272 - return null;
1.273 - }
1.274 - return clazz.cast(ee.getDefaultValue().getValue());
1.275 - }
1.276 - }
1.277 -
1.278 - return null;
1.279 - }
1.280 -
1.281 - private static HintDescription create(CompilationInfo info, Element el, AnnotationMirror transformation, String id, CompilationInfo fake) {
1.282 - Collection rawPatterns = findValue(transformation, "pattern", Collection.class);
1.283 -
1.284 - if (rawPatterns == null || rawPatterns.isEmpty()) {
1.285 - return null;
1.286 - }
1.287 -
1.288 - Iterable<AnnotationMirror> patterns = Utilities.checkedIterableByFilter(rawPatterns, AnnotationMirror.class, true);
1.289 -
1.290 - String patternString = findValue(patterns.iterator().next(), "value", String.class);
1.291 -
1.292 - if (patternString == null) {
1.293 - return null;
1.294 - }
1.295 -
1.296 - Collection rawConstraints = findValue(transformation, "constraint", Collection.class);
1.297 -
1.298 - if (rawConstraints == null) {
1.299 - return null;
1.300 - }
1.301 -
1.302 - Iterable<AnnotationMirror> constraints = Utilities.checkedIterableByFilter(rawConstraints, AnnotationMirror.class, true);
1.303 - Map<String, String> variableTypes = new HashMap<String, String>();
1.304 -
1.305 - for (AnnotationMirror m : constraints) {
1.306 - String var = findValue(m, "variable", String.class);
1.307 - TypeMirror tm = findValue(m, "type", TypeMirror.class);
1.308 -
1.309 - if (var == null || tm == null) {
1.310 - return null;
1.311 - }
1.312 -
1.313 - variableTypes.put(var, tm.toString()); //XXX: toString()
1.314 - }
1.315 -
1.316 - if (!el.getModifiers().contains(Modifier.STATIC) && !variableTypes.containsKey("$this")) {
1.317 - TypeMirror parent = el.getEnclosingElement().asType();
1.318 -
1.319 - variableTypes.put("$this", TypeMirrorHandle.create(fake.getTypes().erasure(parent)).resolve(info).toString()); //XXX: toString()
1.320 - }
1.321 -
1.322 - List<String> aps = new LinkedList<String>();
1.323 -
1.324 - for (AnnotationMirror ap : Utilities.checkedIterableByFilter(findValue(transformation, "antipattern", Collection.class), AnnotationMirror.class, true)) {
1.325 - aps.add(findValue(ap, "value", String.class));
1.326 - }
1.327 -
1.328 - List<FixDescription> fixes = new LinkedList<FixDescription>();
1.329 - Collection rawFixes = findValue(transformation, "fix", Collection.class);
1.330 -
1.331 - if (rawFixes == null) {
1.332 - return null;
1.333 - }
1.334 -
1.335 - for (AnnotationMirror f : Utilities.checkedIterableByFilter(rawFixes, AnnotationMirror.class, true)) {
1.336 - String dn = findValue(f, "displayName", String.class);
1.337 - String to = findValue(f, "value", String.class);
1.338 -
1.339 - if (dn == null || to == null) {
1.340 - return null;
1.341 - }
1.342 -
1.343 - fixes.add(new FixDescription(dn, to));
1.344 - }
1.345 -
1.346 - String displayName = findValue(transformation, "displayName", String.class);
1.347 -
1.348 - if (displayName == null) {
1.349 - return null;//XXX
1.350 - }
1.351 -
1.352 - HintMetadata hm = HintMetadata.Builder.create(id).setDescription(displayName, displayName).setCategory(CATEGORY).build();
1.353 -
1.354 - return HintDescriptionFactory.create()
1.355 - .setMetadata(hm)
1.356 - .setTrigger(PatternDescription.create(patternString, variableTypes))
1.357 - .setWorker(new WorkerImpl(displayName, fixes))
1.358 - .produce();
1.359 - }
1.360 -
1.361 - private static final String CATEGORY = "Transformations";
1.362 -
1.363 - private static final class FixDescription {
1.364 - private final String displayName;
1.365 - private final String pattern;
1.366 -
1.367 - public FixDescription(String displayName, String pattern) {
1.368 - this.displayName = displayName;
1.369 - this.pattern = pattern;
1.370 - }
1.371 -
1.372 - public String getDisplayName() {
1.373 - return displayName;
1.374 - }
1.375 -
1.376 - public String getPattern() {
1.377 - return pattern;
1.378 - }
1.379 -
1.380 - }
1.381 -
1.382 - private static final File ANNOTATIONS_JAR;
1.383 - private static final File NB_OVERLAY_JAR;
1.384 - private static final File JDK_OVERLAY_JAR;
1.385 -
1.386 - static {
1.387 - ANNOTATIONS_JAR = InstalledFileLocator.getDefault().locate("libs/annotations.jar", null, false);
1.388 - NB_OVERLAY_JAR = InstalledFileLocator.getDefault().locate("overlay/org-netbeans-nboverlay.jar", null, false);
1.389 - JDK_OVERLAY_JAR = InstalledFileLocator.getDefault().locate("overlay/jdk.jar", null, false);
1.390 - }
1.391 -
1.392 - private ClassPath prepareOverlayCompileCP() throws IllegalArgumentException {
1.393 - if (NB_OVERLAY_JAR ==null) {
1.394 - return ClassPathSupport.createClassPath(new URL[0]);
1.395 - }
1.396 -
1.397 - return ClassPathSupport.createClassPath(FileUtil.urlForArchiveOrDir(NB_OVERLAY_JAR));
1.398 - }
1.399 -
1.400 - private ClassPath prepareOverlayBootCP() throws IllegalArgumentException {
1.401 - if (ANNOTATIONS_JAR == null) {
1.402 - return ClassPathSupport.createClassPath(new URL[0]);
1.403 - }
1.404 -
1.405 - if (JDK_OVERLAY_JAR == null) {
1.406 - return ClassPathSupport.createClassPath(FileUtil.urlForArchiveOrDir(ANNOTATIONS_JAR));
1.407 - }
1.408 -
1.409 - return ClassPathSupport.createClassPath(FileUtil.urlForArchiveOrDir(ANNOTATIONS_JAR), FileUtil.urlForArchiveOrDir(JDK_OVERLAY_JAR));
1.410 - }
1.411 -
1.412 - private List<HintDescription> processAnnotations(Element e, Element enclosing, CompilationInfo info, CompilationInfo fake) {
1.413 - boolean foundTransformations = false;
1.414 - List<HintDescription> result = new LinkedList<HintDescription>();
1.415 - String id;
1.416 - switch (e.getKind()) {
1.417 - case ANNOTATION_TYPE:
1.418 - case CLASS:
1.419 - case ENUM:
1.420 - case INTERFACE:
1.421 - id = fake.getElements().getBinaryName((TypeElement) e).toString();
1.422 - break;
1.423 - case FIELD:
1.424 - case ENUM_CONSTANT:
1.425 - id = fake.getElements().getBinaryName((TypeElement) enclosing).toString() + e.getSimpleName().toString();
1.426 - break;
1.427 - case CONSTRUCTOR:
1.428 - case METHOD:
1.429 - //XXX: parameters!
1.430 - id = fake.getElements().getBinaryName((TypeElement) enclosing).toString() + e.getSimpleName().toString();
1.431 - break;
1.432 - default:
1.433 - id = "no-id";
1.434 - break;
1.435 - }
1.436 -
1.437 - int index = 0;
1.438 -
1.439 - for (AnnotationMirror am : e.getAnnotationMirrors()) {
1.440 - String fqn = ((TypeElement) am.getAnnotationType().asElement()).getQualifiedName().toString();
1.441 - List<AnnotationMirror> transformations = new LinkedList<AnnotationMirror>();
1.442 - if (TRANSFORMATION.toFQN().equals(fqn)) {
1.443 - transformations.add(am);
1.444 - foundTransformations = true;
1.445 - }
1.446 - if (TRANSFORMATION_SET.toFQN().equals(fqn)) {
1.447 - for (AnnotationMirror m : Utilities.checkedIterableByFilter(findValue(am, "value", Collection.class), AnnotationMirror.class, true)) {
1.448 - transformations.add(m);
1.449 - }
1.450 - foundTransformations = true;
1.451 - }
1.452 -
1.453 - for (AnnotationMirror t : transformations) {
1.454 - HintDescription pd = create(info, e, t, id + "-" + (index++), fake);
1.455 -
1.456 - if (pd != null) {
1.457 - result.add(pd);
1.458 - }
1.459 - }
1.460 - }
1.461 -
1.462 - if (!foundTransformations && e.getKind() == ElementKind.METHOD) {
1.463 - TypeElement owner = (TypeElement) e.getEnclosingElement();
1.464 -
1.465 - for (TypeMirror tm : fake.getTypes().directSupertypes(owner.asType())) {
1.466 - DeclaredType dt = (DeclaredType) tm;
1.467 - TypeElement parent = (TypeElement) dt.asElement();
1.468 -
1.469 - for (ExecutableElement ee : ElementFilter.methodsIn(parent.getEnclosedElements())) {
1.470 - if (!fake.getElements().overrides((ExecutableElement) e, ee, (TypeElement) enclosing)) {
1.471 - continue;
1.472 - }
1.473 - List<HintDescription> r = processAnnotations(ee, enclosing, info, fake);
1.474 -
1.475 - result.addAll(r);
1.476 - }
1.477 -
1.478 - }
1.479 - }
1.480 -
1.481 - return result;
1.482 - }
1.483 -
1.484 - private static String defaultFixDisplayName(CompilationInfo info, Map<String, TreePath> variables, FixDescription d) {
1.485 - Map<String, String> stringsForVariables = new HashMap<String, String>();
1.486 -
1.487 - for (Entry<String, TreePath> e : variables.entrySet()) {
1.488 - Tree t = e.getValue().getLeaf();
1.489 - SourcePositions sp = info.getTrees().getSourcePositions();
1.490 - int startPos = (int) sp.getStartPosition(info.getCompilationUnit(), t);
1.491 - int endPos = (int) sp.getEndPosition(info.getCompilationUnit(), t);
1.492 -
1.493 - stringsForVariables.put(e.getKey(), info.getText().substring(startPos, endPos));
1.494 - }
1.495 -
1.496 - if (!stringsForVariables.containsKey("$this")) {
1.497 - stringsForVariables.put("$this", "this");
1.498 - }
1.499 -
1.500 - String replaceTarget = d.getPattern();
1.501 -
1.502 - for (Entry<String, String> e : stringsForVariables.entrySet()) {
1.503 - String quotedVariable = java.util.regex.Pattern.quote(e.getKey());
1.504 - String quotedTarget = Matcher.quoteReplacement(e.getValue());
1.505 - replaceTarget = replaceTarget.replaceAll(quotedVariable, quotedTarget);
1.506 - }
1.507 -
1.508 - return "Rewrite to " + replaceTarget;
1.509 - }
1.510 -
1.511 -}