parserImport XOCL; import Walkers; context Walkers @Class TypeChecker extends Walker @Attribute reports : Set(TypeCheckReport) (+) end // Contains all the type check reports. @Attribute justFailures : Boolean end // True when just failing checks are recorded. @Constructor(justFailures) ! end @Operation defaultWalk(e:Element,arg:Element):Element null end @Operation reWalk(v:Element,arg:Element):Element null end @Operation walkBoolean(b:Boolean,arg:Element):Element null end @Operation walkInteger(i:Integer,arg:Element):Element null end @Operation walkNull(arg:Element):Element null end @Operation walkSeq(s:SeqOfElement,arg:Element):Element if not s->isEmpty then self.walk(s->head,arg); self.walk(s->tail,arg) end end @Operation walkSet(s:SetOfElement,arg:Element):Element @For x in s do self.walk(x,arg) end end @Operation walkSlot(o:Object,s:String,value,arg:Element) let attribute = o.of().getAttribute(s) in if attribute = null then throw TypeCheckError("No attribute found for " + s) else let type = attribute.type then typeCorrect = value.isKindOf(type) in if typeCorrect then if not justFailures then self.addToReports(TypeCheckReport(o,s,value,type,typeCorrect)) end else self.addToReports(TypeCheckReport(o,s,value,type,typeCorrect)) end; self.walk(value,arg) end end end end @Operation walkString(s:String,arg:Element):Element null end @Operation walkTable(t:Table,arg:Element):Element @For key in t.keys() do self.walk(key,arg); self.walk(t.get(key),arg) end end @Operation walkVector(v:Vector,arg:Element):Element @Count i from 0 to v.size() - 1 do self.walk(v.ref(i),arg) end end end