Skip to content

Commit 427b51d

Browse files
java-team-github-botError Prone Team
authored and
Error Prone Team
committed
GetSeconds to ToSeconds error prone
Per b/201676318, this converts `getSeconds` without corresponding `getNano` to `toSeconds. The bulk of the codebase (java) has been migrated. Only a warning for now (though I supposed GoodTime will make it an error). Will suppress in 3P on a need-to-basis. PiperOrigin-RevId: 688240816
1 parent 82a2168 commit 427b51d

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2018 The Error Prone Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.errorprone.bugpatterns.time;
17+
18+
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
19+
import static com.google.errorprone.bugpatterns.time.NearbyCallers.containsCallToSameReceiverNearby;
20+
import static com.google.errorprone.matchers.Matchers.allOf;
21+
import static com.google.errorprone.matchers.method.MethodMatchers.instanceMethod;
22+
23+
import com.google.errorprone.BugPattern;
24+
import com.google.errorprone.VisitorState;
25+
import com.google.errorprone.bugpatterns.BugChecker;
26+
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
27+
import com.google.errorprone.fixes.SuggestedFixes;
28+
import com.google.errorprone.matchers.Description;
29+
import com.google.errorprone.matchers.Matcher;
30+
import com.google.errorprone.matchers.Matchers;
31+
import com.sun.source.tree.ExpressionTree;
32+
import com.sun.source.tree.MethodInvocationTree;
33+
34+
/** Error prone checking for {@code Duration.getSeconds()} without {@code Duration.getNano()}. */
35+
@BugPattern(
36+
summary = "Prefer duration.toSeconds() over duration.getSeconds()",
37+
explanation =
38+
"duration.getSeconds() is a decomposition API which should always be used alongside"
39+
+ " duration.getNano(). duration.toSeconds() is a conversion API, and the preferred way"
40+
+ " to convert to seconds.",
41+
severity = WARNING)
42+
public final class JavaDurationGetSecondsToToSeconds extends BugChecker
43+
implements MethodInvocationTreeMatcher {
44+
45+
private static final Matcher<ExpressionTree> GET_SECONDS =
46+
instanceMethod().onExactClass("java.time.Duration").named("getSeconds");
47+
private static final Matcher<ExpressionTree> GET_NANO =
48+
allOf(
49+
instanceMethod().onExactClass("java.time.Duration").named("getNano"),
50+
Matchers.not(Matchers.packageStartsWith("java.")));
51+
52+
@Override
53+
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
54+
if (GET_SECONDS.matches(tree, state)) {
55+
if (!containsCallToSameReceiverNearby(tree, GET_NANO, state, /* checkProtoChains= */ false)) {
56+
return describeMatch(tree, SuggestedFixes.renameMethodInvocation(tree, "toSeconds", state));
57+
}
58+
}
59+
return Description.NO_MATCH;
60+
}
61+
}

core/src/main/java/com/google/errorprone/scanner/BuiltInCheckerSuppliers.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@
586586
import com.google.errorprone.bugpatterns.time.InstantTemporalUnit;
587587
import com.google.errorprone.bugpatterns.time.InvalidJavaTimeConstant;
588588
import com.google.errorprone.bugpatterns.time.JavaDurationGetSecondsGetNano;
589+
import com.google.errorprone.bugpatterns.time.JavaDurationGetSecondsToToSeconds;
589590
import com.google.errorprone.bugpatterns.time.JavaDurationWithNanos;
590591
import com.google.errorprone.bugpatterns.time.JavaDurationWithSeconds;
591592
import com.google.errorprone.bugpatterns.time.JavaInstantGetSecondsGetNano;
@@ -970,6 +971,7 @@ public static ScannerSupplier warningChecks() {
970971
JUnitAmbiguousTestClass.class,
971972
JUnitIncompatibleType.class,
972973
JavaDurationGetSecondsGetNano.class,
974+
JavaDurationGetSecondsToToSeconds.class,
973975
JavaDurationWithNanos.class,
974976
JavaDurationWithSeconds.class,
975977
JavaInstantGetSecondsGetNano.class,
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright 2018 The Error Prone Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.errorprone.bugpatterns.time;
17+
18+
import com.google.errorprone.BugCheckerRefactoringTestHelper;
19+
import com.google.errorprone.CompilationTestHelper;
20+
import org.junit.Test;
21+
import org.junit.runner.RunWith;
22+
import org.junit.runners.JUnit4;
23+
24+
/** Tests for {@link JavaDurationGetSecondsToToSeconds}. */
25+
@RunWith(JUnit4.class)
26+
public class JavaDurationGetSecondsToToSecondsTest {
27+
28+
private final CompilationTestHelper compilationHelper =
29+
CompilationTestHelper.newInstance(JavaDurationGetSecondsToToSeconds.class, getClass());
30+
31+
private final BugCheckerRefactoringTestHelper refactorHelper =
32+
BugCheckerRefactoringTestHelper.newInstance(
33+
JavaDurationGetSecondsToToSeconds.class, getClass());
34+
35+
@Test
36+
public void testNegative() {
37+
compilationHelper
38+
.addSourceLines(
39+
"test/TestCase.java",
40+
"""
41+
package test;
42+
43+
import java.time.Duration;
44+
45+
public class TestCase {
46+
public static void foo(Duration duration) {
47+
long seconds = duration.getSeconds();
48+
int nanos = duration.getNano();
49+
}
50+
}
51+
""")
52+
.doTest();
53+
}
54+
55+
@Test
56+
public void testPositive() {
57+
refactorHelper
58+
.addInputLines(
59+
"test/TestCase.java",
60+
"""
61+
package test;
62+
63+
import java.time.Duration;
64+
65+
public class TestCase {
66+
public static void foo(Duration duration) {
67+
long seconds = duration.getSeconds();
68+
}
69+
}
70+
""")
71+
.addOutputLines(
72+
"out/TestCase.java",
73+
"""
74+
package test;
75+
76+
import java.time.Duration;
77+
78+
public class TestCase {
79+
public static void foo(Duration duration) {
80+
long seconds = duration.toSeconds();
81+
}
82+
}
83+
""")
84+
.doTest();
85+
}
86+
}

0 commit comments

Comments
 (0)