/** Extracts reference metrics from a single instruction. */ public void extract(Instruction inst) { String name = null; if (inst == null) { return; } if (!(inst instanceof RootInst)) { refs.increment(inst); } switch (inst.getType()) { case TEXT: refs.textBytes += ((TextInst) inst).getView().length(); break; case ALTERNATES_WITH: AlternatesWithInst alternatesWith = (AlternatesWithInst) inst; extractBlock(alternatesWith.getConsequent()); extract(alternatesWith.getAlternative()); break; case IF: { BlockInstruction blockInst = (BlockInstruction) inst; refs.addIfInstruction(blockInst); if (inst instanceof IfInst) { IfInst ifInst = (IfInst) inst; for (Object[] var : ifInst.getVariables()) { name = ReprEmitter.get(var); refs.addVariable(name); } } else { IfPredicateInst ifInst = (IfPredicateInst) inst; refs.increment(ifInst.getPredicate()); } extractBlock(blockInst.getConsequent()); extract(blockInst.getAlternative()); break; } case OR_PREDICATE: case PREDICATE: PredicateInst predicateInst = (PredicateInst) inst; Predicate predicate = predicateInst.getPredicate(); if (predicate != null) { refs.increment(predicate); List<String> varRefs = predicate.getVariableNames(predicateInst.getArguments()); for (String varRef : varRefs) { refs.addVariable(varRef); } } extractBlock(predicateInst.getConsequent()); extract(predicateInst.getAlternative()); break; case REPEATED: RepeatedInst repeated = (RepeatedInst) inst; name = ReprEmitter.get(repeated.getVariable()); refs.pushSection(name); extractBlock(repeated.getConsequent()); extract(repeated.getAlternative()); extract(repeated.getAlternatesWith()); refs.popSection(); break; case ROOT: extractBlock(((RootInst) inst).getConsequent()); break; case SECTION: SectionInst section = (SectionInst) inst; name = ReprEmitter.get(section.getVariable()); refs.pushSection(name); extractBlock(section.getConsequent()); extract(section.getAlternative()); refs.popSection(); break; case VARIABLE: VariableInst variable = (VariableInst) inst; name = ReprEmitter.get(variable.getVariable()); refs.addVariable(name); for (FormatterCall call : variable.getFormatters()) { refs.increment(call.getFormatter()); } break; default: break; } }