Array[Nothing with java.lang.Object] required in Scala 2.9.1 - arrays

I have a weird compilation error. The offending lines are:
val comboBoxLanguage = new javax.swing.JComboBox
//...
comboBoxLanguage.setModel(new javax.swing.DefaultComboBoxModel(
Array[Object]("Scala", "Java")))
and the error:
error: type mismatch;
found : Array[java.lang.Object]
required: Array[Nothing with java.lang.Object]
Note: java.lang.Object >: Nothing with java.lang.Object, but class Array is invariant in type T.
You may wish to investigate a wildcard type such as `_ >: Nothing with java.lang.Object`. (SLS 3.2.10)
comboBoxLanguage.setModel(new javax.swing.DefaultComboBoxModel( Array[Object]("Scala", "Java")))
According to JavaDoc the constructor of DefaultComboBoxModel expects an Object[], which can be a String[] or whatever array type in Java, since arrays are covariant, but in Scala they are not, so we have to use Array[Object], which shouldn't be a problem.
Why is the compiler expecting Array[Nothing with java.lang.Object]? How can I fix it?
This seems to be new with version 2.9.1 of Scala. My application used to compile until I installed 2.9.1 a couple of days ago. A confusing / worrying thing is that I haven't changed the project compiler library version in IntelliJ, but somehow it seems to be using it, perhaps grabbing it from my SCALA_HOME environment variable?

I think it is not an issue of scala 2.9.1 but new JDK. In JDK7 JComboBox is generic and in your code it is JComboBox[Nothing]. You should explicitly declare comboBoxLanguage variable as
val comboBoxLanguage = new javax.swing.JComboBox[Object]

Related

Why can’t back ticks be used to extract type defination in Typescript

I ran in to the following situation and I couldn't find the possible reason the caused error (TS1005: ']' expected.).
interface IconProps0 {
size: string,
type: string
}
interface IconProps {
iconType?: IconProps0[`type`]; // use backtick - TS1005: ']' expected.
iconSize?: IconProps0['size']; // use single quote
}
It works fine with TypeScript version 4.6 but version 3.9 throws the error. Can the older version of TypeScript just fail to understand the syntax?
Edit
Add the minimal reproducible example
Template literal types of the form `foo${Bar}` were introduced in TypeScript 4.1 and cannot be used in earlier versions. They are useful for string interpolation / substitution / manipulation at the type level, and are overkill for just plain string literals.
On the other hand, string literal types of the form "baz" or 'baz' were introduced in TypeScript 1.8. Unless you need to manipulate strings at the type level, you should probably just use these.

Kotlin: Type inference failed: Not enough information to infer parameter E in fun <E> <init>(): kotlin.collections.ArrayList<E>

I declared a variable like this:
var G: Array<MutableList<Int>> = Array(0) { ArrayList() }
Kotlin gives me the following error:
Kotlin: Type inference failed: Not enough information to infer parameter E in fun <E> <init>(): kotlin.collections.ArrayList<E> /* = java.util.ArrayList<E> */
Please specify it explicitly.
It means Kotlin can't infer the type for the ArrayList which should be Int. So I add Int explicitly for the ArrayList like following:
var G: Array<MutableList<Int>> = Array(0) { ArrayList<Int>() }
Kotlin says - Remove explicit types arguments
In this case, Kotlin is ambivalent about how to act.
So is it possible to write code without explicitly declaring the type of ArrayList?
As discussed here,
The way it works curretly is that whenver we encounter a collection in Kotlin, we load a Kotlin version of this class (e.g. kotlin.Collection) instead of a Java version (java.util.*). Using the type java.util.Collection leads to a warning from the Kotlin compiler, because Kotlin's type checker is designed to distinguish between read-only and mutable collections.
So you can try to use like this,
var G = arrayOf<MutableList<Int>>()
Moreover, here are some a good stuff to know for you.
Kotlin says - Remove explicit types arguments
Kotlin doesn't (you can see there's no warning in https://pl.kotl.in/7v1h5Yobu). It's probably the IDEA plugin which does. If you look at https://youtrack.jetbrains.com/issues/KT?q=Remove%20explicit%20types%20arguments, you can see there are quite a few false positives. It may be worth checking if yours is actually one of them and posting a new issue if it isn't.
var G = Array<MutableList<Int>>(0) { ArrayList() }
should work without warning from IDEA either.

Can type mismatch error from VBScript caused by assessing non-variant array returned by COM interface be resolved by changing languages?

I am using a windows application that provides a COM interface for extension scripts. The scant documentation provides a few examples in VBScript so I started implementing my automation in VBScript.
This would look something like:
Set App = GetObject(, "MYAPP.Application")
MyObj = App.Object
MyArr = MyObj.ArrData
IsArray(MyArr) ' True
TypeName(MyArr) ' Long()
Lbound(MyArr) ' 0
Ubound(MyArr) ' 10
MyArr(1) ' Type Mismatch Error
On closer inspection, the array object is of type Long() (Array of Longs). After researching the problem, it is my understanding that VBScript cannot access elements of an array by index unless the array is of type Variant; that this is a limitation of VBScript as a language. I am not able to implement changes as in this answer because I don't have source access to the application I am trying to extend.
Is the error I am seeing purely a limitation of the language? Will I be able to access the array variables returned by the COM interface by porting my code to another language like C#, for example?
I have confirmed that porting to C# solves the type mismatch error encountered when accessing non-variant array data returned by the COM interface without requiring any change to the COM server.
After including the appropriate references, the code becomes:
var app = (MYAPP.Application)Microsoft.VisualBasic.Interaction.GetObject(null, "MYAPP.Application");
var myObj = (MYAPP.Obj) app.GetObject();
var myArr = (int[]) myObj.GetArrData();
if (myArr.Length() > 0)
{
System.Console.WriteLine(myArr[0]); // prints value at index 0 without error
}
The limitation is therefore with VBScript; the type mismatch is due to the language being able to handle only variant type arrays.

Swift 4.1.2 Autocomplete: Suggesting extensions on Array that it shouldn't

Maybe I'm going crazy here, but extension Array where Element == String in Swift 4.1.2 is exposing its properties in Swift's autocomplete on types when it should not be there.
For example, this extension:
extension Array where Element == String {
public var test: [String] {
return ["test"]
}
}
Then start typing:
[123].te ...
and Swift suggests that the test property is also available on [Int] which is impossible. Then the syntax checker pops up the error:
Type of expression is ambiguous without more context
Is there something I'm missing? Perhaps some other/additional conformance restrictions that need to be used? Or is this a Swift bug?
It appears to be a bug.
This Swift.org bug report demonstrates the same behavior:
https://bugs.swift.org/browse/SR-5388

How to serialize/unserialize an Array of Custom object in Kotlin?

In my Kotlin Android project, I made a FileItem class which extends Serializable
class FileItem(<parameters>) : Serializable, Comparable<FileItem> {
So I needed to Serialize instances of this class into a Bundle
val arguments:Bundle = Bundle()
arguments.putSerializable("folders", folders as Serializable)
where folders has been declared as :
folders:Array<FileItem> (method parameter)
The serialization code above compile without any warning. Meanwhile, the problem comes when I need to unserialize folders items :
val arguments: Bundle? = getArguments()
if (arguments != null){
foldersItems = arguments.getSerializable("folders") as Array<FileItem>
where foldersItems is declared as
var foldersItems: Array<FileItem>?
I get the following warning, that I can't manage to solve without suppress_warning annotation :
w: <Path to my class>: (78, 28): Unchecked cast: java.io.Serializable! to kotlin.Array<com.loloof64.android.chess_positions_archiver.main_file_explorer.FileItem>
This kind of code compiles in Java/Groovy without warning (folderItems is then a FileItem[]), so how can I modify the kotlin code for the compiler to be "satisfied" ?
I noticed in official Kotlin documentation that Kotlin Array does not extend Serializable and is not open for inheritance. Is it possible meanwhite to "add" it via a kind of extension method ?
In fact, the cast is not unchecked, the compiler's warning is misleading.
This happens because in Kotlin arrays are represented by generic class Array<T>, and the compiler treats it as usual generic class with type parameters erased at runtime.
But on JVM arrays have reified types, and when you cast something as Array<SomeType>, the generated bytecode really checks the type parameter to be SomeType as well as something being an Array<*>, which would only happen for any other generic class.
This example shows that the array cast is checked:
val a: Any = Array<Int>(1) { 0 }
val i = a as Array<Int>
val d = a as Array<Double> // gets checked and throws ClassCastException
The easiest solution is indeed to #Suppress("UNCHECKED_CAST"), because actually there should not be any warning.
I filed an issue describing the problem in Kotlin issue tracker.
The cast here is unchecked because the compiler here can't ensure the nullability of array's generic type parameter.
Consider the following example:
fun castAsArrayOfString(param: Any) = param as Array<String>
castAsArrayOfString(arrayOf("a")) // is Array<String>, all ok
castAsArrayOfString(arrayOf("a", null)) // is Array<String>, but contains null
So the compiler warns you about potential type safety problems this cast could introduce.

Resources