EMMA Coverage Report (generated Mon Dec 10 12:01:41 GMT 2007)
[all classes][uk.co.zonetora.fj.model]

COVERAGE SUMMARY FOR SOURCE FILE [ClassDecl.java]

nameclass, %method, %block, %line, %
ClassDecl.java100% (1/1)100% (13/13)92%  (248/269)93%  (51/55)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ClassDecl100% (1/1)100% (13/13)92%  (248/269)93%  (51/55)
checkNoFieldNameShadowing (List): void 100% (1/1)72%  (26/36)71%  (5/7)
lookupMethod (MethodName, ClassTable): Maybe 100% (1/1)79%  (22/28)75%  (3/4)
getFieldType (FieldName): ClassName 100% (1/1)81%  (22/27)75%  (3/4)
ClassDecl (ClassName, ClassName, Constructor): void 100% (1/1)100% (22/22)100% (7/7)
addField (ClassName, FieldName): void 100% (1/1)100% (10/10)100% (2/2)
addMethod (Method): void 100% (1/1)100% (6/6)100% (2/2)
checkCOK (ClassTable): List 100% (1/1)100% (46/46)100% (11/11)
checkConstructorHasGoodArguments (ClassTable): void 100% (1/1)100% (12/12)100% (3/3)
checkConstructorReturnTypeMatchesUp (): void 100% (1/1)100% (13/13)100% (3/3)
getAllReferencedClassNames (): Set 100% (1/1)100% (57/57)100% (9/9)
getClassName (): ClassName 100% (1/1)100% (3/3)100% (1/1)
getFields (): List 100% (1/1)100% (6/6)100% (1/1)
getSuperClass (): ClassName 100% (1/1)100% (3/3)100% (1/1)

1package uk.co.zonetora.fj.model;
2 
3import static uk.co.zonetora.fj.util.ListUtil.mapSnd;
4 
5import java.util.ArrayList;
6import java.util.HashSet;
7import java.util.List;
8import java.util.Set;
9 
10import uk.co.zonetora.fj.passes.FJException;
11import uk.co.zonetora.fj.typecheck.ClassTable;
12import uk.co.zonetora.fj.util.Just;
13import uk.co.zonetora.fj.util.Maybe;
14import uk.co.zonetora.fj.util.Tuple;
15 
16public class ClassDecl {
17 
18        private final ClassName className;
19        private final ClassName superClass;
20        
21        private final List<Tuple<ClassName, FieldName>> fields;
22        
23        private final Constructor constructor;
24        
25        private final List<Method> methods;
26 
27        public ClassDecl(ClassName className, ClassName superClass,
28                                                Constructor constructor) {
29                this.className = className;
30                this.superClass = superClass;
31                this.fields = new ArrayList<Tuple<ClassName,FieldName>>();
32                this.constructor = constructor;
33                this.methods = new ArrayList<Method>();
34        }
35        
36        public void addField(ClassName cn, FieldName fn) {
37                this.fields.add(new Tuple<ClassName,FieldName>(cn,fn));
38        }
39        
40        public void addMethod(Method m) {
41                this.methods.add(m);
42        }
43 
44        public ClassName getClassName() {
45                return this.className;
46        }
47 
48        public ClassName getSuperClass() {
49                return this.superClass;
50        }
51 
52        public Set<ClassName> getAllReferencedClassNames() {
53                Set<ClassName> referencedClassNames = new HashSet<ClassName>();
54                referencedClassNames.add(className);
55                referencedClassNames.add(superClass);
56                for(Tuple<ClassName, FieldName> t : fields) {
57                        referencedClassNames.add(t.getX());
58                }
59                referencedClassNames.addAll(constructor.getAllReferencedClassNames());
60                for(Method m : methods) {
61                        referencedClassNames.addAll(m.getAllReferencedClassNames());
62                }
63                return referencedClassNames;
64        }
65 
66        public List<FJException> checkCOK(ClassTable c) {
67                List<FJException> exceptions = new ArrayList<FJException>();
68                
69                List<Tuple<ClassName, FieldName>> superFields = c.fields(superClass);
70                
71                try{
72                        checkNoFieldNameShadowing(superFields);
73                        checkConstructorReturnTypeMatchesUp();
74                        checkConstructorHasGoodArguments(c);
75                } catch(FJException e) {
76                        exceptions.add(e);
77                        return exceptions;
78                }
79                
80                for(Method m : this.methods) {
81                        exceptions.addAll(m.checkMOk(this, c));
82                }
83                
84                
85                return exceptions;
86        }
87 
88        private void checkConstructorReturnTypeMatchesUp() throws FJException {
89                if(!constructor.getReturnClassName().equals(className)) {
90                        throw new FJException("Constructor has wrong return type"); 
91                }
92        }
93 
94        private void checkConstructorHasGoodArguments(ClassTable c) throws FJException {
95                List<Tuple<ClassName, FieldName>> superFields = c.fields(superClass);
96                
97                constructor.checkFieldsAreSane(fields, superFields);
98        }
99 
100        private void checkNoFieldNameShadowing(List<Tuple<ClassName, FieldName>> superFields) throws FJException {
101                Set<FieldName> superNames = new HashSet<FieldName>(mapSnd(superFields));
102                Set<FieldName> myNames = new HashSet<FieldName>(mapSnd(fields));
103                
104                if(myNames.size() != fields.size()) {
105                        throw new FJException("Duplicate field name(s)");
106                }
107                
108                if(superNames.removeAll(myNames)) {
109                        throw new FJException("Field name shadowed");
110                }
111                
112        }
113 
114        public List<Tuple<ClassName, FieldName>> getFields() {
115                return new ArrayList<Tuple<ClassName,FieldName>>(this.fields);
116        }
117 
118    public Maybe<Method> lookupMethod(MethodName mn, ClassTable ct) {
119        for(Method m : this.methods) {
120            if(m.getName().equals(mn)) {
121                return new Just<Method>(m);
122            }
123        }
124        
125        return ct.mType(mn, this.superClass);
126    }
127 
128    public ClassName getFieldType(FieldName fieldName) throws FJException {
129        for(Tuple<ClassName, FieldName> field : this.fields) {
130            if(field.getY().equals(fieldName)) {
131                return field.getX();
132            }
133        }
134        
135        throw new FJException("Looking up a field that doesn't exist!");
136    }
137        
138}

[all classes][uk.co.zonetora.fj.model]
EMMA 2.0.5312 (C) Vladimir Roubtsov