Search in sources :

Example 16 with PsiAnnotation

use of com.intellij.psi.PsiAnnotation in project google-cloud-intellij by GoogleCloudPlatform.

the class RestSignatureInspection method getPath.

/**
 * Returns the path for psiMethod. The path can be set by the user by setting the path attribute
 * of @ApiMethod. If the path attribute is not set, a default value will be returned.
 *
 * @param psiMethod the method whose path is to be determined
 * @return the path for psiMethod
 */
public String getPath(PsiMethod psiMethod) {
    PsiModifierList modifierList = psiMethod.getModifierList();
    String path = null;
    // Check if the httpMethod was specified by user in @ApiMethod's httpMethod attribute
    for (PsiAnnotation annotation : modifierList.getAnnotations()) {
        try {
            path = getAttributeFromAnnotation(annotation, GctConstants.APP_ENGINE_ANNOTATION_API_METHOD, "path");
        } catch (InvalidAnnotationException ex) {
        // do nothing
        } catch (MissingAttributeException ex) {
            break;
        }
        if (path != null) {
            // path has a default value of ""
            if (!path.isEmpty()) {
                return path;
            } else {
                break;
            }
        }
    }
    // Determine default path
    return getDefaultPath(psiMethod);
}
Also used : PsiAnnotation(com.intellij.psi.PsiAnnotation) PsiModifierList(com.intellij.psi.PsiModifierList)

Example 17 with PsiAnnotation

use of com.intellij.psi.PsiAnnotation in project google-cloud-intellij by GoogleCloudPlatform.

the class ApiNamespaceInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final com.intellij.codeInspection.ProblemsHolder holder, boolean isOnTheFly) {
    return new EndpointPsiElementVisitor() {

        /**
         * Flags @ApiNamespace that have one or more attributes specified where both the OwnerName and
         * OwnerDomain attributes are not specified.
         */
        @Override
        public void visitAnnotation(PsiAnnotation annotation) {
            if (!EndpointUtilities.isEndpointClass(annotation)) {
                return;
            }
            if (!GctConstants.APP_ENGINE_ANNOTATION_API_NAMESPACE.equals(annotation.getQualifiedName())) {
                return;
            }
            PsiAnnotationMemberValue ownerDomainMember = annotation.findAttributeValue(API_NAMESPACE_DOMAIN_ATTRIBUTE);
            if (ownerDomainMember == null) {
                return;
            }
            String ownerDomainWithQuotes = ownerDomainMember.getText();
            PsiAnnotationMemberValue ownerNameMember = annotation.findAttributeValue(API_NAMESPACE_NAME_ATTRIBUTE);
            if (ownerNameMember == null) {
                return;
            }
            String ownerNameWithQuotes = ownerNameMember.getText();
            String ownerDomain = EndpointUtilities.removeBeginningAndEndingQuotes(ownerDomainWithQuotes);
            String ownerName = EndpointUtilities.removeBeginningAndEndingQuotes(ownerNameWithQuotes);
            // Package Path has a default value of ""
            String packagePath = EndpointUtilities.removeBeginningAndEndingQuotes(annotation.findAttributeValue(API_NAMESPACE_PACKAGE_PATH_ATTRIBUTE).getText());
            boolean allUnspecified = ownerDomain.isEmpty() && ownerName.isEmpty() && packagePath.isEmpty();
            boolean ownerFullySpecified = !ownerDomain.isEmpty() && !ownerName.isEmpty();
            // Either everything must be fully unspecified or owner domain/name must both be specified.
            if (!allUnspecified && !ownerFullySpecified) {
                holder.registerProblem(annotation, "Invalid namespace configuration. If a namespace is set," + " make sure to set an Owner Domain and Name. Package Path is optional.", new MyQuickFix());
            }
        }
    };
}
Also used : PsiAnnotation(com.intellij.psi.PsiAnnotation) PsiAnnotationMemberValue(com.intellij.psi.PsiAnnotationMemberValue) NotNull(org.jetbrains.annotations.NotNull)

Example 18 with PsiAnnotation

use of com.intellij.psi.PsiAnnotation in project google-cloud-intellij by GoogleCloudPlatform.

the class MethodNameInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new EndpointPsiElementVisitor() {

        @Override
        public void visitAnnotation(PsiAnnotation annotation) {
            if (!EndpointUtilities.isEndpointClass(annotation)) {
                return;
            }
            if (!GctConstants.APP_ENGINE_ANNOTATION_API_METHOD.equals(annotation.getQualifiedName())) {
                return;
            }
            PsiAnnotationMemberValue memberValue = annotation.findAttributeValue(API_NAME_ATTRIBUTE);
            if (memberValue == null) {
                return;
            }
            String nameValueWithQuotes = memberValue.getText();
            String nameValue = EndpointUtilities.removeBeginningAndEndingQuotes(nameValueWithQuotes);
            if (nameValue.isEmpty()) {
                return;
            }
            if (!API_NAME_PATTERN.matcher(EndpointUtilities.collapseSequenceOfDots(nameValue)).matches()) {
                holder.registerProblem(memberValue, "Invalid method name: letters, digits, underscores and dots are acceptable " + "characters. Leading and trailing dots are prohibited.", new MyQuickFix());
            }
        }
    };
}
Also used : PsiAnnotation(com.intellij.psi.PsiAnnotation) PsiAnnotationMemberValue(com.intellij.psi.PsiAnnotationMemberValue) NotNull(org.jetbrains.annotations.NotNull)

Example 19 with PsiAnnotation

use of com.intellij.psi.PsiAnnotation in project google-cloud-intellij by GoogleCloudPlatform.

the class NamedResourceInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new EndpointPsiElementVisitor() {

        @Override
        public void visitMethod(PsiMethod psiMethod) {
            if (!EndpointUtilities.isEndpointClass(psiMethod)) {
                return;
            }
            if (hasTransformer(psiMethod)) {
                return;
            }
            // Check if method is public or non-static
            if (!EndpointUtilities.isApiMethod(psiMethod)) {
                return;
            }
            PsiParameterList parameterList = psiMethod.getParameterList();
            Map<String, PsiParameter> methodNames = Maps.newHashMap();
            for (PsiParameter psiParameter : parameterList.getParameters()) {
                validateMethodNameUnique(psiParameter, methodNames);
            }
        }

        private void validateMethodNameUnique(PsiParameter psiParameter, Map<String, PsiParameter> methodNames) {
            PsiModifierList modifierList = psiParameter.getModifierList();
            if (modifierList == null) {
                return;
            }
            PsiAnnotation annotation = modifierList.findAnnotation("javax.inject.Named");
            if (annotation == null) {
                annotation = modifierList.findAnnotation(GctConstants.APP_ENGINE_ANNOTATION_NAMED);
                if (annotation == null) {
                    return;
                }
            }
            PsiNameValuePair[] nameValuePairs = annotation.getParameterList().getAttributes();
            if (nameValuePairs.length == 0) {
                // For @Named, @Named()
                holder.registerProblem(annotation, "Parameter name must be specified.", new MissingNameQuickFix());
                return;
            } else if (nameValuePairs.length != 1) {
                return;
            }
            if (nameValuePairs[0] == null) {
                return;
            }
            PsiAnnotationMemberValue memberValue = nameValuePairs[0].getValue();
            if (memberValue == null) {
                return;
            }
            String nameValueWithQuotes = memberValue.getText();
            String nameValue = EndpointUtilities.removeBeginningAndEndingQuotes(nameValueWithQuotes);
            // For @Named("")
            if (nameValue.isEmpty()) {
                holder.registerProblem(annotation, "Parameter name must be specified.", new MissingNameQuickFix());
                return;
            }
            PsiParameter seenParameter = methodNames.get(nameValue);
            if (seenParameter == null) {
                methodNames.put(nameValue, psiParameter);
            } else {
                holder.registerProblem(annotation, "Duplicate parameter name: " + nameValue + ". Parameter names must be unique.", new DuplicateNameQuickFix());
            }
        }
    };
}
Also used : PsiMethod(com.intellij.psi.PsiMethod) PsiNameValuePair(com.intellij.psi.PsiNameValuePair) PsiModifierList(com.intellij.psi.PsiModifierList) PsiParameter(com.intellij.psi.PsiParameter) PsiParameterList(com.intellij.psi.PsiParameterList) PsiAnnotation(com.intellij.psi.PsiAnnotation) Map(java.util.Map) PsiAnnotationMemberValue(com.intellij.psi.PsiAnnotationMemberValue) NotNull(org.jetbrains.annotations.NotNull)

Example 20 with PsiAnnotation

use of com.intellij.psi.PsiAnnotation in project google-cloud-intellij by GoogleCloudPlatform.

the class FullMethodNameInspection method buildVisitor.

@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
    return new EndpointPsiElementVisitor() {

        /**
         * Flags @ApiMethods that have a duplicate API method name.
         */
        @Override
        public void visitClass(PsiClass psiClass) {
            if (!EndpointUtilities.isEndpointClass(psiClass)) {
                return;
            }
            PsiMethod[] allMethods = psiClass.getMethods();
            Map<String, PsiMethod> apiMethodNames = Maps.newHashMap();
            for (PsiMethod psiMethod : allMethods) {
                validateBackendMethodNameUnique(psiMethod, apiMethodNames);
            }
        }

        /**
         * Checks that the API method name specified in @APiMethod's name attribute is unique. API
         * methods.
         */
        private void validateBackendMethodNameUnique(PsiMethod psiMethod, Map<String, PsiMethod> apiMethodNames) {
            // Check if method is a public or non-static
            if (!EndpointUtilities.isApiMethod(psiMethod)) {
                return;
            }
            if (psiMethod.isConstructor()) {
                return;
            }
            // Get @ApiMethod's name attribute
            PsiModifierList modifierList = psiMethod.getModifierList();
            PsiAnnotation apiMethodAnnotation = modifierList.findAnnotation(GctConstants.APP_ENGINE_ANNOTATION_API_METHOD);
            if (apiMethodAnnotation == null) {
                return;
            }
            PsiAnnotationMemberValue apiMethodNameAttribute = apiMethodAnnotation.findAttributeValue(API_METHOD_NAME_ATTRIBUTE);
            if (apiMethodNameAttribute == null) {
                return;
            }
            String nameValueWithQuotes = apiMethodNameAttribute.getText();
            String nameValue = EndpointUtilities.removeBeginningAndEndingQuotes(nameValueWithQuotes);
            if (nameValue.isEmpty()) {
                return;
            }
            // Check that @ApiMethod's name attribute has been used previously
            PsiMethod seenMethod = apiMethodNames.get(nameValue);
            if (seenMethod == null) {
                apiMethodNames.put(nameValue, psiMethod);
            } else {
                holder.registerProblem(apiMethodAnnotation, "Multiple methods with same API method name are prohibited. \"" + nameValue + "\" is the API method name for " + psiMethod.getName() + " and " + seenMethod.getName() + ".", new MyQuickFix());
            }
        }
    };
}
Also used : PsiMethod(com.intellij.psi.PsiMethod) PsiClass(com.intellij.psi.PsiClass) PsiAnnotation(com.intellij.psi.PsiAnnotation) Map(java.util.Map) PsiModifierList(com.intellij.psi.PsiModifierList) PsiAnnotationMemberValue(com.intellij.psi.PsiAnnotationMemberValue) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

PsiAnnotation (com.intellij.psi.PsiAnnotation)61 PsiModifierList (com.intellij.psi.PsiModifierList)18 PsiAnnotationMemberValue (com.intellij.psi.PsiAnnotationMemberValue)14 PsiMethod (com.intellij.psi.PsiMethod)14 NotNull (org.jetbrains.annotations.NotNull)13 Project (com.intellij.openapi.project.Project)12 PsiClass (com.intellij.psi.PsiClass)11 PsiElement (com.intellij.psi.PsiElement)9 MockProblemDescriptor (com.intellij.testFramework.MockProblemDescriptor)6 ProblemDescriptor (com.intellij.codeInspection.ProblemDescriptor)5 PsiParameter (com.intellij.psi.PsiParameter)5 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)5 Nullable (org.jetbrains.annotations.Nullable)5 PsiParameterList (com.intellij.psi.PsiParameterList)4 TestSize (com.google.idea.blaze.base.dependencies.TestSize)3 PsiJavaCodeReferenceElement (com.intellij.psi.PsiJavaCodeReferenceElement)3 PsiNameValuePair (com.intellij.psi.PsiNameValuePair)3 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 Nullable (javax.annotation.Nullable)3