001    /*
002     * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered
003     * by the modified BSD License. You should have received a copy of the
004     * modified BSD license with this compiler.
005     * 
006     * Copyright (c) 2005-2008, Torbjorn Ekman
007     * All rights reserved.
008     */
009    
010    aspect GenericsArrays {
011      refine Arrays eq TypeDecl.arrayType() {
012        String name = name() + "[]";
013    
014        List body = new List();
015        body.add(
016          new FieldDeclaration(
017            new Modifiers(new List().add(new Modifier("public")).add(new Modifier("final"))),
018            new PrimitiveTypeAccess("int"),
019            "length",
020            new Opt() // [Init:Expr]
021          )
022        );
023        MethodDecl clone = null;
024        TypeDecl typeObject = typeObject();
025        for(int i = 0; clone == null && i < typeObject.getNumBodyDecl(); i++) {
026          if(typeObject.getBodyDecl(i) instanceof MethodDecl) {
027            MethodDecl m = (MethodDecl)typeObject.getBodyDecl(i);
028            if(m.name().equals("clone"))
029              clone = m;
030          }
031        }
032        if(clone != null) {
033          body.add(
034              // we create a substituted method that substitutes the clone method in object
035              // this has the following two consequences: the return value will be cast to the
036              // expected return type rather than object, and the invoked method will be the
037              // method in object rather in the array
038              new MethodDeclSubstituted(
039                new Modifiers(new List().add(new Modifier("public"))),
040                new ArrayTypeAccess(createQualifiedAccess()),
041                "clone",
042                new List(),
043                new List(),
044                new Opt(new Block()),
045                (MethodDecl)typeObject().memberMethods("clone").iterator().next()
046              )
047          );
048        }
049        TypeDecl typeDecl =
050          new ArrayDecl(
051            new Modifiers(new List().add(new Modifier("public"))),
052            name,
053            new Opt(typeObject().createQualifiedAccess()), // [SuperClassAccess]
054            new List().add(typeCloneable().createQualifiedAccess()).add(typeSerializable().createQualifiedAccess()), // Implements*
055            body // BodyDecl*
056          );
057        return typeDecl;
058      }
059    
060    }