Package: Context

Context

nameinstructionbranchcomplexitylinemethod
Context(IInterpreterAssistantFactory, ILexLocation, String, Context)
M: 0 C: 43
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 14
100%
M: 0 C: 1
100%
check(ILexNameToken)
M: 0 C: 16
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
deepCopy()
M: 48 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%
format(String, Context)
M: 40 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
get(Object)
M: 0 C: 34
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
getDepth()
M: 9 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getFrame(int)
M: 10 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getGlobal()
M: 0 C: 11
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
getRoot()
M: 14 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
getSelf()
M: 2 C: 7
78%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 1
100%
M: 0 C: 1
100%
getVisibleVariables()
M: 0 C: 24
100%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 5
100%
M: 0 C: 1
100%
locate(ILexNameToken)
M: 18 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
lookup(ILexNameToken)
M: 16 C: 8
33%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 1 C: 3
75%
M: 0 C: 1
100%
printStackFrames(PrintWriter)
M: 122 C: 0
0%
M: 10 C: 0
0%
M: 6 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%
printStackTrace(PrintWriter, boolean)
M: 45 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
putAllNew(NameValuePairList)
M: 0 C: 15
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
putList(NameValuePairList)
M: 0 C: 19
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
putNew(NameValuePair)
M: 0 C: 13
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
readObject(ObjectInputStream)
M: 13 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 4 C: 0
0%
M: 1 C: 0
0%
setPrepost(int, String)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
setThreadState(DBGPReader, CPUValue)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
static {...}
M: 2 C: 12
86%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 3
100%
M: 0 C: 1
100%
toString()
M: 28 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
writeObject(ObjectOutputStream)
M: 19 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: *
3: *        Copyright (C) 2008 Fujitsu Services Ltd.
4: *
5: *        Author: Nick Battle
6: *
7: *        This file is part of VDMJ.
8: *
9: *        VDMJ is free software: you can redistribute it and/or modify
10: *        it under the terms of the GNU General Public License as published by
11: *        the Free Software Foundation, either version 3 of the License, or
12: *        (at your option) any later version.
13: *
14: *        VDMJ is distributed in the hope that it will be useful,
15: *        but WITHOUT ANY WARRANTY; without even the implied warranty of
16: *        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17: *        GNU General Public License for more details.
18: *
19: *        You should have received a copy of the GNU General Public License
20: *        along with VDMJ. If not, see <http://www.gnu.org/licenses/>.
21: *
22: ******************************************************************************/
23:
24: package org.overture.interpreter.runtime;
25:
26: import java.io.PrintWriter;
27: import java.util.LinkedList;
28: import java.util.List;
29:
30: import org.overture.ast.intf.lex.ILexLocation;
31: import org.overture.ast.intf.lex.ILexNameToken;
32: import org.overture.interpreter.assistant.IInterpreterAssistantFactory;
33: import org.overture.interpreter.debug.DBGPReader;
34: import org.overture.interpreter.values.CPUValue;
35: import org.overture.interpreter.values.NameValuePair;
36: import org.overture.interpreter.values.NameValuePairList;
37: import org.overture.interpreter.values.ObjectValue;
38: import org.overture.interpreter.values.OperationValue;
39: import org.overture.interpreter.values.Value;
40: import org.overture.typechecker.util.LexNameTokenMap;
41:
42: /**
43: * A class to hold runtime name/value context information.
44: *
45: * @author Nick, modified by Kenneth Lausdahl
46: */
47:
48:•@SuppressWarnings("serial")
49: public class Context extends LexNameTokenMap<Value>
50: {
51:         /** Debug flag used to include extra information in toString */
52:         public final static boolean DEBUG = true;
53:         /** The running debug id of contexts */
54:         private static int nextid = 0;
55:         /** cache for transient serialization */
56:         private static final CloneTrancientMemoryCache<ThreadState> serilizationCache = new CloneTrancientMemoryCache<ThreadState>();
57:         /** The debug if of this context */
58:         protected final int id;
59:         /** The Assistant factory used by this context */
60:         public final IInterpreterAssistantFactory assistantFactory;
61:         /** The location of the context. */
62:         public final ILexLocation location;
63:         /** The name of the location. */
64:         public final String title;
65:         /** A link to a lower level context, if present. */
66:         public final Context outer;
67:         /** The thread state associated with this context. */
68:         public transient ThreadState threadState = null;
69:         /** Serialization key for the transient threadState **/
70:         private Integer threadStateSerilizationHashedId = null;
71:         /** Non-zero if this is a pre or postcondition call. */
72:         public int prepost = 0;
73:         /** Set to the error message if prepost is set. */
74:         public String prepostMsg = null;
75:         /** Set to the operation being guarded, if any. */
76:         public OperationValue guardOp = null;
77:
78:         /**
79:          * Create a context at the given location.
80:          *
81:          * @param af
82:          * @param location
83:          * @param title
84:          * @param outer
85:          */
86:
87:         public Context(IInterpreterAssistantFactory af, ILexLocation location,
88:                         String title, Context outer)
89:         {
90:                 id = nextid++;
91:                 this.assistantFactory = af;
92:                 this.location = location;
93:                 this.outer = outer;
94:                 this.title = title;
95:
96:•                if (outer != null)
97:                 {
98:                         this.threadState = outer.threadState;
99:                 }
100:         }
101:
102:         /**
103:          * Set the current thread state. Note this must be called from the thread where the context will run, which may not
104:          * be where the thread is created. And it must be called before any context chaining is performed.
105:          *
106:          * @param dbgp
107:          * @param cpu
108:          * TODO
109:          */
110:
111:         public void setThreadState(DBGPReader dbgp, CPUValue cpu)
112:         {
113:                 threadState = new ThreadState(dbgp, cpu);
114:         }
115:
116:         /**
117:          * Find the outermost context from this one.
118:          *
119:          * @return The outermost context.
120:          */
121:
122:         public Context getGlobal()
123:         {
124:                 Context op = this;
125:
126:•                while (op.outer != null)
127:                 {
128:                         op = op.outer;
129:                 }
130:
131:                 return op;
132:         }
133:
134:         /**
135:          * Find the nearest RootContext in the context chain.
136:          *
137:          * @return
138:          */
139:
140:         public RootContext getRoot()
141:         {
142:•                assert outer != null : "Root context is wrong type";
143:                 return outer.getRoot(); // RootContext overrides this!
144:         }
145:
146:         /**
147:          * Make a deep copy of the context, using Value.deepCopy. Every concrete subclass must implements its own version of
148:          * this method.
149:          *
150:          * @return
151:          */
152:
153:         public Context deepCopy()
154:         {
155:                 Context below = null;
156:
157:•                if (outer != null)
158:                 {
159:                         below = outer.deepCopy();
160:                 }
161:
162:                 Context result = new Context(assistantFactory, location, title, below);
163:                 result.threadState = threadState;
164:
165:•                for (ILexNameToken var : keySet())
166:                 {
167:                         Value v = get(var);
168:                         result.put(var, v.deepCopy());
169:                 }
170:
171:                 return result;
172:         }
173:
174:         /**
175:          * Add a list of name/value pairs to this context.
176:          *
177:          * @param nvl
178:          * A list of name/value pairs.
179:          */
180:
181:         public void putList(NameValuePairList nvl)
182:         {
183:•                for (NameValuePair nv : nvl)
184:                 {
185:                         put(nv.name, nv.value);
186:                 }
187:         }
188:
189:         public void putNew(NameValuePair nvp)
190:         {
191:•                if (get(nvp.name) == null)
192:                 {
193:                         put(nvp.name, nvp.value);
194:                 }
195:         }
196:
197:         public void putAllNew(NameValuePairList list)
198:         {
199:•                for (NameValuePair nvp : list)
200:                 {
201:                         putNew(nvp);
202:                 }
203:         }
204:
205:         /**
206:          * Get a name, taking type overloading into account. If we use the superclass method, different names are considered
207:          * different, because the map is driven by the names' hashCodes. The equals method of LexNameToken makes a
208:          * TypeComparator check, which is what we need. But we try a simple super.get() first. TODO Slow though.
209:          */
210:
211:         @Override
212:         public Value get(Object name)
213:         {
214:                 Value rv = super.get(name);
215:
216:•                if (rv == null)
217:                 {
218:•                        for (ILexNameToken var : keySet())
219:                         {
220:•                                if (assistantFactory.getLexNameTokenAssistant().isEqual(var, name))
221:                                 {
222:                                         rv = super.get(var);
223:                                         break;
224:                                 }
225:                         }
226:                 }
227:
228:                 return rv;
229:         }
230:
231:         /**
232:          * Get all visible names from this Context, with more visible values overriding those below.
233:          *
234:          * @return A new Context with all visible names.
235:          */
236:
237:         public Context getVisibleVariables()
238:         {
239:                 Context visible = new Context(assistantFactory, location, title, null);
240:
241:•                if (outer != null)
242:                 {
243:                         visible.putAll(outer.getVisibleVariables());
244:                 }
245:
246:                 visible.putAll(this); // Overriding anything below here
247:                 return visible;
248:         }
249:
250:         /**
251:          * Get the value for a given name. This searches outer contexts, if any are present.
252:          *
253:          * @param name
254:          * The name to look for.
255:          * @return The value of the name, or null.
256:          */
257:
258:         public Value check(ILexNameToken name)
259:         {
260:                 Value v = get(name);
261:
262:•                if (v == null)
263:                 {
264:•                        if (outer != null)
265:                         {
266:                                 return outer.check(name);
267:                         }
268:                 }
269:
270:                 return v;
271:         }
272:
273:         /**
274:          * Locate the Context in a chain that contains a name, if any.
275:          *
276:          * @param name
277:          * @return
278:          */
279:
280:         public Context locate(ILexNameToken name)
281:         {
282:                 Value v = get(name);
283:
284:•                if (v == null)
285:                 {
286:•                        if (outer != null)
287:                         {
288:                                 return outer.locate(name);
289:                         } else
290:                         {
291:                                 return null;
292:                         }
293:                 } else
294:                 {
295:                         return this;
296:                 }
297:         }
298:
299:         /**
300:          * Return the value of a name, else fail. If the name is not present, a {@link ContextException} is thrown.
301:          *
302:          * @param name
303:          * The name to look for.
304:          * @return The value of the name.
305:          */
306:
307:         public Value lookup(ILexNameToken name)
308:         {
309:                 Value v = check(name);
310:
311:•                if (v == null)
312:                 {
313:                         VdmRuntimeError.abort(name.getLocation(), 4034, "Name '" + name
314:                                         + "' not in scope", this);
315:                 }
316:
317:                 return v;
318:         }
319:
320:         @Override
321:         public String toString()
322:         {
323:•                return (DEBUG ? "#" + id + " " : "") + format("", this)
324:                                 + "-------------------\n" + (outer == null ? "" : outer.toString());
325:         }
326:
327:         protected String format(String indent, Context what)
328:         {
329:                 StringBuilder sb = new StringBuilder();
330:
331:•                for (ILexNameToken name : what.keySet())
332:                 {
333:                         sb.append(indent + name + " = " + what.get(name).toShortString(100)
334:                                         + "\n");
335:                 }
336:
337:                 return sb.toString();
338:         }
339:
340:         /**
341:          * This is used by the stack overflow processing via Function/OperationValue.
342:          * It is intended to print the frame titles without recursing, and to
343:          * suppress all but the top and bottom of the (presumably large) stack.
344:          */
345:         private static final int FRAMES_LIMIT        = 50;        // Top count
346:         private static final int TAIL_LIMIT                = 5;        // Bottom count
347:         
348:         public void printStackFrames(PrintWriter out)
349:         {
350:                 Context frame = this;
351:                 out.print(format("\t", frame));
352:                 int count = 0;
353:                 List<String> saved = new LinkedList<String>();
354:
355:•                while (frame.outer != null)
356:                 {
357:•                        if (++count < FRAMES_LIMIT)
358:                         {
359:                                 out.println("In context of " + frame.title + " " + frame.location);
360:                         }
361:                         else
362:                         {
363:                                 saved.add(String.format("In context of " + frame.title + " " + frame.location));
364:                         }
365:                         
366:                         frame = frame.outer;        // NB. DON'T RECURSE!
367:                 }
368:                 
369:                 int skipped = saved.size();
370:                 
371:•                if (skipped < TAIL_LIMIT)
372:                 {
373:•                        for (String s: saved)
374:                         {
375:                                 out.println(s);
376:                         }
377:                 }
378:                 else
379:                 {
380:                         out.println("... skipped " + (skipped - TAIL_LIMIT));
381:                         
382:•                        for (int i = skipped - TAIL_LIMIT; i < skipped; i++)
383:                         {
384:                                 out.println(saved.get(i));
385:                         }
386:                 }
387:
388:                 out.println("In context of " + frame.title);
389:         }
390:
391:         public void printStackTrace(PrintWriter out, boolean variables)
392:         {
393:•                if (outer == null) // Don't expand initial context
394:                 {
395:                         out.println("In context of " + title);
396:                 } else
397:                 {
398:•                        if (variables)
399:                         {
400:                                 out.print(this.format("\t", this));
401:                         }
402:
403:                         out.println("In context of " + title + " " + location);
404:                         outer.printStackTrace(out, variables);
405:                 }
406:         }
407:
408:         public int getDepth()
409:         {
410:•                return outer == null ? 0 : outer.getDepth(); // NB only roots count
411:         }
412:
413:         public Context getFrame(int depth)
414:         {
415:•                return outer == null ? this : outer.getFrame(depth);
416:         }
417:
418:         public ObjectValue getSelf()
419:         {
420:•                return outer == null ? null : outer.getSelf();
421:         }
422:
423:         public void setPrepost(int prepost, String prepostMsg)
424:         {
425:                 this.prepost = prepost;
426:                 this.prepostMsg = prepostMsg;
427:         }
428:
429:         /**
430:          * Custom serialization method handling the transient values
431:          *
432:          * @param stream
433:          * @throws java.io.IOException
434:          */
435:         private synchronized void writeObject(java.io.ObjectOutputStream stream)
436:                         throws java.io.IOException
437:         {
438:                 ThreadState tmp = this.threadState;
439:                 this.threadStateSerilizationHashedId = serilizationCache.store(this.threadState);
440:                 this.threadState = null;
441:                 stream.defaultWriteObject();
442:                 this.threadState = tmp;
443:         }
444:
445:         /**
446:          * Custom de-serialization method handling the transient values
447:          *
448:          * @param stream
449:          * @throws java.io.IOException
450:          * @throws ClassNotFoundException
451:          */
452:         private synchronized void readObject(java.io.ObjectInputStream stream)
453:                         throws java.io.IOException, ClassNotFoundException
454:         {
455:                 stream.defaultReadObject();
456:                 this.threadState = (ThreadState) serilizationCache.load(this.threadStateSerilizationHashedId);
457:                 this.threadStateSerilizationHashedId = null;
458:         }
459: }