/* Ċ Ġ* ĠCopyright Ġ( C ) Ġ 2 0 1 2 ĠThe ĠAndroid ĠOpen ĠSource ĠProject Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ Ċ package Ġcom . android . tools . lint . checks Ċ Ċ import Ġcom . android . Sdk Constants . FORMAT _ METHOD Ċ import Ġcom . android . tools . lint . checks . DateFormat Detector . LOCAL E _ CLS Ċ import Ġcom . android . tools . lint . client . api . Lint Client Ċ import Ġcom . android . tools . lint . client . api . TYPE _ STRING Ċ import Ġcom . android . tools . lint . detector . api . Category Ċ import Ġcom . android . tools . lint . detector . api . Constant Evaluator Ċ import Ġcom . android . tools . lint . detector . api . Detector Ċ import Ġcom . android . tools . lint . detector . api . Implementation Ċ import Ġcom . android . tools . lint . detector . api . Issue Ċ import Ġcom . android . tools . lint . detector . api . Java Context Ċ import Ġcom . android . tools . lint . detector . api . Lint Fix Ċ import Ġcom . android . tools . lint . detector . api . Location Ċ import Ġcom . android . tools . lint . detector . api . Scope Ċ import Ġcom . android . tools . lint . detector . api . Severity Ċ import Ġcom . android . tools . lint . detector . api . Source Code Scanner Ċ import Ġcom . android . tools . lint . detector . api . get MethodName Ċ import Ġcom . intellij . psi . Psi Method Ċ import Ġorg . jetbrains . u ast . U Call Expression Ċ import Ġorg . jetbrains . u ast . U Element Ċ import Ġorg . jetbrains . u ast . U Field Ċ import Ġorg . jetbrains . u ast . U Throw Expression Ċ import Ġorg . jetbrains . u ast . getParent OfType Ċ import Ġjava . util . Arrays Ċ Ċ /** Ċ Ġ* ĠChecks Ġfor Ġerrors Ġrelated Ġto Ġlocale Ġhandling Ċ Ġ*/ Ċ /** ĠConstructs Ġa Ġnew Ġ[ Locale Detector ] Ġ Ġ*/ Ċ class ĠLocale Detector Ġ: ĠDetector (), ĠSource Code Scanner Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġget Applicable Method Names (): ĠList < String >? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠArrays . asList ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTO _ LOWER _ CASE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTO _ UPPER _ CASE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠFORMAT _ METHOD , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠGET _ DEFAULT , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCAPITAL IZE , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠDE CAP ITAL IZE ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġvisit MethodCall ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠJava Context , ĊĠĠĠĠĠĠĠ Ġnode : ĠU Call Expression , ĊĠĠĠĠĠĠĠ Ġmethod : ĠPsi Method ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( method . name Ġ== ĠGET _ DEFAULT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( context . evaluator . is Member In Class ( method , ĠLOCAL E _ CLS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck Locale GetDefault ( context , Ġmethod , Ġnode ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( context . evaluator . is Member In Class ( method , ĠTYPE _ STRING )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( method . name ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFORMAT _ METHOD Ġ-> Ġcheck Format ( context , Ġmethod , Ġnode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTO _ LOWER _ CASE , ĠTO _ UPPER _ CASE Ġ-> Ġcheck Java ToUpper LowerCase ( context , Ġmethod , Ġnode ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( context . evaluator . is Member In Class ( method , ĠK OT LIN _ STRING S _ JVM _ KT )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( method . name ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCAPITAL IZE , ĠDE CAP ITAL IZE Ġ-> Ġcheck Strings Kt ( context , Ġmethod , Ġnode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTO _ LOWER _ CASE , ĠTO _ UPPER _ CASE Ġ-> Ġcheck Strings Kt ( context , Ġmethod , Ġnode ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Java ToUpper LowerCase ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠJava Context , ĊĠĠĠĠĠĠĠ Ġmethod : ĠPsi Method , ĊĠĠĠĠĠĠĠ Ġnode : ĠU Call Expression ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠIn Ġthe ĠIDE , Ġdon 't Ġflag Ġjava Ġto UpperCase / toLowerCase ; Ġthese ĊĠĠĠĠĠĠĠ Ġ// Ġare Ġalready Ġflag ged Ġby Ġbuilt - in ĠIDE Ġins pe ctions , Ġso Ġwe Ġdon 't ĊĠĠĠĠĠĠĠ Ġ// Ġwant Ġduplicate Ġwarnings . ĊĠĠĠĠĠĠĠ Ġif Ġ( Lint Client . is Studio ) Ġreturn ĊĠĠĠĠĠĠĠ Ġif Ġ( method . parameter List . parameters Count Ġ!= Ġ 0 ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġlocation Ġ= Ġcontext . getName Location ( node ) ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠString . format ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Implicit ly Ġusing Ġthe Ġdefault Ġlocale Ġis Ġa Ġcommon Ġsource Ġof Ġbugs : Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Use Ġ`% 1 \$ s ( Locale )` Ġinstead . ĠFor Ġstrings Ġmeant Ġto Ġbe Ġinternal Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" use Ġ` Locale . ROOT `, Ġotherwise Ġ` Locale . getDefault ()`. ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmethod . name ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġcontext . report ( STRING _ LOCAL E , Ġnode , Ġlocation , Ġmessage ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Strings Kt ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠJava Context , ĊĠĠĠĠĠĠĠ Ġmethod : ĠPsi Method , ĊĠĠĠĠĠĠĠ Ġnode : ĠU Call Expression ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( method . parameter List . parameters Count Ġ> Ġ 1 ) Ġreturn ĊĠĠĠĠĠĠĠ Ġval Ġlocation Ġ= Ġcontext . getName Location ( node ) ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĠString . format ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Implicit ly Ġusing Ġthe Ġdefault Ġlocale Ġis Ġa Ġcommon Ġsource Ġof Ġbugs : Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Use Ġ`% 1 \$ s ( Locale )` Ġinstead . ĠFor Ġstrings Ġmeant Ġto Ġbe Ġinternal Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" use Ġ` Locale . ROOT `, Ġotherwise Ġ` Locale . getDefault ()`. ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmethod . name ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġval Ġrange Ġ= Ġcontext . get Call Location ( node , Ġinclude Receiver Ġ= Ġfalse , Ġinclude Arguments Ġ= Ġtrue ) ĊĠĠĠĠĠĠĠ Ġval Ġquick fix Data Ġ= ĠL int Fix . create (). group (). also Ġ{ Ġgroup Builder Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( locale Name Ġin ĠlistOf (" ROOT ", Ġ" getDefault () ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroup Builder . add ( Lint Fix . create () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. name (" Replace Ġwith Ġ`${ method . name }( Locale .$ locale Name )` ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. shared Name (" Use Ġexplicit Ġlocale ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. replace () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. range ( range ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. with ("${ method . name }( java . util . Locale .$ locale Name )") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. short en Names () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}. build () ĊĠĠĠĠĠĠĠ Ġcontext . report ( STRING _ LOCAL E , Ġnode , Ġlocation , Ġmessage , Ġquick fix Data ) ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġprivate Ġfun Ġcheck Format ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠJava Context , ĊĠĠĠĠĠĠĠ Ġmethod : ĠPsi Method , ĊĠĠĠĠĠĠĠ Ġcall : ĠU Call Expression ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠOnly Ġcheck Ġthe Ġnon - locale Ġversion Ġof ĠString . format ĊĠĠĠĠĠĠĠ Ġif Ġ( method . parameter List . parameters Count Ġ== Ġ 0 Ġ|| Ġ! context . evaluator . parameter Has Type ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ 0 , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTYPE _ STRING ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġexpressions Ġ= Ġcall . value Arguments ĊĠĠĠĠĠĠĠ Ġif Ġ( expressions . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// ĠFind Ġthe Ġformatting Ġstring ĊĠĠĠĠĠĠĠ Ġval Ġfirst Ġ= Ġexpressions [ 0 ] ĊĠĠĠĠĠĠĠ Ġval Ġvalue Ġ= ĠConstant Evaluator . evaluate ( context , Ġfirst ) Ġas ? ĠString Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ Ġif Ġ( String Format Detector . is Locale Specific ( value )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Logging Parameter ( context , Ġcall )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( call . getParent OfType < U Element >( U Throw Expression :: class . java , Ġtrue ) Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlocation : ĠLocation Ġ= Ġif Ġ( FORMAT _ METHOD Ġ== Ġget MethodName ( call )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor ĠString # format , Ġinclude Ġreceiver Ġ( String ), Ġbut Ġnot Ġfor Ġ. to Upper case Ġetc ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsince Ġthe Ġreceiver Ġcan Ġoften Ġbe Ġa Ġcomplex Ġexpression ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . get Call Location ( call , Ġtrue , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . get Call Location ( call , Ġfalse , Ġtrue ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Implicit ly Ġusing Ġthe Ġdefault Ġlocale Ġis Ġa Ġcommon Ġsource Ġof Ġbugs : Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Use Ġ` String . format ( Locale , Ġ... )` Ġinstead " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . report ( STRING _ LOCAL E , Ġcall , Ġlocation , Ġmessage ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcheck Locale GetDefault ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠJava Context , ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UNUSED _ PARAMETER ") ĊĠĠĠĠĠĠĠ Ġmethod : ĠPsi Method , ĊĠĠĠĠĠĠĠ Ġnode : ĠU Call Expression ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfield Ġ= Ġnode . getParent OfType < U Field >( U Field :: class . java , Ġtrue ) Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠ Ġval Ġevaluator Ġ= Ġcontext . evaluator ĊĠĠĠĠĠĠĠ Ġif Ġ( evaluator . is Static ( field ) Ġ&& Ġevaluator . is Final ( field )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . report ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFIN AL _ LOCAL E , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnode , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontext . getLocation ( node ), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Assign ing Ġ` Locale . getDefault ()` Ġto Ġa Ġfinal Ġstatic Ġfield Ġis Ġsus pic ious ; Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" this Ġcode Ġwill Ġnot Ġwork Ġcorrectly Ġif Ġthe Ġuser Ġchanges Ġlocale Ġwhile Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" the Ġapp Ġis Ġrunning " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĠReturns Ġtrue Ġif Ġthe Ġgiven Ġnode Ġis Ġa Ġparameter Ġto Ġa ĠLogging Ġcall Ġ Ġ*/ ĊĠĠĠ Ġprivate Ġfun Ġis Logging Parameter ( ĊĠĠĠĠĠĠĠ Ġcontext : ĠJava Context , ĊĠĠĠĠĠĠĠ Ġnode : ĠU Call Expression ĊĠĠĠ Ġ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġparent Call Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnode . getParent OfType < U Call Expression >( U Call Expression :: class . java , Ġtrue ) ĊĠĠĠĠĠĠĠ Ġif Ġ( parent Call Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġget MethodName ( parent Call ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( name Ġ!= Ġnull Ġ&& Ġname . length Ġ== Ġ 1 ) Ġ{ Ġ// Ġ" d ", Ġ" i ", Ġ" e " Ġetc Ġin ĠLog ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Ġ= Ġparent Call . resolve () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcontext . evaluator . is Member In Class ( method , ĠLog Detector . LOG _ CLS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠIMP LEMENT ATION Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ ĠImplementation ( Locale Detector :: class . java , ĠScope . JAVA _ FILE _ SCOPE ) ĊĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTO _ UPPER _ CASE Ġ= Ġ" toUpperCase " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠTO _ LOWER _ CASE Ġ= Ġ" toLowerCase " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠGET _ DEFAULT Ġ= Ġ" getDefault " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠK OT LIN _ STRING S _ JVM _ KT Ġ= Ġ" kotlin . text . Strings Kt __ Strings JVM Kt " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠCAPITAL IZE Ġ= Ġ" capitalize " ĊĠĠĠĠĠĠĠ Ġconst Ġval ĠDE CAP ITAL IZE Ġ= Ġ" de capitalize " ĊĊĠĠĠĠĠĠĠ Ġ/** ĠCalling Ġris ky Ġconvenience Ġmethods Ġ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field ĊĠĠĠĠĠĠĠ Ġval ĠSTRING _ LOCAL E Ġ= ĠIssue . create ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Ġ= Ġ" Default Locale ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbrief Description Ġ= Ġ" Imp lied Ġdefault Ġlocale Ġin Ġcase Ġconversion ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexplanation Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCalling Ġ` String # toLowerCase ()` Ġor Ġ`# toUpperCase ()` Ġ** without Ġspecifying Ġan Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexplicit Ġlocale ** Ġis Ġa Ġcommon Ġsource Ġof Ġbugs . ĠThe Ġreason Ġfor Ġthat Ġis Ġthat Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthose Ġmethods Ġwill Ġuse Ġthe Ġcurrent Ġlocale Ġon Ġthe Ġuser 's Ġdevice , Ġand Ġeven Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthough Ġthe Ġcode Ġappears Ġto Ġwork Ġcorrectly Ġwhen Ġyou Ġare Ġdeveloping Ġthe Ġapp , Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġwill Ġfail Ġin Ġsome Ġlocales . ĠFor Ġexample , Ġin Ġthe ĠTur k ish Ġlocale , Ġthe Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġuppercase Ġreplacement Ġfor Ġ` i ` Ġis Ġ** not ** Ġ` I `. ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠIf Ġyou Ġwant Ġthe Ġmethods Ġto Ġjust Ġperform ĠASCII Ġreplacement , Ġfor Ġexample Ġto Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconvert Ġan Ġenum Ġname , Ġcall Ġ` String # toUpperCase ( Locale . US )` Ġinstead . ĠIf Ġyou Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreally Ġwant Ġto Ġuse Ġthe Ġcurrent Ġlocale , Ġcall Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ` String # toUpperCase ( Locale . getDefault ()) ` Ġinstead . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"" ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmore Info Ġ= Ġ" http :// developer . android . com / reference / java / util / Locale . html # default _ locale ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Ġ= ĠCategory . CORRECT NESS , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpriority Ġ= Ġ 6 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseverity Ġ= ĠSeverity . WARNING , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimplementation Ġ= ĠIMP LEMENT ATION ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġ/** ĠAss uming Ġlocale Ġdoesn 't Ġchange Ġ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Field ĊĠĠĠĠĠĠĠ Ġval ĠFIN AL _ LOCAL E Ġ= ĠIssue . create ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Ġ= Ġ" Constant Locale ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbrief Description Ġ= Ġ" Constant ĠLocale ", ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexplanation Ġ= Ġ""" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAssign ing Ġ` Locale . getDefault ()` Ġto Ġa Ġconstant Ġis Ġsus pic ious , Ġbecause Ġ\ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthe Ġlocale Ġcan Ġchange Ġwhile Ġthe Ġapp Ġis Ġrunning . """, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcategory Ġ= ĠCategory . I 1 8 N , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpriority Ġ= Ġ 6 , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġseverity Ġ= ĠSeverity . WARNING , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġandroid Specific Ġ= Ġtrue , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġimplementation Ġ= ĠIMP LEMENT ATION ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} Ċ } Ċ