Benutzung des TL-2 Typecheckers
Der TL-2 Typechecker ist ähnlich wie verwandte Systemkomponenten
durch
erreichbar.
Benutzungsschnittstelle:
- check checkt die Klassen, die nach Meinung
des Typecheckers geprüft werden müssen in keiner besonderen Reihenfolge
bis zum ersten Fehler.
Bsp: tycoon.tl.typeChecker.check;
'DO'-Kommandos sollen aus dem System rausfliegen, deshalb gibt es
kein 'DO check'.
- checkClass(c :ClassPublic) prüft
die Klasse c unabhängig davon, ob sie geprüft werden
müsste, oder nicht.
Bsp: tycoon.tl.typeChecker.checkClass(String);
- ignore(c :ClassPublic) entfernt c
aus der Agenda, z.B. weil der Typechecker fehlerhaft ist und c
nicht durchgehen läßt. Ändert man eine Klasse, von
der c abhängt, so wandert c wieder auf die Agenda.
(likely to change)
tycoon.tl.typeChecker.ignore(TWLGram); $&^%@^%$#
- agenda gibt die aktuelle Agenda.
tycoon.tl.typeChecker.agenda;
- maxDepth begrenzt die Anzahl der calls in
den Typechecker. Default: 10000. Das kann für komplexe Klassen zu
wenig sein. Dann schafft Abhilfe:
tycoon.tl.typeChecker.maxDepth := große Zahl
- Die Agenda: Ändert sich eine Klasse oder eine Poolmethode, so
werden alle Klassen, die von ihr abhängen, in die Agenda aufgenommen.
Die Abhängigkeiten kann man sich ansehen via
tycoon.tl.typeChecker.dependencies["String"]
Def: Eine Klasse hängt ab von einem Bezeichner, wenn dieser
- Bezeichner einer Superklasse ist
- Bezeichner der Metaklasse ist
- Bezeichner der Self-Signatur ist
- oder sonstwie beim Typechecken dieser Klasse referenziert wird
[wer mal unter die Motorhaube schauen möchte]
- tycoon.tl.typeChecker.logSubTypeTests := true bedeutet soviel
wie Super-Verbose-Mode on und dient eigentlich nur der Fehlersuche.
- ebenso logTypeChecks, logValueChecks
Eigenheiten/Bugs
Typinferenz
Der Inferencer kriegt jetzt mehr raus als der alte, vor allem den wichtigen
Fall:
x.isNil ? { nil } : { x.size }
Dafür funktionieren Typ-Annotationen bei If's und Try's nicht mehr
:
c.domain.isEmpty ? fun() :Type {
ClassInstanceType.new ...
} : {
OperType.new ...
}
(Der Inferencer kriegt in diesem Beispiel nur Void als common supertype
raus). Das fun() :Type bei allen Kontrollstrukturen ignoriert
der Parser nämlich, weil bei ihnen in Zukunft gar keine Fun's sondern
einfach Blöcke hinkommen. Bei "normalen" Funs wird die Typannotation
aber beachtet. Lösung: mit Let-Bindung:
c.domain.isEmpty ? {
let result: Type = ClassInstanceType.new ...
} : {
OperType.new ...
}
Es ist im Moment etwas schwierig zu erkennen, wo der Inferencer seine
Hände im Spiel hatte; da gibt's hoffentlich noch bessere Fehlermeldungen.
Metaklassen
Metaklassen dürfen nicht mehr alles, sondern nur auf private Methoden
ihrer Instanzen zugreifen. Leider kann man das nur sicherstellen bei Variablen,
die via let instance = _new angelegt wurden. Erhält man statt
dessen ein neues Objekt indirekt über eine andere Klassenmethode,
z.B. ein selbstgeschriebenes new, so geht das nicht, und der Typechecker
meckert.
Lösung: ???. Entweder Metaklasse umschreiben, oder aber erst
mal vom Typechecken ausschließen (ignore).
Tycoon-2 Administrator
/ 23.07.97