diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/utils/PsiTypeUtils.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/utils/PsiTypeUtils.java index 6d8423e43..b37ddceb9 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/utils/PsiTypeUtils.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/utils/PsiTypeUtils.java @@ -15,35 +15,17 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiAnnotationMemberValue; -import com.intellij.psi.PsiAnnotationMethod; -import com.intellij.psi.PsiArrayType; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiClassType; -import com.intellij.psi.PsiCompiledElement; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiLiteral; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiMember; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiModifierListOwner; -import com.intellij.psi.PsiParameter; -import com.intellij.psi.PsiReference; -import com.intellij.psi.PsiType; -import com.intellij.psi.PsiTypeParameter; -import com.intellij.psi.PsiVariable; +import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.ClassUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.PsiUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -288,7 +270,7 @@ public static VirtualFile getRootDirectory(PsiElement element) { return getRootDirectory(PsiTreeUtil.getParentOfType(element, PsiFile.class)); } - public static VirtualFile getRootDirectory(PsiFile file) { + public static @Nullable VirtualFile getRootDirectory(PsiFile file) { ProjectFileIndex index = ProjectFileIndex.getInstance(file.getProject()); VirtualFile directory = index.getSourceRootForFile(file.getVirtualFile()); if (directory == null) { @@ -297,25 +279,6 @@ public static VirtualFile getRootDirectory(PsiFile file) { return directory; } - public static String getLocation(Project project, VirtualFile directory) { - String location = null; - Module module = ProjectFileIndex.getInstance(project).getModuleForFile(directory); - if (module != null) { - VirtualFile moduleRoot = LocalFileSystem.getInstance().findFileByIoFile(new File(module.getModuleFilePath()).getParentFile()); - String path = VfsUtilCore.getRelativePath(directory, moduleRoot); - if (path != null) { - location = '/' + module.getName() + '/' + path; - } - } - if (location == null) { - location = directory.getPath(); - } - if (location.endsWith("!/")) { - location = location.substring(0, location.length() - 2); - } - return location; - } - public static boolean overlaps(TextRange typeRange, TextRange methodRange) { if (typeRange == null || methodRange == null) { return false; @@ -347,6 +310,6 @@ public static String getRawResolvedTypeName(PsiMethod method) { * @return */ public static boolean isVoidReturnType(PsiMethod method) { - return PsiType.VOID.equals(method.getReturnType()); + return PsiTypes.voidType().equals(method.getReturnType()); } } diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/graphql/java/MicroProfileGraphQLASTValidator.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/graphql/java/MicroProfileGraphQLASTValidator.java index e1e0fdc5b..2d5d0cb5e 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/graphql/java/MicroProfileGraphQLASTValidator.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/internal/graphql/java/MicroProfileGraphQLASTValidator.java @@ -1,35 +1,21 @@ /******************************************************************************* -* Copyright (c) 2023 Red Hat Inc. and others. -* -* This program and the accompanying materials are made available under the -* terms of the Eclipse Public License v. 2.0 which is available at -* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -* which is available at https://www.apache.org/licenses/LICENSE-2.0. -* -* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -* -* Contributors: -* Red Hat Inc. - initial API and implementation -*******************************************************************************/ + * Copyright (c) 2023 Red Hat Inc. and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ package com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.graphql.java; -import java.text.MessageFormat; -import java.util.logging.Logger; -import java.util.regex.Matcher; - import com.intellij.openapi.module.Module; -import com.intellij.psi.PsiAnnotation; -import com.intellij.psi.PsiAnnotationMemberValue; -import com.intellij.psi.PsiArrayInitializerMemberValue; -import com.intellij.psi.PsiArrayType; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiEnumConstant; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiJvmModifiersOwner; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiParameter; -import com.intellij.psi.PsiType; +import com.intellij.psi.*; import com.intellij.psi.impl.source.PsiClassReferenceType; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.diagnostics.JavaDiagnosticsContext; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.java.validators.JavaASTValidator; @@ -38,18 +24,22 @@ import com.redhat.devtools.intellij.lsp4mp4ij.psi.internal.graphql.TypeSystemDirectiveLocation; import com.redhat.devtools.intellij.quarkus.QuarkusModuleUtil; import org.eclipse.lsp4j.DiagnosticSeverity; +import org.jetbrains.annotations.NotNull; + +import java.text.MessageFormat; +import java.util.logging.Logger; import static com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.AnnotationUtils.getAnnotation; import static com.redhat.devtools.intellij.lsp4mp4ij.psi.core.utils.AnnotationUtils.isMatchAnnotation; /** * Diagnostics for microprofile-graphql. - * + *
* TODO: We currently don't check directives on input/output objects and their properties, because
* it's not trivial to determine whether a class is used as an input, or an output, or both. That
* will possibly require building the whole GraphQL schema on-the-fly, which might be too expensive.
*
- * @see https://download.eclipse.org/microprofile/microprofile-graphql-1.0/microprofile-graphql.html
+ * @see MicroProfile GraphQL
*/
public class MicroProfileGraphQLASTValidator extends JavaASTValidator {
@@ -67,7 +57,7 @@ public class MicroProfileGraphQLASTValidator extends JavaASTValidator {
@Override
public boolean isAdaptedForDiagnostics(JavaDiagnosticsContext context) {
Module javaProject = context.getJavaProject();
- if(PsiTypeUtils.findType(javaProject, MicroProfileGraphQLConstants.QUERY_ANNOTATION) == null) {
+ if (PsiTypeUtils.findType(javaProject, MicroProfileGraphQLConstants.QUERY_ANNOTATION) == null) {
return false;
}
// void GraphQL operations are allowed in Quarkus 3.1 and higher
@@ -81,9 +71,9 @@ public boolean isAdaptedForDiagnostics(JavaDiagnosticsContext context) {
}
@Override
- public void visitMethod(PsiMethod node) {
+ public void visitMethod(@NotNull PsiMethod node) {
validateDirectivesOnMethod(node);
- if(!allowsVoidReturnFromOperations) {
+ if (!allowsVoidReturnFromOperations) {
validateNoVoidReturnedFromOperations(node);
}
validateMultiReturnTypeFromSubscriptions(node);
@@ -92,7 +82,7 @@ public void visitMethod(PsiMethod node) {
}
@Override
- public void visitClass(PsiClass node) {
+ public void visitClass(@NotNull PsiClass node) {
validateDirectivesOnClass(node);
super.visitClass(node);
}
@@ -115,13 +105,13 @@ private void validateDirectivesOnMethod(PsiMethod node) {
private void validateDirectivesOnClass(PsiClass node) {
// a class with @GraphQLApi may only have directives allowed on SCHEMA
- if(getAnnotation(node, MicroProfileGraphQLConstants.GRAPHQL_API_ANNOTATION) != null) {
+ if (getAnnotation(node, MicroProfileGraphQLConstants.GRAPHQL_API_ANNOTATION) != null) {
validateDirectives(node, TypeSystemDirectiveLocation.SCHEMA);
}
// if an interface has a `@Union` annotation, it may only have directives allowed on UNION
// otherwise it may only have directives allowed on INTERFACE
if (node.isInterface()) {
- if(getAnnotation(node, MicroProfileGraphQLConstants.UNION_ANNOTATION) != null) {
+ if (getAnnotation(node, MicroProfileGraphQLConstants.UNION_ANNOTATION) != null) {
validateDirectives(node, TypeSystemDirectiveLocation.UNION);
} else {
validateDirectives(node, TypeSystemDirectiveLocation.INTERFACE);
@@ -132,7 +122,7 @@ else if (node.isEnum()) {
validateDirectives(node, TypeSystemDirectiveLocation.ENUM);
// enum values may only have directives allowed on ENUM_VALUE
for (PsiField field : node.getFields()) {
- if(field instanceof PsiEnumConstant) {
+ if (field instanceof PsiEnumConstant) {
validateDirectives(field, TypeSystemDirectiveLocation.ENUM_VALUE);
}
}
@@ -199,12 +189,11 @@ private PsiClass getDirectiveDeclaration(PsiAnnotation annotation) {
private void validateNoVoidReturnedFromOperations(PsiMethod node) {
// ignore constructors, and non-void methods for now, it's faster than iterating through all annotations
- if (node.getReturnTypeElement() == null ||
- !PsiType.VOID.equals(node.getReturnType())) {
+ if (node.getReturnTypeElement() == null || !PsiTypeUtils.isVoidReturnType(node)) {
return;
}
for (PsiAnnotation annotation : node.getAnnotations()) {
- if (isMatchAnnotation(annotation, MicroProfileGraphQLConstants.QUERY_ANNOTATION) ) {
+ if (isMatchAnnotation(annotation, MicroProfileGraphQLConstants.QUERY_ANNOTATION)) {
super.addDiagnostic(NO_VOID_MESSAGE, //
MicroProfileGraphQLConstants.DIAGNOSTIC_SOURCE, //
node.getReturnTypeElement(), //
@@ -224,12 +213,12 @@ private void validateNoVoidReturnedFromOperations(PsiMethod node) {
* A method annotated with `@Subscription` must return a `Multi` or `Flow.Publisher`.
*/
private void validateMultiReturnTypeFromSubscriptions(PsiMethod node) {
- if(node.getReturnType() == null) {
+ if (node.getReturnType() == null) {
return;
}
for (PsiAnnotation annotation : node.getAnnotations()) {
if (isMatchAnnotation(annotation, MicroProfileGraphQLConstants.SUBSCRIPTION_ANNOTATION)) {
- if(node.getReturnType().equals(PsiType.VOID)) {
+ if (PsiTypeUtils.isVoidReturnType(node)) {
super.addDiagnostic(SUBSCRIPTION_MUST_RETURN_MULTI,
MicroProfileGraphQLConstants.DIAGNOSTIC_SOURCE,
node.getReturnTypeElement(),
@@ -258,7 +247,7 @@ private void validateMultiReturnTypeFromSubscriptions(PsiMethod node) {
* a `Multi` or `Flow.Publisher` type.
*/
private void validateNoMultiReturnTypeFromQueriesAndMutations(PsiMethod node) {
- if(node.getReturnType() == null) {
+ if (node.getReturnType() == null) {
return;
}
for (PsiAnnotation annotation : node.getAnnotations()) {
diff --git a/src/main/java/com/redhat/devtools/intellij/qute/psi/internal/template/JavaTypesSearch.java b/src/main/java/com/redhat/devtools/intellij/qute/psi/internal/template/JavaTypesSearch.java
index 5d310bb7a..dc7bd96f1 100644
--- a/src/main/java/com/redhat/devtools/intellij/qute/psi/internal/template/JavaTypesSearch.java
+++ b/src/main/java/com/redhat/devtools/intellij/qute/psi/internal/template/JavaTypesSearch.java
@@ -121,7 +121,7 @@ private void collectClassesAndInterfaces(PsiPackage packageRoot, ListjavaElement
and null
- * otherwise
- *
- * @param javaElement the Java element
- * @return the resolved type name of the javaElement
and null
- * otherwise
- */
- public static String getResolvedTypeName(PsiElement javaElement) {
- if (javaElement instanceof PsiVariable) {
- return getResolvedTypeName((PsiLocalVariable) javaElement);
- } else if (javaElement instanceof PsiField) {
- return getResolvedTypeName((PsiField) javaElement);
- }
- return null;
- }
-
- /**
- * Returns the resolved type name of the given localVar
and null
- * otherwise
- *
- * @param localVar the local variable
- * @return the resolved type name of the given localVar
and null
- * otherwise
- */
- public static String getResolvedTypeName(PsiLocalVariable localVar) {
- return localVar.getType().getCanonicalText();
- }
-
/**
* Returns the resolved type name of the given field
and null
* otherwise
@@ -93,10 +64,6 @@ public static String getResolvedTypeName(PsiField field) {
return field.getType().getCanonicalText();
}
- public static String getPropertyType(PsiClass psiClass, String typeName) {
- return psiClass != null ? psiClass.getQualifiedName() : typeName;
- }
-
/**
* Returns true if the given javaElement
is from a Java binary, and
* false otherwise
@@ -216,40 +183,40 @@ public static PsiClass findType(String className, Module javaProject, ProgressIn
* Return true if member is static, and false otherwise
*
* @param member the member to check for static
- * @return
+ * @return true if member is static, and false otherwise
*/
public static boolean isStaticMember(PsiMember member) {
- return member.getModifierList().hasExplicitModifier(PsiModifier.STATIC);
+ return member.getModifierList() != null && member.getModifierList().hasExplicitModifier(PsiModifier.STATIC);
}
/**
* Return true if member is private, and false otherwise
*
* @param member the member to check for private access modifier
- * @return
+ * @return true if member is private, and false otherwise
*/
public static boolean isPrivateMember(PsiMember member) {
- return member.getModifierList().hasExplicitModifier(PsiModifier.PRIVATE);
+ return member.getModifierList() != null && member.getModifierList().hasExplicitModifier(PsiModifier.PRIVATE);
}
/**
* Return true if member is public, and false otherwise
*
* @param member the member to check for public access modifier
- * @return
+ * @return true if member is public, and false otherwise
*/
public static boolean isPublicMember(PsiMember member) {
- return member.getModifierList().hasExplicitModifier(PsiModifier.PUBLIC);
+ return member.getModifierList() != null && member.getModifierList().hasExplicitModifier(PsiModifier.PUBLIC);
}
/**
* Return true if method returns `void`, and false otherwise
*
* @param method the method to check return value of
- * @return
+ * @return true if method returns `void`, and false otherwise
*/
public static boolean isVoidReturnType(PsiMethod method) {
- return PsiType.VOID.equals(method.getReturnType());
+ return PsiTypes.voidType().equals(method.getReturnType());
}
/**
diff --git a/src/main/java/com/redhat/microprofile/psi/internal/quarkus/core/properties/QuarkusConfigMappingProvider.java b/src/main/java/com/redhat/microprofile/psi/internal/quarkus/core/properties/QuarkusConfigMappingProvider.java
index 61138e5b2..3bf27b532 100644
--- a/src/main/java/com/redhat/microprofile/psi/internal/quarkus/core/properties/QuarkusConfigMappingProvider.java
+++ b/src/main/java/com/redhat/microprofile/psi/internal/quarkus/core/properties/QuarkusConfigMappingProvider.java
@@ -1,12 +1,12 @@
/*******************************************************************************
-* Copyright (c) 2021 Red Hat Inc. and others.
-* All rights reserved. This program and the accompanying materials
-* which accompanies this distribution, and is available at
-* http://www.eclipse.org/legal/epl-v20.html
-*
-* Contributors:
-* Red Hat Inc. - initial API and implementation
-*******************************************************************************/
+ * Copyright (c) 2021 Red Hat Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * Red Hat Inc. - initial API and implementation
+ *******************************************************************************/
package com.redhat.microprofile.psi.internal.quarkus.core.properties;
import com.intellij.openapi.vfs.VirtualFile;
@@ -68,270 +68,264 @@
/**
* Properties provider to collect Quarkus properties from the Java classes or
* interfaces annotated with "io.smallrye.config.ConfigMapping" annotation.
- *
+ *
* @author Angelo ZERR
- *
* @see https://quarkus.io/guides/config-mappings
*/
public class QuarkusConfigMappingProvider extends AbstractAnnotationTypeReferencePropertiesProvider {
- private static final Logger LOGGER = Logger.getLogger(QuarkusConfigMappingProvider.class.getName());
-
- private static final String[] ANNOTATION_NAMES = { CONFIG_MAPPING_ANNOTATION };
-
- @Override
- protected String[] getAnnotationNames() {
- return ANNOTATION_NAMES;
- }
-
- @Override
- protected void processAnnotation(PsiModifierListOwner javaElement, PsiAnnotation annotation, String annotationName,
- SearchContext context) {
- processConfigMapping(javaElement, annotation, context.getCollector());
- }
-
- // ------------- Process Quarkus ConfigMapping -------------
-
- private void processConfigMapping(PsiModifierListOwner javaElement, PsiAnnotation configMappingAnnotation,
- IPropertiesCollector collector) {
- if (!(javaElement instanceof PsiClass)) {
- return;
- }
- PsiClass configMappingType = (PsiClass) javaElement;
- if (!configMappingType.isInterface()) {
- // @ConfigMapping can be used only with interfaces.
- return;
- }
- // Location (JAR, src)
- VirtualFile packageRoot = PsiTypeUtils.getRootDirectory(PsiTreeUtil.getParentOfType(javaElement, PsiFile.class));
- String location = PsiTypeUtils.getLocation(javaElement.getProject(), packageRoot);
- // Quarkus Extension name
- String extensionName = PsiQuarkusUtils.getExtensionName(location);
-
- String prefix = getPrefixFromAnnotation(configMappingAnnotation);
- if (prefix == null || prefix.trim().isEmpty()) {
- // @ConfigMapping has no prefix
- return;
- }
- // @ConfigMapping(prefix="server") case
- List> databases();
- // extract the type List
> databases();
+ // extract the type List