How to suppress spellcheck on a string constant in Android Kotlin? - android

Android Lint picks up the string constant in this code sample as a spelling error on "dWQGSCDx". According to the docs I should use #SupressLint("Typos") to suppress it but that doesn't achieve that. I see others have suggested using #SuppressWarnings but that is not working either.
/**
* Constants.kt
*/
import android.annotation.SuppressLint
#SuppressLint("Typos")
#SuppressWarnings("SpellCheckingInspection")
const val SOME_STRING_VALUE = "...dWQGSCDx..."
Note this is a file-scoped global constant, it is not inside a class so an annotation cannot be placed on a containing class.
How do I suppress spell-checking of this constant definition without disabling spellcheck entirely and without adding the "mispelt" text to the dictionary?

In Kotlin you can suppress this warning using #Suppress instead of #SuppressWarnings with the following annotation
#Suppress("SpellCheckingInspection")

Related

How to cast String to Input<String> - Kotlin

I am using GraphQL Apollo client call and it generates files. So as a result I got this
val storeNumber: Input<String> = Input.absent()
Instead of regular string. So how can I cast parameter to Input<String> to avoid this error
I don't use Apollo, but found the source code of Input. It depends what version of this library you're using. If you're using an older version, to wrap (not "cast"!) a String as an Input, use Input.Present:
storeNumber = Input.Present(storeNumber)
Note, the term "cast" means promising the compiler that your existing instance is also an instance of something else. That is very different from converting or wrapping an instance of something.
If you're using a newer version of the library, you shouldn't be using the Input class at all. It's been replaced with the Optional class, in which case you would use Optional.Present(storeNumber).
If you want to figure this kind of thing out on your own in the future, try Ctrl+Clicking the function you're working with to jump to its source code. In turn you can Ctrl+Click the types of the function parameters. That would take you to the source code of Input so you could see how to create an instance.

Can we add a #Suppress flag globally?

In kotlin, if we use a when block on an enum while exhausting all the enum values but without adding an else branch, we get this warning: "Enum argument can be null in Java, but exhaustive when contains no null branch".
Android Studio then suggest to add the suppress flag #Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA") either to the statement, function, class or file scope.
Is there any way to add this to the project scope ? Since my project is 100% Kotlin I don't need this warning and would like to disable it globally.

Package Level Protection in Kotlin [duplicate]

In Java, we have the package protected (default) modifier for classes, which allows us to have many classes in a single package but exposes only a few and keeps the logic encapsulated.
With Kotlin this doesn't seem to be the case. If I want a few classes to be visible to each other but no further, I have to use a private modifier which limits visibility to a single file.
So if you want 10 classes in a package but only one of them to be public, you'd have to have one huge file with all the classes in it (and private all over the place).
Is this normal practice or there is a way to achieve some similar modularity in Kotlin?
I don't understand: if they have the notion of a package, why did they get rid of package protected access?
Update: We might have package protected visibility after all
see the discussion here
Update: If you read through the discussion and still think this is a must-have feature for the language, please vote here
Kotlin, compared to Java, seems to rely on packages model to a lesser degree (e.g. directories structure is not bound to packages). Instead, Kotlin offers internal visibility, which is designed for modular project architecture. Using it, you can encapsulate a part of your code inside a separate module.
So, on top level declarations you can use
private to restrict visibility to the file
internal to restrict visibility to the module
At this point, there is no other option for visibility restriction.
As a workaround for me on android I've created #PackagePrivate annotation and lint checks to control access. Here you can find the project.
Lint checks are obviously not that strict as compiler checks and some setup needed to fail the build on errors. But android studio picks up lint checks automatically and shows error immediately while typing. Unfortunately I don't know a way to exclude annotated members from autocomplete.
Also, as lint is a purely compile-time tool, no checks at runtime performed.
As #hotkeys points out, you can use the internal keyword in a module or you can put all classes that would otherwise belong in a package inside a single file, but sticking several classes in a file may be a questionable design decision.
For me, the package visibility is helpful for its documenting value. I want to know what public interface some package is presenting to the rest of the project, hide factory implementation classes and so on.
So even if it's possible to access package-private classes and methods in Java, I still choose to use the package modifier.
For this I created a project with a single annotation:
package com.mycompany.libraries.kotlinannotations;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.SOURCE;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
#Documented
#Retention(SOURCE)
#Target({ TYPE, METHOD, CONSTRUCTOR })
/**
* Use in Kotlin code for documentation purposes.
*
* Whenever a Kotlin class or method is intended to be accesible at package level only.
*
*/
public #interface PackagePrivate {
}
Then I can use this annotation in any Kotlin project.
The second step, which I haven't done yet, is creating a PMD rule to enforce this with maven (or any other build tool for that matter) and also be able to see violations of the rule in my IDE with the pmd plugin.
There no is full Kotlin support in pmd at this moment but it seems to be expected at some point.
A near-replacement for package private visibility is available using the opt-in requirements feature (credit to pdvrieze on Kotlin discussions). This is the annotation syntax typically used to flag experimental features in an API.
To use it, create an annotation denoting package private declarations:
#RequiresOptIn(message = "Only to be used in MyPackage")
#Retention(AnnotationRetention.BINARY)
annotation class MyPackagePrivate
Then annotate any methods you want to be package private with it:
#MyPackagePrivate
fun aPackagePrivateMethod() {
// do something private within a package
}
In this way a warning will be generated on any method that calls the annotated method unless the calling method is itself annotated with the corresponding #OptIn annotation, here shown at class level:
#OptIn(MyPackagePrivate::class)
class AClassInThePackage {
fun userOfPackagePrivateMethod() {
aPackagePrivateMethod()
}
}
This, then, produces a similar effect to Java's package private, except that calling methods need to explicitly opt in to using a package private declaration.
If it is desired to generate an error rather than a warning, the level parameter of #RequiresOptIn can be specified:
#RequiresOptIn(level = RequiresOptIn.Level.ERROR, message = "Only to be used in MyPackage")
// annotation declaration as before
Package-based protection is pointless in Kotlin because packages themselves are unprotected
In Java, package was tied to directory structure. So if you put your classes in com\example\yoursecretengine, any attempt (deliberate or accidental) to add a rogue class there would be easily noticeable. This is the kind of security we've depended on.
Kotlin removes the ties between directory and package, so I can put my class in "my" directory (eg.src\java\pl\agent_l\illegalaccess) yet declare its package as com.example.yoursecretengine - and gain access to all the properties you've meant as package private.
In fact, a Kotlin project works perfectly without ANY package declarations. This only highlights that packages are "more what you'd call guidelines than actual rules". They're a convenience feature, useful only to unclutter namespace and nothing more.
Relevant quotes from kotlinlang:
unlike many other languages, Kotlin packages do not require files to have any specific locations w.r.t. itself; the connection between a file and its package is established only via a package header.
And:
an absence of a package header in a file means it belongs to the special root package.

How to configure lint to ignore specific cases?

Sometimes lint produces false warnins if field is operated via bunch of annotations. For a common example:
#SerializedName("id") #Expose private Integer id;
field id is assigned only via gson.fromJson(). Such operation is invisible for lint, thus it throws warning variable id is never assigned
So I want to configure lint, in this particular case, to ignore checks if field is ever assigned, if it is annotated with #SearializedName (please dont suggest raw #SuppressWarnings("unused") which has to be set manualy for every field and will block checks, if field is ever used)
Gson serialises fields using reflection, which takes place at runtime. That UnusedAssignment inspection finds variables which meet any of the following criteria:
the variable never gets read after assignment
the value is always overwritten with another assignment before the next variable read
the variable initializer is redundant (for one of the above two reasons) - the variable is never used.
Your only option to get rid of warnings for this specific inspection is to suppress them, either by updating your lint.xml, or via #SuppressWarnings("unused"). If you really don't want to do either of those things, then it may be possible to write a custom Lint inspection that ignores fields with a #SerializedName annotation.
The disadvantage of this approach is if you want to use #SerializedName in a class that isn't serialised by Gson, you will no longer get a warning if a variable is unused. It is also much more complicated than adding #SuppressWarnings("unused") to the top of your GSON model classes.

Android ActivityMontior with XTend

I am trying to write an Android app using Xtend, however, I am more or less new in both. I have created a couple of Android examples with Java, but I'm still learning.
In these apps i used the android.app.Instrumentation.ActivityMonitor
in order to check that an Activity had started.
I have read that Xtend does not support Nested classes
No var args, no nested classes, no anonymous classes?
Those language features are not mentioned in the docs, and I could not guess a valid syntax. >I assume they are not available, but I could be wrong.
http://blogs.atlassian.com/2011/11/xtend-first-impressions/
Does this mean the ActivityMonitor cannot be accessed when using Xtend or am I just doing something wrong?
It depends how you used the ActivityMonitor. You cannot define inner classes on your own right now, but static inner classes can be accessed from within Xtend. There are issues with non-static inner classes. The syntax is different to Java, though. Instead of the '.' dot as the delimiter of declaring class and inner class, Xtend uses the '$'. A respective import declaration can ease the pain, here, e.g. import android.app.Instrumentation$ActivityMonitor.

Categories

Resources