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 236244
Collapse All | Expand All

(-)a/java.hints/src/org/netbeans/modules/java/hints/ArithmeticUtilities.java (-2 / +2 lines)
Lines 165-171 Link Here
165
        boolean save = false;
165
        boolean save = false;
166
        ElementValue v = null;
166
        ElementValue v = null;
167
        Map<Object, ElementValue> cache = null;
167
        Map<Object, ElementValue> cache = null;
168
        if (tp.getParentPath() != null) {
168
        if (resolveCompileTimeConstants && tp.getParentPath() != null) {
169
            Tree parentL = tp.getParentPath().getLeaf();
169
            Tree parentL = tp.getParentPath().getLeaf();
170
            switch (parentL.getKind()) {
170
            switch (parentL.getKind()) {
171
                case IF: 
171
                case IF: 
Lines 200-206 Link Here
200
        } catch (ArithmeticException | IndexOutOfBoundsException | IllegalArgumentException ex) {
200
        } catch (ArithmeticException | IndexOutOfBoundsException | IllegalArgumentException ex) {
201
            o = null;
201
            o = null;
202
        }
202
        }
203
        if (save) {
203
        if (cache != null) {
204
            if (v == null) {
204
            if (v == null) {
205
                v = new ElementValue();
205
                v = new ElementValue();
206
                cache.put(tp.getLeaf(), v);
206
                cache.put(tp.getLeaf(), v);
(-)a/java.hints/src/org/netbeans/modules/java/hints/suggestions/UseBDConstFix.java (+200 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.java.hints.suggestions;
43
44
import com.sun.source.tree.MemberSelectTree;
45
import com.sun.source.tree.NewClassTree;
46
import com.sun.source.tree.Tree;
47
import com.sun.source.util.TreePath;
48
import java.math.BigDecimal;
49
import javax.lang.model.SourceVersion;
50
import javax.lang.model.type.TypeMirror;
51
import org.netbeans.modules.java.hints.ArithmeticUtilities;
52
import org.netbeans.modules.java.hints.errors.Utilities;
53
import org.netbeans.spi.editor.hints.ErrorDescription;
54
import org.netbeans.spi.editor.hints.Severity;
55
import org.netbeans.spi.java.hints.ConstraintVariableType;
56
import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
57
import org.netbeans.spi.java.hints.Hint;
58
import org.netbeans.spi.java.hints.HintContext;
59
import org.netbeans.spi.java.hints.JavaFixUtilities;
60
import org.netbeans.spi.java.hints.TriggerPattern;
61
import org.netbeans.spi.java.hints.TriggerPatterns;
62
import org.openide.util.NbBundle.Messages;
63
64
@Messages({
65
    "# {0} - f.e. BigDecimal.ONE",
66
    "ERR_UseBDConstFix=Replace with {0}",
67
    "ERR_CannotParseBigDecimal=Constant does not parse to BigDecimal",
68
    "DN_UseBigDecimalConstants=Use BigDecimal constants where possible",
69
    "DESC_UseBigDecimalConstants=Introduces BigDecimal constants where possible. <p>For example: <tt>new java.math.BigDecimal(1.0)</tt> will be replaced by <tt>BigDecimal.ONE</tt></p>",})
70
/**
71
 * @author markiewb
72
 */
73
@Hint(displayName = "#DN_UseBigDecimalConstants", description = "#DESC_UseBigDecimalConstants", category = "rules15", hintKind = Hint.Kind.INSPECTION, severity = Severity.HINT)
74
public class UseBDConstFix {
75
    @TriggerPatterns(
76
            {
77
                @TriggerPattern(value = "new java.math.BigDecimal(java.math.BigInteger.ZERO)"),
78
                @TriggerPattern(value = "new java.math.BigDecimal(java.math.BigInteger.ONE)"),
79
                @TriggerPattern(value = "new java.math.BigDecimal(java.math.BigInteger.TEN)"),
80
81
                @TriggerPattern(value = "new java.math.BigDecimal(java.math.BigInteger.ZERO, $s)", 
82
                    constraints = @ConstraintVariableType(variable = "$s", type = "int")),
83
                @TriggerPattern(value = "new java.math.BigDecimal(java.math.BigInteger.ONE, $s)", 
84
                    constraints = @ConstraintVariableType(variable = "$s", type = "int")),
85
                @TriggerPattern(value = "new java.math.BigDecimal(java.math.BigInteger.TEN, $s)", 
86
                    constraints = @ConstraintVariableType(variable = "$s", type = "int")),
87
            }
88
    )
89
    public static ErrorDescription convertBigInteger(HintContext ctx) {
90
        if (!isAtLeastJDK5(ctx)) {
91
            return null;
92
        }
93
        TreePath sPath = ctx.getVariables().get("$s"); // NOI18N
94
        if (sPath != null) {
95
            Object scale = ArithmeticUtilities.compute(ctx.getInfo(), sPath, false);
96
            if (!(scale instanceof Integer) || ((Integer)scale != 0)) {
97
                return null;
98
            }
99
        }
100
        NewClassTree nct = (NewClassTree)ctx.getPath().getLeaf();
101
        Tree t = nct.getArguments().get(0);
102
        if (t.getKind() == Tree.Kind.MEMBER_SELECT) {
103
            String s = "BigDecimal." + ((MemberSelectTree)t).getIdentifier().toString(); // NOI18N
104
            return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), Bundle.DN_UseBigDecimalConstants(), 
105
                JavaFixUtilities.rewriteFix(ctx, Bundle.ERR_UseBDConstFix(s), ctx.getPath(), "java.math." + s)); // NOI18N
106
        } else {
107
            return null;
108
        }
109
    }
110
    
111
    @TriggerPatterns(
112
            {
113
                @TriggerPattern(value = "new java.math.BigDecimal($v)", 
114
                    constraints = @ConstraintVariableType(variable="$v", type="java.lang.String")),
115
                @TriggerPattern(value = "java.math.BigDecimal.valueOf($v)", 
116
                    constraints = @ConstraintVariableType(variable="$v", type="java.lang.String")),
117
            }
118
    )
119
    public static ErrorDescription convertString(HintContext ctx) {
120
        if (!isAtLeastJDK5(ctx)) {
121
            return null;
122
        }
123
        TreePath get = ctx.getVariables().get("$v"); // NOI18N
124
        if (null == get) {
125
            return null;
126
        }
127
        // also handles final field references, concatenation etc.
128
        Object o = ArithmeticUtilities.compute(ctx.getInfo(), get, false);
129
        if (!(o instanceof String)) {
130
            return null;
131
        }
132
        final int valueOf;
133
        try {
134
            // must use BigDecimal conversion as float/double recognize hex numbers, BigDecimal does not.
135
            // intValueExact checks both fractional part and overflow
136
            valueOf = new BigDecimal(o.toString()).intValueExact();
137
        } catch (NumberFormatException ex) {
138
            // FIXME - ErrorDescriptionFactory does not allow to override severity; but this becomes a runtime error.
139
            return ErrorDescriptionFactory.forTree(ctx, get, Bundle.ERR_CannotParseBigDecimal());
140
        } catch (ArithmeticException ex) {
141
            return null;
142
        }
143
        return createHintFor(valueOf, ctx);
144
    }
145
146
    @TriggerPatterns(
147
            {
148
                @TriggerPattern(value = "new java.math.BigDecimal($v)"),
149
                @TriggerPattern(value = "java.math.BigDecimal.valueOf($v)"),
150
            }
151
    )
152
    public static ErrorDescription convertPrimitive(HintContext ctx) {
153
        if (!isAtLeastJDK5(ctx)) {
154
            return null;
155
        }
156
        TreePath get = ctx.getVariables().get("$v"); // NOI18N
157
        if (null == get) {
158
            return null;
159
        }
160
        TypeMirror m = ctx.getInfo().getTrees().getTypeMirror(get);
161
        if (m == null) {
162
            return null;
163
        } else if (m.getKind().isPrimitive() || Utilities.isPrimitiveWrapperType(m)) {
164
            Object o = ArithmeticUtilities.compute(ctx.getInfo(), get, false);
165
            if (!(o instanceof Number)) {
166
                return null;
167
            }
168
            double d = ((Number)o).doubleValue();
169
            // do not accept fractional numbers
170
            if (Math.floor(d) == d) {
171
                return createHintFor((int)d, ctx);
172
            }
173
        }
174
        return null;
175
    }
176
    
177
    private static ErrorDescription createHintFor(int value, HintContext ctx) {
178
        String s;
179
        switch (value) {
180
            case 0:
181
                s = "BigDecimal.ZERO"; // NOI18N
182
                break;
183
            case 1:
184
                s = "BigDecimal.ONE"; // NOI18N
185
                break;
186
            case 10:
187
                s = "BigDecimal.TEN"; // NOI18N
188
                break;
189
            default:
190
                return null;
191
        }
192
        return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), Bundle.DN_UseBigDecimalConstants(), 
193
                JavaFixUtilities.rewriteFix(ctx, Bundle.ERR_UseBDConstFix(s), ctx.getPath(), "java.math." + s)); // NOI18N
194
    }
195
    
196
    private static boolean isAtLeastJDK5(HintContext ctx) {
197
        return ctx.getInfo().getSourceVersion().compareTo(SourceVersion.RELEASE_5) >= 0;
198
    }
199
200
}
(-)a/java.hints/test/unit/src/org/netbeans/modules/java/hints/suggestions/UseBDConstFixTest.java (+351 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.java.hints.suggestions;
43
44
import org.junit.Test;
45
import org.netbeans.modules.java.hints.test.api.HintTest;
46
47
/**
48
 * @author markiewb
49
 */
50
public class UseBDConstFixTest {
51
52
    @Test
53
    public void testConvertONE_A() throws Exception {
54
        HintTest.create()
55
                .input("package test;\n"
56
                        + "public class Test {\n"
57
                        + "    public static void main(String[] args) {\n"
58
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"1\");\n"
59
                        + "    }\n"
60
                        + "}\n")
61
                .run(UseBDConstFix.class)
62
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
63
                .applyFix()
64
                .assertCompilable()
65
                .assertOutput("package test;\n"
66
                        + "import java.math.BigDecimal;\n"
67
                        + "public class Test {\n"
68
                        + "    public static void main(String[] args) {\n"
69
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
70
                        + "    }\n"
71
                        + "}\n");
72
73
    }
74
75
    @Test
76
    public void testConvertONE_B() throws Exception {
77
        HintTest.create()
78
                .input("package test;\n"
79
                        + "public class Test {\n"
80
                        + "    public static void main(String[] args) {\n"
81
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"1.0\");\n"
82
                        + "    }\n"
83
                        + "}\n")
84
                .run(UseBDConstFix.class)
85
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
86
                .applyFix()
87
                .assertCompilable()
88
                .assertOutput("package test;\n"
89
                        + "import java.math.BigDecimal;\n"
90
                        + "public class Test {\n"
91
                        + "    public static void main(String[] args) {\n"
92
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
93
                        + "    }\n"
94
                        + "}\n");
95
96
    }
97
98
    @Test
99
    public void testConvertONE_C() throws Exception {
100
        HintTest.create()
101
                .input("package test;\n"
102
                        + "public class Test {\n"
103
                        + "    public static void main(String[] args) {\n"
104
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(1.0);\n"
105
                        + "    }\n"
106
                        + "}\n")
107
                .run(UseBDConstFix.class)
108
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
109
                .applyFix()
110
                .assertCompilable()
111
                .assertOutput("package test;\n"
112
                        + "import java.math.BigDecimal;\n"
113
                        + "public class Test {\n"
114
                        + "    public static void main(String[] args) {\n"
115
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
116
                        + "    }\n"
117
                        + "}\n");
118
119
    }
120
121
    @Test
122
    public void testConvertONE_D() throws Exception {
123
        HintTest.create()
124
                .input("package test;\n"
125
                        + "public class Test {\n"
126
                        + "    public static void main(String[] args) {\n"
127
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(1.00d);\n"
128
                        + "    }\n"
129
                        + "}\n")
130
                .run(UseBDConstFix.class)
131
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
132
                .applyFix()
133
                .assertCompilable()
134
                .assertOutput("package test;\n"
135
                        + "import java.math.BigDecimal;\n"
136
                        + "public class Test {\n"
137
                        + "    public static void main(String[] args) {\n"
138
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
139
                        + "    }\n"
140
                        + "}\n");
141
142
    }
143
144
    @Test
145
    public void testConvertTEN_A() throws Exception {
146
        HintTest.create()
147
                .input("package test;\n"
148
                        + "public class Test {\n"
149
                        + "    public static void main(String[] args) {\n"
150
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"10\");\n"
151
                        + "    }\n"
152
                        + "}\n")
153
                .run(UseBDConstFix.class)
154
                .findWarning("3:31-3:61:hint:" + Bundle.DN_UseBigDecimalConstants())
155
                .applyFix()
156
                .assertCompilable()
157
                .assertOutput("package test;\n"
158
                        + "import java.math.BigDecimal;\n"
159
                        + "public class Test {\n"
160
                        + "    public static void main(String[] args) {\n"
161
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
162
                        + "    }\n"
163
                        + "}\n");
164
165
    }
166
167
    @Test
168
    public void testConvertTEN_B() throws Exception {
169
        HintTest.create()
170
                .input("package test;\n"
171
                        + "public class Test {\n"
172
                        + "    public static void main(String[] args) {\n"
173
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"10.0\");\n"
174
                        + "    }\n"
175
                        + "}\n")
176
                .run(UseBDConstFix.class)
177
                .findWarning("3:31-3:63:hint:" + Bundle.DN_UseBigDecimalConstants())
178
                .applyFix()
179
                .assertCompilable()
180
                .assertOutput("package test;\n"
181
                        + "import java.math.BigDecimal;\n"
182
                        + "public class Test {\n"
183
                        + "    public static void main(String[] args) {\n"
184
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
185
                        + "    }\n"
186
                        + "}\n");
187
188
    }
189
190
    @Test
191
    public void testConvertTEN_C() throws Exception {
192
        HintTest.create()
193
                .input("package test;\n"
194
                        + "public class Test {\n"
195
                        + "    public static void main(String[] args) {\n"
196
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(10.0);\n"
197
                        + "    }\n"
198
                        + "}\n")
199
                .run(UseBDConstFix.class)
200
                .findWarning("3:31-3:61:hint:" + Bundle.DN_UseBigDecimalConstants())
201
                .applyFix()
202
                .assertCompilable()
203
                .assertOutput("package test;\n"
204
                        + "import java.math.BigDecimal;\n"
205
                        + "public class Test {\n"
206
                        + "    public static void main(String[] args) {\n"
207
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
208
                        + "    }\n"
209
                        + "}\n");
210
211
    }
212
213
    @Test
214
    public void testConvertTEN_D() throws Exception {
215
        HintTest.create()
216
                .input("package test;\n"
217
                        + "public class Test {\n"
218
                        + "    public static void main(String[] args) {\n"
219
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(10.00d);\n"
220
                        + "    }\n"
221
                        + "}\n")
222
                .run(UseBDConstFix.class)
223
                .findWarning("3:31-3:63:hint:" + Bundle.DN_UseBigDecimalConstants())
224
                .applyFix()
225
                .assertCompilable()
226
                .assertOutput("package test;\n"
227
                        + "import java.math.BigDecimal;\n"
228
                        + "public class Test {\n"
229
                        + "    public static void main(String[] args) {\n"
230
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
231
                        + "    }\n"
232
                        + "}\n");
233
234
    }
235
236
    @Test
237
    public void testConvertZERO_A() throws Exception {
238
        HintTest.create()
239
                .input("package test;\n"
240
                        + "public class Test {\n"
241
                        + "    public static void main(String[] args) {\n"
242
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"0\");\n"
243
                        + "    }\n"
244
                        + "}\n")
245
                .run(UseBDConstFix.class)
246
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
247
                .applyFix()
248
                .assertCompilable()
249
                .assertOutput("package test;\n"
250
                        + "import java.math.BigDecimal;\n"
251
                        + "public class Test {\n"
252
                        + "    public static void main(String[] args) {\n"
253
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
254
                        + "    }\n"
255
                        + "}\n");
256
257
    }
258
259
    @Test
260
    public void testConvertZERO_B() throws Exception {
261
        HintTest.create()
262
                .input("package test;\n"
263
                        + "public class Test {\n"
264
                        + "    public static void main(String[] args) {\n"
265
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"0.0\");\n"
266
                        + "    }\n"
267
                        + "}\n")
268
                .run(UseBDConstFix.class)
269
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
270
                .applyFix()
271
                .assertCompilable()
272
                .assertOutput("package test;\n"
273
                        + "import java.math.BigDecimal;\n"
274
                        + "public class Test {\n"
275
                        + "    public static void main(String[] args) {\n"
276
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
277
                        + "    }\n"
278
                        + "}\n");
279
280
    }
281
282
    @Test
283
    public void testConvertZERO_C() throws Exception {
284
        HintTest.create()
285
                .input("package test;\n"
286
                        + "public class Test {\n"
287
                        + "    public static void main(String[] args) {\n"
288
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(0.0);\n"
289
                        + "    }\n"
290
                        + "}\n")
291
                .run(UseBDConstFix.class)
292
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
293
                .applyFix()
294
                .assertCompilable()
295
                .assertOutput("package test;\n"
296
                        + "import java.math.BigDecimal;\n"
297
                        + "public class Test {\n"
298
                        + "    public static void main(String[] args) {\n"
299
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
300
                        + "    }\n"
301
                        + "}\n");
302
303
    }
304
305
    @Test
306
    public void testConvertZERO_D() throws Exception {
307
        HintTest.create()
308
                .input("package test;\n"
309
                        + "public class Test {\n"
310
                        + "    public static void main(String[] args) {\n"
311
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(0.00d);\n"
312
                        + "    }\n"
313
                        + "}\n")
314
                .run(UseBDConstFix.class)
315
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
316
                .applyFix()
317
                .assertCompilable()
318
                .assertOutput("package test;\n"
319
                        + "import java.math.BigDecimal;\n"
320
                        + "public class Test {\n"
321
                        + "    public static void main(String[] args) {\n"
322
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
323
                        + "    }\n"
324
                        + "}\n");
325
326
    }
327
328
    @Test
329
    public void testConvertBigInteger_ONE() throws Exception {
330
        HintTest.create()
331
                .input("package test;\n"
332
                        + "import java.math.BigInteger;\n"
333
                        + "public class Test {\n"
334
                        + "    public static void main(String[] args) {\n"
335
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(BigInteger.ONE);\n"
336
                        + "    }\n"
337
                        + "}\n")
338
                .run(UseBDConstFix.class)
339
                .findWarning("4:31-4:71:hint:" + Bundle.DN_UseBigDecimalConstants())
340
                .applyFix()
341
                .assertCompilable()
342
                .assertOutput("package test;\n"
343
                        + "import java.math.BigDecimal;\n"
344
                        + "public class Test {\n"
345
                        + "    public static void main(String[] args) {\n"
346
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
347
                        + "    }\n"
348
                        + "}\n");
349
350
    }
351
}
(-)a/src/org/netbeans/modules/java/hints/suggestions/UseBDConstFix.java (+135 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.java.hints.suggestions;
43
44
import com.sun.source.tree.LiteralTree;
45
import com.sun.source.tree.Tree;
46
import com.sun.source.util.TreePath;
47
import java.math.BigDecimal;
48
import java.math.BigInteger;
49
import java.util.Arrays;
50
import javax.lang.model.SourceVersion;
51
import org.netbeans.modules.java.hints.ArithmeticUtilities;
52
import org.netbeans.spi.editor.hints.ErrorDescription;
53
import org.netbeans.spi.editor.hints.Fix;
54
import org.netbeans.spi.editor.hints.Severity;
55
import org.netbeans.spi.java.hints.ErrorDescriptionFactory;
56
import org.netbeans.spi.java.hints.Hint;
57
import org.netbeans.spi.java.hints.HintContext;
58
import org.netbeans.spi.java.hints.TriggerPattern;
59
import org.netbeans.spi.java.hints.TriggerPatterns;
60
import org.openide.util.NbBundle.Messages;
61
62
@Messages({
63
    "# {0} - f.e. BigDecimal.ONE",
64
    "ERR_UseBDConstFix=Replace with {0}",
65
    "DN_UseBigDecimalConstants=Use BigDecimal constants where possible",
66
    "DESC_UseBigDecimalConstants=Introduces BigDecimal constants where possible. <p>For example: <tt>new java.math.BigDecimal(1.0)</tt> will be replaced by <tt>BigDecimal.ONE</tt></p>",})
67
/**
68
 * @author markiewb
69
 */
70
public class UseBDConstFix {
71
72
    @Hint(displayName = "#DN_UseBigDecimalConstants", description = "#DESC_UseBigDecimalConstants", category = "rules15", hintKind = Hint.Kind.INSPECTION, severity = Severity.HINT)
73
    @TriggerPatterns(
74
            {
75
                @TriggerPattern("new java.math.BigDecimal($v)"),
76
                @TriggerPattern("java.math.BigDecimal.valueOf($v)"),
77
            }
78
    )
79
    public static ErrorDescription convert(HintContext ctx) {
80
        if (!isAtLeastJDK5(ctx)) {
81
            return null;
82
        }
83
84
        TreePath get = ctx.getVariables().get("$v");
85
        if (null == get) {
86
            return null;
87
        }
88
89
        String literal = getLiteralValue(get);
90
91
        BigDecimal valueOf = getArithmeticValue(ctx, get);
92
        Fix fix = null;
93
        if (equals(valueOf, BigDecimal.ONE) || contains(literal, "1", "1.0", "1.00")) {
94
            fix = org.netbeans.spi.java.hints.JavaFixUtilities.rewriteFix(ctx, Bundle.ERR_UseBDConstFix("BigDecimal.ONE"), ctx.getPath(), "java.math.BigDecimal.ONE");
95
        }
96
        if (equals(valueOf, BigDecimal.ZERO) || contains(literal, "0", "0.0", "0.00")) {
97
            fix = org.netbeans.spi.java.hints.JavaFixUtilities.rewriteFix(ctx, Bundle.ERR_UseBDConstFix("BigDecimal.ZERO"), ctx.getPath(), "java.math.BigDecimal.ZERO");
98
        }
99
        if (equals(valueOf, BigDecimal.TEN) || contains(literal, "10", "10.0", "10.00")) {
100
            fix = org.netbeans.spi.java.hints.JavaFixUtilities.rewriteFix(ctx, Bundle.ERR_UseBDConstFix("BigDecimal.TEN"), ctx.getPath(), "java.math.BigDecimal.TEN");
101
        }
102
        if (null != fix) {
103
            return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.DN_UseBigDecimalConstants(), fix);
104
        }
105
        return null;
106
    }
107
108
    private static boolean contains(String literal, String... patterns) {
109
        return Arrays.asList(patterns).contains(literal);
110
    }
111
112
    private static boolean equals(BigDecimal valueOf, final BigDecimal ONE) {
113
        return valueOf != null && ONE.compareTo(valueOf) == 0;
114
    }
115
116
    private static BigDecimal getArithmeticValue(HintContext ctx, TreePath get) {
117
        Number compute = ArithmeticUtilities.compute(ctx.getInfo(), get, true);
118
        if (null != compute) {
119
            return BigDecimal.valueOf(compute.doubleValue());
120
        }
121
        return null;
122
    }
123
124
    private static String getLiteralValue(TreePath get) {
125
        if (get.getLeaf().getKind() == Tree.Kind.STRING_LITERAL) {
126
            return ((LiteralTree) get.getLeaf()).getValue().toString();
127
        }
128
        return null;
129
    }
130
131
    private static boolean isAtLeastJDK5(HintContext ctx) {
132
        return ctx.getInfo().getSourceVersion().compareTo(SourceVersion.RELEASE_5) >= 0;
133
    }
134
135
}
(-)a/test/unit/src/org/netbeans/modules/java/hints/suggestions/UseBDConstFixTest.java (+328 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 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
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.java.hints.suggestions;
43
44
import org.junit.Test;
45
import org.netbeans.modules.java.hints.test.api.HintTest;
46
47
/**
48
 * @author markiewb
49
 */
50
public class UseBDConstFixTest {
51
52
    @Test
53
    public void testConvertONE_A() throws Exception {
54
        HintTest.create()
55
                .input("package test;\n"
56
                        + "public class Test {\n"
57
                        + "    public static void main(String[] args) {\n"
58
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"1\");\n"
59
                        + "    }\n"
60
                        + "}\n")
61
                .run(UseBDConstFix.class)
62
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
63
                .applyFix()
64
                .assertCompilable()
65
                .assertOutput("package test;\n"
66
                        + "import java.math.BigDecimal;\n"
67
                        + "public class Test {\n"
68
                        + "    public static void main(String[] args) {\n"
69
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
70
                        + "    }\n"
71
                        + "}\n");
72
73
    }
74
75
    @Test
76
    public void testConvertONE_B() throws Exception {
77
        HintTest.create()
78
                .input("package test;\n"
79
                        + "public class Test {\n"
80
                        + "    public static void main(String[] args) {\n"
81
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"1.0\");\n"
82
                        + "    }\n"
83
                        + "}\n")
84
                .run(UseBDConstFix.class)
85
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
86
                .applyFix()
87
                .assertCompilable()
88
                .assertOutput("package test;\n"
89
                        + "import java.math.BigDecimal;\n"
90
                        + "public class Test {\n"
91
                        + "    public static void main(String[] args) {\n"
92
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
93
                        + "    }\n"
94
                        + "}\n");
95
96
    }
97
98
    @Test
99
    public void testConvertONE_C() throws Exception {
100
        HintTest.create()
101
                .input("package test;\n"
102
                        + "public class Test {\n"
103
                        + "    public static void main(String[] args) {\n"
104
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(1.0);\n"
105
                        + "    }\n"
106
                        + "}\n")
107
                .run(UseBDConstFix.class)
108
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
109
                .applyFix()
110
                .assertCompilable()
111
                .assertOutput("package test;\n"
112
                        + "import java.math.BigDecimal;\n"
113
                        + "public class Test {\n"
114
                        + "    public static void main(String[] args) {\n"
115
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
116
                        + "    }\n"
117
                        + "}\n");
118
119
    }
120
121
    @Test
122
    public void testConvertONE_D() throws Exception {
123
        HintTest.create()
124
                .input("package test;\n"
125
                        + "public class Test {\n"
126
                        + "    public static void main(String[] args) {\n"
127
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(1.00d);\n"
128
                        + "    }\n"
129
                        + "}\n")
130
                .run(UseBDConstFix.class)
131
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
132
                .applyFix()
133
                .assertCompilable()
134
                .assertOutput("package test;\n"
135
                        + "import java.math.BigDecimal;\n"
136
                        + "public class Test {\n"
137
                        + "    public static void main(String[] args) {\n"
138
                        + "        java.math.BigDecimal a=BigDecimal.ONE;\n"
139
                        + "    }\n"
140
                        + "}\n");
141
142
    }
143
144
    @Test
145
    public void testConvertTEN_A() throws Exception {
146
        HintTest.create()
147
                .input("package test;\n"
148
                        + "public class Test {\n"
149
                        + "    public static void main(String[] args) {\n"
150
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"10\");\n"
151
                        + "    }\n"
152
                        + "}\n")
153
                .run(UseBDConstFix.class)
154
                .findWarning("3:31-3:61:hint:" + Bundle.DN_UseBigDecimalConstants())
155
                .applyFix()
156
                .assertCompilable()
157
                .assertOutput("package test;\n"
158
                        + "import java.math.BigDecimal;\n"
159
                        + "public class Test {\n"
160
                        + "    public static void main(String[] args) {\n"
161
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
162
                        + "    }\n"
163
                        + "}\n");
164
165
    }
166
167
    @Test
168
    public void testConvertTEN_B() throws Exception {
169
        HintTest.create()
170
                .input("package test;\n"
171
                        + "public class Test {\n"
172
                        + "    public static void main(String[] args) {\n"
173
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"10.0\");\n"
174
                        + "    }\n"
175
                        + "}\n")
176
                .run(UseBDConstFix.class)
177
                .findWarning("3:31-3:63:hint:" + Bundle.DN_UseBigDecimalConstants())
178
                .applyFix()
179
                .assertCompilable()
180
                .assertOutput("package test;\n"
181
                        + "import java.math.BigDecimal;\n"
182
                        + "public class Test {\n"
183
                        + "    public static void main(String[] args) {\n"
184
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
185
                        + "    }\n"
186
                        + "}\n");
187
188
    }
189
190
    @Test
191
    public void testConvertTEN_C() throws Exception {
192
        HintTest.create()
193
                .input("package test;\n"
194
                        + "public class Test {\n"
195
                        + "    public static void main(String[] args) {\n"
196
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(10.0);\n"
197
                        + "    }\n"
198
                        + "}\n")
199
                .run(UseBDConstFix.class)
200
                .findWarning("3:31-3:61:hint:" + Bundle.DN_UseBigDecimalConstants())
201
                .applyFix()
202
                .assertCompilable()
203
                .assertOutput("package test;\n"
204
                        + "import java.math.BigDecimal;\n"
205
                        + "public class Test {\n"
206
                        + "    public static void main(String[] args) {\n"
207
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
208
                        + "    }\n"
209
                        + "}\n");
210
211
    }
212
213
    @Test
214
    public void testConvertTEN_D() throws Exception {
215
        HintTest.create()
216
                .input("package test;\n"
217
                        + "public class Test {\n"
218
                        + "    public static void main(String[] args) {\n"
219
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(10.00d);\n"
220
                        + "    }\n"
221
                        + "}\n")
222
                .run(UseBDConstFix.class)
223
                .findWarning("3:31-3:63:hint:" + Bundle.DN_UseBigDecimalConstants())
224
                .applyFix()
225
                .assertCompilable()
226
                .assertOutput("package test;\n"
227
                        + "import java.math.BigDecimal;\n"
228
                        + "public class Test {\n"
229
                        + "    public static void main(String[] args) {\n"
230
                        + "        java.math.BigDecimal a=BigDecimal.TEN;\n"
231
                        + "    }\n"
232
                        + "}\n");
233
234
    }
235
236
    @Test
237
    public void testConvertZERO_A() throws Exception {
238
        HintTest.create()
239
                .input("package test;\n"
240
                        + "public class Test {\n"
241
                        + "    public static void main(String[] args) {\n"
242
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"0\");\n"
243
                        + "    }\n"
244
                        + "}\n")
245
                .run(UseBDConstFix.class)
246
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
247
                .applyFix()
248
                .assertCompilable()
249
                .assertOutput("package test;\n"
250
                        + "import java.math.BigDecimal;\n"
251
                        + "public class Test {\n"
252
                        + "    public static void main(String[] args) {\n"
253
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
254
                        + "    }\n"
255
                        + "}\n");
256
257
    }
258
259
    @Test
260
    public void testConvertZERO_B() throws Exception {
261
        HintTest.create()
262
                .input("package test;\n"
263
                        + "public class Test {\n"
264
                        + "    public static void main(String[] args) {\n"
265
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(\"0.0\");\n"
266
                        + "    }\n"
267
                        + "}\n")
268
                .run(UseBDConstFix.class)
269
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
270
                .applyFix()
271
                .assertCompilable()
272
                .assertOutput("package test;\n"
273
                        + "import java.math.BigDecimal;\n"
274
                        + "public class Test {\n"
275
                        + "    public static void main(String[] args) {\n"
276
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
277
                        + "    }\n"
278
                        + "}\n");
279
280
    }
281
282
    @Test
283
    public void testConvertZERO_C() throws Exception {
284
        HintTest.create()
285
                .input("package test;\n"
286
                        + "public class Test {\n"
287
                        + "    public static void main(String[] args) {\n"
288
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(0.0);\n"
289
                        + "    }\n"
290
                        + "}\n")
291
                .run(UseBDConstFix.class)
292
                .findWarning("3:31-3:60:hint:" + Bundle.DN_UseBigDecimalConstants())
293
                .applyFix()
294
                .assertCompilable()
295
                .assertOutput("package test;\n"
296
                        + "import java.math.BigDecimal;\n"
297
                        + "public class Test {\n"
298
                        + "    public static void main(String[] args) {\n"
299
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
300
                        + "    }\n"
301
                        + "}\n");
302
303
    }
304
305
    @Test
306
    public void testConvertZERO_D() throws Exception {
307
        HintTest.create()
308
                .input("package test;\n"
309
                        + "public class Test {\n"
310
                        + "    public static void main(String[] args) {\n"
311
                        + "        java.math.BigDecimal a=new java.math.BigDecimal(0.00d);\n"
312
                        + "    }\n"
313
                        + "}\n")
314
                .run(UseBDConstFix.class)
315
                .findWarning("3:31-3:62:hint:" + Bundle.DN_UseBigDecimalConstants())
316
                .applyFix()
317
                .assertCompilable()
318
                .assertOutput("package test;\n"
319
                        + "import java.math.BigDecimal;\n"
320
                        + "public class Test {\n"
321
                        + "    public static void main(String[] args) {\n"
322
                        + "        java.math.BigDecimal a=BigDecimal.ZERO;\n"
323
                        + "    }\n"
324
                        + "}\n");
325
326
    }
327
328
}

Return to bug 236244