Mark unused parameters in Kotlin - suppress-warnings

I am defining some functions to be used as callbacks and not all of them use all their parameters.
How can I mark unused parameters so that the compiler won't give me warnings about them?

With the #Suppress annotation You can suppress any diagnostics on any declaration or expression.
Examples:
Suppress warning on parameter:
fun foo(a: Int, #Suppress("UNUSED_PARAMETER") b: Int) = a
Suppress all UNUSED_PARAMETER warnings inside declaration
#Suppress("UNUSED_PARAMETER")
fun foo(a: Int, b: Int) {
fun bar(c: Int) {}
}
#Suppress("UNUSED_PARAMETER")
class Baz {
fun foo(a: Int, b: Int) {
fun bar(c: Int) {}
}
}
Additionally IDEA's intentions(Alt+Enter) can help you to suppress any diagnostics:

If your parameter is in a lambda, you can use an underscore to omit it. This removes the unused parameter warnings. It will also prevent IllegalArgumentException in the case that the parameter was null and was marked non-null.
See https://kotlinlang.org/docs/reference/lambdas.html#underscore-for-unused-variables-since-11

If the functions are part of a class you can declare the containing class open or abstract and the offending methods as open.
open class ClassForCallbacks {
// no warnings here!
open fun methodToBeOverriden(a: Int, b: Boolean) {}
}
Or
abstract class ClassForCallbacks {
// no warnings here!
open fun methodToBeOverriden(a: Int, b: Boolean) {}
}

One can disable these warnings by adding a kotlin compile option flag in build.gradle.
To configure a single task, use its name. Examples:
compileKotlin {
kotlinOptions.suppressWarnings = true
}
compileKotlin {
kotlinOptions {
suppressWarnings = true
}
}
It is also possible to configure all Kotlin compilation tasks in the project:
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
// ...
}
}
If one is using kotlin in Android and want to suppress kotlin compiler warnings, add below in app-module build.gradle file
android{
....other configurations
kotlinOptions {
suppressWarnings = true
}
}
Whether you really need to suppress all kotlin warning for your project or not, its up to you.

Related

Correct method signature for RichGroupReduceFunction?

The below extended class of RichGroupReduceFunction, does not compile. The signature seemingly does not match the interface. I can't tell the difference.
class SPointReduce extends RichGroupReduceFunction[Int, Int] {
override def reduce (
values: Iterable[Int],
out: Collector[Int]): Unit = {
values.foreach {
value: Int =>
out.collect(value)
}
}
}
The compiler reports:
Error:(62, 16) method reduce overrides nothing.
Note: the super classes of class SPointReduce contain the
following, non final members named reduce: def reduce(x$1:
Iterable[Nothing],x$2: org.apache.flink.util.Collector[Nothing]): Unit
override def reduce (
You have to make sure that you import the java.lang.Iterable when you override the reduce method of RichGroupReduceFunction. Otherwise, you will get the above mentioned error.

Method parameters with type like { def foo() }

While scanning through dispatch code base, I noticed a method is defined like this:
def pack[T](req: { def abort() }, result: => T): HttpPackage[T]
The type annotation { def abort() } looks very strange to me. I thought it might be some thing similar to duck typing, so I tried to pass with some thing like object bar { def foo = print("Hello, world!") } but the compiler still complain type mismatched. I googled but couldn't find any article mention about it.
Does anyone know about this type annotation and its use cases?
Thanks in advance.
This defines a parameter req with a structural type i.e. a type defined by the existence of certain members. In this case any type with an abort() method. You can't pass bar since it does not have such a method. If you defined it as:
object Bar {
def abort(): Unit = print("Aborting!")
}
then you can pass it to pack:
pack(Bar, { ... })
This is known as structural typing in the Scala world, or more colloquially, as duck typing. From the linked article:
def quacker(duck: {def quack(value: String): String}) {
println (duck.quack("Quack"))
}
object BigDuck {
def quack(value: String) = {
value.toUpperCase
}
}
quacker(BigDuck)
so your method above will accept any object that defines an abort() method, without implementing a specific interface/trait.
This is particularly useful for handling sets of classes that implement the same methods without a common interface/trait, and that you can't retrofit an interface over (e.g. from legacy apps/libraries)

Scala: "No manifest available for type T"

I am working on a Lift project with mixed Scala and Java code.
On the Java side, I have the following relevant items:
interface IEntity
interface IDAO<T extends IEntity> {
void persist(T t);
}
On the Scala side, I have the following:
abstract class Binding[T <: IEntity] extends NgModel {
def unbind: T
}
class BasicService[E <: IEntity](serviceName: String, dataAccessObject: IDAO[E]) {
def render = renderIfNotAlreadyDefined(
angular.module("myapp.services")
.factory(serviceName,
jsObjFactory()
.jsonCall("persist", (binding: Binding[E]) => { //<---COMPILATION ERROR
try {
dataAccessObject.persist(binding.unbind)
Empty
} catch {
case e: Exception => Failure(e.getMessage)
}
})
)
)
}
This code will not compile. I get the following error at the point indicated above:
No Manifest available for Binding[E].
It is not clear at all to me why this occurs, but I am guessing it has something to do with this being a nested method invocation. The code compiles fine if I declare a member function with Binding[E] as a parameter, for example:
def someFunction(binding: Binding[E] = { // same code as above }
Why does this happen, and how can I work around it?
Turns out this is relatively easily solved by implicitly passing on the manifest for the type in question, either in the constructor or the method itself:
class BasicService[E <: IEntity](serviceName: String, dataAccessObject: IDAO[E])(implicit m: Manifest[Binding[E]]) {
or
def render(implicit m: Manifest[Binding[E]])

Why can't I use this.getClass in auxiliary constructor in scala?

Why can't I use this.getClass in auxiliary constructor in scala? Are there any alternatives?
More specifically, I am trying to call LoggerFactory.getLogger of slf4j in the auxiliary constructor. I have an hack now where I am forced to pass a logger object to the constructor.
A simple contrived example (does not compile) which shows what I am trying to do:
class A (numbers : Double) {
val logger = LoggerFactory.getLogger(this.getClass)
def this(numbersAsStr: String) = this (try { s.toDouble) } catch { case _ => LoggerFactory.getLogger(this.getClass).error("Failed to convert"); 0 }
}
This is actually a limitation of the JVM rather than specifically a Scala problem. Here's a similar example in Java:
public class ThisTest {
public final String name;
public ThisTest(String n) {
name = n;
}
public ThisTest() {
// trying to use `this` in a call to the primary constructor
this(this.getClass().getName());
}
}
When you try to compile it you get an error:
$ javac ThisTest.java
ThisTest.java:10: error: cannot reference this before supertype constructor has been called
this(this.getClass().getName());
^
1 error
The problem is that you're trying to reference this before this any of the super-constructors for this have been called. You will have the restriction that you can't use a this reference in a super() or this() call no matter what JVM language you use, because that's the way classes work on the JVM.
However, you can totally avoid this problem by restructuring your code to put the reference to this after the this() call:
class A (numbers: Double) {
val logger = LoggerFactory.getLogger(this.getClass)
def this(numbersAsStr: String) = {
this ( try { numbersAsStr.toDouble } catch { case _ => 0 } )
LoggerFactory.getLogger(this.getClass).error("Failed to convert");
}
}
You might actually want access to the thrown exception for your log info. In that case, I'd just use LoggerFactory.getLogger(classOf[A]). That won't give you the actual class name if you're using inheritance (which I was assuming was the case here), but if you include the stack trace in the log then you should be able to figure it out.
Not sure I understand the question. Here is a guess:
class Foo(val c: Class[_]) {
def this() = this(classOf[Foo])
}
new Foo().c // -> class Foo

Manifest[T].erasure is deprecated in 2.10, what should I use now?

I have the following code:
object Log {
def get[T](implicit manifest : Manifest[T] ) = {
LoggerFactory.getLogger( manifest.erasure.getName )
}
def getByName( name : String ) = {
LoggerFactory.getLogger(name)
}
}
The idea is to use it like this:
object SimpleFuture {
val log = Log.get[SimpleFuture[Throwable,Nothing]]
}
But the compiler (2.10) now says that manifest.erasure is deprecated. What should I use now for this same functionality?
The simplest fix is to replace the call to erasure with a call to runtimeClass. If you run with -deprecation, the compiler actually gives that recommendation:
warning: method erasure in trait ClassManifestDeprecatedApis is deprecated: Use runtimeClass instead
Alternatively, you can use a class tag:
def get[T](implicit tag : reflect.ClassTag[T] ) = {
LoggerFactory.getLogger( tag.runtimeClass.getName )
}
This alternative is more future proof than using Manifest. Manifest is due for deprecation in 2.10.something or soon after. See the "Type Tags and Manifests" section of this document for more info.
If, like me, you're only interested in avoiding deprecation warnings then you can also use manifest.runtimeClass.getName (instead of manifest.erasure.getName).
IE:
def classOp[T](implicit manifest: Manifest[T]) {
println("Class: " + manifest.runtimeClass.getName)
}
I've also found another technique which I don't fully understand and may or may not be useful...
def classOp[T <: Any : Manifest] {
println("Class: " + manifest[T].runtimeClass.getName)
}