為さねば成らぬ

retia.verno@gmail.com

[Android] (WIP) Android LintのDetectorを読む Day3: AllCapsDetector

ソースコード

https://cs.android.com/android-studio/platform/tools/base/+/mirror-goog-studio-main:lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks/AllCapsDetector.kt

背景

TextViewでtextAllCaps=trueだとテキストに含まれるマークアップが落ちるためチェックしている。 が、実際マークアップが落ちるが何を指しているのかよくわからなかった。要継続調査。

  1. TextView.getTextしたときにマークアップのタグがなくなる?
  2. textAllCapsを変えても、タグが消えるのは同じ

  3. マークアップが効かなくなる?(指定しても太字じゃなくなる)

  4. textAllCaps=trueにしてもマークアップは効いていた

更に、マークアップのテキストをResourceに入れて渡すとこのlintに引っかかるのにResourceに入れずに直だと引っかからなかった。 Resourceに入れずに直だと別のlintで引っかかるため?

気づき

Layoutに対してはLayoutDetectorを用いる

LayoutDetector -> ResourceXmlDetector -> XMLScanner と継承されており、XMLの各要素にアクセス出来るようになっている LayoutDetector を継承し判定を行う。

attributeを判定するときはNSも確認する

    override fun visitAttribute(context: XmlContext, attribute: Attr) {
        if (ANDROID_URI != attribute.namespaceURI) {
            return
        }

attr名が合っててもNameSpaceが異なることがあるのでチェックする

resourceの値を取得する方法

        val client = context.client
        val full = context.isGlobalAnalysis()
        val project = if (full) context.mainProject else context.project
        val repository = client.getResources(project, ALL_DEPENDENCIES)
        val items = repository.getResources(ResourceNamespace.TODO(), url.type, url.name)
        if (items.isEmpty()) {
            return
        }
        val resourceValue = items[0].resourceValue ?: return
        val rawXmlValue = resourceValue.rawXmlValue ?: return

TODOとなっているが実態はRES_AUTOで、これは http://schemas.android.com/apk/res-auto のこと。 名前空間の追跡を用意にするためにログを追加で出してるだけっぽい。

rawXmlValueにテキストが入っているので、そのテキストに対してマークアップがあるか ( < が含まれているか) で判定している。