tags:

views:

112

answers:

2

I'm developing a code generator that will output the following classes/objects:

class A {
   var a : Int = _
   var b : B = _

   class B {
    var b : Int = _
    var c : C = _

    class C {
      var c : Int = _
    }
  }
}

object A {
  val a = ...
  object B extends Base {
    val b = ...
    object C extends Base {
      val c = ...
    }
  }
}

with the user constructing the terms like this:

A (
  a(1),
  B (
    b(2),
    C (
      c(3)
    )
  )
)

Now in order to make it work I have to insert 3 imports in the user code:

import A._
import A.B._
import A.B.C._

This looks ugly to me. May be there is another way to tackle the problem that I'm just blind to see?

Thank you in advance.

+1  A: 

After import A._ B will be in the import scope (at least in Scala 2.8), so you can spare a few letters:

import A._
import B._
import C._
Debilski
Thank you, I'm aware of that. Still it doesn't make things significantly better.
venechka
+1  A: 

You could use defs in your generated code. For example,

object A {
    // ... other code

    def b = B.b   
    def C = B.C
    def c = C.c
}
Aaron Novstrup
That's almost all right, but it makes the structure flat and also not possible if the names clash.
venechka
Hmm, I guess I'm not clear on what you want to achieve. Could you post an example of how clients use the generated code? If I'm reading question correctly, the "user constructing the terms like this" section shows how a user determines what code will be generated, and then a subsequent client will use that generated code by importing the generated `A._`/`B._`/`C._` methods.
Aaron Novstrup
You are right. When I say "the structure is flat" I mean all the nested attributes are visible at toplevel, where they don't make sense, it is sensible to use say C.c only inside B. Also my second objection is when B has a field named 'a' so it cannot be placed together with A.a.
venechka
I fully understand your objections, but I'm apparently missing what you're trying to achieve as an alternative. I thought your question was how to surface the nested methods without requiring 3 separate imports (i.e. with just one import). Using 3 imports also "flattens" the structure and introduces name clashes (which the compiler resolves by using the most recently imported name). With `def`s, you can flatten as much or as little as you like, and you can avoid name clashes by a) using aliases or b) omitting some of the `def`s that would otherwise result in a clash.
Aaron Novstrup
Again, it might help if we could see how you envision clients using the generated code.
Aaron Novstrup