public MethodVisitor visitMethod()

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);
                  }
                }
              }
            };
          }
        };
      }