sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFixUtilities.java
1.1 --- a/sandbox/java.hints/spi.java.hints/src/org/netbeans/spi/java/hints/JavaFixUtilities.java Mon Dec 19 11:37:36 2016 +0100
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,1642 +0,0 @@
1.4 -/*
1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6 - *
1.7 - * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
1.8 - *
1.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
1.10 - * Other names may be trademarks of their respective owners.
1.11 - *
1.12 - * The contents of this file are subject to the terms of either the GNU
1.13 - * General Public License Version 2 only ("GPL") or the Common
1.14 - * Development and Distribution License("CDDL") (collectively, the
1.15 - * "License"). You may not use this file except in compliance with the
1.16 - * License. You can obtain a copy of the License at
1.17 - * http://www.netbeans.org/cddl-gplv2.html
1.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
1.19 - * specific language governing permissions and limitations under the
1.20 - * License. When distributing the software, include this License Header
1.21 - * Notice in each file and include the License file at
1.22 - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
1.23 - * particular file as subject to the "Classpath" exception as provided
1.24 - * by Oracle in the GPL Version 2 section of the License file that
1.25 - * accompanied this code. If applicable, add the following below the
1.26 - * License Header, with the fields enclosed by brackets [] replaced by
1.27 - * your own identifying information:
1.28 - * "Portions Copyrighted [year] [name of copyright owner]"
1.29 - *
1.30 - * If you wish your version of this file to be governed by only the CDDL
1.31 - * or only the GPL Version 2, indicate your decision by adding
1.32 - * "[Contributor] elects to include this software in this distribution
1.33 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
1.34 - * single choice of license, a recipient has the option to distribute
1.35 - * your version of this file under either the CDDL, the GPL Version 2 or
1.36 - * to extend the choice of license to its licensees as provided above.
1.37 - * However, if you add GPL Version 2 code and therefore, elected the GPL
1.38 - * Version 2 license, then the option applies only if the new code is
1.39 - * made subject to such option by the copyright holder.
1.40 - *
1.41 - * Contributor(s):
1.42 - *
1.43 - * Portions Copyrighted 2012 Sun Microsystems, Inc.
1.44 - */
1.45 -package org.netbeans.spi.java.hints;
1.46 -
1.47 -import com.sun.javadoc.Doc;
1.48 -import com.sun.javadoc.Tag;
1.49 -import com.sun.source.tree.AnnotationTree;
1.50 -import com.sun.source.tree.AssignmentTree;
1.51 -import com.sun.source.tree.BinaryTree;
1.52 -import com.sun.source.tree.BlockTree;
1.53 -import com.sun.source.tree.CaseTree;
1.54 -import com.sun.source.tree.CatchTree;
1.55 -import com.sun.source.tree.ClassTree;
1.56 -import com.sun.source.tree.CompilationUnitTree;
1.57 -import com.sun.source.tree.CompoundAssignmentTree;
1.58 -import com.sun.source.tree.ExpressionStatementTree;
1.59 -import com.sun.source.tree.ExpressionTree;
1.60 -import com.sun.source.tree.IdentifierTree;
1.61 -import com.sun.source.tree.IfTree;
1.62 -import com.sun.source.tree.LambdaExpressionTree;
1.63 -import com.sun.source.tree.LiteralTree;
1.64 -import com.sun.source.tree.MemberSelectTree;
1.65 -import com.sun.source.tree.MethodInvocationTree;
1.66 -import com.sun.source.tree.MethodTree;
1.67 -import com.sun.source.tree.ModifiersTree;
1.68 -import com.sun.source.tree.NewArrayTree;
1.69 -import com.sun.source.tree.NewClassTree;
1.70 -import com.sun.source.tree.ParameterizedTypeTree;
1.71 -import com.sun.source.tree.ParenthesizedTree;
1.72 -import com.sun.source.tree.Scope;
1.73 -import com.sun.source.tree.StatementTree;
1.74 -import com.sun.source.tree.SwitchTree;
1.75 -import com.sun.source.tree.Tree;
1.76 -import com.sun.source.tree.Tree.Kind;
1.77 -import com.sun.source.tree.TryTree;
1.78 -import com.sun.source.tree.TypeParameterTree;
1.79 -import com.sun.source.tree.UnaryTree;
1.80 -import com.sun.source.tree.UnionTypeTree;
1.81 -import com.sun.source.tree.VariableTree;
1.82 -import com.sun.source.util.SourcePositions;
1.83 -import com.sun.source.util.TreePath;
1.84 -import com.sun.source.util.TreePathScanner;
1.85 -import com.sun.source.util.TreeScanner;
1.86 -import java.io.IOException;
1.87 -import java.util.ArrayList;
1.88 -import java.util.Arrays;
1.89 -import java.util.Collection;
1.90 -import java.util.Collections;
1.91 -import java.util.EnumMap;
1.92 -import java.util.EnumSet;
1.93 -import java.util.HashMap;
1.94 -import java.util.IdentityHashMap;
1.95 -import java.util.Iterator;
1.96 -import java.util.LinkedList;
1.97 -import java.util.List;
1.98 -import java.util.Map;
1.99 -import java.util.Map.Entry;
1.100 -import java.util.Set;
1.101 -import java.util.concurrent.Callable;
1.102 -import java.util.logging.Level;
1.103 -import java.util.logging.Logger;
1.104 -import java.util.regex.Matcher;
1.105 -import javax.lang.model.element.Element;
1.106 -import javax.lang.model.element.ElementKind;
1.107 -import javax.lang.model.element.Modifier;
1.108 -import javax.lang.model.element.TypeElement;
1.109 -import javax.lang.model.type.TypeKind;
1.110 -import javax.lang.model.type.TypeMirror;
1.111 -import org.netbeans.api.java.classpath.ClassPath;
1.112 -import org.netbeans.api.java.classpath.ClassPath.PathConversionMode;
1.113 -import org.netbeans.api.java.queries.SourceForBinaryQuery;
1.114 -import org.netbeans.api.java.source.ClasspathInfo;
1.115 -import org.netbeans.api.java.source.ClasspathInfo.PathKind;
1.116 -import org.netbeans.api.java.source.CompilationInfo;
1.117 -import org.netbeans.api.java.source.SourceUtils;
1.118 -import org.netbeans.api.java.source.TreeMaker;
1.119 -import org.netbeans.api.java.source.TreePathHandle;
1.120 -import org.netbeans.api.java.source.TypeMirrorHandle;
1.121 -import org.netbeans.api.java.source.WorkingCopy;
1.122 -import org.netbeans.api.java.source.matching.Occurrence;
1.123 -import org.netbeans.api.java.source.matching.Pattern;
1.124 -import org.netbeans.api.project.FileOwnerQuery;
1.125 -import org.netbeans.api.project.Project;
1.126 -import org.netbeans.modules.java.hints.spiimpl.Hacks;
1.127 -import org.netbeans.modules.java.hints.spiimpl.Utilities;
1.128 -import org.netbeans.modules.java.hints.spiimpl.ipi.upgrade.ProjectDependencyUpgrader;
1.129 -import org.netbeans.modules.refactoring.spi.SimpleRefactoringElementImplementation;
1.130 -import org.netbeans.spi.editor.hints.Fix;
1.131 -import org.netbeans.spi.java.classpath.support.ClassPathSupport;
1.132 -import org.netbeans.spi.java.hints.JavaFix.TransformationContext;
1.133 -import org.openide.filesystems.FileObject;
1.134 -import org.openide.filesystems.FileUtil;
1.135 -import org.openide.loaders.DataFolder;
1.136 -import org.openide.loaders.DataObject;
1.137 -import org.openide.loaders.DataObjectNotFoundException;
1.138 -import org.openide.modules.SpecificationVersion;
1.139 -import org.openide.text.PositionBounds;
1.140 -import org.openide.util.Exceptions;
1.141 -import org.openide.util.Lookup;
1.142 -import org.openide.util.NbBundle.Messages;
1.143 -import org.openide.util.NbCollections;
1.144 -
1.145 -/**Factory methods for various predefined {@link JavaFix} implementations.
1.146 - *
1.147 - * @author lahvac
1.148 - */
1.149 -public class JavaFixUtilities {
1.150 -
1.151 - /**Prepare a fix that will replace the given tree node ({@code what}) with the
1.152 - * given code. Any variables in the {@code to} pattern will be replaced with their
1.153 - * values from {@link HintContext#getVariables() }, {@link HintContext#getMultiVariables() }
1.154 - * and {@link HintContext#getVariableNames() }.
1.155 - *
1.156 - * @param ctx basic context for which the fix should be created
1.157 - * @param displayName the display name of the fix
1.158 - * @param what the tree node that should be replaced
1.159 - * @param to the new code that should replaced the {@code what} tree node
1.160 - * @return an editor fix that performs the required transformation
1.161 - */
1.162 - public static Fix rewriteFix(HintContext ctx, String displayName, TreePath what, final String to) {
1.163 - return rewriteFix(ctx.getInfo(), displayName, what, to, ctx.getVariables(), ctx.getMultiVariables(), ctx.getVariableNames(), ctx.getConstraints(), Collections.<String, String>emptyMap());
1.164 - }
1.165 -
1.166 - static Fix rewriteFix(CompilationInfo info, String displayName, TreePath what, final String to, Map<String, TreePath> parameters, Map<String, Collection<? extends TreePath>> parametersMulti, final Map<String, String> parameterNames, Map<String, TypeMirror> constraints, Map<String, String> options, String... imports) {
1.167 - final Map<String, TreePathHandle> params = new HashMap<String, TreePathHandle>();
1.168 - final Map<String, Object> extraParamsData = new HashMap<String, Object>();
1.169 -
1.170 - for (Entry<String, TreePath> e : parameters.entrySet()) {
1.171 - params.put(e.getKey(), TreePathHandle.create(e.getValue(), info));
1.172 - if (e.getValue() instanceof Callable) {
1.173 - try {
1.174 - extraParamsData.put(e.getKey(), ((Callable) e.getValue()).call());
1.175 - } catch (Exception ex) {
1.176 - Exceptions.printStackTrace(ex);
1.177 - }
1.178 - }
1.179 - }
1.180 -
1.181 - final Map<String, Collection<TreePathHandle>> paramsMulti = new HashMap<String, Collection<TreePathHandle>>();
1.182 -
1.183 - for (Entry<String, Collection<? extends TreePath>> e : parametersMulti.entrySet()) {
1.184 - Collection<TreePathHandle> tph = new LinkedList<TreePathHandle>();
1.185 -
1.186 - for (TreePath tp : e.getValue()) {
1.187 - tph.add(TreePathHandle.create(tp, info));
1.188 - }
1.189 -
1.190 - paramsMulti.put(e.getKey(), tph);
1.191 - }
1.192 -
1.193 - final Map<String, TypeMirrorHandle<?>> constraintsHandles = new HashMap<String, TypeMirrorHandle<?>>();
1.194 -
1.195 - for (Entry<String, TypeMirror> c : constraints.entrySet()) {
1.196 - constraintsHandles.put(c.getKey(), TypeMirrorHandle.create(c.getValue()));
1.197 - }
1.198 -
1.199 - if (displayName == null) {
1.200 - displayName = defaultFixDisplayName(info, parameters, to);
1.201 - }
1.202 -
1.203 - return new JavaFixRealImpl(info, what, options, displayName, to, params, extraParamsData, paramsMulti, parameterNames, constraintsHandles, Arrays.asList(imports)).toEditorFix();
1.204 - }
1.205 -
1.206 - /**Creates a fix that removes the given code corresponding to the given tree
1.207 - * node from the source code.
1.208 - *
1.209 - * @param ctx basic context for which the fix should be created
1.210 - * @param displayName the display name of the fix
1.211 - * @param what the tree node that should be removed
1.212 - * @return an editor fix that removes the give tree from the source code
1.213 - */
1.214 - public static Fix removeFromParent(HintContext ctx, String displayName, TreePath what) {
1.215 - return new RemoveFromParent(displayName, ctx.getInfo(), what).toEditorFix();
1.216 - }
1.217 -
1.218 - private static String defaultFixDisplayName(CompilationInfo info, Map<String, TreePath> variables, String replaceTarget) {
1.219 - Map<String, String> stringsForVariables = new HashMap<String, String>();
1.220 -
1.221 - for (Entry<String, TreePath> e : variables.entrySet()) {
1.222 - Tree t = e.getValue().getLeaf();
1.223 - SourcePositions sp = info.getTrees().getSourcePositions();
1.224 - int startPos = (int) sp.getStartPosition(info.getCompilationUnit(), t);
1.225 - int endPos = (int) sp.getEndPosition(info.getCompilationUnit(), t);
1.226 -
1.227 - if (startPos >= 0 && endPos >= 0) {
1.228 - stringsForVariables.put(e.getKey(), info.getText().substring(startPos, endPos));
1.229 - } else {
1.230 - stringsForVariables.put(e.getKey(), "");
1.231 - }
1.232 - }
1.233 -
1.234 - if (!stringsForVariables.containsKey("$this")) {
1.235 - //XXX: is this correct?
1.236 - stringsForVariables.put("$this", "this");
1.237 - }
1.238 -
1.239 - for (Entry<String, String> e : stringsForVariables.entrySet()) {
1.240 - String quotedVariable = java.util.regex.Pattern.quote(e.getKey());
1.241 - String quotedTarget = Matcher.quoteReplacement(e.getValue());
1.242 - replaceTarget = replaceTarget.replaceAll(quotedVariable, quotedTarget);
1.243 - }
1.244 -
1.245 - return "Rewrite to " + replaceTarget;
1.246 - }
1.247 -
1.248 - private static void checkDependency(CompilationInfo copy, Element e, boolean canShowUI) {
1.249 - SpecificationVersion sv = computeSpecVersion(copy, e);
1.250 -
1.251 - while (sv == null && e.getKind() != ElementKind.PACKAGE) {
1.252 - e = e.getEnclosingElement();
1.253 - sv = computeSpecVersion(copy, e);
1.254 - }
1.255 -
1.256 - if (sv == null) {
1.257 - return ;
1.258 - }
1.259 -
1.260 - Project currentProject = FileOwnerQuery.getOwner(copy.getFileObject());
1.261 -
1.262 - if (currentProject == null) {
1.263 - return ;
1.264 - }
1.265 -
1.266 - FileObject file = getFile(copy, e);
1.267 -
1.268 - if (file == null) {
1.269 - return ;
1.270 - }
1.271 -
1.272 - FileObject root = findRootForFile(file, copy.getClasspathInfo());
1.273 -
1.274 - if (root == null) {
1.275 - return ;
1.276 - }
1.277 -
1.278 - Project referedProject = FileOwnerQuery.getOwner(file);
1.279 -
1.280 - if (referedProject != null && currentProject.getProjectDirectory().equals(referedProject.getProjectDirectory())) {
1.281 - return ;
1.282 - }
1.283 -
1.284 - for (ProjectDependencyUpgrader pdu : Lookup.getDefault().lookupAll(ProjectDependencyUpgrader.class)) {
1.285 - if (pdu.ensureDependency(currentProject, root, sv, canShowUI)) {
1.286 - return ;
1.287 - }
1.288 - }
1.289 - }
1.290 -
1.291 - private static java.util.regex.Pattern SPEC_VERSION = java.util.regex.Pattern.compile("[0-9]+(\\.[0-9]+)+");
1.292 -
1.293 - static SpecificationVersion computeSpecVersion(CompilationInfo info, Element el) {
1.294 - if (!Utilities.isJavadocSupported(info)) return null;
1.295 -
1.296 - Doc javaDoc = info.getElementUtilities().javaDocFor(el);
1.297 -
1.298 - if (javaDoc == null) return null;
1.299 -
1.300 - for (Tag since : javaDoc.tags("@since")) {
1.301 - String text = since.text();
1.302 -
1.303 - Matcher m = SPEC_VERSION.matcher(text);
1.304 -
1.305 - if (!m.find()) {
1.306 - continue;
1.307 - }
1.308 -
1.309 - return new SpecificationVersion(m.group()/*ver.toString()*/);
1.310 - }
1.311 -
1.312 - return null;
1.313 - }
1.314 -
1.315 - @SuppressWarnings("deprecation")
1.316 - private static FileObject getFile(CompilationInfo copy, Element e) {
1.317 - return SourceUtils.getFile(e, copy.getClasspathInfo());
1.318 - }
1.319 -
1.320 - private static FileObject findRootForFile(final FileObject file, final ClasspathInfo cpInfo) {
1.321 - ClassPath cp = ClassPathSupport.createProxyClassPath(
1.322 - new ClassPath[] {
1.323 - cpInfo.getClassPath(ClasspathInfo.PathKind.SOURCE),
1.324 - cpInfo.getClassPath(ClasspathInfo.PathKind.BOOT),
1.325 - cpInfo.getClassPath(ClasspathInfo.PathKind.COMPILE),
1.326 - });
1.327 -
1.328 - FileObject root = cp.findOwnerRoot(file);
1.329 -
1.330 - if (root != null) {
1.331 - return root;
1.332 - }
1.333 -
1.334 - for (ClassPath.Entry e : cp.entries()) {
1.335 - FileObject[] sourceRoots = SourceForBinaryQuery.findSourceRoots(e.getURL()).getRoots();
1.336 -
1.337 - if (sourceRoots.length == 0) continue;
1.338 -
1.339 - ClassPath sourcePath = ClassPathSupport.createClassPath(sourceRoots);
1.340 -
1.341 - root = sourcePath.findOwnerRoot(file);
1.342 -
1.343 - if (root != null) {
1.344 - return root;
1.345 - }
1.346 - }
1.347 - return null;
1.348 - }
1.349 -
1.350 - private static boolean isStaticElement(Element el) {
1.351 - if (el == null) return false;
1.352 -
1.353 - if (el.asType() == null || el.asType().getKind() == TypeKind.ERROR) {
1.354 - return false;
1.355 - }
1.356 -
1.357 - if (el.getModifiers().contains(Modifier.STATIC)) {
1.358 - //XXX:
1.359 - if (!el.getKind().isClass() && !el.getKind().isInterface()) {
1.360 - return false;
1.361 - }
1.362 -
1.363 - return true;
1.364 - }
1.365 -
1.366 - if (el.getKind().isClass() || el.getKind().isInterface()) {
1.367 - return el.getEnclosingElement().getKind() == ElementKind.PACKAGE;
1.368 - }
1.369 -
1.370 - return false;
1.371 - }
1.372 -
1.373 - private static class JavaFixRealImpl extends JavaFix {
1.374 - private final String displayName;
1.375 - private final Map<String, TreePathHandle> params;
1.376 - private final Map<String, Object> extraParamsData;
1.377 - private final Map<String, Collection<TreePathHandle>> paramsMulti;
1.378 - private final Map<String, String> parameterNames;
1.379 - private final Map<String, TypeMirrorHandle<?>> constraintsHandles;
1.380 - private final Iterable<? extends String> imports;
1.381 - private final String to;
1.382 -
1.383 - public JavaFixRealImpl(CompilationInfo info, TreePath what, Map<String, String> options, String displayName, String to, Map<String, TreePathHandle> params, Map<String, Object> extraParamsData, Map<String, Collection<TreePathHandle>> paramsMulti, final Map<String, String> parameterNames, Map<String, TypeMirrorHandle<?>> constraintsHandles, Iterable<? extends String> imports) {
1.384 - super(info, what, options);
1.385 -
1.386 - this.displayName = displayName;
1.387 - this.to = to;
1.388 - this.params = params;
1.389 - this.extraParamsData = extraParamsData;
1.390 - this.paramsMulti = paramsMulti;
1.391 - this.parameterNames = parameterNames;
1.392 - this.constraintsHandles = constraintsHandles;
1.393 - this.imports = imports;
1.394 - }
1.395 -
1.396 - @Override
1.397 - protected String getText() {
1.398 - return displayName;
1.399 - }
1.400 -
1.401 - @Override
1.402 - protected void performRewrite(TransformationContext ctx) {
1.403 - final WorkingCopy wc = ctx.getWorkingCopy();
1.404 - TreePath tp = ctx.getPath();
1.405 - final Map<String, TreePath> parameters = new HashMap<String, TreePath>();
1.406 -
1.407 - for (Entry<String, TreePathHandle> e : params.entrySet()) {
1.408 - TreePath p = e.getValue().resolve(wc);
1.409 -
1.410 - if (p == null) {
1.411 - Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", e.getValue());
1.412 - }
1.413 -
1.414 - parameters.put(e.getKey(), p);
1.415 - }
1.416 -
1.417 - final Map<String, Collection<TreePath>> parametersMulti = new HashMap<String, Collection<TreePath>>();
1.418 -
1.419 - for (Entry<String, Collection<TreePathHandle>> e : paramsMulti.entrySet()) {
1.420 - Collection<TreePath> tps = new LinkedList<TreePath>();
1.421 -
1.422 - for (TreePathHandle tph : e.getValue()) {
1.423 - TreePath p = tph.resolve(wc);
1.424 -
1.425 - if (p == null) {
1.426 - Logger.getLogger(JavaFix.class.getName()).log(Level.SEVERE, "Cannot resolve handle={0}", e.getValue());
1.427 - }
1.428 -
1.429 - tps.add(p);
1.430 - }
1.431 -
1.432 - parametersMulti.put(e.getKey(), tps);
1.433 - }
1.434 -
1.435 - Map<String, TypeMirror> constraints = new HashMap<String, TypeMirror>();
1.436 -
1.437 - for (Entry<String, TypeMirrorHandle<?>> c : constraintsHandles.entrySet()) {
1.438 - constraints.put(c.getKey(), c.getValue().resolve(wc));
1.439 - }
1.440 -
1.441 - Scope scope = Utilities.constructScope(wc, constraints, imports);
1.442 -
1.443 - assert scope != null;
1.444 -
1.445 - Tree parsed = Utilities.parseAndAttribute(wc, to, scope);
1.446 -
1.447 - if (parsed.getKind() == Kind.EXPRESSION_STATEMENT && ExpressionTree.class.isAssignableFrom(tp.getLeaf().getKind().asInterface())) {
1.448 - parsed = ((ExpressionStatementTree) parsed).getExpression();
1.449 - }
1.450 -
1.451 - Map<Tree, Tree> rewriteFromTo = new IdentityHashMap<Tree, Tree>();
1.452 - Tree original;
1.453 -
1.454 - if (Utilities.isFakeBlock(parsed)) {
1.455 - TreePath parent = tp.getParentPath();
1.456 - List<? extends StatementTree> statements = ((BlockTree) parsed).getStatements();
1.457 -
1.458 - if (tp.getLeaf().getKind() == Kind.BLOCK) {
1.459 - BlockTree real = (BlockTree) tp.getLeaf();
1.460 - rewriteFromTo.put(original = real, wc.getTreeMaker().Block(statements, real.isStatic()));
1.461 - } else {
1.462 - statements = statements.subList(1, statements.size() - 1);
1.463 -
1.464 - if (parent.getLeaf().getKind() == Kind.BLOCK) {
1.465 - List<StatementTree> newStatements = new LinkedList<StatementTree>();
1.466 -
1.467 - for (StatementTree st : ((BlockTree) parent.getLeaf()).getStatements()) {
1.468 - if (st == tp.getLeaf()) {
1.469 - newStatements.addAll(statements);
1.470 - } else {
1.471 - newStatements.add(st);
1.472 - }
1.473 - }
1.474 -
1.475 - rewriteFromTo.put(original = parent.getLeaf(), wc.getTreeMaker().Block(newStatements, ((BlockTree) parent.getLeaf()).isStatic()));
1.476 - } else {
1.477 - rewriteFromTo.put(original = tp.getLeaf(), wc.getTreeMaker().Block(statements, false));
1.478 - }
1.479 - }
1.480 - } else if (Utilities.isFakeClass(parsed)) {
1.481 - TreePath parent = tp.getParentPath();
1.482 - List<? extends Tree> members = ((ClassTree) parsed).getMembers();
1.483 -
1.484 - members = members.subList(1, members.size());
1.485 -
1.486 - assert parent.getLeaf().getKind() == Kind.CLASS;
1.487 -
1.488 - List<Tree> newMembers = new LinkedList<Tree>();
1.489 -
1.490 - ClassTree ct = (ClassTree) parent.getLeaf();
1.491 -
1.492 - for (Tree t : ct.getMembers()) {
1.493 - if (t == tp.getLeaf()) {
1.494 - newMembers.addAll(members);
1.495 - } else {
1.496 - newMembers.add(t);
1.497 - }
1.498 - }
1.499 -
1.500 - rewriteFromTo.put(original = parent.getLeaf(), wc.getTreeMaker().Class(ct.getModifiers(), ct.getSimpleName(), ct.getTypeParameters(), ct.getExtendsClause(), ct.getImplementsClause(), newMembers));
1.501 - } else if (tp.getLeaf().getKind() == Kind.BLOCK && parametersMulti.containsKey("$$1$") && parsed.getKind() != Kind.BLOCK && StatementTree.class.isAssignableFrom(parsed.getKind().asInterface())) {
1.502 - List<StatementTree> newStatements = new LinkedList<StatementTree>();
1.503 -
1.504 - newStatements.add(wc.getTreeMaker().ExpressionStatement(wc.getTreeMaker().Identifier("$$1$")));
1.505 - newStatements.add((StatementTree) parsed);
1.506 - newStatements.add(wc.getTreeMaker().ExpressionStatement(wc.getTreeMaker().Identifier("$$2$")));
1.507 -
1.508 - parsed = wc.getTreeMaker().Block(newStatements, ((BlockTree) tp.getLeaf()).isStatic());
1.509 -
1.510 - rewriteFromTo.put(original = tp.getLeaf(), parsed);
1.511 - } else {
1.512 - while ( tp.getParentPath().getLeaf().getKind() == Kind.PARENTHESIZED
1.513 - && tp.getLeaf().getKind() != parsed.getKind()
1.514 - && tp.getParentPath() != null
1.515 - && tp.getParentPath().getParentPath() != null
1.516 - && !requiresParenthesis(parsed, tp.getParentPath().getLeaf(), tp.getParentPath().getParentPath().getLeaf())
1.517 - && requiresParenthesis(tp.getLeaf(), tp.getParentPath().getLeaf(), tp.getParentPath().getParentPath().getLeaf()))
1.518 - tp = tp.getParentPath();
1.519 - rewriteFromTo.put(original = tp.getLeaf(), parsed);
1.520 - }
1.521 -
1.522 - //prevent generating QualIdents inside import clauses - might be better to solve that inside ImportAnalysis2,
1.523 - //but that seems not to be straightforward:
1.524 - boolean inImport = parsed.getKind() == Kind.IMPORT;
1.525 - boolean inPackage = false;
1.526 - TreePath w = tp;
1.527 -
1.528 - while (!inImport && w != null) {
1.529 - inImport |= w.getLeaf().getKind() == Kind.IMPORT;
1.530 - inPackage |= w.getParentPath() != null && w.getParentPath().getLeaf().getKind() == Kind.COMPILATION_UNIT && ((CompilationUnitTree) w.getParentPath().getLeaf()).getPackageName() == w.getLeaf();
1.531 - w = w.getParentPath();
1.532 - }
1.533 -
1.534 - final Set<Tree> originalTrees = Collections.newSetFromMap(new IdentityHashMap<Tree, Boolean>());
1.535 -
1.536 - new TreeScanner<Void, Void>() {
1.537 - @Override public Void scan(Tree tree, Void p) {
1.538 - originalTrees.add(tree);
1.539 - return super.scan(tree, p);
1.540 - }
1.541 - }.scan(original, null);
1.542 -
1.543 - new ReplaceParameters(wc, ctx.isCanShowUI(), inImport, parameters, extraParamsData, parametersMulti, parameterNames, rewriteFromTo, originalTrees).scan(new TreePath(tp.getParentPath(), rewriteFromTo.get(original)), null);
1.544 -
1.545 - if (inPackage) {
1.546 - String newPackage = wc.getTreeUtilities().translate(wc.getCompilationUnit().getPackageName(), new IdentityHashMap<Tree, Tree>(rewriteFromTo))./*XXX: not correct*/toString();
1.547 -
1.548 - ClassPath source = wc.getClasspathInfo().getClassPath(PathKind.SOURCE);
1.549 - FileObject ownerRoot = source.findOwnerRoot(wc.getFileObject());
1.550 -
1.551 - if (ownerRoot != null) {
1.552 - ctx.getFileChanges().add(new MoveFile(wc.getFileObject(), ownerRoot, newPackage.replace('.', '/')));
1.553 - } else {
1.554 - Logger.getLogger(JavaFix.class.getName()).log(Level.WARNING, "{0} not on its source path ({1})", new Object[] {FileUtil.getFileDisplayName(wc.getFileObject()), source.toString(PathConversionMode.PRINT)});
1.555 - }
1.556 - }
1.557 -
1.558 - for (Entry<Tree, Tree> e : rewriteFromTo.entrySet()) {
1.559 - wc.rewrite(e.getKey(), e.getValue());
1.560 - }
1.561 - }
1.562 - }
1.563 -
1.564 - private static final Set<Kind> NUMBER_LITERAL_KINDS = EnumSet.of(Kind.FLOAT_LITERAL, Kind.DOUBLE_LITERAL, Kind.INT_LITERAL, Kind.LONG_LITERAL);
1.565 -
1.566 - private static class ReplaceParameters extends TreePathScanner<Number, Void> {
1.567 -
1.568 - private final CompilationInfo info;
1.569 - private final TreeMaker make;
1.570 - private final boolean canShowUI;
1.571 - private final boolean inImport;
1.572 - private final Map<String, TreePath> parameters;
1.573 - private final Map<String, Object> extraParamsData;
1.574 - private final Map<String, Collection<TreePath>> parametersMulti;
1.575 - private final Map<String, String> parameterNames;
1.576 - private final Map<Tree, Tree> rewriteFromTo;
1.577 - private final Set<Tree> originalTrees;
1.578 -
1.579 - public ReplaceParameters(WorkingCopy wc, boolean canShowUI, boolean inImport, Map<String, TreePath> parameters, Map<String, Object> extraParamsData, Map<String, Collection<TreePath>> parametersMulti, Map<String, String> parameterNames, Map<Tree, Tree> rewriteFromTo, Set<Tree> originalTrees) {
1.580 - this.parameters = parameters;
1.581 - this.info = wc;
1.582 - this.make = wc.getTreeMaker();
1.583 - this.canShowUI = canShowUI;
1.584 - this.inImport = inImport;
1.585 - this.extraParamsData = extraParamsData;
1.586 - this.parametersMulti = parametersMulti;
1.587 - this.parameterNames = parameterNames;
1.588 - this.rewriteFromTo = rewriteFromTo;
1.589 - this.originalTrees = originalTrees;
1.590 - }
1.591 -
1.592 - @Override
1.593 - public Number visitIdentifier(IdentifierTree node, Void p) {
1.594 - String name = node.getName().toString();
1.595 - Tree newNode = handleIdentifier(name, node);
1.596 -
1.597 - if (newNode != null) {
1.598 - rewrite(node, newNode);
1.599 - if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) {
1.600 - return (Number) ((LiteralTree) newNode).getValue();
1.601 - }
1.602 - }
1.603 -
1.604 - Element e = info.getTrees().getElement(getCurrentPath());
1.605 -
1.606 - if (e != null && isStaticElement(e) && !inImport) {
1.607 - rewrite(node, make.QualIdent(e));
1.608 - }
1.609 -
1.610 - return super.visitIdentifier(node, p);
1.611 - }
1.612 -
1.613 - @Override
1.614 - public Number visitTypeParameter(TypeParameterTree node, Void p) {
1.615 - String name = node.getName().toString();
1.616 - Tree newNode = handleIdentifier(name, node);
1.617 -
1.618 - if (newNode != null) {
1.619 - rewrite(node, newNode);
1.620 - if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) {
1.621 - return (Number) ((LiteralTree) newNode).getValue();
1.622 - }
1.623 - }
1.624 -
1.625 - return super.visitTypeParameter(node, p);
1.626 - }
1.627 -
1.628 - private Tree handleIdentifier(String name, Tree node) {
1.629 - TreePath tp = parameters.get(name);
1.630 -
1.631 - if (tp != null) {
1.632 - if (tp.getLeaf() instanceof Hacks.RenameTree) {
1.633 - Hacks.RenameTree rt = (Hacks.RenameTree) tp.getLeaf();
1.634 - return make.setLabel(rt.originalTree, rt.newName);
1.635 - }
1.636 - if (!parameterNames.containsKey(name)) {
1.637 - Tree target = tp.getLeaf();
1.638 - if (NUMBER_LITERAL_KINDS.contains(target.getKind())) {
1.639 - return target;
1.640 - }
1.641 - //TODO: might also remove parenthesis, but needs to ensure the diff will still be minimal
1.642 -// while (target.getKind() == Kind.PARENTHESIZED
1.643 -// && !requiresParenthesis(((ParenthesizedTree) target).getExpression(), getCurrentPath().getParentPath().getLeaf())) {
1.644 -// target = ((ParenthesizedTree) target).getExpression();
1.645 -// }
1.646 - if ( getCurrentPath().getParentPath() != null
1.647 - && getCurrentPath().getParentPath().getLeaf().getKind() == Kind.LOGICAL_COMPLEMENT
1.648 - && ( tp.getParentPath() == null
1.649 - || tp.getParentPath().getLeaf().getKind() != Kind.LOGICAL_COMPLEMENT)) {
1.650 - Tree negated = negate((ExpressionTree) tp.getLeaf(), getCurrentPath().getParentPath().getParentPath().getLeaf(), true);
1.651 -
1.652 - if (negated != null) {
1.653 - rewrite(getCurrentPath().getParentPath().getLeaf(), negated);
1.654 - }
1.655 - }
1.656 - if (requiresParenthesis(target, node, getCurrentPath().getParentPath().getLeaf())) {
1.657 - target = make.Parenthesized((ExpressionTree) target);
1.658 - }
1.659 - return target;
1.660 - }
1.661 - }
1.662 -
1.663 - String variableName = parameterNames.get(name);
1.664 -
1.665 - if (variableName != null) {
1.666 - return make.Identifier(variableName);
1.667 - }
1.668 -
1.669 - return null;
1.670 - }
1.671 -
1.672 - @Override
1.673 - public Number visitMemberSelect(MemberSelectTree node, Void p) {
1.674 - Element e = info.getTrees().getElement(getCurrentPath());
1.675 -
1.676 - if (e != null && (e.getKind() != ElementKind.CLASS || ((TypeElement) e).asType().getKind() != TypeKind.ERROR)) {
1.677 - //check correct dependency:
1.678 - checkDependency(info, e, canShowUI);
1.679 -
1.680 - if (isStaticElement(e) && !inImport) {
1.681 - rewrite(node, make.QualIdent(e));
1.682 -
1.683 - return null;
1.684 - }
1.685 - }
1.686 -
1.687 - MemberSelectTree nue = node;
1.688 - String selectedName = node.getIdentifier().toString();
1.689 -
1.690 - if (selectedName.startsWith("$") && parameterNames.get(selectedName) != null) {
1.691 - nue = make.MemberSelect(node.getExpression(), parameterNames.get(selectedName));
1.692 - }
1.693 -
1.694 - if (nue.getExpression().getKind() == Kind.IDENTIFIER) {
1.695 - String name = ((IdentifierTree) nue.getExpression()).getName().toString();
1.696 -
1.697 - if (name.startsWith("$") && parameters.get(name) == null) {
1.698 - //XXX: unbound variable, use identifier instead of member select - may cause problems?
1.699 - rewrite(node, make.Identifier(nue.getIdentifier()));
1.700 - return null;
1.701 - }
1.702 - }
1.703 -
1.704 - if (nue != node) {
1.705 - rewrite(node, nue);
1.706 - }
1.707 -
1.708 - return super.visitMemberSelect(node, p);
1.709 - }
1.710 -
1.711 - @Override
1.712 - public Number visitVariable(VariableTree node, Void p) {
1.713 - String name = node.getName().toString();
1.714 -
1.715 - if (name.startsWith("$")) {
1.716 - String nueName = parameterNames.get(name);
1.717 -
1.718 - if (nueName != null) {
1.719 - name = nueName;
1.720 - }
1.721 - }
1.722 -
1.723 - VariableTree nue = make.Variable(node.getModifiers(), name, node.getType(), resolveOptionalValue(node.getInitializer()));
1.724 -
1.725 - rewrite(node, nue);
1.726 -
1.727 - return super.visitVariable(nue, p);
1.728 - }
1.729 -
1.730 - @Override
1.731 - public Number visitIf(IfTree node, Void p) {
1.732 - IfTree nue = make.If(node.getCondition(), node.getThenStatement(), resolveOptionalValue(node.getElseStatement()));
1.733 -
1.734 - rewrite(node, nue);
1.735 -
1.736 - return super.visitIf(nue, p);
1.737 - }
1.738 -
1.739 - @Override
1.740 - public Number visitMethod(MethodTree node, Void p) {
1.741 - String name = node.getName().toString();
1.742 - String newName = name;
1.743 -
1.744 - if (name.startsWith("$")) {
1.745 - if (parameterNames.containsKey(name)) {
1.746 - newName = parameterNames.get(name);
1.747 - }
1.748 - }
1.749 -
1.750 - List<? extends TypeParameterTree> typeParams = resolveMultiParameters(node.getTypeParameters());
1.751 - List<? extends VariableTree> params = resolveMultiParameters(node.getParameters());
1.752 - List<? extends ExpressionTree> thrown = resolveMultiParameters(node.getThrows());
1.753 -
1.754 - MethodTree nue = make.Method(node.getModifiers(), newName, node.getReturnType(), typeParams, params, thrown, node.getBody(), (ExpressionTree) node.getDefaultValue());
1.755 -
1.756 - rewrite(node, nue);
1.757 -
1.758 - return super.visitMethod(nue, p);
1.759 - }
1.760 -
1.761 - @Override
1.762 - public Number visitClass(ClassTree node, Void p) {
1.763 - String name = node.getSimpleName().toString();
1.764 - String newName = name;
1.765 -
1.766 - if (name.startsWith("$")) {
1.767 - if (parameterNames.containsKey(name)) {
1.768 - newName = parameterNames.get(name);
1.769 - }
1.770 - }
1.771 -
1.772 - List<? extends TypeParameterTree> typeParams = resolveMultiParameters(node.getTypeParameters());
1.773 - List<? extends Tree> implementsClauses = resolveMultiParameters(node.getImplementsClause());
1.774 - List<? extends Tree> members = resolveMultiParameters(Utilities.filterHidden(getCurrentPath(), node.getMembers()));
1.775 - Tree extend = resolveOptionalValue(node.getExtendsClause());
1.776 - ClassTree nue = make.Class(node.getModifiers(), newName, typeParams, extend, implementsClauses, members);
1.777 -
1.778 - rewrite(node, nue);
1.779 -
1.780 - return super.visitClass(nue, p);
1.781 - }
1.782 -
1.783 - @Override
1.784 - public Number visitExpressionStatement(ExpressionStatementTree node, Void p) {
1.785 - CharSequence name = Utilities.getWildcardTreeName(node);
1.786 -
1.787 - if (name != null) {
1.788 - TreePath tp = parameters.get(name.toString());
1.789 -
1.790 - if (tp != null) {
1.791 - rewrite(node, tp.getLeaf());
1.792 - return null;
1.793 - }
1.794 - }
1.795 -
1.796 - return super.visitExpressionStatement(node, p);
1.797 - }
1.798 -
1.799 - @Override
1.800 - public Number visitLiteral(LiteralTree node, Void p) {
1.801 - if (node.getValue() instanceof Number) {
1.802 - return (Number) node.getValue();
1.803 - }
1.804 -
1.805 - return super.visitLiteral(node, p);
1.806 - }
1.807 -
1.808 - @Override
1.809 - public Number visitBinary(BinaryTree node, Void p) {
1.810 - Number left = scan(node.getLeftOperand(), p);
1.811 - Number right = scan(node.getRightOperand(), p);
1.812 -
1.813 - if (left != null && right != null) {
1.814 - Number result = null;
1.815 - switch (node.getKind()) {
1.816 - case MULTIPLY:
1.817 - if (left instanceof Double || right instanceof Double) {
1.818 - result = left.doubleValue() * right.doubleValue();
1.819 - } else if (left instanceof Float || right instanceof Float) {
1.820 - result = left.floatValue() * right.floatValue();
1.821 - } else if (left instanceof Long || right instanceof Long) {
1.822 - result = left.longValue() * right.longValue();
1.823 - } else if (left instanceof Integer || right instanceof Integer) {
1.824 - result = left.intValue() * right.intValue();
1.825 - } else {
1.826 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.827 - }
1.828 - break;
1.829 -
1.830 - case DIVIDE:
1.831 - if (left instanceof Double || right instanceof Double) {
1.832 - result = left.doubleValue() / right.doubleValue();
1.833 - } else if (left instanceof Float || right instanceof Float) {
1.834 - result = left.floatValue() / right.floatValue();
1.835 - } else if (left instanceof Long || right instanceof Long) {
1.836 - result = left.longValue() / right.longValue();
1.837 - } else if (left instanceof Integer || right instanceof Integer) {
1.838 - result = left.intValue() / right.intValue();
1.839 - } else {
1.840 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.841 - }
1.842 - break;
1.843 -
1.844 - case REMAINDER:
1.845 - if (left instanceof Double || right instanceof Double) {
1.846 - result = left.doubleValue() % right.doubleValue();
1.847 - } else if (left instanceof Float || right instanceof Float) {
1.848 - result = left.floatValue() % right.floatValue();
1.849 - } else if (left instanceof Long || right instanceof Long) {
1.850 - result = left.longValue() % right.longValue();
1.851 - } else if (left instanceof Integer || right instanceof Integer) {
1.852 - result = left.intValue() % right.intValue();
1.853 - } else {
1.854 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.855 - }
1.856 - break;
1.857 -
1.858 - case PLUS:
1.859 - if (left instanceof Double || right instanceof Double) {
1.860 - result = left.doubleValue() + right.doubleValue();
1.861 - } else if (left instanceof Float || right instanceof Float) {
1.862 - result = left.floatValue() + right.floatValue();
1.863 - } else if (left instanceof Long || right instanceof Long) {
1.864 - result = left.longValue() + right.longValue();
1.865 - } else if (left instanceof Integer || right instanceof Integer) {
1.866 - result = left.intValue() + right.intValue();
1.867 - } else {
1.868 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.869 - }
1.870 - break;
1.871 -
1.872 - case MINUS:
1.873 - if (left instanceof Double || right instanceof Double) {
1.874 - result = left.doubleValue() - right.doubleValue();
1.875 - } else if (left instanceof Float || right instanceof Float) {
1.876 - result = left.floatValue() - right.floatValue();
1.877 - } else if (left instanceof Long || right instanceof Long) {
1.878 - result = left.longValue() - right.longValue();
1.879 - } else if (left instanceof Integer || right instanceof Integer) {
1.880 - result = left.intValue() - right.intValue();
1.881 - } else {
1.882 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.883 - }
1.884 - break;
1.885 -
1.886 - case LEFT_SHIFT:
1.887 - if (left instanceof Long || right instanceof Long) {
1.888 - result = left.longValue() << right.longValue();
1.889 - } else if (left instanceof Integer || right instanceof Integer) {
1.890 - result = left.intValue() << right.intValue();
1.891 - } else {
1.892 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.893 - }
1.894 - break;
1.895 -
1.896 - case RIGHT_SHIFT:
1.897 - if (left instanceof Long || right instanceof Long) {
1.898 - result = left.longValue() >> right.longValue();
1.899 - } else if (left instanceof Integer || right instanceof Integer) {
1.900 - result = left.intValue() >> right.intValue();
1.901 - } else {
1.902 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.903 - }
1.904 - break;
1.905 -
1.906 - case UNSIGNED_RIGHT_SHIFT:
1.907 - if (left instanceof Long || right instanceof Long) {
1.908 - result = left.longValue() >>> right.longValue();
1.909 - } else if (left instanceof Integer || right instanceof Integer) {
1.910 - result = left.intValue() >>> right.intValue();
1.911 - } else {
1.912 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.913 - }
1.914 - break;
1.915 -
1.916 - case AND:
1.917 - if (left instanceof Long || right instanceof Long) {
1.918 - result = left.longValue() & right.longValue();
1.919 - } else if (left instanceof Integer || right instanceof Integer) {
1.920 - result = left.intValue() & right.intValue();
1.921 - } else {
1.922 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.923 - }
1.924 - break;
1.925 -
1.926 - case XOR:
1.927 - if (left instanceof Long || right instanceof Long) {
1.928 - result = left.longValue() ^ right.longValue();
1.929 - } else if (left instanceof Integer || right instanceof Integer) {
1.930 - result = left.intValue() ^ right.intValue();
1.931 - } else {
1.932 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.933 - }
1.934 - break;
1.935 -
1.936 - case OR:
1.937 - if (left instanceof Long || right instanceof Long) {
1.938 - result = left.longValue() | right.longValue();
1.939 - } else if (left instanceof Integer || right instanceof Integer) {
1.940 - result = left.intValue() | right.intValue();
1.941 - } else {
1.942 - throw new IllegalStateException("left=" + left.getClass() + ", right=" + right.getClass());
1.943 - }
1.944 - break;
1.945 - }
1.946 -
1.947 - if (result != null) {
1.948 - rewrite(node, make.Literal(result));
1.949 -
1.950 - return result;
1.951 - }
1.952 - }
1.953 -
1.954 - return null;
1.955 - }
1.956 -
1.957 - @Override
1.958 - public Number visitUnary(UnaryTree node, Void p) {
1.959 - Number op = scan(node.getExpression(), p);
1.960 -
1.961 - if (op != null) {
1.962 - Number result = null;
1.963 - switch (node.getKind()) {
1.964 - case UNARY_MINUS:
1.965 - if (op instanceof Double) {
1.966 - result = -op.doubleValue();
1.967 - } else if (op instanceof Float) {
1.968 - result = -op.floatValue();
1.969 - } else if (op instanceof Long) {
1.970 - result = -op.longValue();
1.971 - } else if (op instanceof Integer) {
1.972 - result = -op.intValue();
1.973 - } else {
1.974 - throw new IllegalStateException("op=" + op.getClass());
1.975 - }
1.976 - break;
1.977 - case UNARY_PLUS:
1.978 - result = op;
1.979 - break;
1.980 - }
1.981 -
1.982 - if (result != null) {
1.983 - rewrite(node, make.Literal(result));
1.984 -
1.985 - return result;
1.986 - }
1.987 - }
1.988 -
1.989 - return super.visitUnary(node, p);
1.990 - }
1.991 -
1.992 - @Override
1.993 - public Number visitBlock(BlockTree node, Void p) {
1.994 - List<? extends StatementTree> nueStatement = resolveMultiParameters(node.getStatements());
1.995 - BlockTree nue = make.Block(nueStatement, node.isStatic());
1.996 -
1.997 - rewrite(node, nue);
1.998 -
1.999 - return super.visitBlock(nue, p);
1.1000 - }
1.1001 -
1.1002 - @Override
1.1003 - public Number visitCase(CaseTree node, Void p) {
1.1004 - List<? extends StatementTree> statements = (List<? extends StatementTree>) resolveMultiParameters(node.getStatements());
1.1005 - CaseTree nue = make.Case(node.getExpression(), statements);
1.1006 -
1.1007 - rewrite(node, nue);
1.1008 - return super.visitCase(node, p);
1.1009 - }
1.1010 -
1.1011 - @Override
1.1012 - public Number visitMethodInvocation(MethodInvocationTree node, Void p) {
1.1013 - List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
1.1014 - List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
1.1015 - MethodInvocationTree nue = make.MethodInvocation(typeArgs, node.getMethodSelect(), args);
1.1016 -
1.1017 - rewrite(node, nue);
1.1018 -
1.1019 - return super.visitMethodInvocation(nue, p);
1.1020 - }
1.1021 -
1.1022 - @Override
1.1023 - public Number visitNewClass(NewClassTree node, Void p) {
1.1024 - List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
1.1025 - List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
1.1026 - NewClassTree nue = make.NewClass(node.getEnclosingExpression(), typeArgs, node.getIdentifier(), args, node.getClassBody());
1.1027 -
1.1028 - rewrite(node, nue);
1.1029 - return super.visitNewClass(nue, p);
1.1030 - }
1.1031 -
1.1032 - @Override
1.1033 - public Number visitParameterizedType(ParameterizedTypeTree node, Void p) {
1.1034 - List<? extends ExpressionTree> typeArgs = (List<? extends ExpressionTree>) resolveMultiParameters(node.getTypeArguments());
1.1035 - ParameterizedTypeTree nue = make.ParameterizedType(node.getType(), typeArgs);
1.1036 -
1.1037 - rewrite(node, nue);
1.1038 - return super.visitParameterizedType(node, p);
1.1039 - }
1.1040 -
1.1041 - @Override
1.1042 - public Number visitSwitch(SwitchTree node, Void p) {
1.1043 - List<? extends CaseTree> cases = (List<? extends CaseTree>) resolveMultiParameters(node.getCases());
1.1044 - SwitchTree nue = make.Switch(node.getExpression(), cases);
1.1045 -
1.1046 - rewrite(node, nue);
1.1047 - return super.visitSwitch(node, p);
1.1048 - }
1.1049 -
1.1050 - @Override
1.1051 - public Number visitTry(TryTree node, Void p) {
1.1052 - List<? extends Tree> resources = (List<? extends Tree>) resolveMultiParameters(node.getResources());
1.1053 - List<? extends CatchTree> catches = (List<? extends CatchTree>) resolveMultiParameters(node.getCatches());
1.1054 - TryTree nue = make.Try(resources, node.getBlock(), catches, node.getFinallyBlock());
1.1055 -
1.1056 - rewrite(node, nue);
1.1057 - return super.visitTry(node, p);
1.1058 - }
1.1059 -
1.1060 - @Override
1.1061 - public Number visitModifiers(ModifiersTree node, Void p) {
1.1062 - List<AnnotationTree> annotations = new ArrayList<AnnotationTree>(node.getAnnotations());
1.1063 - IdentifierTree ident = !annotations.isEmpty() && annotations.get(0).getAnnotationType().getKind() == Kind.IDENTIFIER ? (IdentifierTree) annotations.get(0).getAnnotationType() : null;
1.1064 -
1.1065 - if (ident != null) {
1.1066 - annotations.remove(0);
1.1067 -
1.1068 - String name = ident.getName().toString();
1.1069 - TreePath orig = parameters.get(name);
1.1070 - ModifiersTree nue;
1.1071 -
1.1072 - if (orig != null && orig.getLeaf().getKind() == Kind.MODIFIERS) {
1.1073 - ModifiersTree origMods = (ModifiersTree) orig.getLeaf();
1.1074 - Object actualContent = extraParamsData.get(name);
1.1075 - Set<Modifier> actualFlags = EnumSet.noneOf(Modifier.class);
1.1076 - boolean[] actualAnnotationsMask = new boolean[0];
1.1077 -
1.1078 - if (actualContent instanceof Object[] && ((Object[]) actualContent)[0] instanceof Set) {
1.1079 - actualFlags.addAll(NbCollections.checkedSetByFilter((Set) ((Object[]) actualContent)[0], Modifier.class, false));
1.1080 - }
1.1081 -
1.1082 - if (actualContent instanceof Object[] && ((Object[]) actualContent)[1] instanceof boolean[]) {
1.1083 - actualAnnotationsMask = (boolean[]) ((Object[]) actualContent)[1];
1.1084 - }
1.1085 -
1.1086 - nue = origMods;
1.1087 -
1.1088 - for (Modifier m : origMods.getFlags()) {
1.1089 - if (actualFlags.contains(m)) continue;
1.1090 - nue = make.removeModifiersModifier(nue, m);
1.1091 - }
1.1092 -
1.1093 - for (Modifier m : node.getFlags()) {
1.1094 - nue = make.addModifiersModifier(nue, m);
1.1095 - }
1.1096 -
1.1097 - int ai = 0;
1.1098 -
1.1099 - OUTER: for (AnnotationTree a : origMods.getAnnotations()) {
1.1100 - if (actualAnnotationsMask.length <= ai || actualAnnotationsMask[ai++]) continue;
1.1101 - for (Iterator<AnnotationTree> it = annotations.iterator(); it.hasNext();) {
1.1102 - AnnotationTree toCheck = it.next();
1.1103 - Collection<? extends Occurrence> match = org.netbeans.api.java.source.matching.Matcher.create(info).setTreeTopSearch().setSearchRoot(new TreePath(getCurrentPath(), a)).match(Pattern.createSimplePattern(new TreePath(getCurrentPath(), toCheck)));
1.1104 -
1.1105 - if (!match.isEmpty()) {
1.1106 - //should be kept:
1.1107 - it.remove();
1.1108 - break OUTER;
1.1109 - }
1.1110 - }
1.1111 -
1.1112 - nue = make.removeModifiersAnnotation(nue, a);
1.1113 - }
1.1114 -
1.1115 - for (AnnotationTree a : annotations) {
1.1116 - nue = make.addModifiersAnnotation(nue, a);
1.1117 - scan(a, p);
1.1118 - }
1.1119 - } else {
1.1120 - nue = make.removeModifiersAnnotation(node, 0);
1.1121 - }
1.1122 -
1.1123 - rewrite(node, nue);
1.1124 -
1.1125 - return null;
1.1126 - }
1.1127 -
1.1128 - return super.visitModifiers(node, p);
1.1129 - }
1.1130 -
1.1131 - @Override
1.1132 - public Number visitNewArray(NewArrayTree node, Void p) {
1.1133 - List<? extends ExpressionTree> dimensions = (List<? extends ExpressionTree>) resolveMultiParameters(node.getDimensions());
1.1134 - List<? extends ExpressionTree> initializers = (List<? extends ExpressionTree>) resolveMultiParameters(node.getInitializers());
1.1135 - NewArrayTree nue = make.NewArray(node.getType(), dimensions, initializers);
1.1136 -
1.1137 - rewrite(node, nue);
1.1138 - return super.visitNewArray(node, p);
1.1139 - }
1.1140 -
1.1141 - @Override
1.1142 - public Number visitLambdaExpression(LambdaExpressionTree node, Void p) {
1.1143 - List<? extends VariableTree> args = resolveMultiParameters(node.getParameters());
1.1144 - LambdaExpressionTree nue = make.LambdaExpression(args, node.getBody());
1.1145 -
1.1146 - rewrite(node, nue);
1.1147 -
1.1148 - return super.visitLambdaExpression(node, p);
1.1149 - }
1.1150 -
1.1151 - @Override
1.1152 - public Number visitAnnotation(AnnotationTree node, Void p) {
1.1153 - List<? extends ExpressionTree> args = resolveMultiParameters(node.getArguments());
1.1154 - AnnotationTree nue = make.Annotation(node.getAnnotationType(), args);
1.1155 -
1.1156 - rewrite(node, nue);
1.1157 -
1.1158 - return super.visitAnnotation(node, p);
1.1159 - }
1.1160 -
1.1161 - private <T extends Tree> List<T> resolveMultiParameters(List<T> list) {
1.1162 - if (list == null) return null;
1.1163 - if (!Utilities.containsMultistatementTrees(list)) return list;
1.1164 -
1.1165 - List<T> result = new LinkedList<T>();
1.1166 -
1.1167 - for (T t : list) {
1.1168 - if (Utilities.isMultistatementWildcardTree(t)) {
1.1169 - Collection<TreePath> embedded = parametersMulti.get(Utilities.getWildcardTreeName(t).toString());
1.1170 -
1.1171 - if (embedded != null) {
1.1172 - for (TreePath tp : embedded) {
1.1173 - result.add((T) tp.getLeaf());
1.1174 - }
1.1175 - }
1.1176 - } else {
1.1177 - result.add(t);
1.1178 - }
1.1179 - }
1.1180 -
1.1181 - return result;
1.1182 - }
1.1183 -
1.1184 - private <T extends Tree> T resolveOptionalValue(T in) {
1.1185 - if (in != null && Utilities.isMultistatementWildcardTree(in)) {
1.1186 - TreePath out = parameters.get(Utilities.getWildcardTreeName(in).toString());
1.1187 - if (out != null) return (T) out.getLeaf();
1.1188 - return null;
1.1189 - }
1.1190 -
1.1191 - return in;
1.1192 - }
1.1193 -
1.1194 - private ExpressionTree negate(ExpressionTree original, Tree parent, boolean nullOnPlainNeg) {
1.1195 - ExpressionTree newTree;
1.1196 - switch (original.getKind()) {
1.1197 - case PARENTHESIZED:
1.1198 - ExpressionTree expr = ((ParenthesizedTree) original).getExpression();
1.1199 - return make.Parenthesized(negate(expr, original, nullOnPlainNeg));
1.1200 - case LOGICAL_COMPLEMENT:
1.1201 - newTree = ((UnaryTree) original).getExpression();
1.1202 - while (newTree.getKind() == Kind.PARENTHESIZED && !JavaFixUtilities.requiresParenthesis(((ParenthesizedTree) newTree).getExpression(), original, parent)) {
1.1203 - newTree = ((ParenthesizedTree) newTree).getExpression();
1.1204 - }
1.1205 - break;
1.1206 - case NOT_EQUAL_TO:
1.1207 - newTree = negateBinaryOperator(original, Kind.EQUAL_TO, false);
1.1208 - break;
1.1209 - case EQUAL_TO:
1.1210 - newTree = negateBinaryOperator(original, Kind.NOT_EQUAL_TO, false);
1.1211 - break;
1.1212 - case BOOLEAN_LITERAL:
1.1213 - newTree = make.Literal(!(Boolean) ((LiteralTree) original).getValue());
1.1214 - break;
1.1215 - case CONDITIONAL_AND:
1.1216 - newTree = negateBinaryOperator(original, Kind.CONDITIONAL_OR, true);
1.1217 - break;
1.1218 - case CONDITIONAL_OR:
1.1219 - newTree = negateBinaryOperator(original, Kind.CONDITIONAL_AND, true);
1.1220 - break;
1.1221 - case LESS_THAN:
1.1222 - newTree = negateBinaryOperator(original, Kind.GREATER_THAN_EQUAL, false);
1.1223 - break;
1.1224 - case LESS_THAN_EQUAL:
1.1225 - newTree = negateBinaryOperator(original, Kind.GREATER_THAN, false);
1.1226 - break;
1.1227 - case GREATER_THAN:
1.1228 - newTree = negateBinaryOperator(original, Kind.LESS_THAN_EQUAL, false);
1.1229 - break;
1.1230 - case GREATER_THAN_EQUAL:
1.1231 - newTree = negateBinaryOperator(original, Kind.LESS_THAN, false);
1.1232 - break;
1.1233 - default:
1.1234 - if (nullOnPlainNeg)
1.1235 - return null;
1.1236 - newTree = make.Unary(Kind.LOGICAL_COMPLEMENT, original);
1.1237 - }
1.1238 -
1.1239 - if (JavaFixUtilities.requiresParenthesis(newTree, original, parent)) {
1.1240 - newTree = make.Parenthesized(newTree);
1.1241 - }
1.1242 -
1.1243 - return newTree;
1.1244 - }
1.1245 -
1.1246 - private ExpressionTree negateBinaryOperator(Tree original, Kind newKind, boolean negateOperands) {
1.1247 - BinaryTree bt = (BinaryTree) original;
1.1248 - BinaryTree nonNegated = make.Binary(newKind,
1.1249 - bt.getLeftOperand(),
1.1250 - bt.getRightOperand());
1.1251 - if (negateOperands) {
1.1252 - ExpressionTree lo = negate(bt.getLeftOperand(), nonNegated, false);
1.1253 - ExpressionTree ro = negate(bt.getRightOperand(), nonNegated, false);
1.1254 - return make.Binary(newKind,
1.1255 - lo != null ? lo : bt.getLeftOperand(),
1.1256 - ro != null ? ro : bt.getRightOperand());
1.1257 - }
1.1258 - return nonNegated;
1.1259 - }
1.1260 -
1.1261 - private void rewrite(Tree from, Tree to) {
1.1262 - if (originalTrees.contains(from)) return ;
1.1263 - rewriteFromTo.put(from, to);
1.1264 - }
1.1265 - }
1.1266 -
1.1267 - private static final Map<Kind, Integer> OPERATOR_PRIORITIES;
1.1268 -
1.1269 - static {
1.1270 - OPERATOR_PRIORITIES = new EnumMap<Kind, Integer>(Kind.class);
1.1271 -
1.1272 - OPERATOR_PRIORITIES.put(Kind.IDENTIFIER, 0);
1.1273 -
1.1274 - for (Kind k : Kind.values()) {
1.1275 - if (k.asInterface() == LiteralTree.class) {
1.1276 - OPERATOR_PRIORITIES.put(k, 0);
1.1277 - }
1.1278 - }
1.1279 -
1.1280 - OPERATOR_PRIORITIES.put(Kind.ARRAY_ACCESS, 1);
1.1281 - OPERATOR_PRIORITIES.put(Kind.METHOD_INVOCATION, 1);
1.1282 - OPERATOR_PRIORITIES.put(Kind.MEMBER_SELECT, 1);
1.1283 - OPERATOR_PRIORITIES.put(Kind.POSTFIX_DECREMENT, 1);
1.1284 - OPERATOR_PRIORITIES.put(Kind.POSTFIX_INCREMENT, 1);
1.1285 - OPERATOR_PRIORITIES.put(Kind.NEW_ARRAY, 1);
1.1286 - OPERATOR_PRIORITIES.put(Kind.NEW_CLASS, 1);
1.1287 -
1.1288 - OPERATOR_PRIORITIES.put(Kind.BITWISE_COMPLEMENT, 2);
1.1289 - OPERATOR_PRIORITIES.put(Kind.LOGICAL_COMPLEMENT, 2);
1.1290 - OPERATOR_PRIORITIES.put(Kind.PREFIX_DECREMENT, 2);
1.1291 - OPERATOR_PRIORITIES.put(Kind.PREFIX_INCREMENT, 2);
1.1292 - OPERATOR_PRIORITIES.put(Kind.UNARY_MINUS, 2);
1.1293 - OPERATOR_PRIORITIES.put(Kind.UNARY_PLUS, 2);
1.1294 -
1.1295 - OPERATOR_PRIORITIES.put(Kind.TYPE_CAST, 3);
1.1296 -
1.1297 - OPERATOR_PRIORITIES.put(Kind.DIVIDE, 4);
1.1298 - OPERATOR_PRIORITIES.put(Kind.MULTIPLY, 4);
1.1299 - OPERATOR_PRIORITIES.put(Kind.REMAINDER, 4);
1.1300 -
1.1301 - OPERATOR_PRIORITIES.put(Kind.MINUS, 5);
1.1302 - OPERATOR_PRIORITIES.put(Kind.PLUS, 5);
1.1303 -
1.1304 - OPERATOR_PRIORITIES.put(Kind.LEFT_SHIFT, 6);
1.1305 - OPERATOR_PRIORITIES.put(Kind.RIGHT_SHIFT, 6);
1.1306 - OPERATOR_PRIORITIES.put(Kind.UNSIGNED_RIGHT_SHIFT, 6);
1.1307 -
1.1308 - OPERATOR_PRIORITIES.put(Kind.INSTANCE_OF, 7);
1.1309 - OPERATOR_PRIORITIES.put(Kind.GREATER_THAN, 7);
1.1310 - OPERATOR_PRIORITIES.put(Kind.GREATER_THAN_EQUAL, 7);
1.1311 - OPERATOR_PRIORITIES.put(Kind.LESS_THAN, 7);
1.1312 - OPERATOR_PRIORITIES.put(Kind.LESS_THAN_EQUAL, 7);
1.1313 -
1.1314 - OPERATOR_PRIORITIES.put(Kind.EQUAL_TO, 8);
1.1315 - OPERATOR_PRIORITIES.put(Kind.NOT_EQUAL_TO, 8);
1.1316 -
1.1317 - OPERATOR_PRIORITIES.put(Kind.AND, 9);
1.1318 - OPERATOR_PRIORITIES.put(Kind.OR, 11);
1.1319 - OPERATOR_PRIORITIES.put(Kind.XOR, 10);
1.1320 -
1.1321 - OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_AND, 12);
1.1322 - OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_OR, 13);
1.1323 -
1.1324 - OPERATOR_PRIORITIES.put(Kind.CONDITIONAL_EXPRESSION, 14);
1.1325 -
1.1326 - OPERATOR_PRIORITIES.put(Kind.AND_ASSIGNMENT, 15);
1.1327 - OPERATOR_PRIORITIES.put(Kind.ASSIGNMENT, 15);
1.1328 - OPERATOR_PRIORITIES.put(Kind.DIVIDE_ASSIGNMENT, 15);
1.1329 - OPERATOR_PRIORITIES.put(Kind.LEFT_SHIFT_ASSIGNMENT, 15);
1.1330 - OPERATOR_PRIORITIES.put(Kind.MINUS_ASSIGNMENT, 15);
1.1331 - OPERATOR_PRIORITIES.put(Kind.MULTIPLY_ASSIGNMENT, 15);
1.1332 - OPERATOR_PRIORITIES.put(Kind.OR_ASSIGNMENT, 15);
1.1333 - OPERATOR_PRIORITIES.put(Kind.PLUS_ASSIGNMENT, 15);
1.1334 - OPERATOR_PRIORITIES.put(Kind.REMAINDER_ASSIGNMENT, 15);
1.1335 - OPERATOR_PRIORITIES.put(Kind.RIGHT_SHIFT_ASSIGNMENT, 15);
1.1336 - OPERATOR_PRIORITIES.put(Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT, 15);
1.1337 - OPERATOR_PRIORITIES.put(Kind.XOR_ASSIGNMENT, 15);
1.1338 - }
1.1339 -
1.1340 - /**Checks whether putting {@code inner} tree into {@code outter} tree,
1.1341 - * when {@code original} is being replaced with {@code inner} requires parentheses.
1.1342 - *
1.1343 - * @param inner the new tree node that will be placed under {@code outter}
1.1344 - * @param original the tree node that is being replaced with {@code inner}
1.1345 - * @param outter the future parent node of {@code inner}
1.1346 - * @return true if and only if inner needs to be wrapped using {@link TreeMaker#Parenthesized(com.sun.source.tree.ExpressionTree) }
1.1347 - * to keep the original meaning.
1.1348 - */
1.1349 - public static boolean requiresParenthesis(Tree inner, Tree original, Tree outter) {
1.1350 - if (!ExpressionTree.class.isAssignableFrom(inner.getKind().asInterface())) return false;
1.1351 - if (!ExpressionTree.class.isAssignableFrom(outter.getKind().asInterface())) return false;
1.1352 -
1.1353 - if (outter.getKind() == Kind.PARENTHESIZED || inner.getKind() == Kind.PARENTHESIZED) return false;
1.1354 -
1.1355 - if (outter.getKind() == Kind.METHOD_INVOCATION) {
1.1356 - if (((MethodInvocationTree) outter).getArguments().contains(original)) return false;
1.1357 - }
1.1358 -
1.1359 - if (outter.getKind() == Kind.NEW_CLASS) {
1.1360 - if (((NewClassTree) outter).getArguments().contains(original)) return false;
1.1361 - }
1.1362 -
1.1363 - Integer innerPriority = OPERATOR_PRIORITIES.get(inner.getKind());
1.1364 - Integer outterPriority = OPERATOR_PRIORITIES.get(outter.getKind());
1.1365 -
1.1366 - if (innerPriority == null || outterPriority == null) {
1.1367 - Logger.getLogger(JavaFix.class.getName()).log(Level.WARNING, "Unknown tree kind(s): {0}/{1}", new Object[] {inner.getKind(), outter.getKind()});
1.1368 - return true;
1.1369 - }
1.1370 -
1.1371 - if (innerPriority > outterPriority) {
1.1372 - return true;
1.1373 - }
1.1374 -
1.1375 - if (innerPriority < outterPriority) {
1.1376 - return false;
1.1377 - }
1.1378 -
1.1379 - //associativity
1.1380 - if (BinaryTree.class.isAssignableFrom(outter.getKind().asInterface())) {
1.1381 - BinaryTree ot = (BinaryTree) outter;
1.1382 -
1.1383 - //TODO: for + it might be possible to skip the parenthesis:
1.1384 - return ot.getRightOperand() == original;
1.1385 - }
1.1386 -
1.1387 - if (CompoundAssignmentTree.class.isAssignableFrom(outter.getKind().asInterface())) {
1.1388 - CompoundAssignmentTree ot = (CompoundAssignmentTree) outter;
1.1389 -
1.1390 - return ot.getVariable() == original;
1.1391 - }
1.1392 -
1.1393 - if (AssignmentTree.class.isAssignableFrom(outter.getKind().asInterface())) {
1.1394 - AssignmentTree ot = (AssignmentTree) outter;
1.1395 -
1.1396 - return ot.getVariable() == original;
1.1397 - }
1.1398 -
1.1399 - return false;
1.1400 - }
1.1401 -
1.1402 - private static final class RemoveFromParent extends JavaFix {
1.1403 -
1.1404 - private final String displayName;
1.1405 -
1.1406 - public RemoveFromParent(String displayName, CompilationInfo info, TreePath toRemove) {
1.1407 - super(info, toRemove);
1.1408 - this.displayName = displayName;
1.1409 - }
1.1410 -
1.1411 - @Override
1.1412 - protected String getText() {
1.1413 - return displayName;
1.1414 - }
1.1415 -
1.1416 - @Override
1.1417 - protected void performRewrite(TransformationContext ctx) {
1.1418 - WorkingCopy wc = ctx.getWorkingCopy();
1.1419 - TreePath tp = ctx.getPath();
1.1420 -
1.1421 - doRemoveFromParent(wc, tp);
1.1422 - }
1.1423 -
1.1424 - private void doRemoveFromParent(WorkingCopy wc, TreePath what) {
1.1425 - TreeMaker make = wc.getTreeMaker();
1.1426 - Tree leaf = what.getLeaf();
1.1427 - Tree parentLeaf = what.getParentPath().getLeaf();
1.1428 -
1.1429 - switch (parentLeaf.getKind()) {
1.1430 - case ANNOTATION:
1.1431 - AnnotationTree at = (AnnotationTree) parentLeaf;
1.1432 - AnnotationTree newAnnot;
1.1433 -
1.1434 - newAnnot = make.removeAnnotationAttrValue(at, (ExpressionTree) leaf);
1.1435 -
1.1436 - wc.rewrite(at, newAnnot);
1.1437 - break;
1.1438 - case BLOCK:
1.1439 - BlockTree bt = (BlockTree) parentLeaf;
1.1440 -
1.1441 - wc.rewrite(bt, make.removeBlockStatement(bt, (StatementTree) leaf));
1.1442 - break;
1.1443 - case CASE:
1.1444 - CaseTree caseTree = (CaseTree) parentLeaf;
1.1445 -
1.1446 - wc.rewrite(caseTree, make.removeCaseStatement(caseTree, (StatementTree) leaf));
1.1447 - break;
1.1448 - case CLASS:
1.1449 - ClassTree classTree = (ClassTree) parentLeaf;
1.1450 - ClassTree nueClassTree;
1.1451 -
1.1452 - if (classTree.getTypeParameters().contains(leaf)) {
1.1453 - nueClassTree = make.removeClassTypeParameter(classTree, (TypeParameterTree) leaf);
1.1454 - } else if (classTree.getExtendsClause() == leaf) {
1.1455 - nueClassTree = make.Class(classTree.getModifiers(), classTree.getSimpleName(), classTree.getTypeParameters(), null, classTree.getImplementsClause(), classTree.getMembers());
1.1456 - } else if (classTree.getImplementsClause().contains(leaf)) {
1.1457 - nueClassTree = make.removeClassImplementsClause(classTree, leaf);
1.1458 - } else if (classTree.getMembers().contains(leaf)) {
1.1459 - nueClassTree = make.removeClassMember(classTree, leaf);
1.1460 - } else {
1.1461 - throw new UnsupportedOperationException();
1.1462 - }
1.1463 -
1.1464 - wc.rewrite(classTree, nueClassTree);
1.1465 - break;
1.1466 - case UNION_TYPE:
1.1467 - UnionTypeTree disjunct = (UnionTypeTree) parentLeaf;
1.1468 - List<? extends Tree> alternatives = new LinkedList<Tree>(disjunct.getTypeAlternatives());
1.1469 -
1.1470 - alternatives.remove(leaf);
1.1471 -
1.1472 - wc.rewrite(disjunct, make.UnionType(alternatives));
1.1473 - break;
1.1474 - case METHOD:
1.1475 - MethodTree mTree = (MethodTree) parentLeaf;
1.1476 - MethodTree newMethod;
1.1477 -
1.1478 - if (mTree.getTypeParameters().contains(leaf)) {
1.1479 - newMethod = make.removeMethodTypeParameter(mTree, (TypeParameterTree) leaf);
1.1480 - } else if (mTree.getParameters().contains(leaf)) {
1.1481 - newMethod = make.removeMethodParameter(mTree, (VariableTree) leaf);
1.1482 - } else if (mTree.getThrows().contains(leaf)) {
1.1483 - newMethod = make.removeMethodThrows(mTree, (ExpressionTree) leaf);
1.1484 - } else {
1.1485 - throw new UnsupportedOperationException();
1.1486 - }
1.1487 -
1.1488 - wc.rewrite(mTree, newMethod);
1.1489 - break;
1.1490 - case METHOD_INVOCATION:
1.1491 - MethodInvocationTree iTree = (MethodInvocationTree) parentLeaf;
1.1492 - MethodInvocationTree newInvocation;
1.1493 -
1.1494 - if (iTree.getTypeArguments().contains(leaf)) {
1.1495 - newInvocation = make.removeMethodInvocationTypeArgument(iTree, (ExpressionTree) leaf);
1.1496 - } else if (iTree.getArguments().contains(leaf)) {
1.1497 - newInvocation = make.removeMethodInvocationArgument(iTree, (ExpressionTree) leaf);
1.1498 - } else {
1.1499 - throw new UnsupportedOperationException();
1.1500 - }
1.1501 -
1.1502 - wc.rewrite(iTree, newInvocation);
1.1503 - break;
1.1504 - case MODIFIERS:
1.1505 - ModifiersTree modsTree = (ModifiersTree) parentLeaf;
1.1506 -
1.1507 - wc.rewrite(modsTree, make.removeModifiersAnnotation(modsTree, (AnnotationTree) leaf));
1.1508 - break;
1.1509 - case NEW_CLASS:
1.1510 - NewClassTree newCTree = (NewClassTree) parentLeaf;
1.1511 - NewClassTree newNCT;
1.1512 -
1.1513 - if (newCTree.getTypeArguments().contains(leaf)) {
1.1514 - newNCT = make.removeNewClassTypeArgument(newCTree, (ExpressionTree) leaf);
1.1515 - } else if (newCTree.getArguments().contains(leaf)) {
1.1516 - newNCT = make.removeNewClassArgument(newCTree, (ExpressionTree) leaf);
1.1517 - } else {
1.1518 - throw new UnsupportedOperationException();
1.1519 - }
1.1520 -
1.1521 - wc.rewrite(newCTree, newNCT);
1.1522 - break;
1.1523 - case PARAMETERIZED_TYPE:
1.1524 - ParameterizedTypeTree parTree = (ParameterizedTypeTree) parentLeaf;
1.1525 -
1.1526 - wc.rewrite(parTree, make.removeParameterizedTypeTypeArgument(parTree, (ExpressionTree) leaf));
1.1527 - break;
1.1528 - case SWITCH:
1.1529 - SwitchTree switchTree = (SwitchTree) parentLeaf;
1.1530 - SwitchTree newSwitch;
1.1531 -
1.1532 - if (switchTree.getCases().contains(leaf)) {
1.1533 - newSwitch = make.removeSwitchCase(switchTree, (CaseTree) leaf);
1.1534 - } else {
1.1535 - throw new UnsupportedOperationException();
1.1536 - }
1.1537 -
1.1538 - wc.rewrite(switchTree, newSwitch);
1.1539 - break;
1.1540 - case TRY:
1.1541 - TryTree tryTree = (TryTree) parentLeaf;
1.1542 - TryTree newTry;
1.1543 -
1.1544 - if (tryTree.getResources().contains(leaf)) {
1.1545 - LinkedList<Tree> resources = new LinkedList<Tree>(tryTree.getResources());
1.1546 -
1.1547 - resources.remove(leaf);
1.1548 -
1.1549 - newTry = make.Try(resources, tryTree.getBlock(), tryTree.getCatches(), tryTree.getFinallyBlock());
1.1550 - } else if (tryTree.getCatches().contains(leaf)) {
1.1551 - newTry = make.removeTryCatch(tryTree, (CatchTree) leaf);
1.1552 - } else {
1.1553 - throw new UnsupportedOperationException();
1.1554 - }
1.1555 -
1.1556 - wc.rewrite(tryTree, newTry);
1.1557 - break;
1.1558 - case EXPRESSION_STATEMENT:
1.1559 - doRemoveFromParent(wc, what.getParentPath());
1.1560 - break;
1.1561 - default:
1.1562 - wc.rewrite(what.getLeaf(), make.Block(Collections.<StatementTree>emptyList(), false));
1.1563 - break;
1.1564 - }
1.1565 - }
1.1566 -
1.1567 - }
1.1568 -
1.1569 - //TODO: from FileMovePlugin
1.1570 - private static class MoveFile extends SimpleRefactoringElementImplementation {
1.1571 -
1.1572 - private FileObject toMove;
1.1573 - private final FileObject sourceRoot;
1.1574 - private final String targetFolderName;
1.1575 -
1.1576 - public MoveFile(FileObject toMove, FileObject sourceRoot, String targetFolderName) {
1.1577 - this.toMove = toMove;
1.1578 - this.sourceRoot = sourceRoot;
1.1579 - this.targetFolderName = targetFolderName;
1.1580 - }
1.1581 -
1.1582 - @Override
1.1583 - @Messages({"#{0} - original file name", "TXT_MoveFile=Move {0}"})
1.1584 - public String getText() {
1.1585 - return Bundle.TXT_MoveFile(toMove.getNameExt());
1.1586 - }
1.1587 -
1.1588 - @Override
1.1589 - public String getDisplayText() {
1.1590 - return getText();
1.1591 - }
1.1592 -
1.1593 - DataFolder sourceFolder;
1.1594 - DataObject source;
1.1595 - @Override
1.1596 - public void performChange() {
1.1597 - try {
1.1598 - FileObject target = FileUtil.createFolder(sourceRoot, targetFolderName);
1.1599 - DataFolder targetFolder = DataFolder.findFolder(target);
1.1600 - if (!toMove.isValid()) {
1.1601 - String path = FileUtil.getFileDisplayName(toMove);
1.1602 - Logger.getLogger(JavaFix.class.getName()).fine("Invalid FileObject " + path + "trying to recreate...");
1.1603 - toMove = FileUtil.toFileObject(FileUtil.toFile(toMove));
1.1604 - if (toMove==null) {
1.1605 - Logger.getLogger(JavaFix.class.getName()).severe("Invalid FileObject " + path + "\n. File not found.");
1.1606 - return;
1.1607 - }
1.1608 - }
1.1609 - source = DataObject.find(toMove);
1.1610 - sourceFolder = source.getFolder();
1.1611 - source.move(targetFolder);
1.1612 - } catch (DataObjectNotFoundException ex) {
1.1613 - ex.printStackTrace();
1.1614 - } catch (IOException ex) {
1.1615 - ex.printStackTrace();
1.1616 - }
1.1617 - }
1.1618 -
1.1619 - @Override
1.1620 - public void undoChange() {
1.1621 - try {
1.1622 - source.move(sourceFolder);
1.1623 - } catch (DataObjectNotFoundException ex) {
1.1624 - ex.printStackTrace();
1.1625 - } catch (IOException ex) {
1.1626 - ex.printStackTrace();
1.1627 - }
1.1628 - }
1.1629 -
1.1630 - @Override
1.1631 - public Lookup getLookup() {
1.1632 - return Lookup.EMPTY;
1.1633 - }
1.1634 -
1.1635 - @Override
1.1636 - public FileObject getParentFile() {
1.1637 - return toMove;
1.1638 - }
1.1639 -
1.1640 - @Override
1.1641 - public PositionBounds getPosition() {
1.1642 - return null;
1.1643 - }
1.1644 - }
1.1645 -}