Introduce parameter initial prototype jet-dev71
authorJan Becicka <jbecicka@netbeans.org>
Fri, 06 May 2011 15:36:19 +0200
branchjet-dev71
changeset 199332ad501b78a7ad
parent 199331 2749d822799a
child 199336 297bd1253a55
Introduce parameter initial prototype
- make final does not work correctly
- replace all occurrences does not work. Depends on hints/jackpot
Issue #176217 - Introduce Parameter Refactoring
refactoring.java/nbproject/project.properties
refactoring.java/src/org/netbeans/modules/refactoring/java/api/IntroduceParameterRefactoring.java
refactoring.java/src/org/netbeans/modules/refactoring/java/api/ui/JavaRefactoringActionsFactory.java
refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ChangeParametersPlugin.java
refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ChangeParamsTransformer.java
refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/IntroduceParameterPlugin.java
refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaRefactoringsFactory.java
refactoring.java/src/org/netbeans/modules/refactoring/java/resources/mf-layer.xml
refactoring.java/src/org/netbeans/modules/refactoring/java/spi/ui/JavaActionsImplementationProvider.java
refactoring.java/src/org/netbeans/modules/refactoring/java/ui/Bundle.properties
refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterAction.java
refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterPanel.form
refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterPanel.java
refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterUI.java
refactoring.java/src/org/netbeans/modules/refactoring/java/ui/JavaActionsImplementationFactory.java
refactoring.java/src/org/netbeans/modules/refactoring/java/ui/JavaRefactoringActionsProvider.java
     1.1 --- a/refactoring.java/nbproject/project.properties	Thu Apr 21 16:33:50 2011 +0200
     1.2 +++ b/refactoring.java/nbproject/project.properties	Fri May 06 15:36:19 2011 +0200
     1.3 @@ -1,7 +1,7 @@
     1.4  javac.source=1.6
     1.5  javadoc.arch=${basedir}/arch.xml
     1.6  
     1.7 -spec.version.base=1.19.0
     1.8 +spec.version.base=1.20.0
     1.9  #test configs
    1.10  test.config.find.includes=\
    1.11      **/FindUsagesSuite.class
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/api/IntroduceParameterRefactoring.java	Fri May 06 15:36:19 2011 +0200
     2.3 @@ -0,0 +1,125 @@
     2.4 +/*
     2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 + *
     2.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
     2.8 + *
     2.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    2.10 + * Other names may be trademarks of their respective owners.
    2.11 + *
    2.12 + * The contents of this file are subject to the terms of either the GNU
    2.13 + * General Public License Version 2 only ("GPL") or the Common
    2.14 + * Development and Distribution License("CDDL") (collectively, the
    2.15 + * "License"). You may not use this file except in compliance with the
    2.16 + * License. You can obtain a copy of the License at
    2.17 + * http://www.netbeans.org/cddl-gplv2.html
    2.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    2.19 + * specific language governing permissions and limitations under the
    2.20 + * License.  When distributing the software, include this License Header
    2.21 + * Notice in each file and include the License file at
    2.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    2.23 + * particular file as subject to the "Classpath" exception as provided
    2.24 + * by Oracle in the GPL Version 2 section of the License file that
    2.25 + * accompanied this code. If applicable, add the following below the
    2.26 + * License Header, with the fields enclosed by brackets [] replaced by
    2.27 + * your own identifying information:
    2.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    2.29 + *
    2.30 + * If you wish your version of this file to be governed by only the CDDL
    2.31 + * or only the GPL Version 2, indicate your decision by adding
    2.32 + * "[Contributor] elects to include this software in this distribution
    2.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    2.34 + * single choice of license, a recipient has the option to distribute
    2.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    2.36 + * to extend the choice of license to its licensees as provided above.
    2.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    2.38 + * Version 2 license, then the option applies only if the new code is
    2.39 + * made subject to such option by the copyright holder.
    2.40 + *
    2.41 + * Contributor(s):
    2.42 + *
    2.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
    2.44 + */
    2.45 +package org.netbeans.modules.refactoring.java.api;
    2.46 +
    2.47 +import org.netbeans.api.java.source.TreePathHandle;
    2.48 +import org.netbeans.modules.refactoring.api.AbstractRefactoring;
    2.49 +import org.openide.util.lookup.Lookups;
    2.50 +
    2.51 +/**
    2.52 + * Introduce parameter refactoring
    2.53 + * @see org.netbeans.modules.refactoring.spi.RefactoringPlugin
    2.54 + * @see org.netbeans.modules.refactoring.spi.RefactoringPluginFactory
    2.55 + * @see org.netbeans.modules.refactoring.api.AbstractRefactoring
    2.56 + * @see org.netbeans.modules.refactoring.api.RefactoringSession
    2.57 + *
    2.58 + * @author  Jan Becicka
    2.59 + */
    2.60 +public final class IntroduceParameterRefactoring extends AbstractRefactoring {
    2.61 +    
    2.62 +    private boolean isFinal;
    2.63 +    private boolean isReplaceAll;
    2.64 +    private boolean isCompatible;
    2.65 +    private String parameterName;
    2.66 +    
    2.67 +    /**
    2.68 +     * Creates a new instance of introduce parameter refactoring.
    2.69 +     *
    2.70 +     * @param expression  refactored expression
    2.71 +     */
    2.72 +    public IntroduceParameterRefactoring(TreePathHandle expression) {
    2.73 +        super(Lookups.singleton(expression));
    2.74 +    }
    2.75 +
    2.76 +    /**
    2.77 +     * introduces new method with new parameter, existing methods delegates to it:
    2.78 +     * e.g.
    2.79 +     * <pre>
    2.80 +     * int originalfoo() {
    2.81 +     *   return 1+1;
    2.82 +     * }
    2.83 +     * </pre>
    2.84 +     * if "1+1" is selected, code is converted to 
    2.85 +     * <pre>
    2.86 +     * int originalfoo() {
    2.87 +     *    return foo(1+1);
    2.88 +     * }
    2.89 +     * 
    2.90 +     * int foo(int newparam) {
    2.91 +     *    return newoaram; 
    2.92 +     * }
    2.93 +     * </pre>
    2.94 +     * 
    2.95 +     * @return 
    2.96 +     */
    2.97 +    public boolean isCompatible() {
    2.98 +        return isCompatible;
    2.99 +    }
   2.100 +
   2.101 +    public void setCompatible(boolean isCompatible) {
   2.102 +        this.isCompatible = isCompatible;
   2.103 +    }
   2.104 +
   2.105 +    public boolean isFinal() {
   2.106 +        return isFinal;
   2.107 +    }
   2.108 +
   2.109 +    public void setFinal(boolean isFinal) {
   2.110 +        this.isFinal = isFinal;
   2.111 +    }
   2.112 +
   2.113 +    public boolean isReplaceAll() {
   2.114 +        return isReplaceAll;
   2.115 +    }
   2.116 +
   2.117 +    public void setReplaceAll(boolean isReplaceAll) {
   2.118 +        this.isReplaceAll = isReplaceAll;
   2.119 +    }
   2.120 +
   2.121 +    public String getParameterName() {
   2.122 +        return parameterName;
   2.123 +    }
   2.124 +
   2.125 +    public void setParameterName(String parameterName) {
   2.126 +        this.parameterName = parameterName;
   2.127 +    }
   2.128 +}
     3.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/api/ui/JavaRefactoringActionsFactory.java	Thu Apr 21 16:33:50 2011 +0200
     3.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/api/ui/JavaRefactoringActionsFactory.java	Fri May 06 15:36:19 2011 +0200
     3.3 @@ -49,6 +49,7 @@
     3.4  import org.netbeans.modules.refactoring.java.ui.ExtractInterfaceAction;
     3.5  import org.netbeans.modules.refactoring.java.ui.ExtractSuperclassAction;
     3.6  import org.netbeans.modules.refactoring.java.ui.InnerToOuterAction;
     3.7 +import org.netbeans.modules.refactoring.java.ui.IntroduceParameterAction;
     3.8  import org.netbeans.modules.refactoring.java.ui.PullUpAction;
     3.9  import org.netbeans.modules.refactoring.java.ui.PushDownAction;
    3.10  import org.netbeans.modules.refactoring.java.ui.UseSuperTypeAction;
    3.11 @@ -130,4 +131,9 @@
    3.12      public static ContextAwareAction extractInterfaceAction() {
    3.13          return ExtractInterfaceAction.findObject(ExtractInterfaceAction.class, true);
    3.14      }
    3.15 +    
    3.16 +    public static ContextAwareAction introduceParameterAction() {
    3.17 +        return IntroduceParameterAction.findObject(IntroduceParameterAction.class, true);
    3.18 +    }
    3.19 +    
    3.20  }
     4.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ChangeParametersPlugin.java	Thu Apr 21 16:33:50 2011 +0200
     4.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ChangeParametersPlugin.java	Fri May 06 15:36:19 2011 +0200
     4.3 @@ -212,7 +212,7 @@
     4.4          Set<FileObject> a = getRelevantFiles();
     4.5          fireProgressListenerStart(ProgressEvent.START, a.size());
     4.6          if (!a.isEmpty()) {
     4.7 -            TransformTask transform = new TransformTask(new ChangeParamsTransformer(refactoring, allMethods), treePathHandle);
     4.8 +            TransformTask transform = new TransformTask(new ChangeParamsTransformer(refactoring.getParameterInfo(), allMethods, refactoring.getModifiers()), treePathHandle);
     4.9              Problem p = createAndAddElements(a, transform, elements, refactoring);
    4.10              if (p != null) {
    4.11                  fireProgressListenerStop();
     5.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ChangeParamsTransformer.java	Thu Apr 21 16:33:50 2011 +0200
     5.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/ChangeParamsTransformer.java	Fri May 06 15:36:19 2011 +0200
     5.3 @@ -53,6 +53,7 @@
     5.4  import com.sun.source.util.TreePath;
     5.5  import java.io.IOException;
     5.6  import java.util.ArrayList;
     5.7 +import java.util.Collection;
     5.8  import java.util.Collections;
     5.9  import java.util.EnumSet;
    5.10  import java.util.HashSet;
    5.11 @@ -88,10 +89,13 @@
    5.12       * @see #init()
    5.13       */
    5.14      private Boolean constructorRefactoring;
    5.15 +    private final ParameterInfo[] paramInfos;
    5.16 +    private Collection<? extends Modifier> newModifiers;
    5.17  
    5.18 -    public ChangeParamsTransformer(ChangeParametersRefactoring refactoring, Set<ElementHandle<ExecutableElement>> am) {
    5.19 -        this.refactoring = refactoring;
    5.20 +    public ChangeParamsTransformer(ChangeParametersRefactoring.ParameterInfo[] paramInfos, Set<ElementHandle<ExecutableElement>> am, Collection<? extends Modifier> newModifiers) {
    5.21 +        this.paramInfos = paramInfos;
    5.22          this.allMethods = am;
    5.23 +        this.newModifiers = newModifiers;
    5.24      }
    5.25  
    5.26      private void init() {
    5.27 @@ -154,7 +158,7 @@
    5.28      
    5.29      private List<ExpressionTree> getNewArguments(List<? extends ExpressionTree> currentArguments) {
    5.30          List<ExpressionTree> arguments = new ArrayList();
    5.31 -        ParameterInfo[] pi = refactoring.getParameterInfo();
    5.32 +        ParameterInfo[] pi = paramInfos;
    5.33          for (int i = 0; i < pi.length; i++) {
    5.34              int originalIndex = pi[i].getOriginalIndex();
    5.35              ExpressionTree vt;
    5.36 @@ -243,7 +247,6 @@
    5.37          return super.visitMethod(tree, p);
    5.38      }
    5.39  
    5.40 -    ChangeParametersRefactoring refactoring;
    5.41      private void renameDeclIfMatch(TreePath path, Tree tree, Element elementToFind) {
    5.42          if (!synthConstructor && workingCopy.getTreeUtilities().isSynthetic(path))
    5.43              return;
    5.44 @@ -254,7 +257,7 @@
    5.45              List<? extends VariableTree> currentParameters = current.getParameters();
    5.46              List<VariableTree> newParameters = new ArrayList<VariableTree>();
    5.47              
    5.48 -            ParameterInfo[] p = refactoring.getParameterInfo();
    5.49 +            ParameterInfo[] p = paramInfos;
    5.50              for (int i=0; i<p.length; i++) {
    5.51                  int originalIndex = p[i].getOriginalIndex();
    5.52                  VariableTree vt;
    5.53 @@ -268,9 +271,9 @@
    5.54  
    5.55              // apply new access modifiers if necessary
    5.56              Set<Modifier> modifiers = new HashSet<Modifier>(current.getModifiers().getFlags());
    5.57 -            if (!el.getEnclosingElement().getKind().isInterface()) {
    5.58 +            if (newModifiers!=null && !el.getEnclosingElement().getKind().isInterface()) {
    5.59                  modifiers.removeAll(ALL_ACCESS_MODIFIERS);
    5.60 -                modifiers.addAll(refactoring.getModifiers());
    5.61 +                modifiers.addAll(newModifiers);
    5.62              }
    5.63  
    5.64              //Compute new imports
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/IntroduceParameterPlugin.java	Fri May 06 15:36:19 2011 +0200
     6.3 @@ -0,0 +1,548 @@
     6.4 +/*
     6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     6.6 + *
     6.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
     6.8 + *
     6.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    6.10 + * Other names may be trademarks of their respective owners.
    6.11 + *
    6.12 + * The contents of this file are subject to the terms of either the GNU
    6.13 + * General Public License Version 2 only ("GPL") or the Common
    6.14 + * Development and Distribution License("CDDL") (collectively, the
    6.15 + * "License"). You may not use this file except in compliance with the
    6.16 + * License. You can obtain a copy of the License at
    6.17 + * http://www.netbeans.org/cddl-gplv2.html
    6.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    6.19 + * specific language governing permissions and limitations under the
    6.20 + * License.  When distributing the software, include this License Header
    6.21 + * Notice in each file and include the License file at
    6.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    6.23 + * particular file as subject to the "Classpath" exception as provided
    6.24 + * by Oracle in the GPL Version 2 section of the License file that
    6.25 + * accompanied this code. If applicable, add the following below the
    6.26 + * License Header, with the fields enclosed by brackets [] replaced by
    6.27 + * your own identifying information:
    6.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    6.29 + *
    6.30 + * If you wish your version of this file to be governed by only the CDDL
    6.31 + * or only the GPL Version 2, indicate your decision by adding
    6.32 + * "[Contributor] elects to include this software in this distribution
    6.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    6.34 + * single choice of license, a recipient has the option to distribute
    6.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    6.36 + * to extend the choice of license to its licensees as provided above.
    6.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    6.38 + * Version 2 license, then the option applies only if the new code is
    6.39 + * made subject to such option by the copyright holder.
    6.40 + *
    6.41 + * Contributor(s):
    6.42 + *
    6.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
    6.44 + */
    6.45 +package org.netbeans.modules.refactoring.java.plugins;
    6.46 +
    6.47 +import com.sun.source.tree.BlockTree;
    6.48 +import com.sun.source.tree.ClassTree;
    6.49 +import com.sun.source.tree.ExpressionTree;
    6.50 +import com.sun.source.tree.MethodTree;
    6.51 +import com.sun.source.tree.ModifiersTree;
    6.52 +import com.sun.source.tree.ReturnTree;
    6.53 +import com.sun.source.tree.StatementTree;
    6.54 +import com.sun.source.tree.Tree;
    6.55 +import com.sun.source.tree.Tree.Kind;
    6.56 +import com.sun.source.tree.TypeParameterTree;
    6.57 +import com.sun.source.tree.VariableTree;
    6.58 +import com.sun.source.util.TreePath;
    6.59 +import java.io.IOException;
    6.60 +import java.text.MessageFormat;
    6.61 +import java.util.*;
    6.62 +import javax.lang.model.element.*;
    6.63 +import javax.lang.model.type.ArrayType;
    6.64 +import javax.lang.model.type.TypeMirror;
    6.65 +import org.netbeans.api.java.source.*;
    6.66 +import org.netbeans.api.java.source.SourceUtils;
    6.67 +import org.netbeans.api.java.source.TreePathHandle;
    6.68 +import org.netbeans.modules.refactoring.api.*;
    6.69 +import org.netbeans.modules.refactoring.java.RetoucheUtils;
    6.70 +import org.netbeans.modules.refactoring.java.api.ChangeParametersRefactoring;
    6.71 +import org.netbeans.modules.refactoring.java.api.IntroduceParameterRefactoring;
    6.72 +import org.netbeans.modules.refactoring.java.spi.JavaRefactoringPlugin;
    6.73 +import org.netbeans.modules.refactoring.spi.RefactoringElementsBag;
    6.74 +import org.openide.filesystems.FileObject;
    6.75 +import org.openide.util.NbBundle;
    6.76 +
    6.77 +/**
    6.78 + * @author  Jan Becicka
    6.79 + */
    6.80 +public class IntroduceParameterPlugin extends JavaRefactoringPlugin {
    6.81 +
    6.82 +    private IntroduceParameterRefactoring refactoring;
    6.83 +    private TreePathHandle treePathHandle;
    6.84 +
    6.85 +    /**
    6.86 +     * Creates a new instance of introduce parameter refactoring plugin.
    6.87 +     *
    6.88 +     * @param method  refactored object, i.e. method or constructor
    6.89 +     */
    6.90 +    public IntroduceParameterPlugin(IntroduceParameterRefactoring refactoring) {
    6.91 +        this.refactoring = refactoring;
    6.92 +        this.treePathHandle = refactoring.getRefactoringSource().lookup(TreePathHandle.class);
    6.93 +    }
    6.94 +
    6.95 +    @Override
    6.96 +    public Problem checkParameters() {
    6.97 +        //TODO:
    6.98 +        return null;
    6.99 +    }
   6.100 +
   6.101 +    @Override
   6.102 +    public Problem fastCheckParameters(CompilationController javac) throws IOException {
   6.103 +
   6.104 +        return null;
   6.105 +    }
   6.106 +
   6.107 +    private static String getString(String key) {
   6.108 +        return NbBundle.getMessage(IntroduceParameterPlugin.class, key);
   6.109 +    }
   6.110 +    private Set<ElementHandle<ExecutableElement>> allMethods;
   6.111 +
   6.112 +    private Set<FileObject> getRelevantFiles() {
   6.113 +        ClasspathInfo cpInfo = getClasspathInfo(refactoring);
   6.114 +        final Set<FileObject> set = new HashSet<FileObject>();
   6.115 +        JavaSource source = JavaSource.create(cpInfo, refactoring.getRefactoringSource().lookup(TreePathHandle.class).getFileObject());
   6.116 +
   6.117 +        try {
   6.118 +            source.runUserActionTask(new CancellableTask<CompilationController>() {
   6.119 +
   6.120 +                public void cancel() {
   6.121 +                    throw new UnsupportedOperationException("Not supported yet."); // NOI18N
   6.122 +                }
   6.123 +
   6.124 +                public void run(CompilationController info) throws Exception {
   6.125 +                    final ClassIndex idx = info.getClasspathInfo().getClassIndex();
   6.126 +                    info.toPhase(JavaSource.Phase.RESOLVED);
   6.127 +                    final ElementUtilities elmUtils = info.getElementUtilities();
   6.128 +
   6.129 +                    //add all references of overriding methods
   6.130 +                    Element el = treePathHandle.resolveElement(info);
   6.131 +                    ElementHandle<TypeElement> enclosingType = ElementHandle.create(elmUtils.enclosingTypeElement(el));
   6.132 +                    allMethods = new HashSet<ElementHandle<ExecutableElement>>();
   6.133 +                    allMethods.add(ElementHandle.create((ExecutableElement) el));
   6.134 +                    for (ExecutableElement e : RetoucheUtils.getOverridingMethods((ExecutableElement) el, info)) {
   6.135 +                        set.add(SourceUtils.getFile(e, info.getClasspathInfo()));
   6.136 +                        ElementHandle<TypeElement> encl = ElementHandle.create(elmUtils.enclosingTypeElement(e));
   6.137 +                        set.addAll(idx.getResources(encl, EnumSet.of(ClassIndex.SearchKind.METHOD_REFERENCES), EnumSet.of(ClassIndex.SearchScope.SOURCE)));
   6.138 +                        allMethods.add(ElementHandle.create(e));
   6.139 +                    }
   6.140 +                    //add all references of overriden methods
   6.141 +                    for (ExecutableElement e : RetoucheUtils.getOverridenMethods((ExecutableElement) el, info)) {
   6.142 +                        set.add(SourceUtils.getFile(e, info.getClasspathInfo()));
   6.143 +                        ElementHandle<TypeElement> encl = ElementHandle.create(elmUtils.enclosingTypeElement(e));
   6.144 +                        set.addAll(idx.getResources(encl, EnumSet.of(ClassIndex.SearchKind.METHOD_REFERENCES), EnumSet.of(ClassIndex.SearchScope.SOURCE)));
   6.145 +                        allMethods.add(ElementHandle.create(e));
   6.146 +                    }
   6.147 +                    set.addAll(idx.getResources(enclosingType, EnumSet.of(ClassIndex.SearchKind.METHOD_REFERENCES), EnumSet.of(ClassIndex.SearchScope.SOURCE)));
   6.148 +                    set.add(SourceUtils.getFile(el, info.getClasspathInfo()));
   6.149 +                }
   6.150 +            }, true);
   6.151 +        } catch (IOException ioe) {
   6.152 +            throw (RuntimeException) new RuntimeException().initCause(ioe);
   6.153 +        }
   6.154 +        return set;
   6.155 +    }
   6.156 +    private ChangeParametersRefactoring.ParameterInfo[] paramTable;
   6.157 +
   6.158 +    public Problem prepare(RefactoringElementsBag elements) {
   6.159 +        if (refactoring.isCompatible()) {
   6.160 +            fireProgressListenerStart(ProgressEvent.START, 1);
   6.161 +            CancellableTask<WorkingCopy> t = new CancellableTask<WorkingCopy>() {
   6.162 +
   6.163 +                @Override
   6.164 +                public void cancel() {
   6.165 +                }
   6.166 +
   6.167 +                @Override
   6.168 +                public void run(WorkingCopy parameter) throws Exception {
   6.169 +                    parameter.toPhase(JavaSource.Phase.RESOLVED);
   6.170 +                    
   6.171 +                        TreePath resolved = treePathHandle.resolve(parameter);
   6.172 +
   6.173 +                        if (resolved == null) {
   6.174 +                            return; //TODO...
   6.175 +                        }
   6.176 +
   6.177 +                        TypeMirror tm = parameter.getTrees().getTypeMirror(resolved);
   6.178 +
   6.179 +                        if (tm == null) {
   6.180 +                            return; //TODO...
   6.181 +                        }
   6.182 +
   6.183 +                        //tm = Utilities.convertIfAnonymous(Utilities.resolveCapturedType(parameter, tm));
   6.184 +
   6.185 +                        Tree original = resolved.getLeaf();
   6.186 +                        boolean variableRewrite = original.getKind() == Kind.VARIABLE;
   6.187 +                        ExpressionTree expression = !variableRewrite ? (ExpressionTree) resolved.getLeaf() : ((VariableTree) original).getInitializer();
   6.188 +                        final TreeMaker make = parameter.getTreeMaker();
   6.189 +
   6.190 +                        boolean expressionStatement = resolved.getParentPath().getLeaf().getKind() == Tree.Kind.EXPRESSION_STATEMENT;
   6.191 +
   6.192 +                        TreePath meth = findMethod(resolved);
   6.193 +
   6.194 +                        if (meth == null) {
   6.195 +                            return; //TODO...
   6.196 +                        }
   6.197 +
   6.198 +                        BlockTree sttmts;
   6.199 +                        int index2;
   6.200 +
   6.201 +                        if (refactoring.isReplaceAll()) {
   6.202 +                            Set<TreePath> candidates = new HashSet<TreePath>();//CopyFinder.computeDuplicates(parameter, resolved, meth, new AtomicBoolean(), null).keySet();
   6.203 +                            for (TreePath p : candidates) {
   6.204 +                                Tree leaf = p.getLeaf();
   6.205 +
   6.206 +                                parameter.rewrite(leaf, make.Identifier(refactoring.getParameterName()));
   6.207 +                            }
   6.208 +
   6.209 +                            int[] out = new int[1];
   6.210 +                            sttmts = findAddPosition(parameter, resolved, candidates, out);
   6.211 +
   6.212 +                            if (sttmts == null) {
   6.213 +                                return;
   6.214 +                            }
   6.215 +
   6.216 +                            index2 = out[0];
   6.217 +                        } else {
   6.218 +                            int[] out = new int[1];
   6.219 +                            sttmts = findAddPosition(parameter, resolved, Collections.<TreePath>emptySet(), out);
   6.220 +
   6.221 +                            if (sttmts == null) {
   6.222 +                                return;
   6.223 +                            }
   6.224 +
   6.225 +                            index2 = out[0];
   6.226 +                        }
   6.227 +
   6.228 +                        List<StatementTree> nueStatements2 = new LinkedList<StatementTree>(sttmts.getStatements());
   6.229 +
   6.230 +                        ExecutableElement currentMethod = (ExecutableElement) parameter.getTrees().getElement(meth);
   6.231 +                        TreeMaker treeMaker = parameter.getTreeMaker();
   6.232 +                        ReturnTree ret = treeMaker.Return(treeMaker.MethodInvocation(Collections.<ExpressionTree>emptyList(), treeMaker.Identifier(currentMethod), toArgs(((MethodTree) meth.getLeaf()).getParameters(), treeMaker, expression)));
   6.233 +                        MethodTree newm = treeMaker.Method(currentMethod, treeMaker.Block(Collections.<StatementTree>singletonList(ret), false));
   6.234 +                        
   6.235 +                        ClassTree clazz = (ClassTree) meth.getParentPath().getLeaf();
   6.236 +                        parameter.rewrite(clazz, treeMaker.addClassMember(clazz, newm));
   6.237 +
   6.238 +                        if (expressionStatement) {
   6.239 +                            nueStatements2.remove(resolved.getParentPath().getLeaf());
   6.240 +                        }
   6.241 +
   6.242 +                        BlockTree nueBlock2 = make.Block(nueStatements2, false);
   6.243 +
   6.244 +                        parameter.rewrite(sttmts, nueBlock2);
   6.245 +                        
   6.246 +                        VariableTree var = treeMaker.Variable(treeMaker.Modifiers(refactoring.isFinal() ? EnumSet.of(Modifier.FINAL) : EnumSet.noneOf(Modifier.class)), refactoring.getParameterName(), make.Identifier(tm.toString()) , null);
   6.247 +
   6.248 +                        parameter.rewrite(meth.getLeaf(),treeMaker.addMethodParameter((MethodTree) meth.getLeaf(), var));
   6.249 +                        
   6.250 +                        Tree origParent = resolved.getParentPath().getLeaf();
   6.251 +                        Tree newParent = parameter.getTreeUtilities().translate(origParent, Collections.singletonMap(resolved.getLeaf(), make.Identifier(refactoring.getParameterName())));
   6.252 +                        parameter.rewrite(origParent, newParent);
   6.253 +                        
   6.254 +                }
   6.255 +            };
   6.256 +            createAndAddElements(Collections.singleton(treePathHandle.getFileObject()), t, elements, refactoring);
   6.257 +            
   6.258 +        } else {
   6.259 +            Set<FileObject> a = getRelevantFiles();
   6.260 +            fireProgressListenerStart(ProgressEvent.START, a.size());
   6.261 +            if (!a.isEmpty()) {
   6.262 +                CancellableTask<WorkingCopy> t = new CancellableTask<WorkingCopy>() {
   6.263 +
   6.264 +                    @Override
   6.265 +                    public void cancel() {
   6.266 +                    }
   6.267 +
   6.268 +                    @Override
   6.269 +                    public void run(WorkingCopy parameter) throws Exception {
   6.270 +                        parameter.toPhase(JavaSource.Phase.RESOLVED);
   6.271 +                        TreePath resolved = treePathHandle.resolve(parameter);
   6.272 +
   6.273 +                        if (resolved == null) {
   6.274 +                            return; //TODO...
   6.275 +                        }
   6.276 +
   6.277 +                        TypeMirror tm = parameter.getTrees().getTypeMirror(resolved);
   6.278 +
   6.279 +                        if (tm == null) {
   6.280 +                            return; //TODO...
   6.281 +                        }
   6.282 +
   6.283 +                        //tm = Utilities.convertIfAnonymous(Utilities.resolveCapturedType(parameter, tm));
   6.284 +
   6.285 +                        Tree original = resolved.getLeaf();
   6.286 +                        boolean variableRewrite = original.getKind() == Kind.VARIABLE;
   6.287 +                        ExpressionTree expression = !variableRewrite ? (ExpressionTree) resolved.getLeaf() : ((VariableTree) original).getInitializer();
   6.288 +                        final TreeMaker make = parameter.getTreeMaker();
   6.289 +
   6.290 +                        boolean expressionStatement = resolved.getParentPath().getLeaf().getKind() == Tree.Kind.EXPRESSION_STATEMENT;
   6.291 +
   6.292 +                        TreePath meth = findMethod(resolved);
   6.293 +
   6.294 +                        if (meth == null) {
   6.295 +                            return; //TODO...
   6.296 +                        }
   6.297 +
   6.298 +                        BlockTree sttmts;
   6.299 +                        int index2;
   6.300 +
   6.301 +                        if (refactoring.isReplaceAll()) {
   6.302 +                            Set<TreePath> candidates = new HashSet<TreePath>();//CopyFinder.computeDuplicates(parameter, resolved, meth, new AtomicBoolean(), null).keySet();
   6.303 +                            for (TreePath p : candidates) {
   6.304 +                                Tree leaf = p.getLeaf();
   6.305 +
   6.306 +                                parameter.rewrite(leaf, make.Identifier(refactoring.getParameterName()));
   6.307 +                            }
   6.308 +
   6.309 +                            int[] out = new int[1];
   6.310 +                            sttmts = findAddPosition(parameter, resolved, candidates, out);
   6.311 +
   6.312 +                            if (sttmts == null) {
   6.313 +                                return;
   6.314 +                            }
   6.315 +
   6.316 +                            index2 = out[0];
   6.317 +                        } else {
   6.318 +                            int[] out = new int[1];
   6.319 +                            sttmts = findAddPosition(parameter, resolved, Collections.<TreePath>emptySet(), out);
   6.320 +
   6.321 +                            if (sttmts == null) {
   6.322 +                                return;
   6.323 +                            }
   6.324 +
   6.325 +                            index2 = out[0];
   6.326 +                        }
   6.327 +
   6.328 +                        List<StatementTree> nueStatements2 = new LinkedList<StatementTree>(sttmts.getStatements());
   6.329 +
   6.330 +                        ExecutableElement currentMethod = (ExecutableElement) parameter.getTrees().getElement(meth);
   6.331 +
   6.332 +                        int originalIndex = 0;
   6.333 +                        List<? extends VariableElement> pars = currentMethod.getParameters();
   6.334 +                        paramTable = new ChangeParametersRefactoring.ParameterInfo[pars.size() + 1];
   6.335 +                        for (VariableElement par : pars) {
   6.336 +                            TypeMirror desc = par.asType();
   6.337 +                            String typeRepresentation;
   6.338 +                            if (currentMethod.isVarArgs() && originalIndex == pars.size() - 1) {
   6.339 +                                typeRepresentation = ((ArrayType) desc).getComponentType().toString() + " ..."; // NOI18N
   6.340 +                            } else {
   6.341 +                                typeRepresentation = desc.toString();
   6.342 +                            }
   6.343 +                            paramTable[originalIndex] = new ChangeParametersRefactoring.ParameterInfo(originalIndex, par.toString(), typeRepresentation, null);
   6.344 +                            originalIndex++;
   6.345 +                        }
   6.346 +
   6.347 +
   6.348 +
   6.349 +                        paramTable[originalIndex] = new ChangeParametersRefactoring.ParameterInfo(-1, refactoring.getParameterName(), tm.toString(), expression.toString());
   6.350 +
   6.351 +
   6.352 +                        if (expressionStatement) {
   6.353 +                            nueStatements2.remove(resolved.getParentPath().getLeaf());
   6.354 +                        }
   6.355 +
   6.356 +                        BlockTree nueBlock2 = make.Block(nueStatements2, false);
   6.357 +
   6.358 +                        parameter.rewrite(sttmts, nueBlock2);
   6.359 +
   6.360 +                        Tree origParent = resolved.getParentPath().getLeaf();
   6.361 +                        Tree newParent = parameter.getTreeUtilities().translate(origParent, Collections.singletonMap(resolved.getLeaf(), make.Identifier(refactoring.getParameterName())));
   6.362 +                        parameter.rewrite(origParent, newParent);
   6.363 +
   6.364 +                    }
   6.365 +                };
   6.366 +
   6.367 +                createAndAddElements(Collections.singleton(treePathHandle.getFileObject()), t, elements, refactoring);
   6.368 +
   6.369 +                TransformTask transform = new TransformTask(new ChangeParamsTransformer(paramTable, allMethods, null), treePathHandle);
   6.370 +                Problem p = createAndAddElements(a, transform, elements, refactoring);
   6.371 +                if (p != null) {
   6.372 +                    fireProgressListenerStop();
   6.373 +                    return p;
   6.374 +                }
   6.375 +
   6.376 +            }
   6.377 +            fireProgressListenerStop();
   6.378 +        }
   6.379 +        return null;
   6.380 +    }
   6.381 +
   6.382 +    private static List<? extends ExpressionTree> toArgs(List<? extends VariableTree> pars, TreeMaker make, ExpressionTree exp) {
   6.383 +        List<ExpressionTree> args = new LinkedList<ExpressionTree>();
   6.384 +        
   6.385 +        for(VariableTree par:pars) {
   6.386 +            args.add(make.Identifier(par.getName()));
   6.387 +        }
   6.388 +        args.add(exp);
   6.389 +        return args;
   6.390 +    }
   6.391 +    
   6.392 +    private static boolean isParentOf(TreePath parent, TreePath path) {
   6.393 +        Tree parentLeaf = parent.getLeaf();
   6.394 +
   6.395 +        while (path != null && path.getLeaf() != parentLeaf) {
   6.396 +            path = path.getParentPath();
   6.397 +        }
   6.398 +
   6.399 +        return path != null;
   6.400 +    }
   6.401 +
   6.402 +    private static boolean isParentOf(TreePath parent, List<? extends TreePath> candidates) {
   6.403 +        for (TreePath tp : candidates) {
   6.404 +            if (!isParentOf(parent, tp)) {
   6.405 +                return false;
   6.406 +            }
   6.407 +        }
   6.408 +
   6.409 +        return true;
   6.410 +    }
   6.411 +
   6.412 +    private static TreePath findStatement(TreePath statementPath) {
   6.413 +        while (statementPath != null
   6.414 +                && (!StatementTree.class.isAssignableFrom(statementPath.getLeaf().getKind().asInterface())
   6.415 +                || (statementPath.getParentPath() != null
   6.416 +                && statementPath.getParentPath().getLeaf().getKind() != Kind.BLOCK))) {
   6.417 +            if (TreeUtilities.CLASS_TREE_KINDS.contains(statementPath.getLeaf().getKind())) {
   6.418 +                return null;
   6.419 +            }
   6.420 +
   6.421 +            statementPath = statementPath.getParentPath();
   6.422 +        }
   6.423 +
   6.424 +        return statementPath;
   6.425 +    }
   6.426 +
   6.427 +    private static TreePath findMethod(TreePath path) {
   6.428 +        while (path != null) {
   6.429 +            if (path.getLeaf().getKind() == Kind.METHOD) {
   6.430 +                return path;
   6.431 +            }
   6.432 +
   6.433 +            if (path.getLeaf().getKind() == Kind.BLOCK
   6.434 +                    && path.getParentPath() != null
   6.435 +                    && TreeUtilities.CLASS_TREE_KINDS.contains(path.getParentPath().getLeaf().getKind())) {
   6.436 +                //initializer:
   6.437 +                return path;
   6.438 +            }
   6.439 +
   6.440 +            path = path.getParentPath();
   6.441 +        }
   6.442 +
   6.443 +        return null;
   6.444 +    }
   6.445 +
   6.446 +    private static BlockTree findAddPosition(CompilationInfo info, TreePath original, Set<? extends TreePath> candidates, int[] outPosition) {
   6.447 +        //find least common block holding all the candidates:
   6.448 +        TreePath statement = original;
   6.449 +
   6.450 +        for (TreePath p : candidates) {
   6.451 +            Tree leaf = p.getLeaf();
   6.452 +            int leafStart = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), leaf);
   6.453 +            int stPathStart = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), statement.getLeaf());
   6.454 +
   6.455 +            if (leafStart < stPathStart) {
   6.456 +                statement = p;
   6.457 +            }
   6.458 +        }
   6.459 +
   6.460 +        List<TreePath> allCandidates = new LinkedList<TreePath>();
   6.461 +
   6.462 +        allCandidates.add(original);
   6.463 +        allCandidates.addAll(candidates);
   6.464 +
   6.465 +        statement = findStatement(statement);
   6.466 +
   6.467 +        if (statement == null) {
   6.468 +            //XXX: well....
   6.469 +            return null;
   6.470 +        }
   6.471 +
   6.472 +        while (statement.getParentPath() != null && !isParentOf(statement.getParentPath(), allCandidates)) {
   6.473 +            statement = statement.getParentPath();
   6.474 +        }
   6.475 +
   6.476 +        //#126269: the common parent may not be block:
   6.477 +        while (statement.getParentPath() != null && statement.getParentPath().getLeaf().getKind() != Kind.BLOCK) {
   6.478 +            statement = statement.getParentPath();
   6.479 +        }
   6.480 +
   6.481 +        if (statement.getParentPath() == null) {
   6.482 +            return null;//XXX: log
   6.483 +        }
   6.484 +        BlockTree statements = (BlockTree) statement.getParentPath().getLeaf();
   6.485 +        StatementTree statementTree = (StatementTree) statement.getLeaf();
   6.486 +
   6.487 +        int index = statements.getStatements().indexOf(statementTree);
   6.488 +
   6.489 +        if (index == (-1)) {
   6.490 +            //really strange...
   6.491 +            return null;
   6.492 +        }
   6.493 +
   6.494 +        outPosition[0] = index;
   6.495 +
   6.496 +        return statements;
   6.497 +    }
   6.498 +
   6.499 +    protected JavaSource getJavaSource(JavaRefactoringPlugin.Phase p) {
   6.500 +        switch (p) {
   6.501 +            case CHECKPARAMETERS:
   6.502 +            case FASTCHECKPARAMETERS:
   6.503 +            case PRECHECK:
   6.504 +                ClasspathInfo cpInfo = getClasspathInfo(refactoring);
   6.505 +                return JavaSource.create(cpInfo, treePathHandle.getFileObject());
   6.506 +        }
   6.507 +        return null;
   6.508 +    }
   6.509 +
   6.510 +    /**
   6.511 +     * Returns list of problems. For the change method signature, there are two
   6.512 +     * possible warnings - if the method is overriden or if it overrides
   6.513 +     * another method.
   6.514 +     *
   6.515 +     * @return  overrides or overriden problem or both
   6.516 +     */
   6.517 +    @Override
   6.518 +    public Problem preCheck(CompilationController info) throws IOException {
   6.519 +        fireProgressListenerStart(refactoring.PRE_CHECK, 4);
   6.520 +        Problem preCheckProblem = null;
   6.521 +        info.toPhase(JavaSource.Phase.RESOLVED);
   6.522 +        preCheckProblem = isElementAvail(treePathHandle, info);
   6.523 +        if (preCheckProblem != null) {
   6.524 +            return preCheckProblem;
   6.525 +        }
   6.526 +        Element el = treePathHandle.resolveElement(info);
   6.527 +        if (!(el.getKind() == ElementKind.METHOD || el.getKind() == ElementKind.CONSTRUCTOR)) {
   6.528 +            preCheckProblem = createProblem(preCheckProblem, true, NbBundle.getMessage(IntroduceParameterPlugin.class, "ERR_ChangeParamsWrongType"));
   6.529 +            return preCheckProblem;
   6.530 +        }
   6.531 +
   6.532 +        preCheckProblem = JavaPluginUtils.isSourceElement(el, info);
   6.533 +        if (preCheckProblem != null) {
   6.534 +            return preCheckProblem;
   6.535 +        }
   6.536 +
   6.537 +        if (info.getElementUtilities().enclosingTypeElement(el).getKind() == ElementKind.ANNOTATION_TYPE) {
   6.538 +            preCheckProblem = new Problem(true, NbBundle.getMessage(IntroduceParameterPlugin.class, "ERR_MethodsInAnnotationsNotSupported"));
   6.539 +            return preCheckProblem;
   6.540 +        }
   6.541 +
   6.542 +        for (ExecutableElement e : RetoucheUtils.getOverridenMethods((ExecutableElement) el, info)) {
   6.543 +            if (RetoucheUtils.isFromLibrary(e, info.getClasspathInfo())) { //NOI18N
   6.544 +                preCheckProblem = createProblem(preCheckProblem, true, NbBundle.getMessage(IntroduceParameterPlugin.class, "ERR_CannnotRefactorLibrary", el));
   6.545 +            }
   6.546 +        }
   6.547 +
   6.548 +        fireProgressListenerStop();
   6.549 +        return preCheckProblem;
   6.550 +    }
   6.551 +}
     7.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaRefactoringsFactory.java	Thu Apr 21 16:33:50 2011 +0200
     7.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/plugins/JavaRefactoringsFactory.java	Fri May 06 15:36:19 2011 +0200
     7.3 @@ -53,6 +53,7 @@
     7.4  import org.netbeans.modules.refactoring.java.api.ExtractInterfaceRefactoring;
     7.5  import org.netbeans.modules.refactoring.java.api.ExtractSuperclassRefactoring;
     7.6  import org.netbeans.modules.refactoring.java.api.InnerToOuterRefactoring;
     7.7 +import org.netbeans.modules.refactoring.java.api.IntroduceParameterRefactoring;
     7.8  import org.netbeans.modules.refactoring.java.api.PullUpRefactoring;
     7.9  import org.netbeans.modules.refactoring.java.api.PushDownRefactoring;
    7.10  import org.netbeans.modules.refactoring.java.api.UseSuperTypeRefactoring;
    7.11 @@ -120,6 +121,8 @@
    7.12                  return new InnerToOuterRefactoringPlugin((InnerToOuterRefactoring) refactoring);
    7.13              } else if (refactoring instanceof ChangeParametersRefactoring) {
    7.14                  return new ChangeParametersPlugin((ChangeParametersRefactoring) refactoring);
    7.15 +            } else if (refactoring instanceof IntroduceParameterRefactoring) {
    7.16 +                return new IntroduceParameterPlugin((IntroduceParameterRefactoring) refactoring);
    7.17              } else if (refactoring instanceof EncapsulateFieldRefactoring) {
    7.18                  return new EncapsulateFieldRefactoringPlugin((EncapsulateFieldRefactoring) refactoring);
    7.19              } else if (refactoring instanceof EncapsulateFieldsRefactoring) {
     8.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/resources/mf-layer.xml	Thu Apr 21 16:33:50 2011 +0200
     8.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/resources/mf-layer.xml	Fri May 06 15:36:19 2011 +0200
     8.3 @@ -118,6 +118,10 @@
     8.4                              <attr name="originalFile" stringvalue="Actions/Refactoring/org-netbeans-modules-refactoring-java-api-ui-EncapsulateFieldAction.instance"/>
     8.5                              <attr name="position" intvalue="1800"/>
     8.6                          </file>
     8.7 +                        <file name="org-netbeans-modules-refactoring-java-api-ui-IntroduceParameterAction.shadow">
     8.8 +                            <attr name="originalFile" stringvalue="Actions/Refactoring/org-netbeans-modules-refactoring-java-api-ui-IntroduceParameterAction.instance"/>
     8.9 +                            <attr name="position" intvalue="1900"/>
    8.10 +                        </file>
    8.11                      </folder>
    8.12              </folder>
    8.13          </folder>
    8.14 @@ -170,6 +174,10 @@
    8.15              <file name="org-netbeans-modules-refactoring-java-api-ui-InnerToOuterAction.instance">
    8.16                  <attr name="instanceCreate" methodvalue="org.netbeans.modules.refactoring.java.api.ui.JavaRefactoringActionsFactory.innerToOuterAction"/>
    8.17              </file>
    8.18 +            <file name="org-netbeans-modules-refactoring-java-api-ui-IntroduceParameterAction.instance">
    8.19 +                <attr name="instanceCreate" methodvalue="org.netbeans.modules.refactoring.java.api.ui.JavaRefactoringActionsFactory.introduceParameterAction"/>
    8.20 +            </file>
    8.21 +
    8.22          </folder>
    8.23          <folder name="Window">
    8.24              <file name="org-netbeans-modules-refactoring-java-callhierarchy-CallHierarchyAction.instance"/>
     9.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/spi/ui/JavaActionsImplementationProvider.java	Thu Apr 21 16:33:50 2011 +0200
     9.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/spi/ui/JavaActionsImplementationProvider.java	Fri May 06 15:36:19 2011 +0200
     9.3 @@ -105,8 +105,24 @@
     9.4      public void doChangeParameters(Lookup lookup) {
     9.5          throw new UnsupportedOperationException("Not implemented"); // NOI18N
     9.6      }
     9.7 +    
     9.8 +    /**
     9.9 +     * @param lookup 
    9.10 +     * @return true if provider can handle find usages
    9.11 +     */
    9.12 +    public boolean canIntroduceParameter(Lookup lookup) {
    9.13 +        return false;
    9.14 +    }
    9.15  
    9.16      /**
    9.17 +     * implementation of "invoke Change Parameters"
    9.18 +     * @param lookup 
    9.19 +     */
    9.20 +    public void doIntroduceParameter(Lookup lookup) {
    9.21 +        throw new UnsupportedOperationException("Not implemented"); // NOI18N
    9.22 +    }
    9.23 +    
    9.24 +    /**
    9.25       * @param lookup 
    9.26       * @return true if provider can handle Pull Up
    9.27       */
    10.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/Bundle.properties	Thu Apr 21 16:33:50 2011 +0200
    10.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/Bundle.properties	Fri May 06 15:36:19 2011 +0200
    10.3 @@ -44,6 +44,10 @@
    10.4  LBL_RenameComments=Apply Rename on &Comments
    10.5  LBL_ChangeMethodSignatureAction=Change Method &Parameters...
    10.6  LBL_ChangeMethodSignature=Change Method Parameters
    10.7 +
    10.8 +LBL_IntroduceParameterAction=Introduce Parameter...
    10.9 +LBL_IntroduceParameter=Introduce Parameter
   10.10 +
   10.11  DSC_Rename=Rename <b>{0}</b> to <b>{1}</b>
   10.12  LBL_WhereUsedAction=Fi&nd Usages
   10.13  LBL_WhereUsed=Find Usages
   10.14 @@ -137,6 +141,7 @@
   10.15  DSC_ChangeParsRootNode=Change parameters of <b>{0}</b> {1} to <b>{2}</b>
   10.16  DSC_ChangeParsRootNodeMethod=method
   10.17  DSC_ChangeParsRootNodeConstr=constructor
   10.18 +DSC_IntroduceParameterRootNode=Introduce parameter <b>{0}</b>.
   10.19  
   10.20  LBL_PackagePrivate=package private
   10.21  LBL_Protected=protected
   10.22 @@ -394,3 +399,7 @@
   10.23  ExtractSuperclassPanel.chooseLabel.AccessibleContext.accessibleDescription=N/A
   10.24  
   10.25  ExtractInterfacePanel.chooseLabel.AccessibleContext.accessibleDescription=N/A
   10.26 +IntroduceParameterPanel.lblName.text=&Name:
   10.27 +IntroduceParameterPanel.chkIsDeclareFinal.text=Declare &Final
   10.28 +IntroduceParameterPanel.chkIsReplaceAll.text=Replace &All Occurences
   10.29 +IntroduceParameterPanel.chkIsCompatible.text=&Compatible
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterAction.java	Fri May 06 15:36:19 2011 +0200
    11.3 @@ -0,0 +1,80 @@
    11.4 +/*
    11.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    11.6 + *
    11.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    11.8 + *
    11.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   11.10 + * Other names may be trademarks of their respective owners.
   11.11 + *
   11.12 + * The contents of this file are subject to the terms of either the GNU
   11.13 + * General Public License Version 2 only ("GPL") or the Common
   11.14 + * Development and Distribution License("CDDL") (collectively, the
   11.15 + * "License"). You may not use this file except in compliance with the
   11.16 + * License. You can obtain a copy of the License at
   11.17 + * http://www.netbeans.org/cddl-gplv2.html
   11.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   11.19 + * specific language governing permissions and limitations under the
   11.20 + * License.  When distributing the software, include this License Header
   11.21 + * Notice in each file and include the License file at
   11.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   11.23 + * particular file as subject to the "Classpath" exception as provided
   11.24 + * by Oracle in the GPL Version 2 section of the License file that
   11.25 + * accompanied this code. If applicable, add the following below the
   11.26 + * License Header, with the fields enclosed by brackets [] replaced by
   11.27 + * your own identifying information:
   11.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   11.29 + *
   11.30 + * If you wish your version of this file to be governed by only the CDDL
   11.31 + * or only the GPL Version 2, indicate your decision by adding
   11.32 + * "[Contributor] elects to include this software in this distribution
   11.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   11.34 + * single choice of license, a recipient has the option to distribute
   11.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   11.36 + * to extend the choice of license to its licensees as provided above.
   11.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   11.38 + * Version 2 license, then the option applies only if the new code is
   11.39 + * made subject to such option by the copyright holder.
   11.40 + *
   11.41 + * Contributor(s):
   11.42 + *
   11.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   11.44 + */
   11.45 +package org.netbeans.modules.refactoring.java.ui;
   11.46 +
   11.47 +import org.netbeans.modules.refactoring.java.ui.JavaActionsImplementationFactory;
   11.48 +import org.netbeans.modules.refactoring.java.ui.JavaRefactoringGlobalAction;
   11.49 +import org.openide.util.HelpCtx;
   11.50 +import org.openide.util.Lookup;
   11.51 +import org.openide.util.NbBundle;
   11.52 +
   11.53 +
   11.54 +/**
   11.55 + * Activates introduce method refactoring.
   11.56 + *
   11.57 + * @author Jan Becicka
   11.58 + */
   11.59 +public class IntroduceParameterAction extends JavaRefactoringGlobalAction {
   11.60 +    
   11.61 +    /** Creates a new instance of ChangeParametersAction
   11.62 +     */
   11.63 +    public IntroduceParameterAction() {
   11.64 +        super(NbBundle.getMessage(ChangeParametersAction.class, "LBL_IntroduceParameterAction"), null); // NOI18N
   11.65 +        putValue("noIconInMenu", Boolean.TRUE); // NOI18N
   11.66 +    }
   11.67 +    
   11.68 +    public final void performAction(Lookup context) {
   11.69 +        JavaActionsImplementationFactory.doIntroduceParameter(context);
   11.70 +    }
   11.71 +    
   11.72 +    public org.openide.util.HelpCtx getHelpCtx() {
   11.73 +        return HelpCtx.DEFAULT_HELP;
   11.74 +    }
   11.75 +
   11.76 +    protected boolean asynchronous() {
   11.77 +        return false;
   11.78 +    }
   11.79 +
   11.80 +    protected boolean enable(Lookup context) {
   11.81 +        return JavaActionsImplementationFactory.canIntroduceParameter(context);
   11.82 +    }
   11.83 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterPanel.form	Fri May 06 15:36:19 2011 +0200
    12.3 @@ -0,0 +1,107 @@
    12.4 +<?xml version="1.1" encoding="UTF-8" ?>
    12.5 +
    12.6 +<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
    12.7 +  <Properties>
    12.8 +    <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
    12.9 +      <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
   12.10 +        <EmptyBorder bottom="11" left="12" right="11" top="12"/>
   12.11 +      </Border>
   12.12 +    </Property>
   12.13 +    <Property name="autoscrolls" type="boolean" value="true"/>
   12.14 +    <Property name="name" type="java.lang.String" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
   12.15 +      <Connection code="getString(&quot;LBL_TitleChangeParameters&quot;)" type="code"/>
   12.16 +    </Property>
   12.17 +  </Properties>
   12.18 +  <AuxValues>
   12.19 +    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
   12.20 +    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
   12.21 +    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
   12.22 +    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
   12.23 +    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
   12.24 +    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
   12.25 +    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
   12.26 +    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
   12.27 +    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
   12.28 +  </AuxValues>
   12.29 +
   12.30 +  <Layout>
   12.31 +    <DimensionLayout dim="0">
   12.32 +      <Group type="103" groupAlignment="0" attributes="0">
   12.33 +          <Group type="102" alignment="0" attributes="0">
   12.34 +              <Component id="lblName" min="-2" max="-2" attributes="0"/>
   12.35 +              <EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
   12.36 +              <Component id="name" pref="336" max="32767" attributes="0"/>
   12.37 +          </Group>
   12.38 +          <Group type="102" alignment="0" attributes="0">
   12.39 +              <Component id="chkIsDeclareFinal" min="-2" max="-2" attributes="0"/>
   12.40 +              <EmptySpace max="-2" attributes="0"/>
   12.41 +          </Group>
   12.42 +          <Group type="102" alignment="0" attributes="0">
   12.43 +              <Component id="chkIsReplaceAll" min="-2" max="-2" attributes="0"/>
   12.44 +              <EmptySpace max="-2" attributes="0"/>
   12.45 +          </Group>
   12.46 +          <Group type="102" alignment="0" attributes="0">
   12.47 +              <Component id="chkIsCompatible" min="-2" max="-2" attributes="0"/>
   12.48 +              <EmptySpace max="-2" attributes="0"/>
   12.49 +          </Group>
   12.50 +      </Group>
   12.51 +    </DimensionLayout>
   12.52 +    <DimensionLayout dim="1">
   12.53 +      <Group type="103" groupAlignment="0" attributes="0">
   12.54 +          <Group type="102" alignment="0" attributes="0">
   12.55 +              <Group type="103" groupAlignment="3" attributes="0">
   12.56 +                  <Component id="lblName" alignment="3" min="-2" max="-2" attributes="0"/>
   12.57 +                  <Component id="name" alignment="3" min="-2" max="-2" attributes="0"/>
   12.58 +              </Group>
   12.59 +              <EmptySpace type="unrelated" max="-2" attributes="0"/>
   12.60 +              <Component id="chkIsDeclareFinal" min="-2" max="-2" attributes="0"/>
   12.61 +              <EmptySpace max="-2" attributes="0"/>
   12.62 +              <Component id="chkIsReplaceAll" min="-2" max="-2" attributes="0"/>
   12.63 +              <EmptySpace max="-2" attributes="0"/>
   12.64 +              <Component id="chkIsCompatible" min="-2" max="-2" attributes="0"/>
   12.65 +          </Group>
   12.66 +      </Group>
   12.67 +    </DimensionLayout>
   12.68 +  </Layout>
   12.69 +  <SubComponents>
   12.70 +    <Component class="javax.swing.JLabel" name="lblName">
   12.71 +      <Properties>
   12.72 +        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
   12.73 +          <ResourceString bundle="org/netbeans/modules/refactoring/java/ui/Bundle.properties" key="IntroduceParameterPanel.lblName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
   12.74 +        </Property>
   12.75 +      </Properties>
   12.76 +    </Component>
   12.77 +    <Component class="javax.swing.JTextField" name="name">
   12.78 +    </Component>
   12.79 +    <Component class="javax.swing.JCheckBox" name="chkIsDeclareFinal">
   12.80 +      <Properties>
   12.81 +        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
   12.82 +          <ResourceString bundle="org/netbeans/modules/refactoring/java/ui/Bundle.properties" key="IntroduceParameterPanel.chkIsDeclareFinal.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
   12.83 +        </Property>
   12.84 +      </Properties>
   12.85 +      <Events>
   12.86 +        <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="chkIsDeclareFinalStateChanged"/>
   12.87 +      </Events>
   12.88 +    </Component>
   12.89 +    <Component class="javax.swing.JCheckBox" name="chkIsReplaceAll">
   12.90 +      <Properties>
   12.91 +        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
   12.92 +          <ResourceString bundle="org/netbeans/modules/refactoring/java/ui/Bundle.properties" key="IntroduceParameterPanel.chkIsReplaceAll.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
   12.93 +        </Property>
   12.94 +      </Properties>
   12.95 +      <Events>
   12.96 +        <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="chkIsReplaceAllStateChanged"/>
   12.97 +      </Events>
   12.98 +    </Component>
   12.99 +    <Component class="javax.swing.JCheckBox" name="chkIsCompatible">
  12.100 +      <Properties>
  12.101 +        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
  12.102 +          <ResourceString bundle="org/netbeans/modules/refactoring/java/ui/Bundle.properties" key="IntroduceParameterPanel.chkIsCompatible.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
  12.103 +        </Property>
  12.104 +      </Properties>
  12.105 +      <Events>
  12.106 +        <EventHandler event="stateChanged" listener="javax.swing.event.ChangeListener" parameters="javax.swing.event.ChangeEvent" handler="chkIsCompatibleStateChanged"/>
  12.107 +      </Events>
  12.108 +    </Component>
  12.109 +  </SubComponents>
  12.110 +</Form>
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterPanel.java	Fri May 06 15:36:19 2011 +0200
    13.3 @@ -0,0 +1,239 @@
    13.4 +/*
    13.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    13.6 + *
    13.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    13.8 + *
    13.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   13.10 + * Other names may be trademarks of their respective owners.
   13.11 + *
   13.12 + * The contents of this file are subject to the terms of either the GNU
   13.13 + * General Public License Version 2 only ("GPL") or the Common
   13.14 + * Development and Distribution License("CDDL") (collectively, the
   13.15 + * "License"). You may not use this file except in compliance with the
   13.16 + * License. You can obtain a copy of the License at
   13.17 + * http://www.netbeans.org/cddl-gplv2.html
   13.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   13.19 + * specific language governing permissions and limitations under the
   13.20 + * License.  When distributing the software, include this License Header
   13.21 + * Notice in each file and include the License file at
   13.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   13.23 + * particular file as subject to the "Classpath" exception as provided
   13.24 + * by Oracle in the GPL Version 2 section of the License file that
   13.25 + * accompanied this code. If applicable, add the following below the
   13.26 + * License Header, with the fields enclosed by brackets [] replaced by
   13.27 + * your own identifying information:
   13.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   13.29 + *
   13.30 + * If you wish your version of this file to be governed by only the CDDL
   13.31 + * or only the GPL Version 2, indicate your decision by adding
   13.32 + * "[Contributor] elects to include this software in this distribution
   13.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   13.34 + * single choice of license, a recipient has the option to distribute
   13.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   13.36 + * to extend the choice of license to its licensees as provided above.
   13.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   13.38 + * Version 2 license, then the option applies only if the new code is
   13.39 + * made subject to such option by the copyright holder.
   13.40 + *
   13.41 + * Contributor(s):
   13.42 + *
   13.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   13.44 + */
   13.45 +package org.netbeans.modules.refactoring.java.ui;
   13.46 +
   13.47 +import java.awt.Component;
   13.48 +import java.io.IOException;
   13.49 +import javax.swing.*;
   13.50 +import javax.swing.event.*;
   13.51 +import org.netbeans.api.java.source.CancellableTask;
   13.52 +import org.netbeans.api.java.source.CompilationController;
   13.53 +import org.netbeans.api.java.source.JavaSource;
   13.54 +import org.netbeans.api.java.source.TreePathHandle;
   13.55 +import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
   13.56 +import org.openide.util.Exceptions;
   13.57 +import org.openide.util.NbBundle;
   13.58 +
   13.59 +/**
   13.60 + * @author Jan Becicka
   13.61 + */
   13.62 +public class IntroduceParameterPanel extends JPanel implements CustomRefactoringPanel {
   13.63 +
   13.64 +    TreePathHandle refactoredObj;
   13.65 +    private ChangeListener parent;
   13.66 +    
   13.67 +    
   13.68 +    public Component getComponent() {
   13.69 +        return this;
   13.70 +    }
   13.71 +
   13.72 +
   13.73 +    /** Creates new form ChangeMethodSignature */
   13.74 +    public IntroduceParameterPanel(TreePathHandle refactoredObj, final ChangeListener parent) {
   13.75 +        this.refactoredObj = refactoredObj;
   13.76 +        this.parent = parent;
   13.77 +        initComponents();
   13.78 +        name.getDocument().addDocumentListener(new DocumentListener() {
   13.79 +
   13.80 +            @Override
   13.81 +            public void insertUpdate(DocumentEvent de) {
   13.82 +                parent.stateChanged(null);
   13.83 +            }
   13.84 +
   13.85 +            @Override
   13.86 +            public void removeUpdate(DocumentEvent de) {
   13.87 +                parent.stateChanged(null);
   13.88 +            }
   13.89 +
   13.90 +            @Override
   13.91 +            public void changedUpdate(DocumentEvent de) {
   13.92 +                parent.stateChanged(null);
   13.93 +            }
   13.94 +        });
   13.95 +    }
   13.96 +    
   13.97 +    private boolean initialized = false;
   13.98 +    public void initialize() {
   13.99 +        try {
  13.100 +            if (initialized) {
  13.101 +                return;
  13.102 +            }
  13.103 +            JavaSource source = JavaSource.forFileObject(refactoredObj.getFileObject());
  13.104 +            source.runUserActionTask(new CancellableTask<CompilationController>() {
  13.105 +                public void run(org.netbeans.api.java.source.CompilationController info) {
  13.106 +                    try {
  13.107 +                        info.toPhase(org.netbeans.api.java.source.JavaSource.Phase.RESOLVED);
  13.108 +                    }
  13.109 +                    catch (IOException ex) {
  13.110 +                        Exceptions.printStackTrace(ex);
  13.111 +                    }
  13.112 +                }
  13.113 +
  13.114 +                public void cancel() {
  13.115 +                }
  13.116 +            }, true);
  13.117 +            initialized = true;
  13.118 +        }
  13.119 +        catch (IOException ex) {
  13.120 +            Exceptions.printStackTrace(ex);
  13.121 +        }
  13.122 +    }
  13.123 +
  13.124 +    /** This method is called from within the constructor to
  13.125 +     * initialize the form.
  13.126 +     * WARNING: Do NOT modify this code. The content of this method is
  13.127 +     * always regenerated by the Form Editor.
  13.128 +     */
  13.129 +    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  13.130 +    private void initComponents() {
  13.131 +
  13.132 +        lblName = new javax.swing.JLabel();
  13.133 +        name = new javax.swing.JTextField();
  13.134 +        chkIsDeclareFinal = new javax.swing.JCheckBox();
  13.135 +        chkIsReplaceAll = new javax.swing.JCheckBox();
  13.136 +        chkIsCompatible = new javax.swing.JCheckBox();
  13.137 +
  13.138 +        setBorder(javax.swing.BorderFactory.createEmptyBorder(12, 12, 11, 11));
  13.139 +        setAutoscrolls(true);
  13.140 +        setName(getString("LBL_TitleChangeParameters"));
  13.141 +
  13.142 +        org.openide.awt.Mnemonics.setLocalizedText(lblName, org.openide.util.NbBundle.getMessage(IntroduceParameterPanel.class, "IntroduceParameterPanel.lblName.text")); // NOI18N
  13.143 +
  13.144 +        org.openide.awt.Mnemonics.setLocalizedText(chkIsDeclareFinal, org.openide.util.NbBundle.getMessage(IntroduceParameterPanel.class, "IntroduceParameterPanel.chkIsDeclareFinal.text")); // NOI18N
  13.145 +        chkIsDeclareFinal.addChangeListener(new javax.swing.event.ChangeListener() {
  13.146 +            public void stateChanged(javax.swing.event.ChangeEvent evt) {
  13.147 +                chkIsDeclareFinalStateChanged(evt);
  13.148 +            }
  13.149 +        });
  13.150 +
  13.151 +        org.openide.awt.Mnemonics.setLocalizedText(chkIsReplaceAll, org.openide.util.NbBundle.getMessage(IntroduceParameterPanel.class, "IntroduceParameterPanel.chkIsReplaceAll.text")); // NOI18N
  13.152 +        chkIsReplaceAll.addChangeListener(new javax.swing.event.ChangeListener() {
  13.153 +            public void stateChanged(javax.swing.event.ChangeEvent evt) {
  13.154 +                chkIsReplaceAllStateChanged(evt);
  13.155 +            }
  13.156 +        });
  13.157 +
  13.158 +        org.openide.awt.Mnemonics.setLocalizedText(chkIsCompatible, org.openide.util.NbBundle.getMessage(IntroduceParameterPanel.class, "IntroduceParameterPanel.chkIsCompatible.text")); // NOI18N
  13.159 +        chkIsCompatible.addChangeListener(new javax.swing.event.ChangeListener() {
  13.160 +            public void stateChanged(javax.swing.event.ChangeEvent evt) {
  13.161 +                chkIsCompatibleStateChanged(evt);
  13.162 +            }
  13.163 +        });
  13.164 +
  13.165 +        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
  13.166 +        this.setLayout(layout);
  13.167 +        layout.setHorizontalGroup(
  13.168 +            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  13.169 +            .addGroup(layout.createSequentialGroup()
  13.170 +                .addComponent(lblName)
  13.171 +                .addGap(2, 2, 2)
  13.172 +                .addComponent(name, javax.swing.GroupLayout.DEFAULT_SIZE, 336, Short.MAX_VALUE))
  13.173 +            .addGroup(layout.createSequentialGroup()
  13.174 +                .addComponent(chkIsDeclareFinal)
  13.175 +                .addContainerGap())
  13.176 +            .addGroup(layout.createSequentialGroup()
  13.177 +                .addComponent(chkIsReplaceAll)
  13.178 +                .addContainerGap())
  13.179 +            .addGroup(layout.createSequentialGroup()
  13.180 +                .addComponent(chkIsCompatible)
  13.181 +                .addContainerGap())
  13.182 +        );
  13.183 +        layout.setVerticalGroup(
  13.184 +            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
  13.185 +            .addGroup(layout.createSequentialGroup()
  13.186 +                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
  13.187 +                    .addComponent(lblName)
  13.188 +                    .addComponent(name, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
  13.189 +                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
  13.190 +                .addComponent(chkIsDeclareFinal)
  13.191 +                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
  13.192 +                .addComponent(chkIsReplaceAll)
  13.193 +                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
  13.194 +                .addComponent(chkIsCompatible))
  13.195 +        );
  13.196 +    }// </editor-fold>//GEN-END:initComponents
  13.197 +
  13.198 +    private void chkIsDeclareFinalStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_chkIsDeclareFinalStateChanged
  13.199 +        parent.stateChanged(null);
  13.200 +    }//GEN-LAST:event_chkIsDeclareFinalStateChanged
  13.201 +
  13.202 +    private void chkIsReplaceAllStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_chkIsReplaceAllStateChanged
  13.203 +        parent.stateChanged(null);
  13.204 +    }//GEN-LAST:event_chkIsReplaceAllStateChanged
  13.205 +
  13.206 +    private void chkIsCompatibleStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_chkIsCompatibleStateChanged
  13.207 +        parent.stateChanged(null);
  13.208 +    }//GEN-LAST:event_chkIsCompatibleStateChanged
  13.209 +    
  13.210 +    // Variables declaration - do not modify//GEN-BEGIN:variables
  13.211 +    private javax.swing.JCheckBox chkIsCompatible;
  13.212 +    private javax.swing.JCheckBox chkIsDeclareFinal;
  13.213 +    private javax.swing.JCheckBox chkIsReplaceAll;
  13.214 +    private javax.swing.JLabel lblName;
  13.215 +    private javax.swing.JTextField name;
  13.216 +    // End of variables declaration//GEN-END:variables
  13.217 +
  13.218 +    private static String getString(String key) {
  13.219 +        return NbBundle.getMessage(ChangeParametersPanel.class, key);
  13.220 +    }
  13.221 +
  13.222 +    public boolean isCompatible() {
  13.223 +        return chkIsCompatible.isSelected();
  13.224 +    }
  13.225 +
  13.226 +    public boolean isDeclareFinal() {
  13.227 +        return chkIsDeclareFinal.isSelected();
  13.228 +    }
  13.229 +
  13.230 +    public boolean isReplaceAll() {
  13.231 +        return chkIsReplaceAll.isSelected();
  13.232 +    }
  13.233 +    
  13.234 +    public String getParameterName() {
  13.235 +        return name.getText();
  13.236 +    }
  13.237 +    
  13.238 +    public void requestFocus() {
  13.239 +        super.requestFocus();
  13.240 +        name.requestFocus();
  13.241 +    }
  13.242 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/IntroduceParameterUI.java	Fri May 06 15:36:19 2011 +0200
    14.3 @@ -0,0 +1,131 @@
    14.4 +/*
    14.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    14.6 + *
    14.7 + * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
    14.8 + *
    14.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   14.10 + * Other names may be trademarks of their respective owners.
   14.11 + *
   14.12 + * The contents of this file are subject to the terms of either the GNU
   14.13 + * General Public License Version 2 only ("GPL") or the Common
   14.14 + * Development and Distribution License("CDDL") (collectively, the
   14.15 + * "License"). You may not use this file except in compliance with the
   14.16 + * License. You can obtain a copy of the License at
   14.17 + * http://www.netbeans.org/cddl-gplv2.html
   14.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
   14.19 + * specific language governing permissions and limitations under the
   14.20 + * License.  When distributing the software, include this License Header
   14.21 + * Notice in each file and include the License file at
   14.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
   14.23 + * particular file as subject to the "Classpath" exception as provided
   14.24 + * by Oracle in the GPL Version 2 section of the License file that
   14.25 + * accompanied this code. If applicable, add the following below the
   14.26 + * License Header, with the fields enclosed by brackets [] replaced by
   14.27 + * your own identifying information:
   14.28 + * "Portions Copyrighted [year] [name of copyright owner]"
   14.29 + *
   14.30 + * If you wish your version of this file to be governed by only the CDDL
   14.31 + * or only the GPL Version 2, indicate your decision by adding
   14.32 + * "[Contributor] elects to include this software in this distribution
   14.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
   14.34 + * single choice of license, a recipient has the option to distribute
   14.35 + * your version of this file under either the CDDL, the GPL Version 2 or
   14.36 + * to extend the choice of license to its licensees as provided above.
   14.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
   14.38 + * Version 2 license, then the option applies only if the new code is
   14.39 + * made subject to such option by the copyright holder.
   14.40 + *
   14.41 + * Contributor(s):
   14.42 + *
   14.43 + * Portions Copyrighted 2011 Sun Microsystems, Inc.
   14.44 + */
   14.45 +package org.netbeans.modules.refactoring.java.ui;
   14.46 +
   14.47 +import java.text.MessageFormat;
   14.48 +import javax.swing.event.ChangeListener;
   14.49 +import org.netbeans.api.java.source.CompilationInfo;
   14.50 +import org.netbeans.api.java.source.TreePathHandle;
   14.51 +import org.netbeans.modules.refactoring.api.AbstractRefactoring;
   14.52 +import org.netbeans.modules.refactoring.api.Problem;
   14.53 +import org.netbeans.modules.refactoring.java.api.IntroduceParameterRefactoring;
   14.54 +import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
   14.55 +import org.netbeans.modules.refactoring.spi.ui.RefactoringUI;
   14.56 +import org.openide.util.HelpCtx;
   14.57 +import org.openide.util.NbBundle;
   14.58 +
   14.59 +/**
   14.60 + *
   14.61 + * @author Jan Becicka
   14.62 + */
   14.63 +public class IntroduceParameterUI implements RefactoringUI {
   14.64 +    
   14.65 +    private TreePathHandle expression;
   14.66 +    private IntroduceParameterPanel panel;
   14.67 +    private IntroduceParameterRefactoring refactoring;
   14.68 +    
   14.69 +    /** Creates a new instance of IntroduceParameterUI */
   14.70 +    private IntroduceParameterUI(TreePathHandle expression, CompilationInfo info) {
   14.71 +        this.refactoring = new IntroduceParameterRefactoring(expression);
   14.72 +        this.expression = expression;
   14.73 +    }
   14.74 +    
   14.75 +    public static IntroduceParameterUI create(TreePathHandle expression, CompilationInfo info) {
   14.76 +        return new IntroduceParameterUI(expression, info);
   14.77 +    }
   14.78 +    
   14.79 +    public String getDescription() {
   14.80 +        return NbBundle.getMessage(IntroduceParameterUI.class, 
   14.81 +                                        "DSC_IntroduceParameterRootNode", refactoring.getParameterName()); // NOI18N
   14.82 +    }
   14.83 +    
   14.84 +    public CustomRefactoringPanel getPanel(ChangeListener parent) {
   14.85 +        if (panel == null) {
   14.86 +            //TODO:
   14.87 +            //parent.setPreviewEnabled(true);
   14.88 +            panel = new IntroduceParameterPanel(expression, parent);
   14.89 +        }
   14.90 +        return panel;
   14.91 +    }
   14.92 +    
   14.93 +    public AbstractRefactoring getRefactoring() {
   14.94 +        return refactoring;
   14.95 +    }
   14.96 +
   14.97 +    public boolean isQuery() {
   14.98 +        return false;
   14.99 +    }
  14.100 +    
  14.101 +    private Problem setParameters(boolean checkOnly) {
  14.102 +        Problem problem = null;
  14.103 +        refactoring.setFinal(panel.isDeclareFinal());
  14.104 +        refactoring.setParameterName(panel.getParameterName());
  14.105 +        refactoring.setCompatible(panel.isCompatible());
  14.106 +        refactoring.setReplaceAll(panel.isReplaceAll());
  14.107 +        if (checkOnly) {
  14.108 +            problem = refactoring.fastCheckParameters();
  14.109 +        } else {
  14.110 +            problem = refactoring.checkParameters();
  14.111 +        }
  14.112 +        return problem;
  14.113 +    }
  14.114 +    
  14.115 +    public String getName() {
  14.116 +        return NbBundle.getMessage(ChangeParametersUI.class, "LBL_IntroduceParameter");
  14.117 +    }
  14.118 +    
  14.119 +    public Problem checkParameters() {
  14.120 +        return setParameters(true);
  14.121 +    }
  14.122 +
  14.123 +    public Problem setParameters() {
  14.124 +        return setParameters(false);
  14.125 +    }
  14.126 +    
  14.127 +    public boolean hasParameters() {
  14.128 +        return true;
  14.129 +    }
  14.130 +    
  14.131 +    public HelpCtx getHelpCtx() {
  14.132 +        return new HelpCtx(ChangeParametersUI.class);
  14.133 +    }
  14.134 +}
    15.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/JavaActionsImplementationFactory.java	Thu Apr 21 16:33:50 2011 +0200
    15.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/JavaActionsImplementationFactory.java	Fri May 06 15:36:19 2011 +0200
    15.3 @@ -75,6 +75,24 @@
    15.4          }
    15.5      }
    15.6  
    15.7 +    public static boolean canIntroduceParameter(Lookup lookup) {
    15.8 +        for (JavaActionsImplementationProvider rafi: implementations.allInstances()) {
    15.9 +            if (rafi.canIntroduceParameter(lookup)) {
   15.10 +                return true;
   15.11 +            }
   15.12 +        }
   15.13 +        return false;
   15.14 +    }
   15.15 +    
   15.16 +    public static void doIntroduceParameter(Lookup lookup) {
   15.17 +        for (JavaActionsImplementationProvider rafi: implementations.allInstances()) {
   15.18 +            if (rafi.canIntroduceParameter(lookup)) {
   15.19 +                rafi.doIntroduceParameter(lookup);
   15.20 +                return;
   15.21 +            }
   15.22 +        }
   15.23 +    }
   15.24 +    
   15.25      public static boolean canEncapsulateFields(Lookup lookup) {
   15.26          for (JavaActionsImplementationProvider rafi: implementations.allInstances()) {
   15.27              if (rafi.canEncapsulateFields(lookup)) {
    16.1 --- a/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/JavaRefactoringActionsProvider.java	Thu Apr 21 16:33:50 2011 +0200
    16.2 +++ b/refactoring.java/src/org/netbeans/modules/refactoring/java/ui/JavaRefactoringActionsProvider.java	Fri May 06 15:36:19 2011 +0200
    16.3 @@ -45,16 +45,26 @@
    16.4  package org.netbeans.modules.refactoring.java.ui;
    16.5  
    16.6  import com.sun.source.tree.ClassTree;
    16.7 +import com.sun.source.tree.ExpressionTree;
    16.8 +import com.sun.source.tree.NewClassTree;
    16.9  import com.sun.source.tree.Tree;
   16.10 +import com.sun.source.tree.Tree.Kind;
   16.11 +import com.sun.source.tree.VariableTree;
   16.12  import com.sun.source.util.TreePath;
   16.13  import java.util.Collection;
   16.14  import java.util.Collections;
   16.15 +import java.util.EnumSet;
   16.16  import java.util.HashSet;
   16.17  import java.util.List;
   16.18 +import java.util.Set;
   16.19  import javax.lang.model.element.Element;
   16.20  import javax.lang.model.element.ElementKind;
   16.21 +import javax.lang.model.type.ErrorType;
   16.22 +import javax.lang.model.type.TypeKind;
   16.23 +import javax.lang.model.type.TypeMirror;
   16.24  import org.netbeans.api.java.source.CompilationInfo;
   16.25  import org.netbeans.api.java.source.TreePathHandle;
   16.26 +import org.netbeans.api.java.source.TreeUtilities;
   16.27  import org.netbeans.modules.refactoring.java.RetoucheUtils;
   16.28  import org.netbeans.modules.refactoring.java.api.ui.JavaRefactoringActionsFactory;
   16.29  import org.netbeans.modules.refactoring.java.spi.ui.JavaActionsImplementationProvider;
   16.30 @@ -496,6 +506,156 @@
   16.31      }
   16.32      
   16.33      @Override
   16.34 +    public boolean canIntroduceParameter(Lookup lookup) {
   16.35 +        Collection<? extends Node> nodes = new HashSet<Node>(lookup.lookupAll(Node.class));
   16.36 +        if(nodes.size() != 1)
   16.37 +            return false;
   16.38 +        Node node = nodes.iterator().next();
   16.39 +        TreePathHandle tph = node.getLookup().lookup(TreePathHandle.class);
   16.40 +        if (tph != null) {
   16.41 +            return RetoucheUtils.isRefactorable(tph.getFileObject());
   16.42 +        }
   16.43 +        DataObject dObj = node.getCookie(DataObject.class);
   16.44 +        if(null == dObj)
   16.45 +            return false;
   16.46 +        FileObject fileObj = dObj.getPrimaryFile();
   16.47 +        if(null == fileObj || !RetoucheUtils.isRefactorable(fileObj))
   16.48 +            return false;
   16.49 +        
   16.50 +        EditorCookie ec = lookup.lookup(EditorCookie.class);
   16.51 +        if (RefactoringActionsProvider.isFromEditor(ec)) {
   16.52 +            return true;
   16.53 +        }
   16.54 +        return false;
   16.55 +    }
   16.56 +
   16.57 +    @Override
   16.58 +    public void doIntroduceParameter(Lookup lookup) {
   16.59 +        Runnable task;
   16.60 +        EditorCookie ec = lookup.lookup(EditorCookie.class);
   16.61 +        if (ec != null) {
   16.62 +            task = new RefactoringActionsProvider.TextComponentTask(ec) {
   16.63 +                protected RefactoringUI createRefactoringUI(TreePathHandle selectedElement,
   16.64 +                        int startOffset,
   16.65 +                        int endOffset,
   16.66 +                        CompilationInfo info) {
   16.67 +                    
   16.68 +                    TreePath tp = validateSelection(info, startOffset, endOffset);
   16.69 +                    if (tp==null)
   16.70 +                        return null;
   16.71 +                    return wrap(IntroduceParameterUI.create(TreePathHandle.create(tp, info), info));
   16.72 +                }
   16.73 +            };
   16.74 +        } else {
   16.75 +            task = new TreePathHandleTask(new HashSet<Node>(lookup.lookupAll(Node.class)), true) {
   16.76 +
   16.77 +                RefactoringUI ui;
   16.78 +
   16.79 +                @Override
   16.80 +                protected void treePathHandleResolved(TreePathHandle handle, CompilationInfo javac) {
   16.81 +                    ui = IntroduceParameterUI.create(handle, javac);
   16.82 +                }
   16.83 +
   16.84 +                @Override
   16.85 +                protected RefactoringUI createRefactoringUI(Collection<TreePathHandle> handles) {
   16.86 +                    return wrap(ui);
   16.87 +                }
   16.88 +            };
   16.89 +        }
   16.90 +        RetoucheUtils.invokeAfterScanFinished(task, RefactoringActionsProvider.getActionName(JavaRefactoringActionsFactory.changeParametersAction()));
   16.91 +    }    
   16.92 +    
   16.93 +    private static final Set<TypeKind> NOT_ACCEPTED_TYPES = EnumSet.of(TypeKind.ERROR, TypeKind.NONE, TypeKind.OTHER, TypeKind.VOID, TypeKind.EXECUTABLE);
   16.94 + 
   16.95 +    static TreePath validateSelection(CompilationInfo ci, int start, int end) {
   16.96 +        return validateSelection(ci, start, end, NOT_ACCEPTED_TYPES);
   16.97 +    }
   16.98 +
   16.99 +    public static TreePath validateSelection(CompilationInfo ci, int start, int end, Set<TypeKind> ignoredTypes) {
  16.100 +        TreePath tp = ci.getTreeUtilities().pathFor((start + end) / 2 + 1);
  16.101 +
  16.102 +        for ( ; tp != null; tp = tp.getParentPath()) {
  16.103 +            Tree leaf = tp.getLeaf();
  16.104 +
  16.105 +            if (   !ExpressionTree.class.isAssignableFrom(leaf.getKind().asInterface())
  16.106 +                && (leaf.getKind() != Kind.VARIABLE || ((VariableTree) leaf).getInitializer() == null))
  16.107 +               continue;
  16.108 +
  16.109 +            long treeStart = ci.getTrees().getSourcePositions().getStartPosition(ci.getCompilationUnit(), leaf);
  16.110 +            long treeEnd   = ci.getTrees().getSourcePositions().getEndPosition(ci.getCompilationUnit(), leaf);
  16.111 +
  16.112 +            if (treeStart != start || treeEnd != end) {
  16.113 +                continue;
  16.114 +            }
  16.115 +
  16.116 +            TypeMirror type = ci.getTrees().getTypeMirror(tp);
  16.117 +
  16.118 +            if (type != null && type.getKind() == TypeKind.ERROR) {
  16.119 +                type = ci.getTrees().getOriginalType((ErrorType) type);
  16.120 +            }
  16.121 +
  16.122 +            if (type == null || ignoredTypes.contains(type.getKind()))
  16.123 +                continue;
  16.124 +
  16.125 +            if(tp.getLeaf().getKind() == Kind.ASSIGNMENT)
  16.126 +                continue;
  16.127 +
  16.128 +            if (tp.getLeaf().getKind() == Kind.ANNOTATION)
  16.129 +                continue;
  16.130 +
  16.131 +            if (!isInsideClass(tp))
  16.132 +                return null;
  16.133 +
  16.134 +            TreePath candidate = tp;
  16.135 +
  16.136 +            tp = tp.getParentPath();
  16.137 +
  16.138 +            while (tp != null) {
  16.139 +                switch (tp.getLeaf().getKind()) {
  16.140 +                    case VARIABLE:
  16.141 +                        VariableTree vt = (VariableTree) tp.getLeaf();
  16.142 +                        if (vt.getInitializer() == leaf) {
  16.143 +                            return candidate;
  16.144 +                        } else {
  16.145 +                            return null;
  16.146 +                        }
  16.147 +                    case NEW_CLASS:
  16.148 +                        NewClassTree nct = (NewClassTree) tp.getLeaf();
  16.149 +                        
  16.150 +                        if (nct.getIdentifier().equals(candidate.getLeaf())) { //avoid disabling hint ie inside of anonymous class higher in treepath
  16.151 +                            for (Tree p : nct.getArguments()) {
  16.152 +                                if (p == leaf) {
  16.153 +                                    return candidate;
  16.154 +                                }
  16.155 +                            }
  16.156 +
  16.157 +                            return null;
  16.158 +                        }
  16.159 +                }
  16.160 +
  16.161 +                leaf = tp.getLeaf();
  16.162 +                tp = tp.getParentPath();
  16.163 +            }
  16.164 +
  16.165 +            return candidate;
  16.166 +        }
  16.167 +
  16.168 +        return null;
  16.169 +    }
  16.170 +
  16.171 +    private static boolean isInsideClass(TreePath tp) {
  16.172 +        while (tp != null) {
  16.173 +            if (TreeUtilities.CLASS_TREE_KINDS.contains(tp.getLeaf().getKind())) {
  16.174 +                return true;
  16.175 +            }
  16.176 +
  16.177 +            tp = tp.getParentPath();
  16.178 +        }
  16.179 +
  16.180 +        return false;
  16.181 +    }
  16.182 +
  16.183 +    @Override
  16.184      public boolean canInnerToOuter(Lookup lookup) {
  16.185          Collection<? extends Node> nodes = new HashSet<Node>(lookup.lookupAll(Node.class));
  16.186          if(nodes.size() != 1)