Clover coverage report - DynamicJava Test Coverage (dynamicjava-20130525-r5436)
Coverage timestamp: Sat May 25 2013 03:01:29 CDT
file stats: LOC: 276   Methods: 14
NCLOC: 156   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
EnumDeclaration.java 0% 0% 0% 0%
coverage
 1    /*
 2    * DynamicJava - Copyright (C) 1999-2001
 3    *
 4    * Permission is hereby granted, free of charge, to any person obtaining a
 5    * copy of this software and associated documentation files
 6    * (the "Software"), to deal in the Software without restriction, including
 7    * without limitation the rights to use, copy, modify, merge, publish,
 8    * distribute, sublicense, and/or sell copies of the Software, and to permit
 9    * persons to whom the Software is furnished to do so, subject to the
 10    * following conditions:
 11    * The above copyright notice and this permission notice shall be included
 12    * in all copies or substantial portions of the Software.
 13    *
 14    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 15    * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 16    * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 17    * IN NO EVENT SHALL DYADE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 18    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 19    * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 20    * DEALINGS IN THE SOFTWARE.
 21    *
 22    * Except as contained in this notice, the name of Dyade shall not be
 23    * used in advertising or otherwise to promote the sale, use or other
 24    * dealings in this Software without prior written authorization from
 25    * Dyade.
 26    *
 27    */
 28   
 29    package koala.dynamicjava.tree;
 30   
 31    import java.util.*;
 32   
 33    import koala.dynamicjava.tree.tiger.GenericReferenceTypeName;
 34    import koala.dynamicjava.tree.visitor.Visitor;
 35   
 36    import static koala.dynamicjava.tree.ModifierSet.Modifier.*;
 37   
 38    /**
 39    * This class represents an enum declaration
 40    *
 41    * @author Moez, Shankar
 42    */
 43   
 44    public class EnumDeclaration extends ClassDeclaration {
 45   
 46    /**
 47    * Creates a new enum declaration
 48    * @param mods the modifiers
 49    * @param name the name of the enum to declare
 50    * @param impl the list of implemented interfaces (a list of list of
 51    * Token). Can be null.
 52    * @param body the list of members declarations
 53    */
 54  0 public EnumDeclaration(ModifierSet mods, String name, List<? extends ReferenceTypeName> impl, EnumBody body) {
 55  0 this(mods, name, impl, body, SourceInfo.NONE);
 56    }
 57   
 58    // /** Flag is set if symbol has a synthetic attribute.
 59    // */
 60    // public static final int SYNTHETIC = 1<<16;
 61    //
 62    // /** Flag is set if symbol is deprecated.
 63    // */
 64    // public static final int DEPRECATED = 1<<17;
 65    //
 66    // /** Flag is set for a variable symbol if the variable's definit
 67    // * has an initializer part.
 68    // */
 69    // public static final int HASINIT = 1<<18;
 70    //
 71    // /** An enumeration type or an enumeration constant.
 72    // */
 73    // public static final int ENUM = 1<<19;
 74   
 75    /**
 76    * Creates a new enum declaration
 77    * @param mods the modifiers
 78    * @param name the name of the enum to declare
 79    * @param impl the list of implemented interfaces (a list of list of
 80    * Token). Can be null.
 81    * @param body the list of members declarations
 82    */
 83  0 public EnumDeclaration(ModifierSet mods, String name, List<? extends ReferenceTypeName> impl, EnumBody body,
 84    SourceInfo si) {
 85    // the first parameter should be (flags | 0x4000),
 86    // but this causes problems when trying to create
 87    // an instance of it using reflection since you
 88    // apparently can't create enum types reflectively
 89    // using newInstance from the class object.
 90    //
 91    // The only real consequence of this is that Class.isEnum()
 92    // will return false, but since dynamicjava uses
 93    // TigerUtilities.isEnum(), this doesn't pose too big of a problem.
 94  0 super(mods,
 95    name, makeTypeName(name), impl,
 96    AddValues(name,
 97    HandleConstructors(name,
 98    makeEnumBodyDeclarationsFromEnumConsts(name, body)),
 99    body.getConstants()),
 100    si);
 101    }
 102   
 103  0 private static ReferenceTypeName makeTypeName(String name) {
 104  0 List<Identifier> c = Arrays.asList(new Identifier("java"), new Identifier("lang"), new Identifier("Enum"));
 105  0 List<TypeName> emptyTargs = Collections.emptyList();
 106  0 List<ReferenceTypeName> targs = Arrays.asList(new ReferenceTypeName(name));
 107  0 List<List<? extends TypeName>> allTArgs = new LinkedList<List<? extends TypeName>>();
 108  0 allTArgs.add(emptyTargs);
 109  0 allTArgs.add(emptyTargs);
 110  0 allTArgs.add(targs);
 111  0 return new GenericReferenceTypeName(c, allTArgs);
 112    }
 113   
 114  0 static List<Node> AddValues(String enumTypeName, List<Node> body, List<EnumConstant> consts){
 115  0 List<Node> newbody = body;
 116   
 117    // public static Foo[] values() { return new Foo[]{ Foo.FIRST, Foo.SECOND, Foo.THIRD }; }
 118  0 ReferenceTypeName enumType = new ReferenceTypeName(enumTypeName);
 119  0 List<Expression> cells = new LinkedList<Expression>();
 120  0 for(EnumConstant c : consts) {
 121  0 cells.add(new StaticFieldAccess(enumType, c.getName()));
 122    }
 123   
 124  0 Expression alloc = new ArrayAllocation(enumType,
 125    new ArrayAllocation.TypeDescriptor(Collections.<Expression>emptyList(), 1,
 126    new ArrayInitializer(cells),
 127    SourceInfo.NONE));
 128  0 Statement valuesBody = new ReturnStatement(alloc);
 129  0 newbody.add(new MethodDeclaration(ModifierSet.make(PUBLIC, STATIC),
 130    new ArrayTypeName(enumType, 1, false),
 131    "values",
 132    Collections.<FormalParameter>emptyList(),
 133    Collections.<ReferenceTypeName>emptyList(),
 134    new BlockStatement(Collections.<Node>singletonList(valuesBody))));
 135   
 136    // public static Foo valueOf(String name) {
 137    // if ("FIRST".equals(name)) return Foo.FIRST;
 138    // if ("SECOND".equals(name)) return Foo.SECOND;
 139    // if ("THIRD".equals(name)) return Foo.THIRD;
 140    // throw new IllegalArgumentException();
 141    // }
 142  0 FormalParameter nameParam = new FormalParameter(ModifierSet.make(),
 143    new ReferenceTypeName("java", "lang", "String"),
 144    "name");
 145  0 List<Node> valueOfBody = new LinkedList<Node>();
 146  0 for (EnumConstant c : consts) {
 147  0 String cn = c.getName();
 148  0 Expression cond = new ObjectMethodCall(new StringLiteral("\"" + cn + "\""), "equals",
 149    Collections.singletonList(new VariableAccess("name")));
 150  0 Statement ret = new ReturnStatement(new StaticFieldAccess(enumType, cn));
 151  0 valueOfBody.add(new IfThenStatement(cond, ret));
 152    }
 153  0 valueOfBody.add(new ThrowStatement(new SimpleAllocation(new ReferenceTypeName("IllegalArgumentException"),
 154    Collections.<Expression>emptyList())));
 155  0 newbody.add(new MethodDeclaration(ModifierSet.make(PUBLIC, STATIC),
 156    enumType,
 157    "valueOf",
 158    Collections.singletonList(nameParam),
 159    Collections.<ReferenceTypeName>emptyList(),
 160    new BlockStatement(valueOfBody)));
 161  0 return newbody;
 162    }
 163   
 164  0 static List<Node> HandleConstructors(String name, List<Node> body){
 165  0 Iterator<Node> it = body.listIterator();
 166   
 167  0 List<FormalParameter> addToConsDeclaration = new LinkedList<FormalParameter>();
 168  0 addToConsDeclaration.add(new FormalParameter(ModifierSet.make(), new ReferenceTypeName("String"), "$1"));
 169  0 addToConsDeclaration.add(new FormalParameter(ModifierSet.make(), new IntTypeName(), "$2"));
 170   
 171  0 List<Expression> args = new LinkedList<Expression>();
 172  0 args.add(new AmbiguousName("$1"));
 173  0 args.add(new AmbiguousName("$2"));
 174   
 175  0 List<FormalParameter> consParams;
 176  0 boolean noConstructor = true;
 177   
 178  0 while(it.hasNext()) {
 179  0 Node current = it.next();
 180  0 if (current instanceof ConstructorDeclaration) {
 181  0 noConstructor = false;
 182   
 183  0 consParams = ((ConstructorDeclaration)current).getParameters();
 184  0 List<FormalParameter> newConsParam = new LinkedList<FormalParameter>();
 185   
 186  0 newConsParam.addAll(addToConsDeclaration);
 187  0 newConsParam.addAll(consParams);
 188   
 189  0 ((ConstructorDeclaration)current).setParameters(newConsParam);
 190   
 191  0 ((ConstructorDeclaration)current).setConstructorCall(new ConstructorCall(null, args, true));
 192    }
 193    }
 194   
 195  0 if (noConstructor) {
 196  0 body.add(new ConstructorDeclaration(ModifierSet.make(PRIVATE), name, addToConsDeclaration,
 197    new LinkedList<ReferenceTypeName>(),
 198    new ConstructorCall(null, args, true),
 199    new LinkedList<Node>()));
 200    }
 201  0 return body;
 202    }
 203   
 204    public static class EnumConstant extends Declaration {
 205    private String name;
 206    private List<Expression> args;
 207    private List<Node> classBody;
 208   
 209  0 public EnumConstant(ModifierSet mods, String _name, List<? extends Expression> _args, List<Node> _classBody,
 210    SourceInfo si) {
 211  0 super(mods, si);
 212  0 name = _name;
 213  0 args = (_args == null) ? null : new ArrayList<Expression>(_args);
 214  0 classBody = _classBody;
 215    }
 216   
 217  0 public String getName() {return name;}
 218  0 public List<Expression> getArguments() {return args;}
 219  0 public List<Node> getClassBody() {return classBody;}
 220   
 221  0 public <T> T acceptVisitor(Visitor<T> visitor) {
 222  0 return visitor.visit(this);
 223    }
 224    }
 225   
 226    public static class EnumBody {
 227    private List<EnumConstant> consts;
 228    private List<Node> decls;
 229   
 230  0 public EnumBody(List<EnumConstant> c, List<Node> d){
 231  0 consts = c;
 232  0 decls = d;
 233    }
 234   
 235  0 public List<EnumConstant> getConstants() {
 236  0 return consts;
 237    }
 238   
 239  0 public List<Node> getDeclarations(){
 240  0 return decls;
 241    }
 242    }
 243   
 244  0 static List<Node> makeEnumBodyDeclarationsFromEnumConsts(String enumTypeName, EnumBody body) {
 245  0 List<EnumConstant> consts = body.getConstants();
 246  0 List<Node> decls = body.getDeclarations();
 247   
 248  0 ReferenceTypeName enumType = new ReferenceTypeName(enumTypeName);
 249   
 250  0 SimpleAllocation allocExpr = null;
 251   
 252  0 Iterator<EnumConstant> it = consts.listIterator();
 253  0 int i = 0;
 254  0 while(it.hasNext()){
 255  0 List<Expression> args = new LinkedList<Expression>();
 256  0 EnumConstant ec = it.next();
 257   
 258  0 args.add(new StringLiteral("\""+ec.getName()+"\""));
 259  0 args.add(new IntegerLiteral(String.valueOf(i++)));
 260   
 261  0 if(ec.getArguments() != null){
 262  0 args.addAll(ec.getArguments());
 263    }
 264   
 265  0 if (ec.getClassBody() != null){
 266  0 allocExpr = new AnonymousAllocation(enumType, args, ec.getClassBody());
 267    }
 268    else {
 269  0 allocExpr = new SimpleAllocation(enumType, args);
 270    }
 271   
 272  0 decls.add(new FieldDeclaration(ModifierSet.make(PUBLIC, STATIC, FINAL, ENUM), enumType, ec.getName(), allocExpr));
 273    }
 274  0 return decls;
 275    }
 276    }