final Name trait_name = readPool(names, p.readU30(), "name");
final int tag = p.readU8();
final int kind = tag & ABCConstants.TRAIT_KIND_MASK;
boolean is_method_getter_setter = false;
ITraitVisitor trait_visitor;
switch (kind)
{
case TRAIT_Var:
case TRAIT_Const:
{
int slot_id = p.readU30();
Name slot_type = readPool(names, p.readU30(), "name");
Object slot_value = readSlotDefault(p);
trait_visitor = traits_visitor.visitSlotTrait(kind, trait_name, slot_id, slot_type, slot_value);
break;
}
case TRAIT_Class:
{
trait_visitor = traits_visitor.visitClassTrait(
kind, trait_name, p.readU30(), this.readPool(classInfos, p.readU30(), "classInfo"));
break;
}
case TRAIT_Method:
case TRAIT_Getter:
case TRAIT_Setter:
{
is_method_getter_setter = true;
}
case TRAIT_Function:
{
trait_visitor = traits_visitor.visitMethodTrait(
kind, trait_name, p.readU30(), this.readPool(methodInfos, p.readU30(), "methodInfo"));
break;
}
default:
{
throw new IllegalArgumentException(String.format("illegal trait kind 0x%h at offset %d", kind, p.pos));
}
}
// provide a nil-visitor when trait visitor is null
if (trait_visitor == null)
trait_visitor = NilVisitors.NIL_TRAIT_VISITOR;
trait_visitor.visitStart();
// method, getter, setter has attributes in the high 4 bits of the kind byte
// 0x01: (1=final,0=virtual), 0x02: (1=override,0=new)
if (is_method_getter_setter)
{
trait_visitor.visitAttribute(Trait.TRAIT_FINAL, functionIsFinal(tag));
trait_visitor.visitAttribute(Trait.TRAIT_OVERRIDE, functionIsOverride(tag));
}
if (traitHasMetadata(tag))
{
final int n_entries = p.readU30();
final IMetadataVisitor mv = trait_visitor.visitMetadata(n_entries);
for (int j = 0; j < n_entries; j++)
{
final Metadata md = readPool(metadata, p.readU30(), "metadata");
if (mv != null)
mv.visit(md);
}
}
trait_visitor.visitEnd();
}
traits_visitor.visitEnd();
}