Porting

I prepared the SWT source trees prior to start the port. This makes better diff views possible. dwt-jsrcs.zip (4,5MB)

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)
  • do global search-replaces
    • :bufdo %s:\<boolean\>:bool:g
    • :bufdo %s:==:is:g
    • :bufdo %s:!=:!is:g
  • save all :wall

Rename all .java files to .d

Save the prepared sources for later merges

interactive search-replace

Again in GVim

  • :bufdo %s:\<String\>:char[]:gc
  • :bufdo %s:\<implements\>:\::gc
  • :bufdo %s:\<extends\>:\::gc
  • :bufdo %s:\<package\>:module:gc
  • save all :wall

Quick Look-over

  • Fix module name
  • Fix constructors

Operators

Change hashCode to toHash and equals to opEquals

Search for \<equals\> and replace by ==/*eq*/

final

final member vars

Change them to const if possible. In Java the initializer can be runtime method call, in D that is only possible with a static constructor. Because of the "circular dependencies" problem 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, the variable is not used in a anonymous class. An exampls:

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 save.

The whole thing is very sensible to errors. The compile does not help you. Because of that use the find function to find all references to a final variable. After rewrite again use the find function and 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 in seldom cases situation, 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();