Skip to content

Instantly share code, notes, and snippets.

@amlcurran
Created January 21, 2021 10:42
Show Gist options
  • Save amlcurran/aaecb3fcc10236be3d7a5a677a96ce3f to your computer and use it in GitHub Desktop.
Save amlcurran/aaecb3fcc10236be3d7a5a677a96ce3f to your computer and use it in GitHub Desktop.
action_sheet_warning:
name: "Action sheets must define a source view and rect, or barButtonItem"
message: "Action sheets on iPad will crash unless they have a source view and rect, or a source barButtonItem on their popoverPresentationController. If you have done this, you can suppress this warning but not before (swiftlint:disable:this action_sheet_warning)."
regex: "UIAlertController\\(.*, preferredStyle: .actionSheet\\)"
severity: warning
package io.freetrade.lintrules
import com.android.tools.lint.client.api.UElementHandler
import com.android.tools.lint.detector.api.Category
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.JavaContext
import com.android.tools.lint.detector.api.LintFix
import com.android.tools.lint.detector.api.Scope
import com.android.tools.lint.detector.api.Severity
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UElement
class LokaliseStyledAttributeLintRule : Detector(), Detector.UastScanner {
override fun getApplicableUastTypes(): List<Class<out UElement>>? {
return listOf(UCallExpression::class.java)
}
override fun createUastHandler(context: JavaContext): UElementHandler? = Finder(context)
companion object {
val LOKALISE_STYLED_ATTRIBUTE = Issue.create(
"StringFromAttributes",
"Strings from attributes can't be replaced at runtime",
"Lokalise won't replace strings retrieved by attributes. Fetch the resource ID from the attributes and use resources.getString() on that.",
Category.I18N,
8,
Severity.ERROR,
Implementation(LokaliseStyledAttributeLintRule::class.java, Scope.JAVA_FILE_SCOPE)
)
}
}
private class Finder(private val context: JavaContext) : UElementHandler() {
override fun visitCallExpression(node: UCallExpression) {
if (node.isCallWeShouldWarnOf()) {
val attributeArgument = node.firstArgumentName()
context.report(
LokaliseStyledAttributeLintRule.LOKALISE_STYLED_ATTRIBUTE,
context.getLocation(node),
"String from attribute $attributeArgument is not replaceable by Localize.",
fixFor(node)
)
}
}
private fun UCallExpression.firstArgumentName() = valueArguments.firstOrNull()?.asRenderString()
// Warn for TypedArray.getString(int)
private fun UCallExpression.isCallWeShouldWarnOf(): Boolean {
val receiverClass = receiverType?.getCanonicalText(false) ?: ""
return receiverClass.contains("TypedArray") && methodName == "getString"
}
private fun fixFor(node: UCallExpression): LintFix = LintFix.create()
.name("Fetch via Resources instead")
.replace()
.autoFix()
.reformat(true)
.shortenNames()
.with("${node.receiver?.asRenderString()}.getStringFromResources(resources, ${node.firstArgumentName()})")
.build()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment