// "Sane": top-level or type argument private void traverse1(N n, ATypeElement te, List<Integer> ls) { N elType = getElementType(n); if (elType == null) { // no array, so the prefix corresponds to the type right here // System.out.printf("non-array: map(%s, getInnerType(%s, %s)=%s)%n", // n, te, ls, getInnerType(te, ls)); map(n, getInnerType(te, ls)); int nta = numTypeArguments(n); for (int tai = 0; tai < nta; tai++) { ls.add(tai); traverse1(getTypeArgument(n, tai), te, ls); ls.remove(ls.size() - 1); } } else { // System.out.printf("array top-level: map(%s, getInnerType(%s, %s)=%s)%n", // n, te, ls, getInnerType(te, ls)); map(n, getInnerType(te, ls)); // at least one array layer to confuse us int layers = 0; while ((elType = getElementType(n)) != null) { ls.add(layers); // System.out.printf("layers=%d, map(%s, getInnerType(%s, %s)=%s)%n", // layers, elType, te, ls, getInnerType(te, ls)); map(elType, getInnerType(te, ls)); ls.remove(ls.size() - 1); n = elType; layers++; } // // n is now the innermost element type // // map it to the prefix // map(n, getInnerType(te, ls)); // hack for type arguments of the innermost element type ls.add(layers - 1); int nta = numTypeArguments(n); for (int tai = 0; tai < nta; tai++) { ls.add(tai); traverse1(getTypeArgument(n, tai), te, ls); ls.remove(ls.size() - 1); } ls.remove(ls.size() - 1); } }
private static ATypeElement getInnerType(ATypeElement te, /*@ReadOnly*/ List<Integer> ls) { if (ls.isEmpty()) return te; else return te.innerTypes.vivify(new InnerTypeLocation(ls)); }