
рдЬрдм рдбреЗрд╡рд▓рдкрд░ рдкрд░реНрдпрд╛рдкреНрдд рд╕рд╛рд╡рдзрд╛рдиреА рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рддреЛ рдЪреАрдЬреЗрдВ рдмрд╣реБрдд рдмреБрд░реА рддрд░рд╣ рд╕реЗ рдЬрд╛ рд╕рдХрддреА рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреНрд▓рд╛рд╕рд┐рдХ рдбреЗрд╡рд▓рдкрд░ рдЪреВрдХ, рдПрдкреАрдЖрдИ рдХреЗ рдПрдХ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИ рдЬреЛ рдкреБрд░рд╛рдиреЗ рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рдирд╣реАрдВ рд╣реИ, рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдЬреЛ рд╡рд┐рд╢реЗрд╖ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрдиреБрдорддрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдЖрд╡реЗрджрди рдХреЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдореЗрдВ рдЕрдВрддрд░рд╛рд▓ред рдФрд░ рдпреЗ рд╕рд┐рд░реНрдл рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рд╣реИрдВред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬрд╛рд╡рд╛ рдФрд░ рдХреЛрдЯрд▓рд┐рди, рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреА рддрд░рд╣, рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдирд┐рд░реНрдорд╛рдг рд╣реИрдВ рдЬреЛ рдЦрд░рд╛рдм рдкреНрд░рджрд░реНрд╢рди рдХрд╛ рдХрд╛рд░рдг рдмрди рд╕рдХрддреЗ рд╣реИрдВред
рдирдорд╕реНрддреЗ рдирдорд╕реНрддреЗ
рдРрд╕реА рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рд▓рд┐рдВрдЯ (рдпрд╛ рд▓рд┐рдВрдЯрд░) рдирд╛рдордХ рдПрдХ рдЙрдкрдХрд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд▓рд┐рдВрдЯ рдПрдХ рд╕реНрдерд┐рд░ рдХреЛрдб рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЙрдкрдХрд░рдг рд╣реИ рдЬреЛ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред рд▓рд┐рдВрдЯ рд╕реНрд░реЛрдд рдХреЛрдб рдХреА рдХрдИ рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЕрдкреНрд░рдпреБрдХреНрдд рдЪрд░ рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рддрд░реНрдХ, рд╢рд░реНрддреЛрдВ рдХрд╛ рд╕рд░рд▓реАрдХрд░рдг, рдЧрд▓рдд рдЧреБрдВрдЬрд╛рдЗрд╢, рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рдЪрд░ рдпрд╛ рдлрд╝рдВрдХреНрд╢рди, рдЦрд░рд╛рдм рдЕрдиреБрдХреВрд▓рд┐рдд рдХреЛрдб рдЖрджрд┐ рдЬреИрд╕реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддрд╛ рд╣реИред рдЬрдм рд╣рдо рдПрдВрдбреНрд░реЙрдЗрдб рдбреЗрд╡рд▓рдкрдореЗрдВрдЯ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╕реИрдХрдбрд╝реЛрдВ рд▓рд┐рдВрдЯ рдЪреЗрдХ рдЖрдЙрдЯ рд╣реЛрддреЗ рд╣реИрдВред
рд▓реЗрдХрд┐рди рдХрднреА-рдХрднреА рд╣рдореЗрдВ рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬреЛ рдЗрди рдореМрдЬреВрджрд╛ рдЪреЗрдХ рджреНрд╡рд╛рд░рд╛ рдХрд╡рд░ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВред
рд╣реИрд▓реЛ рдХрд╕реНрдЯрдо рдЪреЗрдХ рд▓рд┐рдВрдЯ
рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдХреЛрдбрд┐рдВрдЧ рд╢реБрд░реВ рдХрд░реЗрдВ, рд╣рдо рдЕрдкрдиреЗ рд▓рдХреНрд╖реНрдп рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рд▓рд┐рдВрдЯ рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдЪрд░рдг рджрд░ рдЪрд░рдг рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд▓рдХреНрд╖реНрдп рдПрдХ рд╡рд╕реНрддреБ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧрд▓рдд рд╡рд┐рдзрд┐ рдХреЙрд▓ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪреЗрдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИред рдЗрд╕ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реИ рдХрд┐ рджреГрд╢реНрдп рдШрдЯрдХ рдкрд░ рд╢реНрд░реЛрддрд╛ рдХреЛ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдРрд╕рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдШрдЯрдХ рдкрд░ рд▓рдЧрд╛рддрд╛рд░ рдХрдИ рдХреНрд▓рд┐рдХреЛрдВ рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░реЗрдЧрд╛, рддрд╛рдХрд┐ рд╣рдо рдПрдХ рд╣реА рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЛ рдЦреЛрд▓рдиреЗ рдпрд╛ рдХрдИ рдмрд╛рд░ рдиреЗрдЯрд╡рд░реНрдХ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рд╕реЗ рдмрдЪ рд╕рдХреЗрдВред
рд▓рд┐рдВрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЪреЗрдХ рдХреЛ рдорд╛рдирдХ рдЬрд╛рд╡рд╛ (рдпрд╛ рдХреЛрдЯрд▓рд┐рди) рдореЙрдбреНрдпреВрд▓ рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЖрд░рдВрдн рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЧреНрд░реЗрдбрд▓-рдЖрдзрд╛рд░рд┐рдд рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ рд╣реИ (рдЗрд╕рдореЗрдВ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╣реЛрдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ)ред
рдлрд┐рд░ рд▓рд┐рдВрдЯ рдирд┐рд░реНрднрд░рддрд╛ рдЬреЛрдбрд╝реЗрдВред рдЕрдкрдиреЗ рдореЙрдбреНрдпреВрд▓ рдХреЗ build.gradle
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
compileOnly "com.android.tools.lint:lint-api:$lintVersion" compileOnly "com.android.tools.lint:lint-checks:$lintVersion"
рдЕрдм рдПрдХ рдЪрд╛рд▓ рд╣реИ рдЬреЛ рдореИрдВрдиреЗ рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рд╢реЛрдз рдХрд░рддреЗ рд╕рдордп рд╕реАрдЦреАред lintVersion
рдХреЛ gradlePluginVersion + 23.0.0
lintVersion
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред gradlePluginVersion
рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реНрддрд░ рдкрд░ build.gradle
рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдПрдХ рдЪрд░ рд╣реИред рдФрд░ рдлрд┐рд▓рд╣рд╛рд▓, рдирд╡реАрдирддрдо рд╕реНрдерд┐рд░ рд╕рдВрд╕реНрдХрд░рдг 3.3.0 рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ lintVersion
рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдкреНрд░рддреНрдпреЗрдХ рд▓рд┐рдВрдЯ рдЪреЗрдХ рдореЗрдВ 4 рднрд╛рдЧ рд╣реЛрддреЗ рд╣реИрдВ:
- рд╕рдорд╕реНрдпрд╛ рд╣рдорд╛рд░реЗ рдХреЛрдб рдХреА рд╕рдорд╕реНрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рд░реЛрдХрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдЬрдм рд▓рд┐рдВрдЯ рдЪреЗрдХ рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдбрд┐рдЯреЗрдХреНрдЯрд░ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдЦреЛрдЬрдиреЗ рд╡рд╛рд▓рд╛ рдЙрдкрдХрд░рдг рд╣реИ рдЬреЛ рд▓рд┐рдВрдЯ рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
- рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рдРрд╕рд╛ рдХреНрд╖реЗрддреНрд░ рд╣реИ рдЬрд╣рд╛рдВ рдПрдХ рд╕рдорд╕реНрдпрд╛ рдЙрддреНрдкрдиреНрди рд╣реЛ рд╕рдХрддреА рд╣реИ (рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓, рдПрдХреНрд╕рдПрдордПрд▓ рдлрд╝рд╛рдЗрд▓, рд╕рдВрдХрд▓рд┐рдд рдХреЛрдб, рдЖрджрд┐)ред
- рдПрдХ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдПрдХ рдХрд╕реНрдЯрдо рд▓рд┐рдВрдЯ рдЪреЗрдХ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдореМрдЬреВрджрд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдореЗрдВ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдЪреЗрдХ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рдЪрд▓реЛ рд╣рдорд╛рд░реЗ рдХрд╕реНрдЯрдо рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрдирд╛рдХрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдПрдХ рдбрд┐рдЯреЗрдХреНрдЯрд░ рдФрд░ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдХ рд╡рд░реНрдЧ рд╣реЛрддрд╛ рд╣реИред
val correctClickListenerImplementation = Implementation(CorrectClickListenerDetector::class.java, Scope.JAVA_FILE_SCOPE)
рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ Scope.JAVA_FILE_SCOPE
рднреА Scope.JAVA_FILE_SCOPE
рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░реЗрдЧрд╛ред
рд╕рдорд╕реНрдпрд╛
рдЕрдЧрд▓рд╛ рдХрджрдо рд╕рдорд╕реНрдпрд╛ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рдХрдИ рднрд╛рдЧ рд╣реЛрддреЗ рд╣реИрдВ:
- рдЖрдИрдбреА рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИред
- рд╡рд┐рд╡рд░рдг - рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд (5-6 рд╢рдмреНрдж) рдХрдердиред
- рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдпрд╣ рдХреИрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд╕реБрдЭрд╛рд╡ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдкреВрд░рд╛ рд╡рд┐рд╡рд░рдгред
- рд╢реНрд░реЗрдгреА - рд╕рдорд╕реНрдпрд╛ рдХреА рд╢реНрд░реЗрдгреА (рдкреНрд░рджрд░реНрд╢рди, рдЕрдиреБрд╡рд╛рдж, рд╕реБрд░рдХреНрд╖рд╛, рдЖрджрд┐)ред
- рдкреНрд░рд╛рдердорд┐рдХрддрд╛ - 1 рд╕реЗ 10 рдХреА рд╕реАрдорд╛ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдорд╣рддреНрд╡, рдЬрд╣рд╛рдВ 10 рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╣реИред рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд▓рд┐рдВрдЯ рдХреЗ рд▓реЙрдиреНрдЪ рд╣реЛрдиреЗ рдкрд░ рдмрдирд╛рдИ рдЧрдИ рд░рд┐рдкреЛрд░реНрдЯ рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
- рдЧрдВрднреАрд░рддрд╛ - рд╕рдорд╕реНрдпрд╛ рдХреА рдЧрдВрднреАрд░рддрд╛ (рдШрд╛рддрдХ, рддреНрд░реБрдЯрд┐, рдЪреЗрддрд╛рд╡рдиреА, рд╕реВрдЪрдирд╛ рдпрд╛ рдЕрдирджреЗрдЦреА)ред
- рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
val ISSUE_CLICK_LISTENER = Issue.create( id = "UnsafeClickListener", briefDescription = "Unsafe click listener", explanation = """" This check ensures you call click listener that is throttled instead of a normal one which does not prevent double clicks. """.trimIndent(), category = Category.CORRECTNESS, priority = 6, severity = Severity.WARNING, implementation = correctClickListenerImplementation )
рдбрд┐рдЯреЗрдХреНрдЯрд░
рд▓рд┐рдВрдЯ рдПрдкреАрдЖрдИ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдЗрдВрдЯрд░рдлреЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рдЙрди рддрд░реАрдХреЛрдВ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдХреЛрдб рдХреЗ рдЙрди рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдФрд░ рдПрдХреНрд╕реЗрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреА рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВред
- UastScanner - рдЬрд╛рд╡рд╛ рдпрд╛ рдХреЛрдЯрд▓рд┐рди рдлрд╛рдЗрд▓реЗрдВ (UAST - Unified Abstract Syntax Tree (рд░реВрд╕реА рдПрдХреАрдХреГрдд рд╕рд╛рд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА ))ред
- рдХреНрд▓рд╛рд╕рд╕реНрдХреИрдирд░ - рд╕рдВрдХрд▓рд┐рдд рдлрд╛рдЗрд▓реЗрдВ ( рдмрд╛рдпрдЯреЗрдХреЛрдб )ред
- BinaryResourceScanner - рджреНрд╡рд┐рдЖрдзрд╛рд░реА рд╕рдВрд╕рд╛рдзрди рдЬреИрд╕реЗ рдмрд┐рдЯрдореИрдкреНрд╕ рдпрд╛
res/raw
рдлрд╛рдЗрд▓реЗрдВред - ResourceFolderScanner - рд╕рдВрд╕рд╛рдзрди рдлрд╝реЛрд▓реНрдбрд░ (рдЙрдирдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд╝рд╛рдЗрд▓реЗрдВ рдирд╣реАрдВ)ред
- XmlScanner - XML тАЛтАЛрдлрд╝рд╛рдЗрд▓реЗрдВред
- GradleScanner - рдЧреНрд░реЗрдб рдлрд╛рдЗрд▓ред
- OtherFileScanner - рдмрд╛рдХреА рд╕рдм рдХреБрдЫред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, Detector
рд╡рд░реНрдЧ рдПрдХ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЙрдкрд░реЛрдХреНрдд рдкреНрд░рддреНрдпреЗрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рд╕рднреА рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЦрд╛рд▓реА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдПрдХ рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдиреЗ рдкрд░ рдкреВрд░реНрдг рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдЕрдм рд╣рдо рдПрдХ рдбрд┐рдЯреЗрдХреНрдЯрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ рдЬреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рд╕рд╣реА рд╡рд┐рдзрд┐ рдХреЙрд▓ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдЧрд╛ред
private const val REPORT_MESSAGE = "Use setThrottlingClickListener" class CorrectClickListenerDetector : Detector(), Detector.UastScanner { override fun getApplicableUastTypes(): List<Class<out UElement>>? { return listOf<Class<out UElement>>(UCallExpression::class.java) } /** * UAST, , * UAST . UElementHandler, * , , * , , , , .. * , * . тАФ , * , , . */ override fun createUastHandler(context: JavaContext): UElementHandler? { return object: UElementHandler() { override fun visitCallExpression(node: UCallExpression) { if (node.methodName != null && node.methodName?.equals("setOnClickListener", ignoreCase = true) == true) { context.report(ISSUE_CLICK_LISTENER, node, context.getLocation(node), REPORT_MESSAGE, createFix()) } } } } private fun createFix(): LintFix { return fix().replace().text("setOnClickListener").with("setThrottlingClickListener").build() } }
рд░рдЬрд┐рд╕реНрдЯреНрд░реА
рдЖрдЦрд┐рд░реА рдЪреАрдЬ рдЬреЛ рд╣рдореЗрдВ рдХрд░рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рд╡рд╣ рд╣реИ рд╣рдорд╛рд░реА рд░рдЬрд┐рд╕реНрдЯреНрд░реА рдореЗрдВ рд╕рдорд╕реНрдпрд╛рдПрдВ рдЬреЛрдбрд╝рдирд╛ рдФрд░ рд▓рд┐рдВрдЯ рдХреЛ рдмрддрд╛рдирд╛ рдХрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕рдорд╕реНрдпрд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реА рд╣реИ рдЬрд┐рд╕реЗ рдЗрд╕реЗ рдорд╛рдирдХ рдПрдХ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
class MyIssueRegistry : IssueRegistry() { override val issues: List<Issue> = listOf(ISSUE_CLICK_LISTENER) }
build.gradle
рдореЙрдбреНрдпреВрд▓ рд╕реНрддрд░ рдореЗрдВ:
jar { manifest { attributes("Lint-Registry-v2": "co.infinum.lint.MyIssueRegistry") } }
рдЬрд╣рд╛рдВ co.infinum.lint
рдХреНрд▓рд╛рд╕ MyIssueRegistry
рдХрд╛ рдкреИрдХреЗрдЬ рд╣реИред рдЕрдм рдЖрдк gradlew
рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ jar
рдХрд╛рд░реНрдп рдХреЛ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА build/libs
рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗрдиреА рдЪрд╛рд╣рд┐рдПред
рдпрд╣рд╛рдБ рдПрдХ рд▓рд┐рдВрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдЬрд╛рдБрдЪ рдХрд╛ рдПрдХ рдФрд░ рдЙрджрд╛рд╣рд░рдг рд╣реИ, рдЬрд╣рд╛рдБ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ XML рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПред
рдХреЗ рдЙрдкрдпреЛрдЧ
рдЖрдкрдХрд╛ рдирдпрд╛ рд▓рд┐рдВрдЯ рдЪреЗрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред рдпрджрд┐ рдпрд╣ рдЪреЗрдХ рд╕рднреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ ~/.android/lint
рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ (рдпрджрд┐ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ рддреЛ рдЖрдк рдЗрд╕реЗ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ)ред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рдореЙрдбреНрдпреВрд▓ рдореЗрдВ рдЕрдкрдирд╛ рдЪреЗрдХ рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рдореЙрдбреНрдпреВрд▓ рдХреЛ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдирд┐рд░реНрднрд░рддрд╛ рдХреА рддрд░рд╣ рд╕рдХреНрд╖рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ lintChecks
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ред
рдХреНрдпрд╛ рдпрд╣ рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИ?
рд▓рд┐рдВрдЯ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдЙрдкрдХрд░рдг рд╣реИ рдЬрд┐рд╕реЗ рд╣рд░ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЕрдкрдиреЗ рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕рдВрднрд╛рд╡рд┐рдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдЬрд▓реНрдж рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдмрд╣реБрдд рдорджрджрдЧрд╛рд░ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХрд╕реНрдЯрдо рдЪреЗрдХ рд▓рд┐рдЦрдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ, рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рдПрдкреАрдЖрдИ рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдХрд╛рд░рдг, рд╡реЗ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рд▓рд╛рдпрдХ рд╣реИрдВ рдФрд░ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЖрдкрдХреЛ рдмрд╣реБрдд рд╕рдордп рдФрд░ рдкреНрд░рдпрд╛рд╕ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВред