Package: Environment

Environment

nameinstructionbranchcomplexitylinemethod
Environment(ITypeCheckerAssistantFactory, Environment)
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
dupHideCheck(List, NameScope)
M: 21 C: 122
85%
M: 2 C: 22
92%
M: 2 C: 11
85%
M: 3 C: 21
88%
M: 0 C: 1
100%
getEnclosingDefinition()
M: 0 C: 15
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isFunctional()
M: 0 C: 16
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
isFunctionalError()
M: 2 C: 14
88%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 3
100%
M: 0 C: 1
100%
listAlternatives(ILexNameToken)
M: 0 C: 24
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 5
100%
M: 0 C: 1
100%
markUsed()
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
setEnclosingDefinition(PDefinition)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
setFunctional(Boolean, Boolean)
M: 0 C: 17
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 5
100%
M: 0 C: 1
100%
toString()
M: 28 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
unusedCheck(Environment)
M: 0 C: 14
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 5
100%
M: 0 C: 1
100%

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.typechecker;
25:
26: import java.util.List;
27: import java.util.Set;
28:
29: import org.overture.ast.definitions.AStateDefinition;
30: import org.overture.ast.definitions.PDefinition;
31: import org.overture.ast.definitions.SClassDefinition;
32: import org.overture.ast.intf.lex.ILexNameToken;
33: import org.overture.ast.lex.LexNameList;
34: import org.overture.ast.typechecker.NameScope;
35: import org.overture.typechecker.assistant.ITypeCheckerAssistantFactory;
36:
37: /**
38: * The parent class of all type checking environments.
39: */
40:
41: abstract public class Environment
42: {
43:         public final ITypeCheckerAssistantFactory af;
44:
45:         /** The environment chain. */
46:         protected final Environment outer;
47:
48:         /** The enclosing func/op definition at this point, or null. */
49:         private PDefinition enclosingDefinition = null;
50:         
51:         /** Whether we are in a functional or operational context. */
52:         private Boolean isFunctional = null;
53:         
54:         /** Whether a functional context should generate errors or warnings for operation calls. */
55:         private Boolean isFunctionalError = false;
56:
57:         /**
58:          * Create an environment linking to the given outer chain.
59:          *
60:          * @param af
61:          * @param outer
62:          */
63:
64:         public Environment(ITypeCheckerAssistantFactory af, Environment outer)
65:         {
66:                 this.af = af;
67:                 this.outer = outer;
68:         }
69:
70:         /**
71:          * The the definitions that this environment can find
72:          *
73:          * @return
74:          */
75:         protected abstract List<PDefinition> getDefinitions();
76:
77:         /**
78:          * Check whether the list of definitions passed contains any duplicates, or whether any names in the list hide the
79:          * same name further down the environment chain.
80:          *
81:          * @param list
82:          * The list of definitions to check.
83:          */
84:
85:         protected void dupHideCheck(List<PDefinition> list, NameScope scope)
86:         {
87:                 LexNameList allnames = af.createPDefinitionListAssistant().getVariableNames(list);
88:
89:•                for (ILexNameToken n1 : allnames)
90:                 {
91:                         LexNameList done = new LexNameList();
92:
93:•                        for (ILexNameToken n2 : allnames)
94:                         {
95:•                                if (n1 != n2 && n1.equals(n2) && !done.contains(n1))
96:                                 {
97:                                         TypeChecker.warning(5007, "Duplicate definition: " + n1, n1.getLocation());
98:                                         done.add(n1);
99:                                 }
100:                         }
101:
102:•                        if (outer != null)
103:                         {
104:                                 // We search for any scoped name (ie. the first), but then check
105:                                 // the scope matches what we can see. If we pass scope to findName
106:                                 // it throws errors if the name does not match the scope.
107:
108:                                 PDefinition def = outer.findName(n1, NameScope.NAMESANDSTATE);
109:
110:                                 // TODO: RWL: This is not sound, however the behaviour below is not sound
111:                                 // in case def.getNameScope is null.
112:•                                if (def != null && def.getNameScope() == null)
113:                                 {
114:                                         def.setNameScope(NameScope.GLOBAL);
115:                                 }
116:
117:•                                if (def != null && !def.getLocation().equals(n1.getLocation())
118:•                                                && def.getNameScope().matches(scope))
119:                                 {
120:                                         // Reduce clutter for names in the same module/class
121:                                         String message = null;
122:
123:•                                        if (def.getLocation().getFile().equals(n1.getLocation().getFile()))
124:                                         {
125:                                                 message = def.getName() + " "
126:                                                                 + def.getLocation().toShortString()
127:                                                                 + " hidden by " + n1.getFullName();
128:                                         } else
129:                                         {
130:                                                 message = def.getName() + " " + def.getLocation()
131:                                                                 + " hidden by " + n1.getFullName();
132:                                         }
133:
134:                                         TypeChecker.warning(5008, message, n1.getLocation());
135:                                 }
136:                         }
137:                 }
138:         }
139:
140:         public PDefinition getEnclosingDefinition()
141:         {
142:•                if (enclosingDefinition != null)
143:                 {
144:                         return enclosingDefinition;
145:                 }
146:
147:•                return outer == null ? null : outer.getEnclosingDefinition();
148:         }
149:
150:         public void setEnclosingDefinition(PDefinition def)
151:         {
152:                 enclosingDefinition = def;
153:         }
154:
155:         public boolean isFunctional()
156:         {
157:•                if (isFunctional != null)
158:                 {
159:                         return isFunctional;
160:                 }
161:
162:•                return outer == null ? false : outer.isFunctional();
163:         }
164:         
165:         public boolean isFunctionalError()
166:         {
167:•                if (isFunctional != null)        // Only valid when isFunctional set
168:                 {
169:                         return isFunctionalError;
170:                 }
171:
172:•                return outer == null ? false : outer.isFunctionalError();
173:         }
174:         
175:         public void setFunctional(Boolean functional, Boolean errors)
176:         {
177:                 isFunctional = functional;
178:
179:•                if (functional != null && functional)
180:                 {
181:                         isFunctionalError = errors;
182:                 }
183:                 else
184:                 {
185:                         isFunctionalError = false;
186:                 }
187:         }
188:
189:         /**
190:          * Find a name in the environment of the given scope.
191:          *
192:          * @param name
193:          * @param scope
194:          * @return
195:          */
196:         abstract public PDefinition findName(ILexNameToken name, NameScope scope);
197:
198:         /**
199:          * Find a type in the environment.
200:          *
201:          * @param name
202:          * @param fromModule
203:          * @return
204:          */
205:         abstract public PDefinition findType(ILexNameToken name, String fromModule);
206:
207:         /**
208:          * Find the state defined in the environment, if any.
209:          *
210:          * @return
211:          */
212:         abstract public AStateDefinition findStateDefinition();
213:
214:         /**
215:          * Find the enclosing class definition, if any.
216:          *
217:          * @return
218:          */
219:         abstract public SClassDefinition findClassDefinition();
220:
221:         /**
222:          * True if the calling context is a static function or operation.
223:          *
224:          * @return
225:          */
226:         abstract public boolean isStatic();
227:
228:         /** Check whether any definitions in the environment were unused. */
229:         abstract public void unusedCheck();
230:
231:         /**
232:          * True if this is a VDM++ environment.
233:          *
234:          * @return
235:          */
236:         abstract public boolean isVDMPP();
237:
238:         /**
239:          * True if this is a VDM-RT "system" environment.
240:          *
241:          * @return
242:          */
243:         abstract public boolean isSystem();
244:
245:         /**
246:          * Find functions and operations of the given basic name.
247:          *
248:          * @param name
249:          * @return
250:          */
251:         abstract public Set<PDefinition> findMatches(ILexNameToken name);
252:
253:         /** Mark all definitions, at this level, used. */
254:         public void markUsed()
255:         {
256:                 // Nothing, by default. Implemented in flat environments.
257:         }
258:
259:         /**
260:          * Add details to a TC error with alternative fn/op name possibilities.
261:          *
262:          * @param name
263:          */
264:         public void listAlternatives(ILexNameToken name)
265:         {
266:•                for (PDefinition possible : findMatches(name))
267:                 {
268:•                        if (af.createPDefinitionAssistant().isFunctionOrOperation(possible))
269:                         {
270:                                 TypeChecker.detail("Possible", possible.getName());
271:                         }
272:                 }
273:         }
274:
275:         /**
276:          * Unravelling unused check.
277:          *
278:          * @param downTo
279:          */
280:         public void unusedCheck(Environment downTo)
281:         {
282:                 Environment p = this;
283:
284:•                while (p != null && p != downTo)
285:                 {
286:                         p.unusedCheck();
287:                         p = p.outer;
288:                 }
289:         }
290:
291:         public String toString()
292:         {
293:                 StringBuilder sb = new StringBuilder();
294:•                for (PDefinition d : getDefinitions())
295:                 {
296:                         sb.append("\n---\n");
297:                         sb.append(d.toString());
298:                 }
299:
300:                 return sb.toString();
301:         }
302:
303: }