Java Layers Release Notes
Java Layers Home

JL Download

Installation Notes

Release Notes

Quick Reference

Code Generation

 

JL 0.37

The limitations and restrictions described for Release .21b still apply for this release, but the following enhancements and changes were made:

  1. Fixed constructor propagation bug.
  2. Made -JavaCompAll the default compiler option.  Added -JavaCompRoot compiler option for support of old default behavior, which passes only the root generated source file to javac.

JL 0.35

The limitations and restrictions described for Release .21b still apply for this release, but the following enhancements and changes were made:

  1. Race condition between jlc and javac processes eliminated.
  2. Improper scoping of exception variable in catch clauses fixed.
  3. Better error handling for duplicate field declarations.

JL 0.33

The limitations and restrictions described for Release .21b still apply for this release, but the following enhancements and changes were made:

  1. Support for This usage in inheritance clauses of nested types.  For example, the following declaration defines Inner1 to be the subclass of the most refined subclass of Outer1 defined in an instantiation.  The implicit This type parameter refers to the This-binding of Outer1, which can be Outer1 or a subclass of Outer1.

    class Outer1<>
    {
      static class Inner1 extends This {}
    }
     

    Using This, a nested class can be defined to inherit from the most refined subclass of a sibling nested class.  In the example below, InnerB does not inherit from its sibling InnerA.  Instead, the specification of This.InnerA means that InnerB inherits from the InnerA of the most refined subclass Outer2 generated by an instantiation.  

    class Outer2<>
    {
      static class InnerA {}
      static class InnerB extends This.InnerA {}
    }


  2. Fixed a number of bugs, including one that broke method overloading.

JL 0.30

The limitations and restrictions described for Release .21b still apply for this release, but the following enhancements and changes were made:

  1. Support for the Sibling pattern.  The Sibling pattern describes an inheritance relationship between sibling types nested in the same type.  The relationship allows one sibling to inherit from a subtype of the other sibling.  

    For example, the following code implements the Sibling pattern.  First, Parent.Inner1 and Parent.Inner2 are siblings.  Second, Parent.Inner2 extends Child.Inner1, a subclass of Parent.Inner1, completing the Sibling pattern.

    public class Parent
    {
     public static class Inner1 {}

     public static class Inner2
      extends Child.Inner1 {}
    }  

    public class Child
    {
     public static class Inner1
      extends Parent.Inner1 {}

     public static class Inner2
      extends Parent.Inner2 {}
    }

    In JL, mixins can be used with the Sibling pattern to create flexible inheritance hierarchies among sibling types.

  2. Added the -JavaCompAll compiler option, which instructs jlc to invoke javac and explicitly list all source files in the invocation string.  This option can be used with code that implements the Sibling pattern described above so that the standard javac compiler will successfully execute. 

  3. jlc no longer deletes .class files during compilation.  Name mangling, nested types and the possibility that programmers use the dollar sign in type names makes the explicit deletion of class files non-trivial.  Programmers can always delete class files before invoking jlc.  jlc continues to delete X.java when compiling X.jl, and class files are overwritten when the javac compiler is invoked.   

  4. CLASSPATH and SOURCEPATH values are only included in the javac invocation string if they were explicitly specified on the jlc command line.

  5. Other minor changes.

 

JL 0.21b

The .21b release of JL represents the first release that contains a reasonable implementation of all planned features.  The Limitations list enumerates significant limitations of the current implementation.  The Restrictions list enumerates less important support issues.  

Limitations

  1. Expression types are not resolved.

    This implementation limitation means that instantiations of parametric types cannot be used in all places that non-parametric type names can be used. 

    In JL, type names that appear in JL source code are resolved when their fully-qualified class or interface names are known.  Once type names are fully-qualified, some representation of the type can be loaded or generated by the compiler.  

    JL currently resolves all names that appear in statements that require types, such as inheritance clauses of class or interface declarations, field declarations, formal parameter declarations, etc.  In each of these cases, the source code name appears in a statement, not an expression.  To resolve these name, JL does not have to resolve references to fields, local variables or methods.

    For our current experiments with JL this is sufficient, so JL doesn't attempt to resolve names in expressions.  This means that instantiations of parametric types that appear in expressions are not currently processed.  Below are examples of statements that contain expressions that JL does not process.

    fld.m().Inner<int>.m2();
    fld.m().Inner<int>.x = 7;
    if (fld.Inner2<String>.bool) {}


    The instantiation of parametric types in each of the above expressions will be disallowed by JL, assuming "fld" represents some field reference.

  2. Partial support for non-static nested parametric classes.

    Limitation 1 described above effects JL's ability to fully support non-static nested parametric classes, which are often called inner classes in Java.  JL compiles inner classes correctly, but it cannot compile allocation statements of inner class objects because these statements use the qualified form of new.  Qualified new calls require field references to be resolved, something JL doesn't do yet.

    The following code, which assumes parametric type Outer<T> has an inner class named Inner<U>, illustrates the limitation in the current version of JL:

    Outer<int> outer = new Outer<int>();
    Outer<int>.Inner<String> in = outer.new Inner<String>();


    JL compilation will fail on the second line of code because Inner can't be resolved given that "outer.new" is not used in resolution process.  There is, however, a work-around for this problem, which is described in detail for those that need to use parametric inner classes.  

  3. The JL Semantic Checking language feature is not implemented.

    The requires and provides are, however, reserved keywords.

  4. JL doesn't write extended attributes to class files.

    JL-specific data known at compile time is not saved to the bytecode files that are ultimately generated.  This often means that unless the JL source code is recompiled, some important information is lost.  For example, class files contain no information about which constructors are propagatable.

    Here's a list of some of the JL information that should be added to class files as extended attributes for use by jlc and other JL utilities:

    - Unmangled instantiation name.
    - Constructor propagation information.
    - Nested class propagation information.
    - Semantic checking information.

Restrictions

  1. JL source files cannot contain more than one top-level type declaration.

  2. Local classes cannot be parameterized.

    Allow parameterized local classes seems like overkill and more complication than any programmer really needs. There are also technical challenges involving naming if this
    were to be allowed.

  3. Other restrictions on local classes.

    Anonymous classes observe restrictions that apply to all local classes.  The restrictions are that local classes:

    - Cannot be parameterized (as mentioned above).
    - Cannot use unqualified This or propagate in their bodies.
    - Cannot use provides or requires.

    On the other hand, local classes:

    - Can use deeply (but not anonymous classes).
    - Can use type parameters defined in enclosing types.
    - Can instantiate parametric types.
    - Can inherit from instantiated parametric types.
    - Can use qualified This.

    Thus, anonymous classes can inherit from an instantiated parametric type.

  4. Propagated constructors cannot call this(..).

    The implementation difficulty here is that the type of an arbitrary expression may need to be resolved to select the correct constructor to call.  

    Another complication is that possible target constructors for a this(..) invocation must also be guaranteed to be propagated.  The target of this(..) must also be a propagated constructor because a specific superclass constructor eventually must be called with its propagated arguments.

Last Modified:  11/05/2001 02:51 PM