Package: Utils

Utils

nameinstructionbranchcomplexitylinemethod
Utils()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
abs(Object)
M: 10 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
computeDiv(double, double)
M: 22 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
copy(Object)
M: 9 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
div(Object, Object)
M: 15 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
divide(Object, Object)
M: 25 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
empty(Object)
M: 33 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
equals(Object, Object)
M: 37 C: 39
51%
M: 13 C: 9
41%
M: 9 C: 3
25%
M: 6 C: 7
54%
M: 0 C: 1
100%
floor(Object)
M: 10 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
formatFields(Object[])
M: 55 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
get(Object, Object)
M: 24 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
getDoubleValue(Object)
M: 2 C: 10
83%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 3
75%
M: 0 C: 1
100%
hashCode(Object[])
M: 32 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
index(Object)
M: 26 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
isIntWithinRange(Object, int)
M: 2 C: 16
89%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 1 C: 3
75%
M: 0 C: 1
100%
isVoidValue(Object)
M: 7 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
is_(Object, Object)
M: 89 C: 33
27%
M: 28 C: 10
26%
M: 19 C: 1
5%
M: 26 C: 11
30%
M: 0 C: 1
100%
is_Tuple(Object, Class[])
M: 12 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
is_bool(Object)
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
is_char(Object)
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
is_int(Double)
M: 1 C: 16
94%
M: 3 C: 3
50%
M: 3 C: 1
25%
M: 0 C: 2
100%
M: 0 C: 1
100%
is_int(Object)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
is_nat(Object)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
is_nat1(Object)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
is_rat(Object)
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
is_real(Object)
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
is_token(Object)
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
mapSeqUpdate(Object, Object, Object)
M: 31 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
mod(Object, Object)
M: 23 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
postCheck(Object, boolean, String)
M: 16 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
pow(Object, Object)
M: 16 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
rem(Object, Object)
M: 21 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
report(String, boolean, Object[])
M: 107 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 23 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 0 C: 61
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 15
100%
M: 0 C: 1
100%
toInt(Number)
M: 26 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
toString(Object)
M: 40 C: 22
35%
M: 8 C: 4
33%
M: 6 C: 1
14%
M: 8 C: 6
43%
M: 0 C: 1
100%
validateIntOperands(Object, Object)
M: 34 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
validateNumber(Object, String)
M: 18 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
validateNumbers(Object, Object, String)
M: 25 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * #%~
3: * VDM Code Generator Runtime
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.codegen.runtime;
23:
24: public class Utils
25: {
26:         public static final Object VOID_VALUE = new Object();
27:
28:         // Used to pass type arguments for instantiated functions in the generated code
29:         public static final Object NAT = new Object();
30:         public static final Object NAT1 = new Object();
31:         public static final Object INT = new Object();
32:         public static final Object REAL = new Object();
33:         public static final Object RAT = new Object();
34:         public static final Object BOOL = new Object();
35:         public static final Object CHAR = new Object();
36:         public static final Object TOKEN = new Object();
37:         public static final Object STRING = new Object();
38:         public static final Object SEQ_OF_ANYTHING = new Object();
39:         public static final Object SET_OF_ANYTHING = new Object();
40:         public static final Object MAP_ANYTHING_TO_ANYTHING = new Object();
41:         public static final Object UNKNOWN = new Object();
42:         // Only basic types, set of ?, seq of ?, map ? to ?, quotes, unions of non-collection types, strings, polymorphic types, the unknown type and records can currently be used as polymorphic type arguments
43:         public static final Object TYPE_NOT_SUPPORTED = new Object();
44:
45:         public static boolean isVoidValue(Object value)
46:         {
47:•                return value == VOID_VALUE;
48:         }
49:
50:         public static boolean empty(Object col)
51:         {
52:•                if (col instanceof VDMSet)
53:                 {
54:                         return ((VDMSet) col).isEmpty();
55:•                } else if (col instanceof VDMSeq)
56:                 {
57:                         return ((VDMSeq) col).isEmpty();
58:•                } else if (col instanceof VDMMap)
59:                 {
60:                         return ((VDMMap) col).isEmpty();
61:                 } else
62:                 {
63:                         throw new IllegalArgumentException("Expected collection to be either a VDM set, map or sequence. Got: "
64:                                         + col);
65:                 }
66:         }
67:
68:         public static int hashCode(Object... fields)
69:         {
70:•                if (fields == null)
71:                 {
72:                         throw new IllegalArgumentException("Fields cannot be null");
73:                 }
74:
75:                 int hashcode = 0;
76:
77:•                for (int i = 0; i < fields.length; i++)
78:                 {
79:                         Object currentField = fields[i];
80:•                        hashcode += currentField != null ? currentField.hashCode() : 0;
81:                 }
82:
83:                 return hashcode;
84:         }
85:
86:         public static Object get(Object col, Object index)
87:         {
88:•                if (col instanceof VDMSeq)
89:                 {
90:                         VDMSeq seq = (VDMSeq) col;
91:                         return seq.get(Utils.index(index));
92:•                } else if (col instanceof VDMMap)
93:                 {
94:                         return MapUtil.get((VDMMap) col, index);
95:                 } else
96:                 {
97:                         throw new IllegalArgumentException("Only a map or a sequence can be read");
98:                 }
99:         }
100:
101:         @SuppressWarnings("unchecked")
102:         public static void mapSeqUpdate(Object col, Object index, Object value)
103:         {
104:•                if (col instanceof VDMSeq)
105:                 {
106:                         VDMSeq seq = (VDMSeq) col;
107:                         seq.set(index(index), value);
108:•                } else if (col instanceof VDMMap)
109:                 {
110:                         VDMMap map = (VDMMap) col;
111:                         map.put(index, value);
112:                 } else
113:                 {
114:                         throw new IllegalArgumentException("Only a map or a sequence can be updated");
115:                 }
116:         }
117:
118:         public static int index(Object value)
119:         {
120:•                if (!(value instanceof Number))
121:                 {
122:                         throw new IllegalArgumentException("The value to be converted must be a java.lang.Number");
123:                 }
124:
125:                 Number numberValue = (Number) value;
126:
127:•                if (numberValue.longValue() < 1)
128:                 {
129:                         throw new IllegalArgumentException("VDM subscripts must be >= 1");
130:                 }
131:
132:                 return toInt(numberValue) - 1;
133:         }
134:
135:         public static String formatFields(Object... fields)
136:         {
137:•                if (fields == null)
138:                 {
139:                         throw new IllegalArgumentException("Fields cannot be null in formatFields");
140:                 }
141:
142:                 StringBuilder str = new StringBuilder();
143:
144:•                if (fields.length > 0)
145:                 {
146:                         str.append(Utils.toString(fields[0]));
147:
148:•                        for (int i = 1; i < fields.length; i++)
149:                         {
150:                                 str.append(", " + Utils.toString(fields[i]));
151:                         }
152:                 }
153:                 return "(" + str.toString() + ")";
154:         }
155:
156:         @SuppressWarnings("unchecked")
157:         public static <T> T copy(T t)
158:         {
159:•                if (t instanceof ValueType)
160:                 {
161:                         return (T) ((ValueType) t).copy();
162:                 } else
163:                 {
164:                         return t;
165:                 }
166:         }
167:
168:         public static String toString(Object obj)
169:         {
170:•                if (obj == null)
171:                 {
172:                         return "nil";
173:•                } else if (obj == VOID_VALUE)
174:                 {
175:                         return "()";
176:•                } else if (obj instanceof Number)
177:                 {
178:                         Number n = (Number) obj;
179:
180:•                        if (n.doubleValue() % 1 == 0)
181:                         {
182:                                 return Long.toString(n.longValue());
183:                         } else
184:                         {
185:                                 return Double.toString(n.doubleValue());
186:                         }
187:•                } else if (obj instanceof Character)
188:                 {
189:                         return "'" + obj + "'";
190:•                } else if (obj instanceof String)
191:                 {
192:                         return "\"" + obj.toString() + "\"";
193:                 }
194:
195:                 return obj.toString();
196:         }
197:
198:         public static boolean equals(Object left, Object right)
199:         {
200:•                if (left instanceof Long && right instanceof Long)
201:                 {
202:                         Long leftLong = (Long) left;
203:                         Long rightLong = (Long) right;
204:
205:•                        return leftLong.compareTo(rightLong) == 0;
206:                 }
207:
208:•                if (left instanceof Integer && right instanceof Integer)
209:                 {
210:                         Integer leftInt = (Integer) left;
211:                         Integer rightInt = (Integer) right;
212:
213:•                        return leftInt.compareTo(rightInt) == 0;
214:                 }
215:
216:•                if (left instanceof Number && right instanceof Number)
217:                 {
218:                         Double leftNumber = ((Number) left).doubleValue();
219:                         Double rightNumber = ((Number) right).doubleValue();
220:
221:•                        return leftNumber.compareTo(rightNumber) == 0;
222:                 }
223:
224:•                return left != null ? left.equals(right) : right == null;
225:         }
226:
227:         public static <T> T postCheck(T returnValue, boolean postResult,
228:                         String name)
229:         {
230:•                if (postResult)
231:                 {
232:                         return returnValue;
233:                 }
234:
235:                 throw new RuntimeException("Postcondition failure: post_" + name);
236:         }
237:
238:         public static boolean is_bool(Object value)
239:         {
240:                 return value instanceof Boolean;
241:         }
242:
243:         public static boolean is_nat(Object value)
244:         {
245:                 return isIntWithinRange(value, 0);
246:         }
247:
248:         public static boolean is_nat1(Object value)
249:         {
250:                 return isIntWithinRange(value, 1);
251:         }
252:
253:         public static boolean is_int(Object value)
254:         {
255:                 Double doubleValue = getDoubleValue(value);
256:
257:                 return is_int(doubleValue);
258:         }
259:
260:         public static boolean is_rat(Object value)
261:         {
262:                 return value instanceof Number;
263:         }
264:
265:         public static boolean is_real(Object value)
266:         {
267:                 return value instanceof Number;
268:         }
269:
270:         public static boolean is_char(Object value)
271:         {
272:                 return value instanceof Character;
273:         }
274:
275:         public static boolean is_token(Object value)
276:         {
277:                 return value instanceof Token;
278:         }
279:
280:         @SuppressWarnings("rawtypes")
281:         public static boolean is_Tuple(Object exp, Class... types)
282:         {
283:•                return exp instanceof Tuple && ((Tuple) exp).compatible(types);
284:         }
285:
286:         @SuppressWarnings("rawtypes")
287:         public static boolean is_(Object exp, Object type)
288:         {
289:                 // Handle polymorphic type arguments
290:•                if(type == NAT)
291:                 {
292:                         return is_nat(exp);
293:                 }
294:•                else if(type == NAT1)
295:                 {
296:                         return is_nat1(exp);
297:                 }
298:•                else if(type == INT)
299:                 {
300:                         return is_int(exp);
301:                 }
302:•                else if(type == REAL)
303:                 {
304:                         return is_real(exp);
305:                 }
306:•                else if(type == RAT)
307:                 {
308:                         return is_rat(exp);
309:                 }
310:•                else if(type == BOOL)
311:                 {
312:                         return is_bool(exp);
313:                 }
314:•                else if(type == CHAR)
315:                 {
316:                         return is_char(exp);
317:                 }
318:•                else if(type == TOKEN)
319:                 {
320:                         return is_token(exp);
321:                 }
322:•                else if(type == TYPE_NOT_SUPPORTED)
323:                 {
324:                         throw new IllegalArgumentException("Only basic types, set of ?, seq of ?, map ? to ?, quotes, unions of non-collection types, strings, polymorphic types,"
325:                                         + " the unknown type and records can currently be used as polymorphic type arguments");
326:                 }
327:•                else if(type == STRING)
328:                 {
329:                         return exp instanceof String;
330:                 }
331:•                else if(type == SEQ_OF_ANYTHING)
332:                 {
333:                         return exp instanceof VDMSeq;
334:                 }
335:•                else if(type == SET_OF_ANYTHING)
336:                 {
337:                         return exp instanceof VDMSet;
338:                 }
339:•                else if(type == MAP_ANYTHING_TO_ANYTHING)
340:                 {
341:                         return exp instanceof VDMMap;
342:                 }
343:•                else if(type == UNKNOWN)
344:                 {
345:                         return true;
346:                 }
347:•                else if(type instanceof VDMSet)
348:                 {
349:                         // Special case; union of quotes
350:
351:•                        for(Object o : ((VDMSet) type))
352:                         {
353:•                                if(is_(exp, o))
354:                                 {
355:                                         return true;
356:                                 }
357:                         }
358:
359:                         return false;
360:                 }
361:•                else if(type instanceof Class)
362:                 {
363:                         return ((Class) type).isInstance(exp);
364:                 }
365:                 else
366:                 {
367: // If we are checking if a value is a quote
368:•                        return exp == type;
369:                 }
370:         }
371:
372:         public static double divide(Object left, Object right)
373:         {
374:                 validateNumbers(left, right, "divide");
375:
376:                 double leftDouble = ((Number) left).doubleValue();
377:                 double rightDouble = ((Number) right).doubleValue();
378:
379:•                if (rightDouble == 0L)
380:                 {
381:                         throw new ArithmeticException("Division by zero is undefined");
382:                 }
383:
384:                 return leftDouble / rightDouble;
385:         }
386:
387:         public static long div(Object left, Object right)
388:         {
389:                 validateIntOperands(left, right);
390:
391:                 Number leftInt = (Number) left;
392:                 Number rightInt = (Number) right;
393:
394:                 return computeDiv(leftInt.doubleValue(), rightInt.doubleValue());
395:         }
396:
397:         public static long mod(Object left, Object right)
398:         {
399:                 validateIntOperands(left, right);
400:
401:                 double leftInt = ((Number) left).doubleValue();
402:                 double rightInt = ((Number) right).doubleValue();
403:
404:                 return (long) (leftInt
405:                                 - rightInt * (long) Math.floor(leftInt / rightInt));
406:         }
407:
408:         public static long rem(Object left, Object right)
409:         {
410:                 validateIntOperands(left, right);
411:
412:                 double leftInt = ((Number) left).doubleValue();
413:                 double rightInt = ((Number) right).doubleValue();
414:
415:                 return (long) (leftInt - rightInt * computeDiv(leftInt, rightInt));
416:         }
417:
418:         public static double floor(Object arg)
419:         {
420:                 validateNumber(arg, "floor");
421:
422:                 Number number = (Number) arg;
423:
424:                 return Math.floor(number.doubleValue());
425:         }
426:
427:         public static double abs(Object arg)
428:         {
429:                 validateNumber(arg, "abs");
430:
431:                 Number number = (Number) arg;
432:
433:                 return Math.abs(number.doubleValue());
434:         }
435:
436:         public static double pow(Object a, Object b)
437:         {
438:                 validateNumbers(a, b, "pow");
439:
440:                 Number aNumber = (Number) a;
441:                 Number bNumber = (Number) b;
442:
443:                 return Math.pow(aNumber.doubleValue(), bNumber.doubleValue());
444:         }
445:
446:         /* @ pure @ */
447:         public static boolean report(String name, boolean res, Object... params)
448:         {
449:•                if (res)
450:                 {
451:                         return true;
452:                 }
453:
454:                 StringBuilder sb = new StringBuilder();
455:                 sb.append(name);
456:                 sb.append('(');
457:
458:•                if (params.length > 1)
459:                 {
460:                         String del = ", ";
461:                         String eq = " = ";
462:
463:                         sb.append(params[0]);
464:                         sb.append(eq);
465:                         sb.append(Utils.toString(params[1]));
466:
467:•                        for (int i = 2; i < params.length; i = i + 2)
468:                         {
469:                                 sb.append(del);
470:                                 sb.append(params[i]);
471:                                 sb.append(eq);
472:                                 sb.append(Utils.toString(params[i + 1]));
473:                         }
474:                 }
475:
476:                 sb.append(')');
477:                 sb.append(" is " + res);
478:                 sb.append('\n');
479:
480:                 System.out.println(sb.toString());
481:                 AssertionError error = new AssertionError();
482:                 error.printStackTrace(System.out);
483:                 throw error;
484:         }
485:
486:         static int toInt(Number value)
487:         {
488:                 long valueLong = value.longValue();
489:
490:•                if (valueLong < Integer.MIN_VALUE || valueLong > Integer.MAX_VALUE)
491:                 {
492:                         throw new IllegalArgumentException(valueLong
493:                                         + " Casting the long to an int will change its value");
494:                 }
495:                 return (int) valueLong;
496:         }
497:
498:         private static void validateIntOperands(Object left, Object right)
499:         {
500:•                if (!(is_int(left) && is_int(right)))
501:                 {
502:                         throw new ArithmeticException("Operands must be integers. Got left "
503:                                         + left + " and right" + right);
504:                 }
505:
506:•                if (((Number) right).longValue() == 0L)
507:                 {
508:                         throw new ArithmeticException("Division by zero is undefined");
509:                 }
510:         }
511:
512:         private static long computeDiv(double lv, double rv)
513:         {
514:•                if (lv / rv < 0)
515:                 {
516:                         return (long) -Math.floor(Math.abs(lv / rv));
517:                 } else
518:                 {
519:                         return (long) Math.floor(Math.abs(-lv / rv));
520:                 }
521:         }
522:
523:         private static boolean is_int(Double doubleValue)
524:         {
525:•                return doubleValue != null && doubleValue == Math.floor(doubleValue)
526:•                                && !Double.isInfinite(doubleValue);
527:         }
528:
529:         private static boolean isIntWithinRange(Object value, int lowerLimit)
530:         {
531:                 Double doubleValue = getDoubleValue(value);
532:
533:•                if (!is_int(doubleValue))
534:                 {
535:                         return false;
536:                 }
537:
538:•                return doubleValue >= lowerLimit;
539:         }
540:
541:         private static Double getDoubleValue(Object value)
542:         {
543:•                if (!(value instanceof Number))
544:                 {
545:                         return null;
546:                 }
547:
548:                 Double doubleValue = ((Number) value).doubleValue();
549:
550:                 return doubleValue;
551:         }
552:
553:         static void validateNumbers(Object left, Object right, String operator)
554:         {
555:•                if (!(left instanceof Number) || !(right instanceof Number))
556:                 {
557:                         throw new IllegalArgumentException(operator
558:                                         + " is only supported for numbers. Got " + left + " and "
559:                                         + right);
560:                 }
561:         }
562:
563:         private static void validateNumber(Object arg, String operator)
564:         {
565:•                if (!(arg instanceof Number))
566:                 {
567:                         throw new IllegalArgumentException(operator
568:                                         + " is only supported for numbers. Got " + arg);
569:                 }
570:         }
571: }