Scala Corner Case#1: Implement Method of Java Interface with Type Parameter Omitted by It's Sub-Class
The progress of rewriting Erlang plugin for NetBeans in Scala has reached a phase, that the Editor itself works smooth and better than ErlyBird now, the next step is to integrate an Erlang project management and index the modules/functions of OTP/project to provide smart auto-completion.
Now Scala has been proved that it can be integrated into an existed large Java based framework (NetBeans IDE here) without no much problems, I'll begin to rewrite Scala plugin in Scala soon.
Although in most cases, Scala can call existed Java code or classes smoothly, there are still some corner cases. I'll record these corner cases in blogs. Here's the first one which I also posted on scala-user mailing-list, but have not yet got final answer.
Let's begin with a detailed example:
There is a Java interface A:
public interface A<T extends String> { void run(T t); }
Which has a type parameter <T extends String> and abstract method run(T t)
Then a Java abstract class B extended A. But, B, as it, omitted type parameter from A. This is unsafe but valid in Java:
public abstract class B implements A { public String me() { return "I'm B"; } }
Assume above classes A and B have been compiled under javac, and packed in a jar library, and I can not patch it anymore. Now I need to write a class S in Scala which should extend B:
class S extends B { override def run[T <: String](t:T) = {println(t)} }
scalac will complain as:
/Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:1: error:
class S needs to be abstract, since method run in trait A of type
(T)Unit is not defined
class S extends B {
/Users/dcaoyuan/NetBeansProjects/ScalaTestCase/src/S.scala:3: error:
method run overrides nothing
def run[T <: String](t:T) = {println(t)}
I than tried "forSome" type:
class S extends B { override def run(t:T forSome {type T <: String}) = {println(t)} }
The code still did not work.
It seems that, since B omitted A's type parameter T, I have no way to get what is T, and can not successfully implement "run(T t)" method.
I also tried other forms of "forSome" usages, and always failed.
But I think Scala can always be saved with mixed Java/Scala code in such corner case, that's what I believed. So, I thought about it later when my brain was spare, and finally got a solution:
I wrote another Java abstract class B1 which extends B and pretended to have implemented "run(T t)", but actually called another new abstract method "runImpl(String t)"
public abstract class B1 extends B { public void run(String t) { runImpl(t); } public abstract void runImpl(String t); }
Now I can let Scala S extends B1 and implement "runImpl(String t)" instead of extending B and implementing "run(T t)".
class S extends B1 { override def runImpl(t:String) = {println(t)} }
Yes, scalac won't complain about "runImpl(t:String)" at all, and I got S successfully extends B by bridge class B1.
But I still hope scalac can resolve it directly, with a warning message instead of failing to compile it.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/blog_logo.png)
rss
Comments
Hi Caoyuan, I am writing a Perl plugin 'nbPerl'. I am new to language plugin development, so I plan to imitate step by step your development of Erlang plugin, maybe even to the point of writing it in Scala. My question is, is CSL included in NetBeans 6.5? If not, how do I install the module? Please also provide any other pointers/tips that you deem helpful.
Z.S.
CSL is not moved to main trunk yet, you have to clone the branch: http://hg.netbeans.org/jet-parsing-api/ and work on it.
By working on it, do you mean, build the module? I tried to run ant in the csl.api directory, but it has failed to build with error. nbbuild/default.xml:50 taskdef class org.netbeans.nbbuil.JHIndexer cannot be found.
When I tried to build Netbeans by going into nbbuild folder and executing ant, I got errors of the form Element <a> doesn't support nested element of type <b>.
Z.S:
http://wiki.netbeans.org/WorkingWithNetBeansSources
I used to: ant clean; ant build to build whole IDE every week or so.
Z.S:
per <a href=" http://nbperl.blogspot.com/2009/02/using-csl-common-scripting-language-in.html">your blog entry</a>
My comment in BLOD means nothing, it was actually caused by you with a "<b>" at the end of your last comment input. I end it here with a "</b>"</b>
For your experience, I have no much idea, since I cannot tell you why your ant version shown 1.6.5, I even don't know your os environment, you should fix it first as 1.7.1 is a requirement.
BTW, the building process is about 1 hour, this also happens on me, that's life. And I've told you that I clean and build whole things every week.
Writing language supporting is a time-consumed work, it's boring and tied, whatever under Eclipse, under NetBeans, under IDEA.
Cheers, -Caoyuan