@Override
 public void visitClass(@NotNull PsiClass aClass) {
   // no call to super, so it doesn't drill down
   if (aClass.isInterface() || aClass.isAnnotationType()) {
     return;
   }
   if (!SerializationUtils.isSerializable(aClass)) {
     return;
   }
   PsiClass ancestor = aClass.getSuperClass();
   final Set<PsiClass> visitedClasses = new HashSet<PsiClass>(16);
   while (ancestor != null && SerializationUtils.isSerializable(ancestor)) {
     ancestor = ancestor.getSuperClass();
     if (!visitedClasses.add(ancestor)) {
       return;
     }
   }
   if (ancestor == null) {
     return; // can't happen, since Object isn't serializable,
     //// but I don't trust the PSI as far as I can throw it
   }
   if (classHasNoArgConstructor(ancestor)) {
     return;
   }
   registerClassError(aClass, ancestor);
 }
  @Override
  public List<AbstractStepDefinition> loadStepsFor(
      @Nullable PsiFile featureFile, @NotNull Module module) {
    final GlobalSearchScope dependenciesScope =
        module.getModuleWithDependenciesAndLibrariesScope(true);

    PsiClass stepDefAnnotationClass =
        JavaPsiFacade.getInstance(module.getProject())
            .findClass(CUCUMBER_RUNTIME_JAVA_STEP_DEF_ANNOTATION, dependenciesScope);
    if (stepDefAnnotationClass == null) {
      return Collections.emptyList();
    }

    final List<AbstractStepDefinition> result = new ArrayList<>();
    final Query<PsiClass> stepDefAnnotations =
        AnnotatedElementsSearch.searchPsiClasses(stepDefAnnotationClass, dependenciesScope);
    for (PsiClass annotationClass : stepDefAnnotations) {
      if (annotationClass.isAnnotationType()) {
        final Query<PsiMethod> javaStepDefinitions =
            AnnotatedElementsSearch.searchPsiMethods(annotationClass, dependenciesScope);
        for (PsiMethod stepDefMethod : javaStepDefinitions) {
          result.add(new JavaStepDefinition(stepDefMethod));
        }
      }
    }
    return result;
  }
  private static boolean isClassAccepted(
      final PsiClass clazz,
      @Nullable final ClassKind classKind,
      final boolean instantiatable,
      final boolean concrete,
      final boolean notInterface,
      final boolean notEnum) {
    if (classKind == ClassKind.ANNOTATION) return clazz.isAnnotationType();
    if (classKind == ClassKind.ENUM) return clazz.isEnum();

    if (instantiatable) {
      if (PsiUtil.isInstantiatable(clazz)) {
        return true;
      }
    } else if (concrete) {
      if (!clazz.hasModifierProperty(PsiModifier.ABSTRACT) && !clazz.isInterface()) {
        return true;
      }
    } else if (notInterface) {
      if (!clazz.isInterface()) {
        return true;
      }
    } else if (notEnum) {
      if (!clazz.isEnum()) {
        return true;
      }
    } else {
      return true;
    }
    return false;
  }
  @NotNull
  public GrAnnotation addAnnotation(@NotNull @NonNls String qualifiedName) {
    final PsiClass psiClass =
        JavaPsiFacade.getInstance(getProject()).findClass(qualifiedName, getResolveScope());
    final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(getProject());
    GrAnnotation annotation;
    if (psiClass != null && psiClass.isAnnotationType()) {
      annotation = (GrAnnotation) addAfter(factory.createModifierFromText("@xxx"), null);
      annotation.getClassReference().bindToElement(psiClass);
    } else {
      annotation =
          (GrAnnotation) addAfter(factory.createModifierFromText("@" + qualifiedName), null);
    }

    final PsiElement parent = getParent();
    if (!(parent instanceof GrParameter)) {
      final ASTNode node = annotation.getNode();
      final ASTNode treeNext = node.getTreeNext();
      if (treeNext != null) {
        getNode().addLeaf(TokenType.WHITE_SPACE, "\n", treeNext);
      } else {
        parent.getNode().addLeaf(TokenType.WHITE_SPACE, "\n", getNode().getTreeNext());
      }
    }

    return annotation;
  }
  // returns contained element
  private static PsiClass contained(PsiClass annotationType) {
    if (!annotationType.isAnnotationType()) return null;
    PsiMethod[] values = annotationType.findMethodsByName("value", false);
    if (values.length != 1) return null;
    PsiMethod value = values[0];
    PsiType returnType = value.getReturnType();
    if (!(returnType instanceof PsiArrayType)) return null;
    PsiType type = ((PsiArrayType) returnType).getComponentType();
    if (!(type instanceof PsiClassType)) return null;
    PsiClass contained = ((PsiClassType) type).resolve();
    if (contained == null || !contained.isAnnotationType()) return null;
    if (PsiImplUtil.findAnnotation(
            contained.getModifierList(), CommonClassNames.JAVA_LANG_ANNOTATION_REPEATABLE)
        == null) return null;

    return contained;
  }
 private static boolean isTestSubjectClass(PsiClass klass) {
   if (klass.isEnum()
       || klass.isInterface()
       || klass.isAnnotationType()
       || TestUtil.isTestClass(klass)) {
     return false;
   }
   return true;
 }
  private static void findClassUsages(
      final PsiClass psiClass,
      final PsiElement[] allElementsToDelete,
      final List<UsageInfo> usages) {
    final boolean justPrivates = containsOnlyPrivates(psiClass);
    final String qualifiedName = psiClass.getQualifiedName();
    final boolean annotationType = psiClass.isAnnotationType() && qualifiedName != null;

    ReferencesSearch.search(psiClass)
        .forEach(
            reference -> {
              final PsiElement element = reference.getElement();

              if (!isInside(element, allElementsToDelete)) {
                PsiElement parent = element.getParent();
                if (parent instanceof PsiReferenceList) {
                  final PsiElement pparent = parent.getParent();
                  if (pparent instanceof PsiClass
                      && element instanceof PsiJavaCodeReferenceElement) {
                    final PsiClass inheritor = (PsiClass) pparent;
                    // If psiClass contains only private members, then it is safe to remove it and
                    // change inheritor's extends/implements accordingly
                    if (justPrivates) {
                      if (parent.equals(inheritor.getExtendsList())
                          || parent.equals(inheritor.getImplementsList())) {
                        usages.add(
                            new SafeDeleteExtendsClassUsageInfo(
                                (PsiJavaCodeReferenceElement) element, psiClass, inheritor));
                        return true;
                      }
                    }
                  }
                }
                LOG.assertTrue(element.getTextRange() != null);
                final PsiFile containingFile = psiClass.getContainingFile();
                boolean sameFileWithSingleClass = false;
                if (containingFile instanceof PsiClassOwner) {
                  final PsiClass[] classes = ((PsiClassOwner) containingFile).getClasses();
                  sameFileWithSingleClass =
                      classes.length == 1
                          && classes[0] == psiClass
                          && element.getContainingFile() == containingFile;
                }

                final boolean safeDelete = sameFileWithSingleClass || isInNonStaticImport(element);
                if (annotationType && parent instanceof PsiAnnotation) {
                  usages.add(
                      new SafeDeleteAnnotation((PsiAnnotation) parent, psiClass, safeDelete));
                } else {
                  usages.add(
                      new SafeDeleteReferenceJavaDeleteUsageInfo(element, psiClass, safeDelete));
                }
              }
              return true;
            });
  }
 @Nullable
 private static PsiClass getRepeatableContainer(@NotNull PsiAnnotation annotation) {
   PsiAnnotationMemberValue containerRef = PsiImplUtil.findAttributeValue(annotation, null);
   if (!(containerRef instanceof PsiClassObjectAccessExpression)) return null;
   PsiType containerType = ((PsiClassObjectAccessExpression) containerRef).getOperand().getType();
   if (!(containerType instanceof PsiClassType)) return null;
   PsiClass container = ((PsiClassType) containerType).resolve();
   if (container == null || !container.isAnnotationType()) return null;
   return container;
 }
 @Override
 @NotNull
 public PsiClass createAnnotationType(@NotNull PsiDirectory dir, @NotNull String name)
     throws IncorrectOperationException {
   String templateName = JavaTemplateUtil.INTERNAL_ANNOTATION_TYPE_TEMPLATE_NAME;
   PsiClass someClass = createClassFromTemplate(dir, name, templateName);
   if (!someClass.isAnnotationType()) {
     throw new IncorrectOperationException(getIncorrectTemplateMessage(templateName));
   }
   return someClass;
 }
  @Test
  public void shouldNotFindBuilderForAnnotationType() {
    // given
    given(psiClass.isAnnotationType()).willReturn(true);

    // when
    PsiClass result = builderFinder.findBuilderForClass(psiClass);

    // then
    assertThat(result, is(nullValue()));
  }
  @Before
  public void setUp() {
    given(psiClass.isEnum()).willReturn(false);
    given(psiClass.isInterface()).willReturn(false);
    given(psiClass.isAnnotationType()).willReturn(false);
    given(psiClass.getProject()).willReturn(project);
    given(psiClass.getName()).willReturn(CLASS_NAME);

    given(builderClass.getName()).willReturn(BUILDER_NAME);
    given(builderClass.getProject()).willReturn(project);
  }
  @Override
  public boolean execute(
      @NotNull final AnnotatedElementsSearch.Parameters p,
      @NotNull final Processor<PsiModifierListOwner> consumer) {
    final PsiClass annClass = p.getAnnotationClass();
    assert annClass.isAnnotationType()
        : "Annotation type should be passed to annotated members search";

    final String annotationFQN = annClass.getQualifiedName();
    assert annotationFQN != null;

    final SearchScope useScope = p.getScope();

    for (final PsiElement elt : getJetAnnotationCandidates(annClass, useScope)) {
      if (notJetAnnotationEntry(elt)) continue;

      ApplicationManager.getApplication()
          .runReadAction(
              new Runnable() {
                @Override
                public void run() {
                  // TODO LazyResolve
                  AnalyzeExhaust analyzeExhaust =
                      WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(
                          (JetFile) elt.getContainingFile());
                  JetDeclaration parentOfType =
                      PsiTreeUtil.getParentOfType(elt, JetDeclaration.class);
                  if (parentOfType == null) return;
                  BindingContext context = analyzeExhaust.getBindingContext();
                  AnnotationDescriptor annotationDescriptor =
                      context.get(BindingContext.ANNOTATION, (JetAnnotationEntry) elt);
                  if (annotationDescriptor == null) return;

                  ClassifierDescriptor descriptor =
                      annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
                  if (descriptor == null) return;
                  if (!(DescriptorUtils.getFQName(descriptor).getFqName().equals(annotationFQN)))
                    return;

                  if (parentOfType instanceof JetClass) {
                    JetLightClass lightClass = JetLightClass.wrapDelegate((JetClass) parentOfType);
                    consumer.process(lightClass);
                  } else if (parentOfType instanceof JetNamedFunction) {
                    PsiMethod wrappedMethod =
                        JetLightClass.wrapMethod((JetNamedFunction) parentOfType);
                    consumer.process(wrappedMethod);
                  }
                }
              });
    }

    return true;
  }
    private static boolean containsError(PsiAnnotation annotation) {
      final PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
      if (nameRef == null) {
        return true;
      }
      final PsiClass aClass = (PsiClass) nameRef.resolve();
      if (aClass == null || !aClass.isAnnotationType()) {
        return true;
      }
      final Set<String> names = new HashSet<String>();
      final PsiAnnotationParameterList annotationParameterList = annotation.getParameterList();
      if (PsiUtilCore.hasErrorElementChild(annotationParameterList)) {
        return true;
      }
      final PsiNameValuePair[] attributes = annotationParameterList.getAttributes();
      for (PsiNameValuePair attribute : attributes) {
        final PsiReference reference = attribute.getReference();
        if (reference == null) {
          return true;
        }
        final PsiMethod method = (PsiMethod) reference.resolve();
        if (method == null) {
          return true;
        }
        final PsiAnnotationMemberValue value = attribute.getValue();
        if (value == null || PsiUtilCore.hasErrorElementChild(value)) {
          return true;
        }
        if (value instanceof PsiAnnotation && containsError((PsiAnnotation) value)) {
          return true;
        }
        if (!hasCorrectType(value, method.getReturnType())) {
          return true;
        }
        final String name = attribute.getName();
        if (!names.add(name != null ? name : PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME)) {
          return true;
        }
      }

      for (PsiMethod method : aClass.getMethods()) {
        if (!(method instanceof PsiAnnotationMethod)) {
          continue;
        }
        final PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
        if (annotationMethod.getDefaultValue() == null
            && !names.contains(annotationMethod.getName())) {
          return true; // missing a required argument
        }
      }
      return false;
    }
Example #14
0
  /**
   * Returns a set of targets where the given annotation may be applied, or {@code null} when the
   * type is not a valid annotation.
   */
  @Nullable
  public static Set<TargetType> getAnnotationTargets(@NotNull PsiClass annotationType) {
    if (!annotationType.isAnnotationType()) return null;
    PsiModifierList modifierList = annotationType.getModifierList();
    if (modifierList == null) return null;
    PsiAnnotation target =
        modifierList.findAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_TARGET);
    if (target == null)
      return DEFAULT_TARGETS; // if omitted it is applicable to all but Java 8
                              // TYPE_USE/TYPE_PARAMETERS targets

    return extractRequiredAnnotationTargets(target.findAttributeValue(null));
  }
 @Nullable
 public static HighlightInfo checkCyclicMemberType(PsiTypeElement typeElement, PsiClass aClass) {
   LOG.assertTrue(aClass.isAnnotationType());
   PsiType type = typeElement.getType();
   final Set<PsiClass> checked = new HashSet<PsiClass>();
   if (cyclicDependencies(aClass, type, checked, aClass.getManager())) {
     String description = JavaErrorMessages.message("annotation.cyclic.element.type");
     return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
         .range(typeElement)
         .descriptionAndTooltip(description)
         .create();
   }
   return null;
 }
    @Override
    public Boolean visitClassType(PsiClassType classType) {
      if (classType.getParameters().length > 0) {
        PsiClassType rawType = classType.rawType();
        return rawType.equalsToText(CommonClassNames.JAVA_LANG_CLASS);
      }

      PsiClass aClass = classType.resolve();
      if (aClass != null && (aClass.isAnnotationType() || aClass.isEnum())) {
        return Boolean.TRUE;
      }

      return classType.equalsToText(CommonClassNames.JAVA_LANG_CLASS)
          || classType.equalsToText(CommonClassNames.JAVA_LANG_STRING);
    }
 private static boolean cyclicDependencies(
     PsiClass aClass, PsiType type, @NotNull Set<PsiClass> checked, @NotNull PsiManager manager) {
   final PsiClass resolvedClass = PsiUtil.resolveClassInType(type);
   if (resolvedClass != null && resolvedClass.isAnnotationType()) {
     if (aClass == resolvedClass) {
       return true;
     }
     if (!checked.add(resolvedClass) || !manager.isInProject(resolvedClass)) return false;
     final PsiMethod[] methods = resolvedClass.getMethods();
     for (PsiMethod method : methods) {
       if (cyclicDependencies(aClass, method.getReturnType(), checked, manager)) return true;
     }
   }
   return false;
 }
 @Override
 public void visitClass(@NotNull PsiClass aClass) {
   if (!aClass.isInterface() || aClass.isAnnotationType()) {
     return;
   }
   if (ignoreInterfacesThatOnlyDeclareConstants && aClass.getMethods().length == 0) {
     if (aClass.getFields().length != 0) {
       return;
     }
   }
   if (InheritanceUtil.hasImplementation(aClass)) {
     return;
   }
   registerClassError(aClass);
 }
  public static boolean hasAccessibleConstructor(PsiType type) {
    if (type instanceof PsiArrayType) return true;

    final PsiClass psiClass = PsiUtil.resolveClassInType(type);
    if (psiClass == null || psiClass.isEnum() || psiClass.isAnnotationType()) return false;

    if (!(psiClass instanceof PsiCompiledElement)) return true;

    final PsiMethod[] methods = psiClass.getConstructors();
    if (methods.length == 0) return true;

    for (final PsiMethod method : methods) {
      if (!method.hasModifierProperty(PsiModifier.PRIVATE)) return true;
    }
    return false;
  }
  @Nullable
  public static HighlightInfo checkMissingAttributes(PsiAnnotation annotation) {
    PsiJavaCodeReferenceElement nameRef = annotation.getNameReferenceElement();
    if (nameRef == null) return null;
    PsiClass aClass = (PsiClass) nameRef.resolve();
    if (aClass != null && aClass.isAnnotationType()) {
      Set<String> names = new HashSet<String>();
      PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes();
      for (PsiNameValuePair attribute : attributes) {
        final String name = attribute.getName();
        if (name != null) {
          names.add(name);
        } else {
          names.add(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME);
        }
      }

      PsiMethod[] annotationMethods = aClass.getMethods();
      List<String> missed = new ArrayList<String>();
      for (PsiMethod method : annotationMethods) {
        if (PsiUtil.isAnnotationMethod(method)) {
          PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method;
          if (annotationMethod.getDefaultValue() == null) {
            if (!names.contains(annotationMethod.getName())) {
              missed.add(annotationMethod.getName());
            }
          }
        }
      }

      if (!missed.isEmpty()) {
        StringBuffer buff = new StringBuffer("'" + missed.get(0) + "'");
        for (int i = 1; i < missed.size(); i++) {
          buff.append(", ");
          buff.append("'").append(missed.get(i)).append("'");
        }

        String description = JavaErrorMessages.message("annotation.missing.attribute", buff);
        return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
            .range(nameRef)
            .descriptionAndTooltip(description)
            .create();
      }
    }

    return null;
  }
Example #21
0
 private static String getContainingClassDescription(PsiClass aClass, String formatted) {
   if (aClass instanceof PsiAnonymousClass) {
     return LangBundle.message("java.terms.of.anonymous.class", formatted);
   } else {
     final String qualifiedName = aClass.getQualifiedName();
     final String className = qualifiedName != null ? qualifiedName : aClass.getName();
     if (aClass.isInterface()) {
       return LangBundle.message("java.terms.of.interface", formatted, className);
     }
     if (aClass.isEnum()) {
       return LangBundle.message("java.terms.of.enum", formatted, className);
     }
     if (aClass.isAnnotationType()) {
       return LangBundle.message("java.terms.of.annotation.type", formatted, className);
     }
     return LangBundle.message("java.terms.of.class", formatted, className);
   }
 }
  @NotNull
  public static TargetType[] getApplicableElementTypeFields(PsiElement owner) {
    if (owner instanceof PsiClass) {
      PsiClass aClass = (PsiClass) owner;
      if (aClass.isAnnotationType()) {
        return new TargetType[] {TargetType.ANNOTATION_TYPE, TargetType.TYPE};
      } else if (aClass instanceof GrTypeParameter) {
        return new TargetType[] {TargetType.TYPE_PARAMETER};
      } else {
        return new TargetType[] {TargetType.TYPE};
      }
    }
    if (owner instanceof GrMethod) {
      if (((PsiMethod) owner).isConstructor()) {
        return new TargetType[] {TargetType.CONSTRUCTOR};
      } else {
        return new TargetType[] {TargetType.METHOD};
      }
    }
    if (owner instanceof GrVariableDeclaration) {
      final GrVariable[] variables = ((GrVariableDeclaration) owner).getVariables();
      if (variables.length == 0) {
        return TargetType.EMPTY_ARRAY;
      }
      if (variables[0] instanceof GrField || ResolveUtil.isScriptField(variables[0])) {
        return new TargetType[] {TargetType.FIELD};
      } else {
        return new TargetType[] {TargetType.LOCAL_VARIABLE};
      }
    }
    if (owner instanceof GrParameter) {
      return new TargetType[] {TargetType.PARAMETER};
    }
    if (owner instanceof GrPackageDefinition) {
      return new TargetType[] {TargetType.PACKAGE};
    }
    if (owner instanceof GrTypeElement) {
      return new TargetType[] {TargetType.TYPE_USE};
    }

    return TargetType.EMPTY_ARRAY;
  }
 @NotNull
 public static PsiClassType[] getExtendsListTypes(@NotNull PsiClass psiClass) {
   if (psiClass.isEnum()) {
     PsiClassType enumSuperType =
         getEnumSuperType(
             psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory());
     return enumSuperType == null ? PsiClassType.EMPTY_ARRAY : new PsiClassType[] {enumSuperType};
   }
   if (psiClass.isAnnotationType()) {
     return new PsiClassType[] {
       getAnnotationSuperType(
           psiClass, JavaPsiFacade.getInstance(psiClass.getProject()).getElementFactory())
     };
   }
   final PsiReferenceList extendsList = psiClass.getExtendsList();
   if (extendsList != null) {
     return extendsList.getReferencedTypes();
   }
   return PsiClassType.EMPTY_ARRAY;
 }
    private void checkMember(@NotNull final PsiMember member) {
      if (member.hasModifierProperty(PsiModifier.PRIVATE)
          || member.hasModifierProperty(PsiModifier.NATIVE)) return;
      if (member instanceof PsiMethod && member instanceof SyntheticElement || !member.isPhysical())
        return;

      if (member instanceof PsiMethod) {
        PsiMethod method = (PsiMethod) member;
        if (!method.getHierarchicalMethodSignature().getSuperSignatures().isEmpty()) {
          log(member.getName() + " overrides");
          return; // overrides
        }
        if (MethodUtils.isOverridden(method)) {
          log(member.getName() + " overridden");
          return;
        }
      }
      if (member instanceof PsiEnumConstant) return;
      if (member instanceof PsiClass
          && (member instanceof PsiAnonymousClass
              || member instanceof PsiTypeParameter
              || member instanceof PsiSyntheticClass
              || PsiUtil.isLocalClass((PsiClass) member))) {
        return;
      }
      final PsiClass memberClass = member.getContainingClass();
      if (memberClass != null
          && (memberClass.isInterface()
              || memberClass.isEnum()
              || memberClass.isAnnotationType()
              || PsiUtil.isLocalClass(memberClass) && member instanceof PsiClass)) {
        return;
      }
      final PsiFile memberFile = member.getContainingFile();
      Project project = memberFile.getProject();

      if (myDeadCodeInspection.isEntryPoint(member)) {
        log(member.getName() + " is entry point");
        return;
      }

      PsiModifierList memberModifierList = member.getModifierList();
      if (memberModifierList == null) return;
      final int currentLevel = PsiUtil.getAccessLevel(memberModifierList);
      final AtomicInteger maxLevel = new AtomicInteger(PsiUtil.ACCESS_LEVEL_PRIVATE);
      final AtomicBoolean foundUsage = new AtomicBoolean();
      PsiDirectory memberDirectory = memberFile.getContainingDirectory();
      final PsiPackage memberPackage =
          memberDirectory == null
              ? null
              : JavaDirectoryService.getInstance().getPackage(memberDirectory);
      log(member.getName() + ": checking effective level for " + member);
      boolean result =
          UnusedSymbolUtil.processUsages(
              project,
              memberFile,
              member,
              new EmptyProgressIndicator(),
              null,
              new Processor<UsageInfo>() {
                @Override
                public boolean process(UsageInfo info) {
                  foundUsage.set(true);
                  PsiFile psiFile = info.getFile();
                  if (psiFile == null) return true;
                  if (!(psiFile instanceof PsiJavaFile)) {
                    log("     refd from " + psiFile.getName() + "; set to public");
                    maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC);
                    if (memberClass != null) {
                      childMembersAreUsedOutsideMyPackage.add(memberClass);
                    }
                    return false; // referenced from XML, has to be public
                  }
                  // int offset = info.getNavigationOffset();
                  // if (offset == -1) return true;
                  PsiElement element = info.getElement();
                  if (element == null) return true;
                  @PsiUtil.AccessLevel
                  int level =
                      getEffectiveLevel(element, psiFile, memberFile, memberClass, memberPackage);
                  log(
                      "    ref in file "
                          + psiFile.getName()
                          + "; level = "
                          + PsiUtil.getAccessModifier(level)
                          + "; ("
                          + element
                          + ")");
                  while (true) {
                    int oldLevel = maxLevel.get();
                    if (level <= oldLevel || maxLevel.compareAndSet(oldLevel, level)) break;
                  }
                  if (level == PsiUtil.ACCESS_LEVEL_PUBLIC && memberClass != null) {
                    childMembersAreUsedOutsideMyPackage.add(memberClass);
                  }

                  return level != PsiUtil.ACCESS_LEVEL_PUBLIC;
                }
              });

      if (!foundUsage.get()) {
        log(member.getName() + " unused; ignore");
        return; // do not propose private for unused method
      }
      int max = maxLevel.get();
      if (max == PsiUtil.ACCESS_LEVEL_PRIVATE && memberClass == null) {
        max = PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL;
      }

      log(member.getName() + ": effective level is '" + PsiUtil.getAccessModifier(max) + "'");

      if (max < currentLevel) {
        if (max == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL
            && member instanceof PsiClass
            && childMembersAreUsedOutsideMyPackage.contains(member)) {
          log(member.getName() + "  children used outside my package; ignore");
          return; // e.g. some public method is used outside my package (without importing class)
        }
        PsiElement toHighlight =
            currentLevel == PsiUtil.ACCESS_LEVEL_PACKAGE_LOCAL
                ? ((PsiNameIdentifierOwner) member).getNameIdentifier()
                : ContainerUtil.find(
                    memberModifierList.getChildren(),
                    new Condition<PsiElement>() {
                      @Override
                      public boolean value(PsiElement element) {
                        return element instanceof PsiKeyword
                            && element.getText().equals(PsiUtil.getAccessModifier(currentLevel));
                      }
                    });
        assert toHighlight != null
            : member
                + " ; "
                + ((PsiNameIdentifierOwner) member).getNameIdentifier()
                + "; "
                + memberModifierList.getText();
        myHolder.registerProblem(
            toHighlight,
            "Access can be " + PsiUtil.getAccessModifier(max),
            new ChangeModifierFix(PsiUtil.getAccessModifier(max)));
      }
    }
Example #25
0
  public SNode convertClass(PsiClass x) {

    final Wrappers._T<SNode> classifier = new Wrappers._T<SNode>();

    if (x.isAnnotationType()) {
      classifier.value =
          SConceptOperations.createNewNode("jetbrains.mps.baseLanguage.structure.Annotation", null);
    } else if (x.isEnum()) {
      classifier.value =
          SConceptOperations.createNewNode("jetbrains.mps.baseLanguage.structure.EnumClass", null);
    } else if (x.isInterface()) {
      classifier.value =
          SConceptOperations.createNewNode("jetbrains.mps.baseLanguage.structure.Interface", null);
    } else {
      classifier.value =
          SConceptOperations.createNewNode(
              "jetbrains.mps.baseLanguage.structure.ClassConcept", null);
    }

    final SNode ourConcept = SNodeOperations.getConceptDeclaration(classifier.value);

    SPropertyOperations.set(classifier.value, "name", x.getName());
    SLinkOperations.setTarget(classifier.value, "visibility", getVisibility(x), true);
    SConceptPropertyOperations.setBoolean(classifier.value, "final", isFinal(x));
    addTypeParams(x, classifier.value);

    if (isNotEmpty_rbndtb_a0m0a(SPropertyOperations.getString(classifier.value, "name"))) {
      String id =
          SNodeId.Foreign.ID_PREFIX + SPropertyOperations.getString(classifier.value, "name");
      classifier.value.setId(new SNodeId.Foreign(id));
    }

    Sequence.fromIterable(Sequence.fromArray(x.getFields()))
        .visitAll(
            new IVisitor<PsiField>() {
              public void visit(PsiField it) {
                SNode node = convertField(it, ourConcept);

                if (SNodeOperations.isInstanceOf(
                    node, "jetbrains.mps.baseLanguage.structure.StaticFieldDeclaration")) {
                  ListSequence.fromList(
                          SLinkOperations.getTargets(classifier.value, "staticField", true))
                      .addElement(
                          SNodeOperations.cast(
                              node, "jetbrains.mps.baseLanguage.structure.StaticFieldDeclaration"));
                } else if (SNodeOperations.isInstanceOf(
                    node, "jetbrains.mps.baseLanguage.structure.FieldDeclaration")) {
                  ListSequence.fromList(
                          SLinkOperations.getTargets(
                              SNodeOperations.cast(
                                  classifier.value,
                                  "jetbrains.mps.baseLanguage.structure.ClassConcept"),
                              "field",
                              true))
                      .addElement(
                          SNodeOperations.cast(
                              node, "jetbrains.mps.baseLanguage.structure.FieldDeclaration"));
                }
              }
            });

    Sequence.fromIterable(Sequence.fromArray(x.getMethods()))
        .visitAll(
            new IVisitor<PsiMethod>() {
              public void visit(PsiMethod it) {
                SNode node = convertMethod(it, ourConcept);

                if (SNodeOperations.isInstanceOf(
                    node, "jetbrains.mps.baseLanguage.structure.InstanceMethodDeclaration")) {
                  ListSequence.fromList(
                          SLinkOperations.getTargets(classifier.value, "method", true))
                      .addElement(
                          SNodeOperations.cast(
                              node,
                              "jetbrains.mps.baseLanguage.structure.InstanceMethodDeclaration"));
                } else if (SNodeOperations.isInstanceOf(
                    node, "jetbrains.mps.baseLanguage.structure.StaticMethodDeclaration")) {
                  ListSequence.fromList(
                          SLinkOperations.getTargets(
                              SNodeOperations.cast(
                                  classifier.value,
                                  "jetbrains.mps.baseLanguage.structure.ClassConcept"),
                              "staticMethod",
                              true))
                      .addElement(
                          SNodeOperations.cast(
                              node,
                              "jetbrains.mps.baseLanguage.structure.StaticMethodDeclaration"));
                } else if (SNodeOperations.isInstanceOf(
                    node, "jetbrains.mps.baseLanguage.structure.ConstructorDeclaration")) {
                  ListSequence.fromList(
                          SLinkOperations.getTargets(
                              SNodeOperations.cast(
                                  classifier.value,
                                  "jetbrains.mps.baseLanguage.structure.ClassConcept"),
                              "constructor",
                              true))
                      .addElement(
                          SNodeOperations.cast(
                              node, "jetbrains.mps.baseLanguage.structure.ConstructorDeclaration"));
                }
              }
            });

    return classifier.value;
  }
  public PsiElement findTargetMember(PsiElement element) {

    IGosuMethod method = PsiTreeUtil.getParentOfType(element, IGosuMethod.class);
    IGosuStatementList stList = PsiTreeUtil.getParentOfType(element, IGosuStatementList.class);
    if (method != null && stList == null) {
      return method;
    }

    if (PsiTreeUtil.getParentOfType(element, PsiParameterList.class) != null) {
      return PsiTreeUtil.getParentOfType(element, PsiMethod.class);
    }

    final PsiTypeParameterList typeParameterList =
        PsiTreeUtil.getParentOfType(element, PsiTypeParameterList.class);
    if (typeParameterList != null) {
      return PsiTreeUtil.getParentOfType(typeParameterList, PsiMember.class);
    }

    final PsiElement elementParent = element.getParent();
    if (elementParent instanceof PsiMethod
        && ((PsiMethod) elementParent).getNameIdentifier() == element) {
      final PsiClass containingClass = ((PsiMethod) elementParent).getContainingClass();
      if (containingClass != null && containingClass.isAnnotationType()) {
        return null;
      }
      return elementParent;
    }
    if (elementParent instanceof PsiClass
        && ((PsiClass) elementParent).getNameIdentifier() == element) {
      if (((PsiClass) elementParent).isAnnotationType()) {
        return null;
      }
      return elementParent;
    }

    final PsiCallExpression expression =
        PsiTreeUtil.getParentOfType(element, PsiCallExpression.class);
    if (expression != null) {
      final PsiExpression qualifierExpression;
      if (expression instanceof PsiMethodCallExpression) {
        qualifierExpression =
            ((PsiMethodCallExpression) expression).getMethodExpression().getQualifierExpression();
      } else if (expression instanceof PsiNewExpression) {
        qualifierExpression = ((PsiNewExpression) expression).getQualifier();
      } else {
        qualifierExpression = null;
      }
      if (PsiTreeUtil.isAncestor(qualifierExpression, element, false)) {
        final PsiExpressionList expressionList =
            PsiTreeUtil.getParentOfType(qualifierExpression, PsiExpressionList.class);
        if (expressionList != null) {
          final PsiElement parent = expressionList.getParent();
          if (parent instanceof PsiCallExpression) {
            return ((PsiCallExpression) parent).resolveMethod();
          }
        }
      } else {
        return expression.resolveMethod();
      }
    }

    final PsiReferenceParameterList referenceParameterList =
        PsiTreeUtil.getParentOfType(element, PsiReferenceParameterList.class);
    if (referenceParameterList != null) {
      final PsiJavaCodeReferenceElement referenceElement =
          PsiTreeUtil.getParentOfType(referenceParameterList, PsiJavaCodeReferenceElement.class);
      if (referenceElement != null) {
        final PsiElement resolved = referenceElement.resolve();
        if (resolved instanceof PsiClass) {
          return resolved;
        } else if (resolved instanceof PsiMethod) {
          return resolved;
        }
      }
    }
    return null;
  }