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

COVERAGE SUMMARY FOR SOURCE FILE [Method.java]

nameclass, %method, %block, %line, %
Method.java100% (2/2)73%  (11/15)64%  (179/279)69%  (39.2/57)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Method$1100% (1/1)50%  (1/2)47%  (9/19)50%  (2/4)
run (Method): Object 0%   (0/1)0%   (0/10)0%   (0/2)
Method$1 (Method, List): void 100% (1/1)100% (9/9)100% (2/2)
     
class Method100% (1/1)77%  (10/13)65%  (170/260)71%  (38.2/54)
access$0 (Method, Method): Collection 0%   (0/1)0%   (0/5)0%   (0/1)
addArgument (ClassName, ArgumentName): void 0%   (0/1)0%   (0/10)0%   (0/2)
checkMethodOverridesCorrectly (Method): Collection 0%   (0/1)0%   (0/34)0%   (0/6)
sanityCheckArguments (): Collection 100% (1/1)63%  (24/38)71%  (5/7)
getAllReferencedClassNames (): Set 100% (1/1)71%  (25/35)77%  (4.6/6)
typeCheckCode (ClassName, ClassTable): Collection 100% (1/1)73%  (45/62)69%  (7.6/11)
<static initializer> 100% (1/1)100% (6/6)100% (2/2)
Method (ClassName, MethodName, Term): void 100% (1/1)100% (17/17)100% (6/6)
checkMOk (ClassDecl, ClassTable): List 100% (1/1)100% (39/39)100% (9/9)
getArguments (): List 100% (1/1)100% (6/6)100% (1/1)
getName (): Object 100% (1/1)100% (3/3)100% (1/1)
getReturnType (): ClassName 100% (1/1)100% (3/3)100% (1/1)
getThisArgName (): ArgumentName 100% (1/1)100% (2/2)100% (1/1)

1package uk.co.zonetora.fj.model;
2 
3import static uk.co.zonetora.fj.util.ListUtil.mapFst;
4import static uk.co.zonetora.fj.util.ListUtil.mapSnd;
5 
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Set;
11 
12import uk.co.zonetora.fj.passes.FJException;
13import uk.co.zonetora.fj.typecheck.ClassTable;
14import uk.co.zonetora.fj.typecheck.TypeCheck;
15import uk.co.zonetora.fj.typecheck.TypeEnvironment;
16import uk.co.zonetora.fj.util.Arrow;
17import uk.co.zonetora.fj.util.Tuple;
18 
19public class Method {
20    
21    private static final ArgumentName thisArgName = new ArgumentName("this");
22    
23    public static ArgumentName getThisArgName() {
24            return thisArgName;
25    }
26    
27        private final ClassName returnType;
28        private final MethodName methodName;
29        private final List<Tuple<ClassName, ArgumentName>> arguments;
30        private final Term code;
31        
32        public Method(ClassName returnType, MethodName methodName, Term code) {
33                this.returnType = returnType;
34                this.methodName = methodName;
35                this.code = code;
36                this.arguments = new ArrayList<Tuple<ClassName,ArgumentName>>();
37        }
38        
39        public void addArgument(ClassName cn, ArgumentName an) {
40                this.arguments.add(new Tuple<ClassName, ArgumentName>(cn,an));
41        }
42 
43        public Set<ClassName> getAllReferencedClassNames() {
44                Set<ClassName> allReferencedClassNames = new HashSet<ClassName>();
45                allReferencedClassNames.add(this.returnType);
46                
47                for(Tuple<ClassName, ArgumentName> arg : this.arguments) {
48                        allReferencedClassNames.add(arg.getX());
49                }
50                
51                allReferencedClassNames.addAll(this.code.getAllReferencedClassNames());
52                
53                return allReferencedClassNames;
54        }
55 
56        public List<FJException> checkMOk(ClassDecl decl, ClassTable c) {
57        final List<FJException> exceptions = new ArrayList<FJException>();
58        
59        exceptions.addAll(sanityCheckArguments());
60        if(exceptions.isEmpty()) {
61            c.mType(this.methodName, decl.getSuperClass()).maybe(
62                    null,
63                    new Arrow<Method, Object>() {
64                        public Object run(Method arg) {
65                            exceptions.addAll(checkMethodOverridesCorrectly(arg));
66                            return null;
67                        }
68                    }
69            );
70            
71        }
72        
73        if(exceptions.isEmpty()) {
74            exceptions.addAll(typeCheckCode(decl.getClassName(), c));
75        }
76        
77        return exceptions;
78        }
79 
80    private Collection< ? extends FJException> typeCheckCode(ClassName thisClassName, ClassTable ct) {
81        List<FJException> exceptions = new ArrayList<FJException>();
82        
83        TypeEnvironment te = new TypeEnvironment();
84        te.addBinding(Method.thisArgName, thisClassName);
85        
86        for(Tuple<ClassName, ArgumentName> arg : this.arguments) {
87            te.addBinding(arg.getY(), arg.getX());
88        }
89        
90        try {
91            ClassName codeType = new TypeCheck(te, ct).typeCheck(this.code);
92 
93            if(!ct.subtype(codeType, this.returnType)) {
94                exceptions.add(new FJException("Method return type is not a supertype of the code type"));
95            }
96        } catch (FJException e) {
97            exceptions.add(e);
98        }
99        
100        return exceptions;
101    }
102 
103    private Collection< ? extends FJException> sanityCheckArguments() {
104        List<FJException> exceptions = new ArrayList<FJException>();
105        Set<ArgumentName> args = new HashSet<ArgumentName>(mapSnd(this.arguments));
106        if(args.size() != this.arguments.size()) {
107            exceptions.add(new FJException("Duplicate argument name in method"));
108        }
109        
110        if(args.contains(Method.thisArgName)) {
111            exceptions.add(new FJException("this as an argument name in method"));
112        }
113        
114        return exceptions;
115    }
116 
117    public Object getName() {
118        return this.methodName;
119    }
120 
121    private Collection< ? extends FJException> checkMethodOverridesCorrectly(Method superClassVersion) {
122        List<FJException> exceptions = new ArrayList<FJException>();
123        
124        if(!mapFst(superClassVersion.arguments).equals(mapFst(this.arguments))) {
125            exceptions.add(new FJException("Method does not override argumets correctly"));
126        }
127        
128        if(!this.returnType.equals(superClassVersion.returnType)) {
129            exceptions.add(new FJException("Method does not override return type correctly"));
130        }
131        
132        return exceptions;
133    }
134 
135    public List<Tuple<ClassName, ArgumentName>> getArguments() {
136        return new ArrayList<Tuple<ClassName, ArgumentName>>(this.arguments);
137    }
138 
139    public ClassName getReturnType() {
140        return this.returnType;
141    }
142 
143    
144}

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