static L> tok_typesAndNamesOfParams(L tok) { try { new L> out; for (int i = 1; i < l(tok); ) { S t = tok.get(i); if (eq(t, "final")) t = get(tok, i += 2); assertTrue(isIdentifier(t)); i += 2; S type = t, name = "?"; while (eq(get(tok, i), ".")) { type += "." + assertIdentifier(get(tok, i+2)); i += 4; } // just a parameter name, no type if (eqOneOf(get(tok, i), null, ",")) { name = type; type = "?"; } else { if (eq(tok.get(i), "<")) { int j = findEndOfTypeArgs(tok, i)-1; while (eq(get(tok, j), "[") && eq(get(tok, j+2), "]")) j += 4; type += trimJoinSubList(tok, i, j+1); S id = assertIdentifier(tok.get(j+2)); i = j+2; } while (eq(get(tok, i), "[") && eq(get(tok, i+2), "]")) { i += 4; type += "[]"; } name = assertIdentifier(tok.get(i)); i += 2; while (eq(get(tok, i), "[") && eq(get(tok, i+2), "]")) { i += 4; type += "[]"; } if (i < l(tok)) { assertEquals(get(tok, i), ","); i += 2; } } out.add(pair(type, name)); } ret out; } catch e { print("Bad parameter declaration: " + join(tok)); throw rethrow(e); } } static L tok_typesOfParams(S s) { ret tok_typesOfParams(javaTok(s)); }