This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 180007
Collapse All | Expand All

(-)a/java.hints/src/org/netbeans/modules/java/hints/errors/RemoveInvalidModifier.java (+195 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2010 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
package org.netbeans.modules.java.hints.errors;
45
46
import com.sun.source.tree.ClassTree;
47
import com.sun.source.tree.MethodTree;
48
import com.sun.source.tree.ModifiersTree;
49
import com.sun.source.tree.Tree.Kind;
50
import com.sun.source.util.TreePath;
51
import java.util.ArrayList;
52
import java.util.Arrays;
53
import java.util.Collection;
54
import java.util.EnumSet;
55
import java.util.HashMap;
56
import java.util.HashSet;
57
import java.util.List;
58
import java.util.Locale;
59
import java.util.Map;
60
import java.util.Set;
61
import java.util.regex.Matcher;
62
import java.util.regex.Pattern;
63
import javax.lang.model.element.Modifier;
64
import javax.tools.Diagnostic;
65
import org.netbeans.api.java.source.CompilationInfo;
66
import org.netbeans.api.java.source.TreeMaker;
67
import org.netbeans.modules.java.hints.spi.ErrorRule;
68
import org.netbeans.modules.java.hints.spi.ErrorRule.Data;
69
import org.netbeans.spi.editor.hints.Fix;
70
import org.netbeans.spi.java.hints.support.FixFactory;
71
import org.openide.util.NbBundle;
72
73
@NbBundle.Messages({
74
    "DN_RemoveInvalidModifier=Remove invalid modifier",
75
    "DESC_RemoveInvalidModifier=Remove invalid modifier",
76
    "# {0} - modifier like private, public, protected",
77
    "# {1} - number of invalid modifiers",
78
    "FIX_RemoveInvalidModifier=Remove invalid ''{0}'' {1,choice,0#modifiers|1#modifier|1<modifiers} "
79
})
80
public class RemoveInvalidModifier implements ErrorRule<Void> {
81
    public static final String ERROR_PATTERN = "modifier (.+?) not allowed here";
82
83
    private static final Set<String> CODES = new HashSet<>(Arrays.asList(
84
            "compiler.err.mod.not.allowed.here"
85
    ));
86
    
87
    @Override
88
    public Set<String> getCodes() {
89
        return CODES;
90
    }
91
92
    @Override
93
    public List<Fix> run(CompilationInfo compilationInfo, String diagnosticKey, int offset, TreePath treePath, Data<Void> data) {
94
        EnumSet<Kind> supportedKinds = EnumSet.of(Kind.CLASS, Kind.INTERFACE, Kind.METHOD);
95
        boolean isSupported = (supportedKinds.contains(treePath.getLeaf().getKind()));
96
	if (!isSupported) {
97
	    return null;
98
	}
99
        String invalidMod = getInvalidModifier(compilationInfo, treePath, CODES);
100
        if (null==invalidMod)
101
        {
102
            return null;
103
        }
104
105
        //support multiple invalid modifiers
106
        Collection<Modifier> modss=convertToModifiers(invalidMod.split(","));
107
        TreePath modifierTreePath = TreePath.getPath(treePath, getModifierTree(treePath));
108
        Fix removeModifiersFix = FixFactory.removeModifiersFix(compilationInfo, modifierTreePath, new HashSet<>(modss), NbBundle.getMessage(RemoveInvalidModifier.class, "FIX_RemoveInvalidModifier", invalidMod, modss.size()));
109
        return Arrays.asList(removeModifiersFix);
110
    }
111
    
112
113
    @Override
114
    public void cancel() {
115
    }
116
117
    @Override
118
    public String getId() {
119
        return RemoveInvalidModifier.class.getName();
120
    }
121
122
    @Override
123
    public String getDisplayName() {
124
        return NbBundle.getMessage(RemoveInvalidModifier.class, "DN_RemoveInvalidModifier");
125
    }
126
127
    public String getDescription() {
128
        return NbBundle.getMessage(RemoveInvalidModifier.class, "DESC_RemoveInvalidModifier");
129
    }
130
131
    /**
132
     * Returns the diagnostics entry
133
     * @param compilationInfo
134
     * @param start
135
     * @param codes
136
     * @return 
137
     */
138
    private Diagnostic getDiagnostic(CompilationInfo compilationInfo, long start, Set<String> errorCodes) {
139
        Diagnostic result = null;
140
        for (Diagnostic d : compilationInfo.getDiagnostics()) {
141
            if (start != d.getStartPosition()) {
142
                continue;
143
            }
144
            if (!errorCodes.contains(d.getCode())) {
145
                continue;
146
            }
147
            result=d;
148
        }
149
        return result;
150
    }
151
152
    private String getInvalidModifier(CompilationInfo compilationInfo, TreePath treePath, Set<String> codes) {
153
        long start = compilationInfo.getTrees().getSourcePositions().getStartPosition(compilationInfo.getCompilationUnit(), treePath.getLeaf());
154
        Diagnostic diagnostic = getDiagnostic(compilationInfo, start, codes);
155
        if (null==diagnostic){
156
            return null;
157
        }
158
        //parse the error message
159
        //HACK: hope this will be stable in the long term
160
        String message = diagnostic.getMessage(Locale.ENGLISH);
161
        Matcher matcher = Pattern.compile(ERROR_PATTERN).matcher(message);
162
        if (!matcher.find()) {
163
            return null;
164
        }
165
        return matcher.group(1);
166
    }
167
168
    private Collection<Modifier> convertToModifiers(String... mods) {
169
        final Map<String, Modifier> map = new HashMap<>();
170
        for (Modifier modifier : Modifier.values()) {
171
            map.put(modifier.toString(), modifier);
172
        }
173
174
        //convert to modifier
175
        List<Modifier> result = new ArrayList<>();
176
        for (String string : mods) {
177
            result.add(map.get(string));
178
        }
179
        return result;
180
    }
181
182
    private ModifiersTree getModifierTree(TreePath treePath) {
183
        Kind kind = treePath.getLeaf().getKind();
184
        switch (kind) {
185
            case CLASS:
186
                return ((ClassTree) treePath.getLeaf()).getModifiers();
187
            case INTERFACE:
188
                return ((ClassTree) treePath.getLeaf()).getModifiers();
189
            case METHOD:
190
                return ((MethodTree) treePath.getLeaf()).getModifiers();
191
            default:
192
                throw new UnsupportedOperationException("kind " + kind + " not yet suppported");
193
        }
194
    }
195
}
(-)a/java.hints/src/org/netbeans/modules/java/hints/resources/layer.xml (+1 lines)
Lines 180-185 Link Here
180
                <file name="org-netbeans-modules-java-hints-errors-RemoveFinalModifierFromVariable.instance">
180
                <file name="org-netbeans-modules-java-hints-errors-RemoveFinalModifierFromVariable.instance">
181
                        <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.hints.errors.AddOrRemoveFinalModifier.createRemoveFinalFromVariable"/>
181
                        <attr name="instanceCreate" methodvalue="org.netbeans.modules.java.hints.errors.AddOrRemoveFinalModifier.createRemoveFinalFromVariable"/>
182
                </file>
182
                </file>
183
		<file name="org-netbeans-modules-java-hints-errors-RemoveInvalidModifier.instance"/>
183
		<file name="org-netbeans-modules-java-hints-errors-RemoveUselessCast.instance"/>
184
		<file name="org-netbeans-modules-java-hints-errors-RemoveUselessCast.instance"/>
184
                <file name="org-netbeans-modules-java-hints-errors-SuppressWarningsFixer.instance"/>
185
                <file name="org-netbeans-modules-java-hints-errors-SuppressWarningsFixer.instance"/>
185
                <file name="org-netbeans-modules-java-hints-errors-NotInitializedVariable.instance"/>                
186
                <file name="org-netbeans-modules-java-hints-errors-NotInitializedVariable.instance"/>                
(-)a/java.hints/test/unit/src/org/netbeans/modules/java/hints/errors/RemoveOverrideTest.java (-27 / +125 lines)
Lines 48-92 Link Here
48
import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
48
import org.netbeans.modules.java.hints.infrastructure.ErrorHintsTestBase;
49
import org.netbeans.spi.editor.hints.Fix;
49
import org.netbeans.spi.editor.hints.Fix;
50
50
51
/**
51
 /**
52
 *
52
  *
53
 * @author lahvac
53
  * @author markiewb
54
 */
54
  */
55
public class RemoveOverrideTest extends ErrorHintsTestBase {
55
public class RemoveInvalidModifierTest extends ErrorHintsTestBase {
56
    
56
57
    public RemoveOverrideTest(String name) {
57
    public RemoveInvalidModifierTest(String name) {
58
        super(name);
58
	super(name);
59
    }
60
61
    public void testRemovePrivate() throws Exception {
62
	performFixTest("test/AnotherClass.java",
63
		"public class AnotherClass {\n"
64
		+ "    public void testMethod() {\n"
65
		+ "        setRunnable(new Runnable() {\n"
66
		+ "            public void run() {}\n"
67
		+ "            private class MemberClass {} // quick fix for this line - remove modifier\n"
68
		+ "        }\n"
69
		+ "        );\n"
70
		+ "    }\n"
71
		+ "    private void setRunnable(Runnable runnable) {}\n"
72
		+ "}",
73
		-1,
74
		Bundle.FIX_RemoveInvalidModifier("private", 1),
75
		("public class AnotherClass {\n"
76
		+ "    public void testMethod() {\n"
77
		+ "        setRunnable(new Runnable() {\n"
78
		+ "            public void run() {}\n"
79
		+ "            class MemberClass {} // quick fix for this line - remove modifier\n"
80
		+ "        }\n"
81
		+ "        );\n"
82
		+ "    }\n"
83
		+ "    private void setRunnable(Runnable runnable) {}\n"
84
		+ "}").replaceAll("[ \t\n]+", " "));
85
    }
86
87
    public void testRemoveProtected() throws Exception {
88
	performFixTest("test/AnotherClass.java",
89
		"public class AnotherClass {\n"
90
		+ "    public void testMethod() {\n"
91
		+ "        setRunnable(new Runnable() {\n"
92
		+ "            public void run() {}\n"
93
		+ "            protected class MemberClass {} // quick fix for this line - remove modifier\n"
94
		+ "        }\n"
95
		+ "        );\n"
96
		+ "    }\n"
97
		+ "    private void setRunnable(Runnable runnable) {}\n"
98
		+ "}",
99
		-1,
100
		Bundle.FIX_RemoveInvalidModifier("protected", 1),
101
		("public class AnotherClass {\n"
102
		+ "    public void testMethod() {\n"
103
		+ "        setRunnable(new Runnable() {\n"
104
		+ "            public void run() {}\n"
105
		+ "            class MemberClass {} // quick fix for this line - remove modifier\n"
106
		+ "        }\n"
107
		+ "        );\n"
108
		+ "    }\n"
109
		+ "    private void setRunnable(Runnable runnable) {}\n"
110
		+ "}").replaceAll("[ \t\n]+", " "));
111
    }
112
113
    public void testRemovePublic() throws Exception {
114
	performFixTest("test/AnotherClass.java",
115
		"public class AnotherClass {\n"
116
		+ "    public void testMethod() {\n"
117
		+ "        setRunnable(new Runnable() {\n"
118
		+ "            public void run() {}\n"
119
		+ "            public class MemberClass {} // quick fix for this line - remove modifier\n"
120
		+ "        }\n"
121
		+ "        );\n"
122
		+ "    }\n"
123
		+ "    private void setRunnable(Runnable runnable) {}\n"
124
		+ "}",
125
		-1,
126
		Bundle.FIX_RemoveInvalidModifier("public", 1),
127
		("public class AnotherClass {\n"
128
		+ "    public void testMethod() {\n"
129
		+ "        setRunnable(new Runnable() {\n"
130
		+ "            public void run() {}\n"
131
		+ "            class MemberClass {} // quick fix for this line - remove modifier\n"
132
		+ "        }\n"
133
		+ "        );\n"
134
		+ "    }\n"
135
		+ "    private void setRunnable(Runnable runnable) {}\n"
136
		+ "}").replaceAll("[ \t\n]+", " "));
137
    }
138
    public void testRemoveStatic() throws Exception {
139
	performFixTest("test/AnotherClass.java",
140
		"public class AnotherClass {\n"
141
		+ "    public class Foo() {\n"
142
		+ "         public static class Bar() {\n"
143
		+ "         }\n"
144
		+ "    }\n"
145
		+ "}",
146
		-1,
147
		Bundle.FIX_RemoveInvalidModifier("static", 1),
148
		("public class AnotherClass {\n"
149
		+ "    public class Foo() {\n"
150
		+ "         public class Bar() {\n"
151
		+ "         }\n"
152
		+ "    }\n"
153
		+ "}").replaceAll("[ \t\n]+", " "));
59
    }
154
    }
60
    
155
    
61
    public void testRemoveOverride() throws Exception {
156
    public void testRemoveNativeFromInterface() throws Exception {
62
        performFixTest("test/Test.java",
157
        performFixTest("test/AnotherInterface.java",
63
                       "package test;\n" +
158
                "public native interface AnotherInterface {}",
64
                       "public class Test {\n" +
159
                -1,
65
                       "    @Override public void test() {\n" +
160
                Bundle.FIX_RemoveInvalidModifier("native", 1),
66
                       "    }\n" +
161
                ("public interface AnotherInterface {}").replaceAll("[ \t\n]+", " "));
67
                       "}\n",
162
    }
68
                       -1,
163
    
69
                       Bundle.FIX_RemoveOverride(),
164
    public void testRemoveMultipleFromMethod() throws Exception {
70
                       ("package test;\n" +
165
        performFixTest("test/AnotherInterface.java",
71
                       "public class Test {\n" +
166
                "public interface I {\n"
72
                       "    public void test() {\n" +
167
                + "    private native void ttt();\n"
73
                       "    }\n" +
168
                + "}",
74
                       "}\n").replaceAll("[ \t\n]+", " "));
169
                -1,
170
                Bundle.FIX_RemoveInvalidModifier("private,native", 2),
171
                ("public interface I {\n"
172
                + "    void ttt();\n"
173
                + "}").replaceAll("[ \t\n]+", " "));
75
    }
174
    }
76
175
77
    @Override
176
    @Override
78
    protected List<Fix> computeFixes(CompilationInfo info, int pos, TreePath path) throws Exception {
177
    protected List<Fix> computeFixes(CompilationInfo info, int pos, TreePath path) throws Exception {
79
        return new RemoveOverride().run(info, null, pos, path, null);
178
	return new RemoveInvalidModifier().run(info, null, pos, path, null);
80
    }
179
    }
81
180
82
    @Override
181
    @Override
83
    protected String toDebugString(CompilationInfo info, Fix f) {
182
    protected String toDebugString(CompilationInfo info, Fix f) {
84
        return f.getText();
183
	return f.getText();
85
    }
184
    }
86
185
87
    @Override
186
    @Override
88
    protected Set<String> getSupportedErrorKeys() {
187
    protected Set<String> getSupportedErrorKeys() {
89
        return new RemoveOverride().getCodes();
188
	return new RemoveInvalidModifier().getCodes();
90
    }
189
    }
91
190
}
92
}

Return to bug 180007