• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
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 
17 package com.android.providers.media;
18 
19 import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
20 
21 import com.google.auto.service.AutoService;
22 import com.google.errorprone.BugPattern;
23 import com.google.errorprone.VisitorState;
24 import com.google.errorprone.bugpatterns.BugChecker;
25 import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
26 import com.google.errorprone.matchers.ChildMultiMatcher;
27 import com.google.errorprone.matchers.Description;
28 import com.google.errorprone.matchers.FieldMatchers;
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 @AutoService(BugChecker.class)
35 @BugPattern(
36     name = "MediaProviderLocaleRoot",
37     summary = "Verifies that all case-altering methods use Locale.ROOT",
38     severity = WARNING)
39 public final class LocaleRootChecker extends BugChecker implements MethodInvocationTreeMatcher {
40     private static final Matcher<ExpressionTree> STRING_TO_UPPER_CASE =
41             Matchers.instanceMethod().onExactClass("java.lang.String").named("toUpperCase");
42     private static final Matcher<ExpressionTree> STRING_TO_LOWER_CASE =
43             Matchers.instanceMethod().onExactClass("java.lang.String").named("toLowerCase");
44     private static final Matcher<ExpressionTree> LOCALE_ROOT =
45             FieldMatchers.staticField("java.util.Locale", "ROOT");
46 
47     private static final Matcher<ExpressionTree> MISSING_LOCALE_ROOT = Matchers.anyOf(
48             Matchers.methodInvocation(
49                     STRING_TO_UPPER_CASE,
50                     ChildMultiMatcher.MatchType.ALL,
51                     Matchers.anyOf(Matchers.nothing(), Matchers.not(LOCALE_ROOT))),
52             Matchers.methodInvocation(
53                     STRING_TO_LOWER_CASE,
54                     ChildMultiMatcher.MatchType.ALL,
55                     Matchers.anyOf(Matchers.nothing(), Matchers.not(LOCALE_ROOT)))
56             );
57 
58     @Override
matchMethodInvocation(MethodInvocationTree tree, VisitorState state)59     public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
60         if (MISSING_LOCALE_ROOT.matches(tree, state)) {
61             return buildDescription(tree)
62                     .setMessage("All case-altering methods must declare Locale.ROOT")
63                     .build();
64         }
65         return Description.NO_MATCH;
66     }
67 }
68