#221848: adding fix for default constructor that cannot call a super constructor.
authorJan Lahoda <jlahoda@netbeans.org>
Wed, 26 Dec 2012 09:13:48 +0100
changeset 17903609aa2c6a4a0
parent 17902 e2fbf3dfa87c
child 17904 f7635c415afc
child 17969 f33977d64816
#221848: adding fix for default constructor that cannot call a super constructor.
javahints/nbproject/project.properties
javahints/nbproject/project.xml
javahints/src/org/netbeans/modules/javahints/AddConstructor.java
javahints/src/org/netbeans/modules/javahints/Bundle.properties
javahints/src/org/netbeans/modules/javahints/resources/layer.xml
javahints/test/unit/src/org/netbeans/modules/javahints/AddConstructorTest.java
javahints/test/unit/src/org/netbeans/modules/javahints/Bundle_test.properties
     1.1 --- a/javahints/nbproject/project.properties	Wed Dec 12 19:19:27 2012 +0100
     1.2 +++ b/javahints/nbproject/project.properties	Wed Dec 26 09:13:48 2012 +0100
     1.3 @@ -50,7 +50,7 @@
     1.4  auxiliary.org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width=80
     1.5  javac.compilerargs=-Xlint:unchecked
     1.6  javac.source=1.6
     1.7 -spec.version.base=2.58.0
     1.8 +spec.version.base=2.59.0
     1.9  
    1.10  nbm.needs.restart=true
    1.11  requires.nb.javac=true
     2.1 --- a/javahints/nbproject/project.xml	Wed Dec 12 19:19:27 2012 +0100
     2.2 +++ b/javahints/nbproject/project.xml	Wed Dec 26 09:13:48 2012 +0100
     2.3 @@ -154,6 +154,15 @@
     2.4                      </run-dependency>
     2.5                  </dependency>
     2.6                  <dependency>
     2.7 +                    <code-name-base>org.netbeans.modules.editor.util</code-name-base>
     2.8 +                    <build-prerequisite/>
     2.9 +                    <compile-dependency/>
    2.10 +                    <run-dependency>
    2.11 +                        <release-version>1</release-version>
    2.12 +                        <specification-version>1.52</specification-version>
    2.13 +                    </run-dependency>
    2.14 +                </dependency>
    2.15 +                <dependency>
    2.16                      <code-name-base>org.netbeans.modules.java.editor</code-name-base>
    2.17                      <build-prerequisite/>
    2.18                      <compile-dependency/>
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/javahints/src/org/netbeans/modules/javahints/AddConstructor.java	Wed Dec 26 09:13:48 2012 +0100
     3.3 @@ -0,0 +1,166 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
     3.8 + *
     3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    3.10 + * Other names may be trademarks of their respective owners.
    3.11 + *
    3.12 + * The contents of this file are subject to the terms of either the GNU
    3.13 + * General Public License Version 2 only ("GPL") or the Common
    3.14 + * Development and Distribution License("CDDL") (collectively, the
    3.15 + * "License"). You may not use this file except in compliance with the
    3.16 + * License. You can obtain a copy of the License at
    3.17 + * http://www.netbeans.org/cddl-gplv2.html
    3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.19 + * specific language governing permissions and limitations under the
    3.20 + * License.  When distributing the software, include this License Header
    3.21 + * Notice in each file and include the License file at
    3.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    3.23 + * particular file as subject to the "Classpath" exception as provided
    3.24 + * by Oracle in the GPL Version 2 section of the License file that
    3.25 + * accompanied this code. If applicable, add the following below the
    3.26 + * License Header, with the fields enclosed by brackets [] replaced by
    3.27 + * your own identifying information:
    3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    3.29 + *
    3.30 + * If you wish your version of this file to be governed by only the CDDL
    3.31 + * or only the GPL Version 2, indicate your decision by adding
    3.32 + * "[Contributor] elects to include this software in this distribution
    3.33 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    3.34 + * single choice of license, a recipient has the option to distribute
    3.35 + * your version of this file under either the CDDL, the GPL Version 2 or
    3.36 + * to extend the choice of license to its licensees as provided above.
    3.37 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    3.38 + * Version 2 license, then the option applies only if the new code is
    3.39 + * made subject to such option by the copyright holder.
    3.40 + *
    3.41 + * Contributor(s):
    3.42 + *
    3.43 + * Portions Copyrighted 2012 Sun Microsystems, Inc.
    3.44 + */
    3.45 +package org.netbeans.modules.javahints;
    3.46 +
    3.47 +import com.sun.source.tree.ClassTree;
    3.48 +import com.sun.source.tree.MethodTree;
    3.49 +import com.sun.source.tree.Scope;
    3.50 +import com.sun.source.util.TreePath;
    3.51 +import java.util.ArrayList;
    3.52 +import java.util.Arrays;
    3.53 +import java.util.Collections;
    3.54 +import java.util.HashSet;
    3.55 +import java.util.List;
    3.56 +import java.util.Set;
    3.57 +import javax.lang.model.element.Element;
    3.58 +import javax.lang.model.element.ExecutableElement;
    3.59 +import javax.lang.model.element.TypeElement;
    3.60 +import javax.lang.model.element.VariableElement;
    3.61 +import javax.lang.model.type.DeclaredType;
    3.62 +import javax.lang.model.type.ExecutableType;
    3.63 +import javax.lang.model.type.TypeKind;
    3.64 +import javax.lang.model.type.TypeMirror;
    3.65 +import javax.lang.model.util.ElementFilter;
    3.66 +import org.netbeans.api.java.source.CompilationInfo;
    3.67 +import org.netbeans.api.java.source.ElementHandle;
    3.68 +import org.netbeans.api.java.source.GeneratorUtilities;
    3.69 +import org.netbeans.api.java.source.TreeUtilities;
    3.70 +import org.netbeans.lib.editor.util.StringEscapeUtils;
    3.71 +import org.netbeans.modules.java.hints.spi.ErrorRule;
    3.72 +import org.netbeans.spi.editor.hints.Fix;
    3.73 +import org.netbeans.spi.java.hints.JavaFix;
    3.74 +import org.openide.util.NbBundle;
    3.75 +
    3.76 +/**
    3.77 + *
    3.78 + * @author lahvac
    3.79 + */
    3.80 +public class AddConstructor implements ErrorRule<Void> {
    3.81 +
    3.82 +    private static final Set<String> ERROR_CODES = new HashSet<String>(Arrays.asList(
    3.83 +            "compiler.err.cant.apply.symbol.1")); // NOI18N
    3.84 +    
    3.85 +    @Override
    3.86 +    public Set<String> getCodes() {
    3.87 +        return ERROR_CODES;
    3.88 +    }
    3.89 +
    3.90 +    @Override
    3.91 +    public List<Fix> run(CompilationInfo info, String diagnosticKey, int offset, TreePath treePath, Data<Void> data) {
    3.92 +        if (!TreeUtilities.CLASS_TREE_KINDS.contains(treePath.getLeaf().getKind())) return Collections.emptyList();
    3.93 +        
    3.94 +        Element el = info.getTrees().getElement(treePath);
    3.95 +        
    3.96 +        if (el == null || !el.getKind().isClass()) return Collections.emptyList();
    3.97 +        
    3.98 +        TypeElement clazz = (TypeElement) el;
    3.99 +        TypeMirror superType = clazz.getSuperclass();
   3.100 +        
   3.101 +        if (superType.getKind() != TypeKind.DECLARED) return Collections.emptyList();
   3.102 +        
   3.103 +        TypeElement superClazz = (TypeElement) info.getTypes().asElement(superType);
   3.104 +        DeclaredType targetType = (DeclaredType) clazz.asType();
   3.105 +        Scope classScope = info.getTrees().getScope(treePath);
   3.106 +        List<Fix> result = new ArrayList<Fix>();
   3.107 +        
   3.108 +        for (ExecutableElement constr : ElementFilter.constructorsIn(superClazz.getEnclosedElements())) {
   3.109 +            if (!info.getTrees().isAccessible(classScope, constr, (DeclaredType) superType)) continue;
   3.110 +            
   3.111 +            StringBuilder name = new StringBuilder();
   3.112 +            
   3.113 +            name.append(clazz.getSimpleName()).append("(");
   3.114 +            
   3.115 +            ExecutableType target = (ExecutableType) info.getTypes().asMemberOf(targetType, constr);
   3.116 +            boolean firstParam = true;
   3.117 +            
   3.118 +            for (TypeMirror p : target.getParameterTypes()) {
   3.119 +                if (!firstParam) name.append(", ");
   3.120 +                firstParam = false;
   3.121 +                name.append(info.getTypeUtilities().getTypeName(p));
   3.122 +            }
   3.123 +            
   3.124 +            name.append(")");
   3.125 +            result.add(new FixImpl(info, treePath, constr, StringEscapeUtils.escapeHtml(name.toString())).toEditorFix());
   3.126 +        }
   3.127 +        
   3.128 +        return result;
   3.129 +    }
   3.130 +
   3.131 +    @Override
   3.132 +    public String getId() {
   3.133 +        return AddConstructor.class.getName();
   3.134 +    }
   3.135 +
   3.136 +    @Override
   3.137 +    public String getDisplayName() {
   3.138 +        return "";
   3.139 +    }
   3.140 +
   3.141 +    @Override
   3.142 +    public void cancel() {
   3.143 +    }
   3.144 +    
   3.145 +    private static final class FixImpl extends JavaFix {
   3.146 +
   3.147 +        private final ElementHandle<ExecutableElement> constr;
   3.148 +        private final String constrName;
   3.149 +        public FixImpl(CompilationInfo info, TreePath tp, ExecutableElement constr, String constrName) {
   3.150 +            super(info, tp);
   3.151 +            this.constr = ElementHandle.create(constr);
   3.152 +            this.constrName = constrName;
   3.153 +        }
   3.154 +
   3.155 +        @Override
   3.156 +        protected String getText() {
   3.157 +            return NbBundle.getMessage(AddConstructor.class, "FIX_AddConstructor", constrName);
   3.158 +        }
   3.159 +
   3.160 +        @Override
   3.161 +        protected void performRewrite(TransformationContext ctx) throws Exception {
   3.162 +            TypeElement clazz = (TypeElement) ctx.getWorkingCopy().getTrees().getElement(ctx.getPath());
   3.163 +            GeneratorUtilities gu = GeneratorUtilities.get(ctx.getWorkingCopy());
   3.164 +            MethodTree newConstr = gu.createConstructor(clazz, Collections.<VariableElement>emptyList(), constr.resolve(ctx.getWorkingCopy()));
   3.165 +            ctx.getWorkingCopy().rewrite(ctx.getPath().getLeaf(), gu.insertClassMember((ClassTree) ctx.getPath().getLeaf(), newConstr));
   3.166 +        }
   3.167 +        
   3.168 +    }
   3.169 +}
     4.1 --- a/javahints/src/org/netbeans/modules/javahints/Bundle.properties	Wed Dec 12 19:19:27 2012 +0100
     4.2 +++ b/javahints/src/org/netbeans/modules/javahints/Bundle.properties	Wed Dec 26 09:13:48 2012 +0100
     4.3 @@ -143,3 +143,5 @@
     4.4  
     4.5  DN_MissingReturn=Method Missing a Return Statement
     4.6  FIX_AddReturn=Add return statement
     4.7 +
     4.8 +FIX_AddConstructor=Add Constructor - {0}
     5.1 --- a/javahints/src/org/netbeans/modules/javahints/resources/layer.xml	Wed Dec 12 19:19:27 2012 +0100
     5.2 +++ b/javahints/src/org/netbeans/modules/javahints/resources/layer.xml	Wed Dec 26 09:13:48 2012 +0100
     5.3 @@ -50,6 +50,7 @@
     5.4                  <file name="org-netbeans-modules-javahints-TypoDetector.instance"/>
     5.5                  <file name="org-netbeans-modules-javahints-TypeInForEachLoop.instance"/>
     5.6                  <file name="org-netbeans-modules-javahints-MakeStatic.instance"/>
     5.7 +                <file name="org-netbeans-modules-javahints-AddConstructor.instance"/>
     5.8              </folder>
     5.9  
    5.10              <folder name="hints">
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/javahints/test/unit/src/org/netbeans/modules/javahints/AddConstructorTest.java	Wed Dec 26 09:13:48 2012 +0100
     6.3 @@ -0,0 +1,95 @@
     6.4 +/*
     6.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     6.6 + *
     6.7 + * Copyright 2012 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 2012 Sun Microsystems, Inc.
    6.44 + */
    6.45 +package org.netbeans.modules.javahints;
    6.46 +
    6.47 +import com.sun.source.util.TreePath;
    6.48 +import java.util.List;
    6.49 +import java.util.Set;
    6.50 +import org.netbeans.api.java.source.CompilationInfo;
    6.51 +import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
    6.52 +import org.netbeans.spi.editor.hints.Fix;
    6.53 +import org.openide.util.NbBundle;
    6.54 +
    6.55 +/**
    6.56 + *
    6.57 + * @author lahvac
    6.58 + */
    6.59 +public class AddConstructorTest extends ErrorHintsTestBase {
    6.60 +    
    6.61 +    public AddConstructorTest(String name) {
    6.62 +        super(name);
    6.63 +    }
    6.64 +    
    6.65 +    public void testSimple() throws Exception {
    6.66 +        performFixTest("test/Test.java",
    6.67 +                       "package test; public class Test extends A { } class A { A(String str) {} }",
    6.68 +                       -1,
    6.69 +                       "FIX_AddConstructor:Test(String)",
    6.70 +                       "package test; public class Test extends A { public Test(String str) { super(str); } } class A { A(String str) {} }");
    6.71 +    }
    6.72 +    
    6.73 +    public void testInaccessible() throws Exception {
    6.74 +        performAnalysisTest("test/Test.java",
    6.75 +                            "package test; public class Test extends A { } class A { private A(String str) {} }",
    6.76 +                            -1);
    6.77 +    }
    6.78 +
    6.79 +    @Override
    6.80 +    protected Set<String> getSupportedErrorKeys() {
    6.81 +        return new AddConstructor().getCodes();
    6.82 +    }
    6.83 +
    6.84 +    @Override
    6.85 +    protected List<Fix> computeFixes(CompilationInfo info, int pos, TreePath path) {
    6.86 +        return new AddConstructor().run(info, null, pos, path, null);
    6.87 +    }
    6.88 +
    6.89 +    @Override
    6.90 +    protected String toDebugString(CompilationInfo info, Fix f) {
    6.91 +        return f.getText();
    6.92 +    }
    6.93 +    
    6.94 +    static {
    6.95 +        NbBundle.setBranding("test");
    6.96 +    }
    6.97 +
    6.98 +}
     7.1 --- a/javahints/test/unit/src/org/netbeans/modules/javahints/Bundle_test.properties	Wed Dec 12 19:19:27 2012 +0100
     7.2 +++ b/javahints/test/unit/src/org/netbeans/modules/javahints/Bundle_test.properties	Wed Dec 26 09:13:48 2012 +0100
     7.3 @@ -16,3 +16,5 @@
     7.4  #Microsystems, Inc. All Rights Reserved.
     7.5  DN_NegateCondition=Negate condition
     7.6  FIX_AddReturn=FIX_AddReturn
     7.7 +
     7.8 +FIX_AddConstructor=FIX_AddConstructor:{0}