Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Porting

It is an important step to first prepare the Java sources. And it should always be done in the exact same and documented way. This makes it possible to merge later versions of the Java sources. For the already prepared sources, see below.

Prepare the source

In Eclipse

  • Take the whole source tree and create an Eclipse Java project.
  • Use "organize imports" to expand star (*) imports.
  • Use package renaming.

After that use GVim

  • Load all files into gvim
  • Remove tabs with ":bufdo retab" (having tabstop=4)
  • Convert all files to unix format ":bufdo set ff=unix"
  • Do global search-replaces
    • ":set noignorecase"
    • ":bufdo %s:\<boolean\>:bool:g"
    • ":bufdo %s:\>==: ==:g" insert space if needed
    • ":bufdo %s:==\<:== :g" insert space if needed
    • ":bufdo %s:==:is:g"
    • ":bufdo %s:\>!=: !=:g" insert space if needed
    • ":bufdo %s:!=\<:!= :g" insert space if needed
    • ":bufdo %s:!=:!is:g"
  • Create a keyboard macro that corrects the package statement and inserts the utils import
    • "qq" start recording keyboard macro 'q'
    • "gg/package<ENTER>cemodule<ESC>" search for package and replace with module
    • "o<C-r>%<BS><BS>;<ESC>bv0d" in a new line insert the current file name, remove the '.d', append ';', remove the path
    • "kJxxi.<ESC>" Join lines, delete spaces, connect with dot
    • "o<ENTER>import dwt.dwthelper.utils;<ENTER><ESC>" insert the import
    • "q" end the key macro recording
    • undo all by pressing 'u' several times
    • ":bufdo! normal @q" apply the keyboard macro to all loaded buffers
  • Save all ":wall"

Rename all .java files to .d

Save the prepared sources for later merges.

Use the prepared source archives

These archives contain the sources already renamed and prepared.

3.4M7:

3.4:

The addons package now contains the sources for jface, jface.text (Editor support), ui.* (forms and workbench), equinox (OSGi), and draw2d (from GEF). More than 3000 files.

3.4.1:

Quick Look-over

  • Fix constructors

Operators

Change hashCode to toHash and equals to opEquals

Search for \<equals\> and replace with opEquals

final

final member vars

Change them to const if possible. In Java, the initializer can be a runtime method call, but in D that is only possible with a static constructor. Because of "circular dependency" problems, the use of static constructors is not always possible. Try to eliminate them.

  • Use version statements.
  • Use ctfe.
  • Use the normal constructor to initialize static members. Have them not const.

final local vars or parameters

In general, the final keyword can be removed here. But keep them until you have checked that the variable is not used in an anonymous class. An example:

void func( final Display display ){
  addListener( new Listener(){
    void handle( Event e ){
      display.doSomething();
    }
  });
}

In Java, the anonymous class can access local vars if they are final. In D1.x this will result in stack corruption if the handler is executed after func-execution was completed. The local var needs to become a member var of the anonymous class:

void func( Display display ){
  addListener( new class( display ) Listener {
    Display d;
    this( Display d ){ this.d = d; }
    void handle( Event e ){
      d.doSomething();
    }
  });
}

Now this is safe.

This whole process is very sensitive to errors. The compiler does not help you. Because of that, use the find function to find all references to each final variable. After rewriting, use the find function again to make sure you did not miss a reference.

Evaluation order

Evaluation order is not defined in D, but in Java it is. So there are occasional cases where runtime errors occur because of that.

Java:

array1[index] = array2[index++];

ported to D:

array1[index] = array2[index];
index++;

Java:

result = ( popNextByte() << 8 ) | popNextByte();

ported to D:

result = popNextByte() << 8;
result |= popNextByte();