示例#1
0
 @Nullable
 private static PsiReferenceParameterList extractReferenceParameterList(
     final PsiClass superClass, final PsiReferenceList extendsList) {
   for (PsiJavaCodeReferenceElement referenceElement : extendsList.getReferenceElements()) {
     final PsiElement element = referenceElement.resolve();
     if (element instanceof PsiClass
         && InheritanceUtil.isInheritorOrSelf((PsiClass) element, superClass, true)) {
       return referenceElement.getParameterList();
     }
   }
   return null;
 }
 @Nullable
 private PsiType extractListTypeFromContainingClass(
   PsiElement element) {
   PsiClass listClass = PsiTreeUtil.getParentOfType(element,
                                                    PsiClass.class);
   if (listClass == null) {
     return null;
   }
   final PsiMethod[] getMethods =
     listClass.findMethodsByName("get", true);
   if (getMethods.length == 0) {
     return null;
   }
   final PsiType type = getMethods[0].getReturnType();
   if (!(type instanceof PsiClassType)) {
     return null;
   }
   final PsiClassType classType = (PsiClassType)type;
   final PsiClass parameterClass = classType.resolve();
   if (parameterClass == null) {
     return null;
   }
   PsiClass subClass = null;
   while (listClass != null && !listClass.hasTypeParameters()) {
     subClass = listClass;
     listClass = listClass.getSuperClass();
   }
   if (listClass == null || subClass == null) {
     return TypeUtils.getObjectType(element);
   }
   final PsiTypeParameter[] typeParameters =
     listClass.getTypeParameters();
   if (!parameterClass.equals(typeParameters[0])) {
     return TypeUtils.getObjectType(element);
   }
   final PsiReferenceList extendsList = subClass.getExtendsList();
   if (extendsList == null) {
     return null;
   }
   final PsiJavaCodeReferenceElement[] referenceElements =
     extendsList.getReferenceElements();
   if (referenceElements.length == 0) {
     return null;
   }
   final PsiType[] types =
     referenceElements[0].getTypeParameters();
   if (types.length == 0) {
     return TypeUtils.getObjectType(element);
   }
   return types[0];
 }
  private static void processCallerMethod(
      JavaChangeInfo changeInfo,
      PsiMethod caller,
      PsiMethod baseMethod,
      boolean toInsertParams,
      boolean toInsertThrows)
      throws IncorrectOperationException {
    LOG.assertTrue(toInsertParams || toInsertThrows);
    if (toInsertParams) {
      List<PsiParameter> newParameters = new ArrayList<PsiParameter>();
      ContainerUtil.addAll(newParameters, caller.getParameterList().getParameters());
      final JavaParameterInfo[] primaryNewParms = changeInfo.getNewParameters();
      PsiSubstitutor substitutor =
          baseMethod == null
              ? PsiSubstitutor.EMPTY
              : ChangeSignatureProcessor.calculateSubstitutor(caller, baseMethod);
      for (JavaParameterInfo info : primaryNewParms) {
        if (info.getOldIndex() < 0)
          newParameters.add(createNewParameter(changeInfo, info, substitutor));
      }
      PsiParameter[] arrayed = newParameters.toArray(new PsiParameter[newParameters.size()]);
      boolean[] toRemoveParm = new boolean[arrayed.length];
      Arrays.fill(toRemoveParm, false);
      resolveParameterVsFieldsConflicts(arrayed, caller, caller.getParameterList(), toRemoveParm);
    }

    if (toInsertThrows) {
      List<PsiJavaCodeReferenceElement> newThrowns = new ArrayList<PsiJavaCodeReferenceElement>();
      final PsiReferenceList throwsList = caller.getThrowsList();
      ContainerUtil.addAll(newThrowns, throwsList.getReferenceElements());
      final ThrownExceptionInfo[] primaryNewExns = changeInfo.getNewExceptions();
      for (ThrownExceptionInfo thrownExceptionInfo : primaryNewExns) {
        if (thrownExceptionInfo.getOldIndex() < 0) {
          final PsiClassType type =
              (PsiClassType) thrownExceptionInfo.createType(caller, caller.getManager());
          final PsiJavaCodeReferenceElement ref =
              JavaPsiFacade.getInstance(caller.getProject())
                  .getElementFactory()
                  .createReferenceElementByType(type);
          newThrowns.add(ref);
        }
      }
      PsiJavaCodeReferenceElement[] arrayed =
          newThrowns.toArray(new PsiJavaCodeReferenceElement[newThrowns.size()]);
      boolean[] toRemoveParm = new boolean[arrayed.length];
      Arrays.fill(toRemoveParm, false);
      ChangeSignatureUtil.synchronizeList(
          throwsList, Arrays.asList(arrayed), ThrowsList.INSTANCE, toRemoveParm);
    }
  }
 private static boolean isInExtendsList(
     final RefJavaElement to, final PsiReferenceList extendsList) {
   if (extendsList != null) {
     final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements();
     for (PsiJavaCodeReferenceElement referenceElement : referenceElements) {
       final PsiReferenceParameterList parameterList = referenceElement.getParameterList();
       if (parameterList != null) {
         for (PsiType type : parameterList.getTypeArguments()) {
           if (extendsList
               .getManager()
               .areElementsEquivalent(PsiUtil.resolveClassInType(type), to.getElement())) {
             return true;
           }
         }
       }
     }
   }
   return false;
 }
 public void testClassTypeParamsPresentation() throws Exception {
   PsiClass psiClass = getTestClass();
   final PsiReferenceList extendsList = psiClass.getExtendsList();
   final PsiJavaCodeReferenceElement referenceElement = extendsList.getReferenceElements()[0];
   final PsiClass superClass = extendsList.getReferencedTypes()[0].resolve();
   final File htmlPath =
       new File(
           JavaTestUtil.getJavaTestDataPath()
               + "/codeInsight/javadocIG/"
               + getTestName(true)
               + ".html");
   String htmlText = FileUtil.loadFile(htmlPath);
   String docInfo =
       new JavaDocumentationProvider().getQuickNavigateInfo(superClass, referenceElement);
   assertNotNull(docInfo);
   assertEquals(
       StringUtil.convertLineSeparators(htmlText.trim()),
       StringUtil.convertLineSeparators(docInfo.trim()));
 }
 public List<PsiJavaCodeReferenceElement> getChildren(PsiReferenceList throwsList) {
   return Arrays.asList(throwsList.getReferenceElements());
 }
  private void generatorLayoutCode(String contextName, String findPre) {
    List<Element> editTextElements = new ArrayList<>();
    List<Element> clickableElements = new ArrayList<>();
    List<Element> itemClickableElements = new ArrayList<>();

    // generator findViewById code in initView() method
    StringBuilder initView = new StringBuilder();
    if (TextUtils.isEmpty(findPre)) {
      initView.append("private void initView() {\n");
    } else {
      initView.append("private void initView(View " + findPre + ") {\n");
    }

    for (Element element : mElements) {
      String pre = TextUtils.isEmpty(findPre) ? "" : findPre + ".";
      initView.append(
          element.getFieldName()
              + " = ("
              + element.name
              + ") "
              + pre
              + "findViewById("
              + element.getFullID()
              + ");\n");

      // set flag
      if (element.isEditText) {
        editTextElements.add(element);
      }
      if (element.isClickable) {
        clickableElements.add(element);
      }
      if (element.isItemClickable) {
        itemClickableElements.add(element);
      }
    }

    // generator EditText validate code if need
    StringBuilder sbEditText = new StringBuilder();
    if (editTextElements.size() > 0) {

      sbEditText.append("private void submit() {\n");
      sbEditText.append("\t\t// validate\n");

      for (Element element : editTextElements) {
        // generator EditText string name
        String idName = element.id;
        int index = idName.lastIndexOf("_");
        String name = index == -1 ? idName : idName.substring(index + 1);
        if (name.equals(idName)) {
          name += "String";
        }

        sbEditText.append("String " + name + " = " + idName + ".getText().toString().trim();\n");
        sbEditText.append("if(TextUtils.isEmpty(" + name + ")) {\n");
        // 提示的toast为EditText的hint文字,无hint时格式为"name不能为空"
        String emptyTint = name + "不能为空";
        String hint = element.xml.getAttributeValue("android:hint");
        if (!TextUtils.isEmpty(hint) && !hint.startsWith("@string")) {
          emptyTint = hint;
        }
        sbEditText.append(
            "Toast.makeText("
                + contextName
                + ", \""
                + emptyTint
                + "\", Toast.LENGTH_SHORT).show();\n");
        sbEditText.append("return;\n");
        sbEditText.append("}\n");
        sbEditText.append("\n");
      }

      sbEditText.append("\t\t// TODO validate success, do something\n");
      sbEditText.append("\n\n}\n");
    }

    // generator clickable code if need
    StringBuilder sbClickable = new StringBuilder();
    if (clickableElements.size() > 0) {
      // let class implement OnClickListener
      PsiReferenceList implementsList = mClass.getImplementsList();
      if (implementsList != null) {
        PsiJavaCodeReferenceElement[] referenceElements = implementsList.getReferenceElements();
        boolean hasImpl = false;
        for (PsiJavaCodeReferenceElement re : referenceElements) {
          hasImpl = re.getText().contains("OnClickListener");
        }
        // add implement if not exist
        if (!hasImpl) {
          PsiJavaCodeReferenceElement pjcre =
              mFactory.createReferenceElementByFQClassName(
                  "android.view.View.OnClickListener", mClass.getResolveScope());
          implementsList.add(pjcre);
        }
      }

      initView.append("\n");

      sbClickable
          .append("@Override public void onClick(View v) {\n")
          .append("switch (v.getId()) {\n");

      for (Element element : clickableElements) {
        // generator setOnClickListener code in initView()
        initView.append(element.getFieldName() + ".setOnClickListener(this);\n");

        // generator override public void onClick(View v) method
        sbClickable.append("case " + element.getFullID() + " :\n\nbreak;\n");
      }
      sbClickable.append("}\n}");
    }

    // generator itemClickable code if need
    for (Element element : itemClickableElements) {
      // generator setOnClickListener code in initView()
      initView.append(
          element.getFieldName()
              + ".setOnItemClickListener(new AdapterView.OnItemClickListener() {\n");
      initView.append("@Override\n");
      initView.append(
          "public void onItemClick(AdapterView<?> parent, View view, int position, long id) {\n\n");
      initView.append("}\n");
      initView.append("});\n");
    }

    initView.append("}\n");

    PsiMethod[] initViewMethods = mClass.findMethodsByName("initView", false);
    if (initViewMethods.length > 0 && initViewMethods[0].getBody() != null) {
      // already have method
      // append non-repeated field
      PsiCodeBlock initViewMethodBody = initViewMethods[0].getBody();

      for (Element element : mElements) {

        // append findViewById
        String pre = TextUtils.isEmpty(findPre) ? "" : findPre + ".";
        String s2 =
            element.getFieldName()
                + " = ("
                + element.name
                + ") "
                + pre
                + "findViewById("
                + element.getFullID()
                + ");";
        initViewMethodBody.add(mFactory.createStatementFromText(s2, initViewMethods[0]));

        // append setOnClickListener
        String s1 = element.getFieldName() + ".setOnClickListener(this);";
        initViewMethodBody.add(mFactory.createStatementFromText(s1, initViewMethods[0]));
      }
    } else {
      // new method
      mClass.add(mFactory.createMethodFromText(initView.toString(), mClass));
    }

    if (clickableElements.size() > 0) {
      PsiMethod[] onClickMethods = mClass.findMethodsByName("onClick", false);
      if (onClickMethods.length > 0 && onClickMethods[0].getBody() != null) {
        // already have method
        // append non-repeated field
        PsiCodeBlock onClickMethodBody = onClickMethods[0].getBody();

        for (PsiElement element : onClickMethodBody.getChildren()) {
          if (element instanceof PsiSwitchStatement) {
            PsiSwitchStatement switchStatement = (PsiSwitchStatement) element;
            PsiCodeBlock body = switchStatement.getBody();
            if (body != null) {
              for (Element clickableElement : clickableElements) {
                String caseStr = "case " + clickableElement.getFullID() + " :";
                body.add(mFactory.createStatementFromText(caseStr, body));
                body.add(mFactory.createStatementFromText("break;", body));
              }
            }
            break;
          }
        }
      } else {
        // new method
        mClass.add(mFactory.createMethodFromText(sbClickable.toString(), mClass));
      }
    }

    if (editTextElements.size() > 0) {
      mClass.add(mFactory.createMethodFromText(sbEditText.toString(), mClass));
    }
  }