in src/org/intellij/grammar/java/JavaHelper.java [668:775]
public MethodVisitor visitMethod(int access,
String name,
String desc,
String signature,
String[] exceptions) {
MethodInfo m = getMethodInfo(myInfo.name, name, ObjectUtils.chooseNotNull(signature, desc), exceptions);
m.modifiers = access;
m.methodType = "<init>".equals(name)? MethodType.CONSTRUCTOR :
Modifier.isStatic(access) ? MethodType.STATIC :
MethodType.INSTANCE;
myInfo.methods.add(m);
class ParamTypeAnno { int index; String anno; TypePath path; }
List<ParamTypeAnno> typeAnnos = new SmartList<>();
return new MethodVisitor(ASM_OPCODES) {
@Override
public void visitEnd() {
m.annotatedTypes.addAll(m.types);
int[] plainOffsets = new int[m.types.size()];
for (ParamTypeAnno ta : typeAnnos) {
int idx = ta.index == 0 ? 0 : 2 * (ta.index - 1) + 1;
String prevType = m.annotatedTypes.get(idx);
boolean isArray = false;
if (ta.path != null) {
isArray = true;
int typePtr = prevType.length();
for (int i = 0; i < ta.path.getLength(); i++, typePtr -= 2) {
if (!(ta.path.getStep(i) == TypePath.ARRAY_ELEMENT && typePtr > 2 &&
prevType.charAt(typePtr - 2) == '[' && prevType.charAt(typePtr - 1) == ']')) {
isArray = false;
break;
}
}
if (isArray && typePtr > 2 && prevType.charAt(typePtr - 1) == ']') isArray = false;
}
if (ta.path != null && !isArray) continue;
int bracketIdx = prevType.indexOf('[');
String newType;
if (!isArray && bracketIdx > 0) {
boolean addSpace = prevType.charAt(bracketIdx - 1) != ' ';
newType = prevType.substring(0, bracketIdx) + (addSpace ? " " : "") + "@" + ta.anno + " " + prevType.substring(bracketIdx);
}
else {
int offset = plainOffsets[idx];
newType = prevType.substring(0, offset) + "@" + ta.anno + " " + prevType.substring(offset);
plainOffsets[idx] += 2 + ta.anno.length();
}
m.annotatedTypes.set(idx, newType);
if (isArray || bracketIdx < 1) {
m.annotations.get(ta.index).remove(ta.anno);
}
}
}
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
String anno = fixClassName(desc.substring(1, desc.length() - 1));
return new MyAnnotationVisitor() {
@Override
public void visitEnd() {
if (annoParamCounter != 0) return;
m.annotations.get(0).add(anno);
}
};
}
@Override
public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
String anno = fixClassName(desc.substring(1, desc.length() - 1));
return new MyAnnotationVisitor() {
@Override
public void visitEnd() {
if (annoParamCounter != 0) return;
m.annotations.get(parameter + 1).add(anno);
}
};
}
@Override
public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
String anno = fixClassName(desc.substring(1, desc.length() - 1));
TypeReference typeReference = new TypeReference(typeRef);
return new MyAnnotationVisitor() {
@Override
public void visitEnd() {
if (annoParamCounter != 0) return;
if (typeReference.getSort() == TypeReference.METHOD_TYPE_PARAMETER) {
m.generics.get(typeReference.getTypeParameterIndex()).getAnnotations().add(anno);
}
else if (typeReference.getSort() == TypeReference.METHOD_RETURN ||
typeReference.getSort() == TypeReference.METHOD_FORMAL_PARAMETER) {
ParamTypeAnno o = new ParamTypeAnno();
o.index = typeReference.getSort() == TypeReference.METHOD_RETURN ? 0 : typeReference.getFormalParameterIndex() + 1;
o.anno = anno;
o.path = typePath;
typeAnnos.add(o);
}
else if (typeReference.getSort() == TypeReference.METHOD_TYPE_PARAMETER_BOUND) {
List<String> bounds = m.generics.get(typeReference.getTypeParameterIndex()).extendsList;
if (typeReference.getTypeParameterBoundIndex() <= bounds.size()) {
String prev = bounds.get(typeReference.getTypeParameterBoundIndex() - 1);
bounds.set(typeReference.getTypeParameterBoundIndex() - 1, "@" + anno + " " + prev);
}
}
}
};
}
};
}