Method: findThread(SClassDefinition)

1: /*
2: * #%~
3: * The VDM Type Checker
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.typechecker.assistant.definition;
23:
24: import java.util.HashSet;
25: import java.util.LinkedList;
26: import java.util.List;
27: import java.util.Set;
28: import java.util.Vector;
29:
30: import org.overture.ast.analysis.AnalysisException;
31: import org.overture.ast.analysis.QuestionAnswerAdaptor;
32: import org.overture.ast.assistant.IAstAssistant;
33: import org.overture.ast.definitions.ABusClassDefinition;
34: import org.overture.ast.definitions.AClassInvariantDefinition;
35: import org.overture.ast.definitions.ACpuClassDefinition;
36: import org.overture.ast.definitions.AExplicitOperationDefinition;
37: import org.overture.ast.definitions.AInheritedDefinition;
38: import org.overture.ast.definitions.APerSyncDefinition;
39: import org.overture.ast.definitions.ASystemClassDefinition;
40: import org.overture.ast.definitions.AValueDefinition;
41: import org.overture.ast.definitions.PDefinition;
42: import org.overture.ast.definitions.SClassDefinition;
43: import org.overture.ast.factory.AstFactory;
44: import org.overture.ast.intf.lex.ILexLocation;
45: import org.overture.ast.intf.lex.ILexNameToken;
46: import org.overture.ast.lex.LexNameToken;
47: import org.overture.ast.patterns.PPattern;
48: import org.overture.ast.statements.PStm;
49: import org.overture.ast.typechecker.ClassDefinitionSettings;
50: import org.overture.ast.typechecker.NameScope;
51: import org.overture.ast.typechecker.Pass;
52: import org.overture.ast.types.AClassType;
53: import org.overture.ast.types.AOperationType;
54: import org.overture.ast.types.PType;
55: import org.overture.typechecker.Environment;
56: import org.overture.typechecker.FlatCheckedEnvironment;
57: import org.overture.typechecker.FlatEnvironment;
58: import org.overture.typechecker.TypeCheckInfo;
59: import org.overture.typechecker.TypeCheckerErrors;
60: import org.overture.typechecker.assistant.ITypeCheckerAssistantFactory;
61:
62: public class SClassDefinitionAssistantTC implements IAstAssistant
63: {
64:         protected static ITypeCheckerAssistantFactory af;
65:
66:         @SuppressWarnings("static-access")
67:         public SClassDefinitionAssistantTC(ITypeCheckerAssistantFactory af)
68:         {
69:                 this.af = af;
70:         }
71:
72:         public boolean hasSupertype(SClassDefinition classDefinition, PType other)
73:         {
74:
75:                 if (af.createPTypeAssistant().equals(getType(classDefinition), other))
76:                 {
77:                         return true;
78:                 } else
79:                 {
80:                         for (PType type : classDefinition.getSupertypes())
81:                         {
82:                                 AClassType sclass = (AClassType) type;
83:
84:                                 if (af.createAClassTypeAssistant().hasSupertype(sclass, other))
85:                                 {
86:                                         return true;
87:                                 }
88:                         }
89:                 }
90:
91:                 return false;
92:         }
93:
94:         public boolean isAccessible(Environment env, PDefinition field,
95:                         boolean needStatic)
96:         {
97:                 SClassDefinition self = env.findClassDefinition();
98:                 SClassDefinition target = field.getClassDefinition();
99:
100:                 if (self == null) // Not called from within a class member
101:                 {
102:                         // We're outside, so just public access
103:                         return af.createPAccessSpecifierAssistant().isPublic(field.getAccess());
104:                 } else
105:                 {
106:                         AClassType selftype = (AClassType) getType(self);
107:                         AClassType targtype = (AClassType) getType(target);
108:
109:                         if (!af.createPTypeAssistant().equals(selftype, targtype))
110:                         {
111:                                 if (af.createAClassTypeAssistant().hasSupertype(selftype, targtype))
112:                                 {
113:                                         // We're a subclass, so see public or protected
114:                                         return !af.createPAccessSpecifierAssistant().isPrivate(field.getAccess());
115:                                 } else
116:                                 {
117:                                         // We're outside, so just public/static access
118:                                         return af.createPAccessSpecifierAssistant().isPublic(field.getAccess())
119:                                                         && (needStatic ? af.createPAccessSpecifierAssistant().isStatic(field.getAccess())
120:                                                                         : true);
121:                                 }
122:                         } else
123:                         {
124:                                 // else same type, so anything goes
125:                                 return true;
126:                         }
127:                 }
128:         }
129:
130:         // public static PDefinition findType(SClassDefinition classdef,
131:         // ILexNameToken sought, String fromModule)
132:         // {
133:         // // FIXME: This method is used and outside the TypeFinder visitor so I can't delete it!
134:         // // It is used in this class "public class PrivateClassEnvironment"
135:         // // How do I proceed in this case?
136:         // if (!sought.getExplicit()
137:         // && sought.getName().equals(classdef.getName().getName())
138:         // || sought.equals(classdef.getName().getClassName()))
139:         // {
140:         // return classdef; // Class referred to as "A" or "CLASS`A"
141:         // }
142:         //
143:         // PDefinition def = PDefinitionAssistantTC.findType(classdef.getDefinitions(), sought, null);
144:         //
145:         // if (def == null)
146:         // {
147:         // for (PDefinition d : classdef.getAllInheritedDefinitions())
148:         // {
149:         // PDefinition indef = PDefinitionAssistantTC.findType(d, sought, null);
150:         //
151:         // if (indef != null)
152:         // {
153:         // def = indef;
154:         // break;
155:         // }
156:         // }
157:         // }
158:         //
159:         // return def;
160:         // }
161:
162:         public Set<PDefinition> findMatches(SClassDefinition classdef,
163:                         ILexNameToken sought)
164:         {
165:
166:                 Set<PDefinition> set = af.createPDefinitionListAssistant().findMatches(classdef.getDefinitions(), sought);
167:                 set.addAll(af.createPDefinitionListAssistant().findMatches(classdef.getAllInheritedDefinitions(), sought));
168:                 return set;
169:         }
170:
171:         public PDefinition findName(List<SClassDefinition> classes,
172:                         ILexNameToken name, NameScope scope)
173:         {
174:
175:                 SClassDefinition d = get(classes, name.getModule());
176:                 if (d != null)
177:                 {
178:                         PDefinition def = af.createPDefinitionAssistant().findName(d, name, scope);
179:
180:                         if (def != null)
181:                         {
182:                                 return def;
183:                         }
184:                 }
185:
186:                 return null;
187:         }
188:
189:         private SClassDefinition get(List<SClassDefinition> classes, String module)
190:         {
191:
192:                 for (SClassDefinition sClassDefinition : classes)
193:                 {
194:                         if (sClassDefinition.getName().getName().equals(module))
195:                         {
196:                                 return sClassDefinition;
197:                         }
198:                 }
199:                 return null;
200:         }
201:
202:         public PDefinition findType(List<SClassDefinition> classes,
203:                         ILexNameToken name)
204:         {
205:
206:                 for (SClassDefinition d : classes)
207:                 {
208:                         PDefinition def = af.createPDefinitionAssistant().findType(d, name, null);
209:
210:                         if (def != null)
211:                         {
212:                                 return def;
213:                         }
214:                 }
215:
216:                 return null;
217:         }
218:
219:         public Set<PDefinition> findMatches(List<SClassDefinition> classes,
220:                         ILexNameToken name)
221:         {
222:
223:                 Set<PDefinition> set = new HashSet<PDefinition>();
224:
225:                 for (SClassDefinition d : classes)
226:                 {
227:                         set.addAll(af.createSClassDefinitionAssistant().findMatches(d, name));
228:                 }
229:
230:                 return set;
231:         }
232:
233:         public void unusedCheck(List<SClassDefinition> classes)
234:         {
235:                 for (SClassDefinition d : classes)
236:                 {
237:                         af.createPDefinitionAssistant().unusedCheck(d);
238:                 }
239:
240:         }
241:
242:         // public static List<PDefinition> getLocalDefinitions(
243:         // SClassDefinition classDefinition)
244:         // {
245:         //
246:         // List<PDefinition> all = new Vector<PDefinition>();
247:         //
248:         // all.addAll(classDefinition.getLocalInheritedDefinitions());
249:         // all.addAll(PDefinitionListAssistantTC.singleDefinitions(classDefinition.getDefinitions()));
250:         //
251:         // return all;
252:         // }
253:
254:         public void implicitDefinitions(SClassDefinition d,
255:                         Environment publicClasses)
256:         {
257:                 if (d instanceof ASystemClassDefinition)
258:                 {
259:                         af.createPDefinitionAssistant().implicitDefinitions(d, publicClasses);
260:                         // ASystemClassDefinitionAssistantTC.implicitDefinitions((ASystemClassDefinition) d, );
261:                 } else
262:                 {
263:                         implicitDefinitionsBase(d, publicClasses);
264:                 }
265:
266:         }
267:
268:         public void implicitDefinitionsBase(SClassDefinition d,
269:                         Environment publicClasses)
270:         {
271:                 setInherited(d, publicClasses);
272:                 setInheritedDefinitions(d);
273:
274:                 AExplicitOperationDefinition invariant = getInvDefinition(d);
275:
276:                 d.setInvariant(invariant);
277:
278:                 if (invariant != null)
279:                 {
280:                         af.createPDefinitionAssistant().setClassDefinition(invariant, d);
281:                 }
282:         }
283:
284:         private AExplicitOperationDefinition getInvDefinition(SClassDefinition d)
285:         {
286:
287:                 List<PDefinition> invdefs = getInvDefs(d);
288:
289:                 if (invdefs.isEmpty())
290:                 {
291:                         return null;
292:                 }
293:
294:                 // Location of last local invariant
295:                 ILexLocation invloc = invdefs.get(invdefs.size() - 1).getLocation();
296:
297:                 AOperationType type = AstFactory.newAOperationType(invloc, new Vector<PType>(), AstFactory.newABooleanBasicType(invloc));
298:                 type.setPure(true);
299:
300:                 LexNameToken invname = new LexNameToken(d.getName().getName(), "inv_"
301:                                 + d.getName().getName(), invloc);
302:
303:                 PStm body = AstFactory.newAClassInvariantStm(invname, invdefs);
304:
305:                 return AstFactory.newAExplicitOperationDefinition(invname, type, new Vector<PPattern>(), null, null, body);
306:         }
307:
308:         public List<PDefinition> getInvDefs(SClassDefinition def)
309:         {
310:                 List<PDefinition> invdefs = new Vector<PDefinition>();
311:
312:                 if (def.getGettingInvDefs())
313:                 {
314:                         // reported elsewhere
315:                         return invdefs;
316:                 }
317:
318:                 def.setGettingInvDefs(true);
319:
320:                 for (SClassDefinition d : def.getSuperDefs())
321:                 {
322:                         invdefs.addAll(getInvDefs(d));
323:                 }
324:
325:                 for (PDefinition d : def.getDefinitions())
326:                 {
327:                         if (d instanceof AClassInvariantDefinition)
328:                         {
329:                                 invdefs.add(d);
330:                         }
331:                 }
332:
333:                 def.setGettingInvDefs(false);
334:                 return invdefs;
335:         }
336:
337:         private void setInheritedDefinitions(SClassDefinition definition)
338:         {
339:                 List<PDefinition> indefs = new Vector<PDefinition>();
340:
341:                 for (SClassDefinition sclass : definition.getSuperDefs())
342:                 {
343:                         indefs.addAll(getInheritable(sclass));
344:                 }
345:
346:                 // The inherited definitions are ordered such that the
347:                 // definitions, taken in order, will consider the overriding
348:                 // members before others.
349:
350:                 List<PDefinition> superInheritedDefinitions = new Vector<PDefinition>();
351:
352:                 for (PDefinition d : indefs)
353:                 {
354:                         superInheritedDefinitions.add(d);
355:
356:                         ILexNameToken localname = d.getName().getModifiedName(definition.getName().getName());
357:
358:                         if (af.createPDefinitionListAssistant().findName(definition.getDefinitions(), localname, NameScope.NAMESANDSTATE) == null ||
359:                                 af.createPDefinitionAssistant().isSubclassResponsibility(d))
360:                         {
361:                                 AInheritedDefinition local = AstFactory.newAInheritedDefinition(localname, d);
362:                                 definition.getLocalInheritedDefinitions().add(local);
363:                         }
364:                 }
365:
366:                 definition.setSuperInheritedDefinitions(superInheritedDefinitions);
367:                 definition.setAllInheritedDefinitions(new Vector<PDefinition>());
368:                 definition.getAllInheritedDefinitions().addAll(superInheritedDefinitions);
369:                 definition.getAllInheritedDefinitions().addAll(definition.getLocalInheritedDefinitions());
370:
371:         }
372:
373:         private List<PDefinition> getInheritable(SClassDefinition def)
374:         {
375:
376:                 List<PDefinition> defs = new Vector<PDefinition>();
377:
378:                 if (def.getGettingInheritable())
379:                 {
380:                         TypeCheckerErrors.report(3009, "Circular class hierarchy detected: "
381:                                         + def.getName(), def.getLocation(), def);
382:                         return defs;
383:                 }
384:
385:                 def.setGettingInheritable(true);
386:
387:                 // The inherited definitions are ordered such that the
388:                 // definitions, taken in order, will consider the overriding
389:                 // members before others. So we add the local definitions
390:                 // before the inherited ones.
391:
392:                 List<PDefinition> singles = af.createPDefinitionListAssistant().singleDefinitions(def.getDefinitions());
393:
394:                 for (PDefinition d : singles)
395:                 {
396:                         if (!af.createPAccessSpecifierAssistant().isPrivate(d.getAccess()))
397:                         {
398:                                 defs.add(d);
399:                         }
400:                 }
401:
402:                 for (SClassDefinition sclass : def.getSuperDefs())
403:                 {
404:                         List<PDefinition> sdefs = getInheritable(sclass);
405:
406:                         for (PDefinition d : sdefs)
407:                         {
408:                                 defs.add(d);
409:
410:                                 ILexNameToken localname = d.getName().getModifiedName(def.getName().getName());
411:
412:                                 if (af.createPDefinitionListAssistant().findName(defs, localname, NameScope.NAMESANDSTATE) == null)
413:                                 {
414:                                         AInheritedDefinition local = AstFactory.newAInheritedDefinition(localname, d);
415:                                         defs.add(local);
416:                                 }
417:                         }
418:                 }
419:
420:                 def.setGettingInheritable(false);
421:                 return defs;
422:         }
423:
424:         private void setInherited(SClassDefinition d, Environment base)
425:         {
426:                 switch (d.getSettingHierarchy())
427:                 {
428:                         case UNSET:
429:                                 d.setSettingHierarchy(ClassDefinitionSettings.INPROGRESS);
430:                                 break;
431:
432:                         case INPROGRESS:
433:                                 TypeCheckerErrors.report(3002, "Circular class hierarchy detected: "
434:                                                 + d.getName(), d.getLocation(), d);
435:                                 return;
436:
437:                         case DONE:
438:                                 return;
439:                 }
440:
441:                 af.createPDefinitionListAssistant().implicitDefinitions(d.getDefinitions(), base);
442:
443:                 for (ILexNameToken supername : d.getSupernames())
444:                 {
445:                         PDefinition def = base.findType(supername, null);
446:
447:                         if (def == null)
448:                         {
449:                                 TypeCheckerErrors.report(3003, "Undefined superclass: "
450:                                                 + supername, d.getLocation(), d);
451:                         } else if (def instanceof ACpuClassDefinition)
452:                         {
453:                                 TypeCheckerErrors.report(3298, "Cannot inherit from CPU", d.getLocation(), d);
454:                         } else if (def instanceof ABusClassDefinition)
455:                         {
456:                                 TypeCheckerErrors.report(3299, "Cannot inherit from BUS", d.getLocation(), d);
457:                         } else if (def instanceof ASystemClassDefinition)
458:                         {
459:                                 TypeCheckerErrors.report(3278, "Cannot inherit from system class "
460:                                                 + supername, d.getLocation(), d);
461:                         } else if (def instanceof SClassDefinition)
462:                         {
463:                                 SClassDefinition superdef = (SClassDefinition) def;
464:                                 setInherited(superdef, base);
465:
466:                                 d.getSuperDefs().add(superdef);
467:                                 d.getSupertypes().add(af.createPDefinitionAssistant().getType(superdef));
468:                         } else
469:                         {
470:                                 TypeCheckerErrors.report(3004, "Superclass name is not a class: "
471:                                                 + supername, d.getLocation(), d);
472:                         }
473:                 }
474:
475:                 d.setSettingHierarchy(ClassDefinitionSettings.DONE);
476:                 return;
477:
478:         }
479:
480:         public void typeResolve(SClassDefinition d,
481:                         QuestionAnswerAdaptor<TypeCheckInfo, PType> rootVisitor,
482:                         TypeCheckInfo question) throws AnalysisException
483:         {
484:
485:                 Environment cenv = new FlatEnvironment(question.assistantFactory, d.getDefinitions(), question.env);
486:                 af.createPDefinitionListAssistant().typeResolve(d.getDefinitions(), rootVisitor, new TypeCheckInfo(question.assistantFactory, cenv));
487:         }
488:
489:         public PDefinition findThread(SClassDefinition d)
490:         {
491:                 // return SClassDefinitionAssistantTC.findName(d, d.getName().getThreadName(), NameScope.NAMES);
492:                 return af.createPDefinitionAssistant().findName(d, d.getName().getThreadName(), NameScope.NAMES);
493:         }
494:
495:         public PDefinition findConstructor(SClassDefinition classdef,
496:                         List<PType> argtypes)
497:         {
498:
499:                 LexNameToken constructor = getCtorName(classdef, argtypes);
500:                 return af.createPDefinitionAssistant().findName(classdef, constructor, NameScope.NAMES);
501:         }
502:
503:         public static LexNameToken getCtorName(SClassDefinition classdef,
504:                         List<PType> argtypes)
505:         {
506:                 ILexNameToken name = classdef.getName();
507:                 LexNameToken cname = new LexNameToken(name.getName(), name.getName(), classdef.getLocation());
508:                 cname.setTypeQualifier(argtypes);
509:                 return cname;
510:         }
511:
512:         public PType getType(SClassDefinition def)
513:         {
514:                 if (def.getClasstype() == null)
515:                 {
516:                         def.setClasstype(AstFactory.newAClassType(def.getLocation(), def));
517:                 }
518:
519:                 return def.getClasstype();
520:         }
521:
522:         public void checkOver(SClassDefinition c)
523:         {
524:                 int inheritedThreads = 0;
525:                 af.createSClassDefinitionAssistant().checkOverloads(c);
526:
527:                 List<List<PDefinition>> superlist = new Vector<List<PDefinition>>();
528:
529:                 for (PDefinition def : c.getSuperDefs())
530:                 {
531:                         SClassDefinition superdef = (SClassDefinition) def;
532:                         List<PDefinition> inheritable = af.createSClassDefinitionAssistant().getInheritable(superdef);
533:                         superlist.add(inheritable);
534:
535:                         if (checkOverrides(c, inheritable))
536:                         {
537:                                 inheritedThreads++;
538:                         }
539:                 }
540:
541:                 if (inheritedThreads > 1)
542:                 {
543:                         TypeCheckerErrors.report(3001, "Class inherits thread definition from multiple supertypes", c.getLocation(), c);
544:                 }
545:
546:                 checkAmbiguities(c, superlist);
547:
548:         }
549:
550:         private void checkAmbiguities(SClassDefinition c,
551:                         List<List<PDefinition>> superlist)
552:         {
553:                 int count = superlist.size();
554:
555:                 for (int i = 0; i < count; i++)
556:                 {
557:                         List<PDefinition> defs = superlist.get(i);
558:
559:                         for (int j = i + 1; j < count; j++)
560:                         {
561:                                 List<PDefinition> defs2 = superlist.get(j);
562:                                 checkAmbiguities(c, defs, defs2);
563:                         }
564:                 }
565:
566:         }
567:
568:         private void checkAmbiguities(SClassDefinition c, List<PDefinition> defs,
569:                         List<PDefinition> defs2)
570:         {
571:
572:                 for (PDefinition indef : defs)
573:                 {
574:                         ILexNameToken localName = indef.getName().getModifiedName(c.getName().getName());
575:
576:                         for (PDefinition indef2 : defs2)
577:                         {
578:                                 if (!indef.getLocation().equals(indef2.getLocation())
579:                                                 && af.createPDefinitionAssistant().kind(indef).equals(af.createPDefinitionAssistant().kind(indef2)))
580:                                 {
581:                                         ILexNameToken localName2 = indef2.getName().getModifiedName(c.getName().getName());
582:
583:                                         if (af.getLexNameTokenAssistant().isEqual(localName, localName2))
584:                                         {
585:                                                 PDefinition override = af.createPDefinitionListAssistant().findName(c.getDefinitions(), localName, NameScope.NAMESANDSTATE);
586:
587:                                                 if (override == null) // OK if we override the ambiguity
588:                                                 {
589:                                                         TypeCheckerErrors.report(3276, "Ambiguous definitions inherited by "
590:                                                                         + c.getName().getName(), c.getLocation(), c);
591:                                                         TypeCheckerErrors.detail("1", indef.getName() + " "
592:                                                                         + indef.getLocation());
593:                                                         TypeCheckerErrors.detail("2", indef2.getName()
594:                                                                         + " " + indef2.getLocation());
595:                                                 }
596:                                         }
597:                                 }
598:                         }
599:                 }
600:
601:         }
602:
603:         private boolean checkOverrides(SClassDefinition c,
604:                         List<PDefinition> inheritable)
605:         {
606:                 boolean inheritedThread = false;
607:
608:                 for (PDefinition indef : inheritable)
609:                 {
610:                         if (indef.getName().getName().equals("thread"))
611:                         {
612:                                 inheritedThread = true;
613:                                 continue; // No other checks needed for threads
614:                         }
615:
616:                         ILexNameToken localName = indef.getName().getModifiedName(c.getName().getName());
617:
618:                         PDefinition override = af.createPDefinitionListAssistant().findName(c.getDefinitions(), localName, NameScope.NAMESANDSTATE);
619:
620:                         if (override == null)
621:                         {
622:                                 override = af.createPDefinitionListAssistant().findType(c.getDefinitions(), localName, null);
623:                         }
624:
625:                         if (override != null)
626:                         {
627:                                 if (!af.createPDefinitionAssistant().kind(indef).equals(af.createPDefinitionAssistant().kind(override)))
628:                                 {
629:                                         TypeCheckerErrors.report(3005, "Overriding a superclass member of a different kind: "
630:                                                         + override.getName(), override.getName().getLocation(), override);
631:                                         TypeCheckerErrors.detail2("This", af.createPDefinitionAssistant().kind(override), "Super", af.createPDefinitionAssistant().kind(indef));
632:                                 } else if (af.createPAccessSpecifierAssistant().narrowerThan(override.getAccess(), indef.getAccess()))
633:                                 {
634:                                         TypeCheckerErrors.report(3006, "Overriding definition reduces visibility", override.getName().getLocation(),override);
635:                                         TypeCheckerErrors.detail2("This", override.getAccess().getAccess()+" "+ override.getName(), "Super",indef.getAccess().getAccess()+" "+ indef.getName());
636:                                 }
637:                                 else if (override.getAccess().getPure() != indef.getAccess().getPure())
638:                                 {
639:                                         TypeCheckerErrors.report(3341, "Overriding definition must " + (override.getAccess().getPure() ? "not" : "also") + " be pure", override.getName().getLocation(),override);
640:                                 } else
641:                                 {
642:                                         PType to = af.createPDefinitionAssistant().getType(indef);
643:                                         PType from = af.createPDefinitionAssistant().getType(override);
644:
645:                                         // Note this uses the "parameters only" comparator option
646:
647:                                         if (!af.getTypeComparator().compatible(to, from, true))
648:                                         {
649:                                                 TypeCheckerErrors.report(3007, "Overriding member incompatible type: "
650:                                                                 + override.getName().getName(), override.getLocation(), override);
651:                                                 TypeCheckerErrors.detail2("This", override.getType(), "Super", indef.getType());
652:                                         }
653:                                 }
654:                         }
655:                 }
656:
657:                 return inheritedThread;
658:         }
659:
660:         private void checkOverloads(SClassDefinition c)
661:         {
662:                 List<String> done = new Vector<String>();
663:
664:                 List<PDefinition> singles = af.createPDefinitionListAssistant().singleDefinitions(c.getDefinitions());
665:
666:                 for (PDefinition def1 : singles)
667:                 {
668:                         for (PDefinition def2 : singles)
669:                         {
670:                                 if (def1 != def2
671:                                                 && def1.getName() != null
672:                                                 && def2.getName() != null
673:                                                 && def1.getName().getName().equals(def2.getName().getName())
674:                                                 && !done.contains(def1.getName().getName()))
675:                                 {
676:                                         if (af.createPDefinitionAssistant().isFunction(def1)
677:                                                         && af.createPDefinitionAssistant().isFunction(def2)
678:                                                         || af.createPDefinitionAssistant().isOperation(def1)
679:                                                         && af.createPDefinitionAssistant().isOperation(def2))
680:                                         {
681:                                                 PType to = def1.getType();
682:                                                 PType from = def2.getType();
683:
684:                                                 // Note this uses the "parameters only" comparator option
685:
686:                                                 if (af.getTypeComparator().compatible(to, from, true))
687:                                                 {
688:                                                         TypeCheckerErrors.report(3008, "Overloaded members indistinguishable: "
689:                                                                         + def1.getName().getName(), def1.getLocation(), def1);
690:                                                         TypeCheckerErrors.detail2(def1.getName().getName(), def1.getType(), def2.getName().getName(), def2.getType());
691:                                                         done.add(def1.getName().getName());
692:                                                 }
693:                                         } else
694:                                         {
695:                                                 // Class invariants can duplicate if there are several
696:                                                 // "inv" clauses in one class...
697:
698:                                                 if (!(def1 instanceof AClassInvariantDefinition)
699:                                                                 && !(def2 instanceof AClassInvariantDefinition)
700:                                                                 && !(def1 instanceof APerSyncDefinition)
701:                                                                 && !(def2 instanceof APerSyncDefinition))
702:                                                 {
703:                                                         TypeCheckerErrors.report(3017, "Duplicate definitions for "
704:                                                                         + def1.getName().getName(), def1.getName().getLocation(), def1);
705:                                                         TypeCheckerErrors.detail2(def1.getName().getName(), def1.getLocation().getFile().getName()
706:                                                                         + " " + def1.getLocation().toShortString(), def2.getName().getName(), def2.getLocation().getFile().getName()
707:                                                                         + " " + def2.getLocation().toShortString());
708:                                                         done.add(def1.getName().getName());
709:                                                 }
710:                                         }
711:                                 }
712:                         }
713:                 }
714:
715:         }
716:
717:         public void typeCheckPass(SClassDefinition c, Pass p, Environment base,
718:                         QuestionAnswerAdaptor<TypeCheckInfo, PType> tc)
719:                         throws AnalysisException
720:         {
721:                 if (c.getTypeChecked())
722:                 {
723:                         return;
724:                 }
725:
726:                 if (p == Pass.TYPES) // First one
727:                 {
728:                         PDefinitionListAssistantTC assistant = af.createPDefinitionListAssistant();
729:                         assistant.removeDuplicates(c.getLocalInheritedDefinitions());
730:                         List<PDefinition> localDefs = new LinkedList<PDefinition>();
731:                         localDefs.addAll(c.getDefinitions());
732:                         localDefs.addAll(c.getLocalInheritedDefinitions());
733:                         c.setIsAbstract(assistant.hasSubclassResponsibilities(assistant.removeAbstracts(localDefs)));
734:                 }
735:
736:                 for (PDefinition d : c.getDefinitions())
737:                 {
738:                         if (d.getPass() == p)
739:                         {
740:                                 Environment env = base;
741:
742:                                 if (d instanceof AValueDefinition)
743:                                 {
744:                                         // ValueDefinition body always a static context
745:                                         FlatCheckedEnvironment checked = new FlatCheckedEnvironment(af, new Vector<PDefinition>(), base, NameScope.NAMES);
746:                                         checked.setStatic(true);
747:                                         env = checked;
748:                                 }
749:
750:                                 d.apply(tc, new TypeCheckInfo(af, env, NameScope.NAMES));
751:                         }
752:                 }
753:
754:                 if (c.getInvariant() != null && c.getInvariant().getPass() == p)
755:                 {
756:                         c.getInvariant().apply(tc, new TypeCheckInfo(af, base, NameScope.NAMES));
757:                 }
758:
759:         }
760:
761:         public void initializedCheck(SClassDefinition c)
762:         {
763:                 af.createPDefinitionListAssistant().initializedCheck(c.getDefinitions());
764:         }
765:
766: }