EMMA Coverage Report (generated Thu Jan 20 11:39:44 EST 2011)
[all classes][com.hammurapi.extract.java]

COVERAGE SUMMARY FOR SOURCE FILE [Params.java]

nameclass, %method, %block, %line, %
Params.java100% (1/1)100% (9/9)82%  (549/667)81%  (96.7/120)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Params100% (1/1)100% (9/9)82%  (549/667)81%  (96.7/120)
translate (Object [], Object): Object [] 100% (1/1)55%  (38/69)70%  (7/10)
equals (Object): boolean 100% (1/1)71%  (48/68)59%  (13/22)
Params (Java$Atom, String [], Class [], Class): void 100% (1/1)80%  (175/220)85%  (29/34)
map (int []): Params 100% (1/1)87%  (95/109)75%  (15/20)
hashCode (): int 100% (1/1)90%  (54/60)97%  (7.7/8)
traverse (AST, AST, int, String [], int, Set, String []): boolean 100% (1/1)97%  (70/72)92%  (12/13)
extractTopLevelNames (String, String []): Set 100% (1/1)100% (61/61)100% (11/11)
getIdentity (): List 100% (1/1)100% (5/5)100% (1/1)
isContextDependent (): boolean 100% (1/1)100% (3/3)100% (1/1)

1package com.hammurapi.extract.java;
2 
3import java.io.StringReader;
4import java.util.Arrays;
5import java.util.HashSet;
6import java.util.List;
7import java.util.Set;
8import java.util.TreeSet;
9 
10import org.codehaus.janino.Java.Atom;
11 
12import antlr.ASTFactory;
13import antlr.RecognitionException;
14import antlr.TokenStreamException;
15import antlr.collections.AST;
16 
17import com.hammurapi.extract.ComparisonResult;
18import com.hammurapi.extract.ExtractorException;
19import com.hammurapi.extract.ExtractorFactory;
20import com.hammurapi.grammar.java.JavaLexer;
21import com.hammurapi.grammar.java.JavaRecognizer;
22import com.hammurapi.grammar.java.JavaTokenTypes;
23 
24/**
25 * Helper class which analyzes parameter usage.
26 * @author Pavel Vlasov
27 *
28 * @param <T>
29 * @param <C>
30 */
31class Params<T, C> {
32        
33        String[] names;
34        
35        Class<?>[] types;
36        
37        boolean doArgs = true;
38        
39        boolean referencesArgs = false;
40        
41        Set<Integer> indices = new TreeSet<Integer>();
42        
43        Integer[] ia;
44        
45        Set<String> topLevelNames;
46 
47        Atom expr;
48 
49        private AST ast;
50 
51        boolean contextDependent;
52 
53        private String[] parameterNames;
54 
55        private Class<T>[] parameterTypes;
56 
57        private Class<C> contextType;
58        
59        Params(
60                        Atom expr, 
61                        String[] parameterNames, 
62                        Class<T>[] parameterTypes, 
63                        Class<C> contextType) throws RecognitionException, TokenStreamException {
64 
65                // For mapping.
66                this.parameterNames = parameterNames;
67                this.parameterTypes = parameterTypes;
68                this.contextType = contextType;
69                
70                for (String pn: parameterNames) {
71                        if (pn!=null) {
72                                doArgs = false;
73                                break;
74                        }
75                }
76                
77                topLevelNames = extractTopLevelNames(expr.toString(), parameterNames);                
78                referencesArgs = topLevelNames.contains(ExtractorFactory.ARGS_BINDING);
79                
80                for (int i=0; i<parameterNames.length; ++i) {
81                        if (doArgs || (parameterNames[i]!=null && topLevelNames.contains(parameterNames[i]))) {
82                                indices.add(i);
83                        }
84                }                
85                
86                if (doArgs) {
87                        if (referencesArgs) {
88                                names = new String[] {ExtractorFactory.ARGS_BINDING, ExtractorFactory.CONTEXT_BINDING};                        
89                                types = new Class[] {Object[].class, contextType};  // TODO Calculate common superclass above object.
90                        } else {
91                                names = new String[] {ExtractorFactory.CONTEXT_BINDING};                        
92                                types = new Class[] {contextType};                                
93                        }
94                } else {
95                        ia = indices.toArray(new Integer[indices.size()]);
96                        contextDependent = topLevelNames.contains(ExtractorFactory.CONTEXT_BINDING);
97                        names = new String[ia.length+(contextDependent ? 1 : 0)];
98                        types = new Class[names.length];
99                        for (int i=0; i<ia.length; ++i) {
100                                names[i] = parameterNames[ia[i]];
101                                types[i] = parameterTypes[ia[i]];
102                        }
103                        if (contextDependent) {
104                                names[ia.length] = ExtractorFactory.CONTEXT_BINDING;
105                                types[ia.length] = contextType;
106                        }
107                }                
108                
109                this.expr = expr;
110        }
111        
112        Object[] translate(Object[] args, C context) {
113                if (doArgs) {
114                        if (referencesArgs) {
115                                return contextDependent ? new Object[] {args, context} : new Object[] {args};
116                        }
117                        return new Object[] {context};                        
118                }
119                
120                Object[] ret = new Object[types.length];
121                for (int i=0; i<ia.length; ++i) {
122                        ret[i] = args[ia[i]];
123                }
124                if (contextDependent) {
125                        ret[ia.length] = context;
126                }
127                return ret;
128        }
129        
130        boolean isContextDependent() {
131                return contextDependent;
132        }
133        
134        private Set<String> extractTopLevelNames(String cnd, String[] parameterNames) throws RecognitionException, TokenStreamException {
135                Set<String> ret = new HashSet<String>();
136                
137                StringReader parserInput = new StringReader("{ x = "+cnd+"; }");
138                JavaLexer lexer = new JavaLexer(parserInput);
139                JavaRecognizer parser = new JavaRecognizer(lexer);
140                ASTFactory astFactory = new ASTFactory();
141                astFactory.setASTNodeClass(ParamsAST.class);
142                parser.setASTFactory(astFactory);
143                parser.statement();
144                ast = parser.getAST().getFirstChild().getFirstChild().getFirstChild().getNextSibling();
145                traverse(ast, null, -1, parser.getTokenNames(), 0, ret, parameterNames);                
146                return ret;
147        }
148        
149        private boolean traverse(AST ast, AST parent, int index, String[] tokenNames, int level, Set<String> collector, String[] parameterNames) {
150                // If "self" IDENT doesn't have DOT as parent with index > 0 then this is it!
151                if (ast.getType()==JavaTokenTypes.IDENT 
152                                && ast.getText()!=null
153                                && ast.getText().trim().length()>0
154                                && !(parent!=null && parent.getType()==JavaTokenTypes.DOT && index>0)) {
155                        collector.add(ast.getText());
156                        for (int i=0; i<parameterNames.length; ++i) {
157                                if (ast.getText().equals(parameterNames[i])) {
158                                        ((ParamsAST) ast).parameterIndex=i;
159                                }
160                        }
161                }
162                int i=0;
163                for (AST child = ast.getFirstChild(); child!=null; child=child.getNextSibling()) {
164                        if (traverse(child, ast, i++, tokenNames, level+1, collector, parameterNames)) {
165                                return true;
166                        }
167                }
168                return false;
169        }
170 
171        @Override
172        public int hashCode() {
173                final int prime = 31;
174                int result = 1;
175                result = prime * result + ((expr == null) ? 0 : expr.toString().hashCode());
176                result = prime * result + (doArgs ? 1231 : 1237);
177                result = prime * result + ((indices == null) ? 0 : indices.hashCode());
178                result = prime * result + Arrays.hashCode(names);
179                result = prime * result + Arrays.hashCode(types);
180                return result;
181        }
182        
183        @Override
184        public boolean equals(Object obj) {
185                if (this == obj)
186                        return true;
187                if (obj == null)
188                        return false;
189                if (getClass() != obj.getClass())
190                        return false;
191                Params other = (Params) obj;
192                if (ast == null) {
193                        if (other.ast != null)
194                                return false;
195                } else if (!ast.equals(other.ast))
196                        return false;
197                if (doArgs != other.doArgs)
198                        return false;
199                if (indices == null) {
200                        if (other.indices != null)
201                                return false;
202                } else if (!indices.equals(other.indices))
203                        return false;
204                
205                // Names are irrelevant because of normalized tree.
206//                if (!Arrays.equals(names, other.names))
207//                        return false;
208                if (!Arrays.equals(types, other.types))
209                        return false;
210                return true;
211        }
212        
213        Params<T,C> map(int[] map) {
214                if (ComparisonResult.isOneToOneMapping(map)) {
215                        return this;
216                }
217                
218                Set<Integer> unmappedIndexes = new HashSet<Integer>();
219                for (int i=0; i<parameterNames.length; ++i) {
220                        if (parameterNames[i]!=null) {
221                                unmappedIndexes.add(i);
222                        }
223                }
224                
225                String[] newParameterNames = new String[parameterNames.length];
226                Class<T>[] newParameterTypes = new Class[parameterTypes.length];
227                
228                for (int i=0; i<map.length; ++i) {
229                        if (map[i]>=0 && map[i]<parameterNames.length) {
230                                newParameterNames[i] = parameterNames[map[i]];
231                                newParameterTypes[i] = parameterTypes[map[i]];
232                                unmappedIndexes.remove(map[i]);
233                        }
234                }
235                
236                if (!unmappedIndexes.isEmpty()) {
237                        return null; // Could not map all indexes.
238                }
239 
240                try {
241                        return new Params<T,C>(expr, newParameterNames, newParameterTypes, contextType);
242                } catch (RecognitionException e) {
243                        throw new ExtractorException(e);
244                } catch (TokenStreamException e) {
245                        throw new ExtractorException(e);
246                }
247        }
248 
249        List<Object> getIdentity() {
250                return ((ParamsAST) ast).getIdentity();
251        }
252}

[all classes][com.hammurapi.extract.java]
EMMA 2.0.5312 EclEmma Fix 2 (C) Vladimir Roubtsov