refactoring of reconciler design to avoid running through all the ast visitor mechanics for each validation

This commit is contained in:
Martin Lippert
2024-04-26 18:49:33 +02:00
parent 71bcc7a580
commit 129ff45161
22 changed files with 731 additions and 454 deletions

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -29,15 +29,23 @@ public abstract class AbstractSecurityLamdaDslReconciler implements JdtAstReconc
private QuickfixRegistry registry; private QuickfixRegistry registry;
AbstractSecurityLamdaDslReconciler(QuickfixRegistry registry) { public AbstractSecurityLamdaDslReconciler(QuickfixRegistry registry) {
this.registry = registry; this.registry = registry;
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
boolean isCompleteAst) throws RequiredCompleteAstException { ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
if (visitor != null) {
cu.accept(visitor);
}
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
if (isCompleteAst) { if (isCompleteAst) {
cu.accept(new ASTVisitor() { return new ASTVisitor() {
@Override @Override
public boolean visit(MethodInvocation node) { public boolean visit(MethodInvocation node) {
@@ -66,28 +74,27 @@ public abstract class AbstractSecurityLamdaDslReconciler implements JdtAstReconc
return true; return true;
} }
}); };
} else { } else {
if (ReconcileUtils.isAnyTypeUsed(cu, List.of(getTargetTypeFqName()))) { if (ReconcileUtils.isAnyTypeUsed(cu, List.of(getTargetTypeFqName()))) {
throw new RequiredCompleteAstException(); throw new RequiredCompleteAstException();
} }
else {
return null;
}
} }
} }
protected abstract String getFixLabel();
protected abstract String getRecipeId();
protected abstract String getProblemLabel();
abstract protected String getTargetTypeFqName();
abstract protected Collection<String> getApplicableMethodNames();
private static MethodInvocation findTopLevelMethodInvocation(MethodInvocation m) { private static MethodInvocation findTopLevelMethodInvocation(MethodInvocation m) {
for (; m.getParent() instanceof MethodInvocation; m = (MethodInvocation) m.getParent()) {} for (; m.getParent() instanceof MethodInvocation; m = (MethodInvocation) m.getParent()) {}
return m; return m;
} }
protected abstract String getFixLabel();
protected abstract String getRecipeId();
protected abstract String getProblemLabel();
abstract protected String getTargetTypeFqName();
abstract protected Collection<String> getApplicableMethodNames();
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -48,21 +48,40 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconciler, ApplicationContextAware { public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconciler, ApplicationContextAware {
private static final String PROBLEM_LABEL = "'@Configuration' is missing on a class defining Spring Beans"; private static final String PROBLEM_LABEL = "'@Configuration' is missing on a class defining Spring Beans";
private static final String FIX_LABEL = "Add missing '@Configuration' annotations over classes"; private static final String FIX_LABEL = "Add missing '@Configuration' annotations over classes";
private QuickfixRegistry quickfixRegistry; private QuickfixRegistry quickfixRegistry;
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
public AddConfigurationIfBeansPresentReconciler(QuickfixRegistry quickfixRegistry) { public AddConfigurationIfBeansPresentReconciler(QuickfixRegistry quickfixRegistry) {
this.quickfixRegistry = quickfixRegistry; this.quickfixRegistry = quickfixRegistry;
} }
@Override
public boolean isApplicable(IJavaProject project) {
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-context");
return version != null && version.compareTo(new Version(3, 0, 0, null)) >= 0;
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public ProblemType getProblemType() {
boolean isCompleteAst) { return Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION;
cu.accept(new ASTVisitor() { }
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(TypeDeclaration classDecl) { public boolean visit(TypeDeclaration classDecl) {
@@ -86,7 +105,7 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
return true; return true;
} }
}); };
} }
private boolean isApplicableClass(IJavaProject project, CompilationUnit cu, TypeDeclaration classDecl) { private boolean isApplicableClass(IJavaProject project, CompilationUnit cu, TypeDeclaration classDecl) {
@@ -179,20 +198,4 @@ public class AddConfigurationIfBeansPresentReconciler implements JdtAstReconcile
return false; return false;
} }
@Override
public boolean isApplicable(IJavaProject project) {
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-context");
return version != null && version.compareTo(new Version(3, 0, 0, null)) >= 0;
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.MISSING_CONFIGURATION_ANNOTATION;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -75,11 +75,27 @@ public class AnnotationNodeReconciler implements JdtAstReconciler {
}; };
config.addListener(evt -> this.spelExpressionReconciler.setEnabled(config.isSpelExpressionValidationEnabled())); config.addListener(evt -> this.spelExpressionReconciler.setEnabled(config.isSpelExpressionValidationEnabled()));
} }
@Override
public boolean isApplicable(IJavaProject project) {
return true;
}
@Override
public ProblemType getProblemType() {
return SpelProblemType.JAVA_SPEL_EXPRESSION_SYNTAX;
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) { public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
cu.accept(new ASTVisitor() { ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu,
IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(SingleMemberAnnotation node) { public boolean visit(SingleMemberAnnotation node) {
@@ -111,7 +127,7 @@ public class AnnotationNodeReconciler implements JdtAstReconciler {
return super.visit(node); return super.visit(node);
} }
}); };
} }
private void visitAnnotation(IJavaProject project, URI docUri, Annotation node, IProblemCollector problemCollector) { private void visitAnnotation(IJavaProject project, URI docUri, Annotation node, IProblemCollector problemCollector) {
@@ -123,16 +139,4 @@ public class AnnotationNodeReconciler implements JdtAstReconciler {
} }
} }
@Override
public boolean isApplicable(IJavaProject project) {
return true;
}
@Override
public ProblemType getProblemType() {
return SpelProblemType.JAVA_SPEL_EXPRESSION_SYNTAX;
}
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -32,17 +32,11 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler { public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
private static final String FQN_HTTP_SECURITY = "org.springframework.security.config.annotation.web.builders.HttpSecurity"; private static final String FQN_HTTP_SECURITY = "org.springframework.security.config.annotation.web.builders.HttpSecurity";
private static final String AUTHORIZE_REQUESTS = "authorizeRequests"; private static final String AUTHORIZE_REQUESTS = "authorizeRequests";
private static final String AUTHORIZE_REQUESTS_PROBLEM_LABEL = "HttpSecurity API 'authorizeRequests(...)' is outdated"; private static final String AUTHORIZE_REQUESTS_PROBLEM_LABEL = "HttpSecurity API 'authorizeRequests(...)' is outdated";
private static final String AUTHORIZE_REQUESTS_FIX_LABEL = "Replace with 'authorizeHttpRequests(...)' and related types"; private static final String AUTHORIZE_REQUESTS_FIX_LABEL = "Replace with 'authorizeHttpRequests(...)' and related types";
private static final String FQN_INTERCEPTOR_URL_CONFIG = "org.springframework.security.config.annotation.web.configurers.AbstractInterceptUrlConfigurer"; private static final String FQN_INTERCEPTOR_URL_CONFIG = "org.springframework.security.config.annotation.web.configurers.AbstractInterceptUrlConfigurer";
private static final String FQN_EXPR_AUTH_CONFIG = "org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer"; private static final String FQN_EXPR_AUTH_CONFIG = "org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer";
private static final String FQN_EXPR_INTERCEPT_REG = "org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry"; private static final String FQN_EXPR_INTERCEPT_REG = "org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry";
private QuickfixRegistry registry; private QuickfixRegistry registry;
@@ -52,10 +46,29 @@ public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public boolean isApplicable(IJavaProject project) {
boolean isCompleteAst) throws RequiredCompleteAstException { Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
return version != null && version.compareTo(new Version(5, 6, 0, null)) >= 0;
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.HTTP_SECURITY_AUTHORIZE_HTTP_REQUESTS;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
if (visitor != null) {
cu.accept(visitor);
}
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
if (isCompleteAst) { if (isCompleteAst) {
cu.accept(new ASTVisitor() { return new ASTVisitor() {
@Override @Override
public boolean visit(MethodInvocation node) { public boolean visit(MethodInvocation node) {
@@ -84,7 +97,7 @@ public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
return true; return true;
} }
}); };
} else { } else {
boolean needsFullAst = ReconcileUtils.isAnyTypeUsed(cu, List.of( boolean needsFullAst = ReconcileUtils.isAnyTypeUsed(cu, List.of(
FQN_HTTP_SECURITY, FQN_HTTP_SECURITY,
@@ -92,21 +105,13 @@ public class AuthorizeHttpRequestsReconciler implements JdtAstReconciler {
FQN_EXPR_AUTH_CONFIG, FQN_EXPR_AUTH_CONFIG,
FQN_EXPR_INTERCEPT_REG FQN_EXPR_INTERCEPT_REG
)); ));
if (needsFullAst) { if (needsFullAst) {
throw new RequiredCompleteAstException(); throw new RequiredCompleteAstException();
} }
return null;
} }
} }
@Override
public boolean isApplicable(IJavaProject project) {
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
return version != null && version.compareTo(new Version(5, 6, 0, null)) >= 0;
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.HTTP_SECURITY_AUTHORIZE_HTTP_REQUESTS;
}
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -18,7 +18,6 @@ import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.ASTVisitor;
@@ -57,14 +56,32 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public boolean isApplicable(IJavaProject project) {
boolean isCompleteAst) throws RequiredCompleteAstException { return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_CONSTRUCTOR_PARAMETER_INJECTION;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
if (visitor != null) {
cu.accept(visitor);
}
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
Path sourceFile = Paths.get(docUri); Path sourceFile = Paths.get(docUri);
// Check if source file belongs to non-test java sources folder // Check if source file belongs to non-test java sources folder
if (IClasspathUtil.getProjectJavaSourceFoldersWithoutTests(project.getClasspath()) if (IClasspathUtil.getProjectJavaSourceFoldersWithoutTests(project.getClasspath())
.anyMatch(f -> sourceFile.startsWith(f.toPath()))) { .anyMatch(f -> sourceFile.startsWith(f.toPath()))) {
AtomicBoolean completeAstRequired = new AtomicBoolean(false);
cu.accept(new ASTVisitor() { return new ASTVisitor() {
@Override @Override
public boolean visit(FieldDeclaration field) { public boolean visit(FieldDeclaration field) {
@@ -84,8 +101,7 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
problemCollector.accept(createProblem(cu, field, fieldName, docUri)); problemCollector.accept(createProblem(cu, field, fieldName, docUri));
} else if (constructors.size() == 1) { } else if (constructors.size() == 1) {
if (!isCompleteAst) { if (!isCompleteAst) {
completeAstRequired.set(true); throw new RequiredCompleteAstException();
return false;
} }
if (!isAssigningField(constructors.get(0), variableDeclarationFragment.resolveBinding(), if (!isAssigningField(constructors.get(0), variableDeclarationFragment.resolveBinding(),
fieldName)) { fieldName)) {
@@ -98,8 +114,7 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
.limit(2).collect(Collectors.toList()); .limit(2).collect(Collectors.toList());
if (autowiredConstructors.size() == 1) { if (autowiredConstructors.size() == 1) {
if (!isCompleteAst) { if (!isCompleteAst) {
completeAstRequired.set(true); throw new RequiredCompleteAstException();
return false;
} else if (!isAssigningField(autowiredConstructors.get(0), } else if (!isAssigningField(autowiredConstructors.get(0),
variableDeclarationFragment.resolveBinding(), fieldName)) { variableDeclarationFragment.resolveBinding(), fieldName)) {
problemCollector.accept(createProblem(cu, field, fieldName, docUri)); problemCollector.accept(createProblem(cu, field, fieldName, docUri));
@@ -112,12 +127,11 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
return true; return true;
} }
}); };
if (completeAstRequired.get()) { }
throw new RequiredCompleteAstException(); else {
} return null;
} }
} }
private ReconcileProblemImpl createProblem(CompilationUnit cu, FieldDeclaration field, String fieldName, private ReconcileProblemImpl createProblem(CompilationUnit cu, FieldDeclaration field, String fieldName,
@@ -157,14 +171,4 @@ public class AutowiredFieldIntoConstructorParameterReconciler implements JdtAstR
return false; return false;
} }
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_CONSTRUCTOR_PARAMETER_INJECTION;
}
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2022, 2023 VMware, Inc. * Copyright (c) 2022, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -46,8 +46,7 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
public class BeanMethodNotPublicReconciler implements JdtAstReconciler { public class BeanMethodNotPublicReconciler implements JdtAstReconciler {
private static final Logger log = LoggerFactory.getLogger(BeanMethodNotPublicReconciler.class); private static final Logger log = LoggerFactory.getLogger(BeanMethodNotPublicReconciler.class);
private static final String LABEL = "Remove 'public' from @Bean method";
private static final String LABEL = "Remove 'public' from @Bean method";
private final QuickfixRegistry quickfixRegistry; private final QuickfixRegistry quickfixRegistry;
@@ -55,6 +54,62 @@ public class BeanMethodNotPublicReconciler implements JdtAstReconciler {
this.quickfixRegistry = quickfixRegistry; this.quickfixRegistry = quickfixRegistry;
} }
@Override
public boolean isApplicable(IJavaProject project) {
Version version = SpringProjectUtil.getDependencyVersion(project, SpringProjectUtil.SPRING_BOOT);
return version != null && version.getMajor() >= 2;
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_PUBLIC_BEAN_METHOD;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override
public boolean visit(SingleMemberAnnotation node) {
try {
visitAnnotation(project, cu, docUri, node, problemCollector);
} catch (Exception e) {
}
return super.visit(node);
}
@Override
public boolean visit(NormalAnnotation node) {
try {
visitAnnotation(project, cu, docUri, node, problemCollector);
} catch (Exception e) {
}
return super.visit(node);
}
@Override
public boolean visit(MarkerAnnotation node) {
try {
visitAnnotation(project, cu, docUri, node, problemCollector);
} catch (Exception e) {
}
return super.visit(node);
}
};
}
public static final boolean isNotOverridingPublicMethod(IMethodBinding methodBinding) {
return !isOverriding(methodBinding) && (methodBinding.getModifiers() & Modifier.PUBLIC) != 0;
}
private void visitAnnotation(IJavaProject project, CompilationUnit cu, URI docUri, Annotation node, IProblemCollector problemCollector) { private void visitAnnotation(IJavaProject project, CompilationUnit cu, URI docUri, Annotation node, IProblemCollector problemCollector) {
ITypeBinding typeBinding = node.resolveTypeBinding(); ITypeBinding typeBinding = node.resolveTypeBinding();
if (typeBinding != null && Annotations.BEAN.equals(typeBinding.getQualifiedName()) && node.getParent() instanceof MethodDeclaration) { if (typeBinding != null && Annotations.BEAN.equals(typeBinding.getQualifiedName()) && node.getParent() instanceof MethodDeclaration) {
@@ -95,10 +150,6 @@ public class BeanMethodNotPublicReconciler implements JdtAstReconciler {
return false; return false;
} }
public static final boolean isNotOverridingPublicMethod(IMethodBinding methodBinding) {
return !isOverriding(methodBinding) && (methodBinding.getModifiers() & Modifier.PUBLIC) != 0;
}
private void addQuickFixes(CompilationUnit cu, URI docUri, ReconcileProblemImpl problem, MethodDeclaration method) { private void addQuickFixes(CompilationUnit cu, URI docUri, ReconcileProblemImpl problem, MethodDeclaration method) {
if (quickfixRegistry != null) { if (quickfixRegistry != null) {
@@ -130,49 +181,4 @@ public class BeanMethodNotPublicReconciler implements JdtAstReconciler {
} }
} }
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
cu.accept(new ASTVisitor() {
@Override
public boolean visit(SingleMemberAnnotation node) {
try {
visitAnnotation(project, cu, docUri, node, problemCollector);
} catch (Exception e) {
}
return super.visit(node);
}
@Override
public boolean visit(NormalAnnotation node) {
try {
visitAnnotation(project, cu, docUri, node, problemCollector);
} catch (Exception e) {
}
return super.visit(node);
}
@Override
public boolean visit(MarkerAnnotation node) {
try {
visitAnnotation(project, cu, docUri, node, problemCollector);
} catch (Exception e) {
}
return super.visit(node);
}
});
}
@Override
public boolean isApplicable(IJavaProject project) {
Version version = SpringProjectUtil.getDependencyVersion(project, SpringProjectUtil.SPRING_BOOT);
return version != null && version.getMajor() >= 2;
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_PUBLIC_BEAN_METHOD;
}
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -44,12 +44,27 @@ public class BeanPostProcessingIgnoreInAotReconciler implements JdtAstReconciler
public BeanPostProcessingIgnoreInAotReconciler(QuickfixRegistry registry) { public BeanPostProcessingIgnoreInAotReconciler(QuickfixRegistry registry) {
this.registry = registry; this.registry = registry;
} }
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public ProblemType getProblemType() {
boolean isCompleteAst) throws RequiredCompleteAstException { return SpringAotJavaProblemType.JAVA_BEAN_POST_PROCESSOR_IGNORED_IN_AOT;
AtomicBoolean requiresFullAst = new AtomicBoolean(false); }
cu.accept(new ASTVisitor() {
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(TypeDeclaration typeDecl) { public boolean visit(TypeDeclaration typeDecl) {
@@ -77,7 +92,7 @@ public class BeanPostProcessingIgnoreInAotReconciler implements JdtAstReconciler
}); });
markProblem = returnsTrue.get(); markProblem = returnsTrue.get();
} else { } else {
requiresFullAst.set(true); throw new RequiredCompleteAstException();
} }
} else { } else {
markProblem = true; markProblem = true;
@@ -93,27 +108,14 @@ public class BeanPostProcessingIgnoreInAotReconciler implements JdtAstReconciler
problemCollector.accept(problem); problemCollector.accept(problem);
} }
} }
return !requiresFullAst.get(); return true;
} }
private boolean isApplicable(ITypeBinding type) { };
return ReconcileUtils.implementsType(RUNTIME_BEAN_POST_PROCESSOR, type) && ReconcileUtils.implementsType(COMPILE_BEAN_POST_PROCESSOR, type);
}
});
if (requiresFullAst.get()) {
throw new RequiredCompleteAstException();
}
} }
@Override private static boolean isApplicable(ITypeBinding type) {
public boolean isApplicable(IJavaProject project) { return ReconcileUtils.implementsType(RUNTIME_BEAN_POST_PROCESSOR, type) && ReconcileUtils.implementsType(COMPILE_BEAN_POST_PROCESSOR, type);
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return SpringAotJavaProblemType.JAVA_BEAN_POST_PROCESSOR_IGNORED_IN_AOT;
} }
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -33,11 +33,26 @@ public class Boot3NotSupportedTypeReconciler implements JdtAstReconciler {
"java.lang.SecurityManager", "java.lang.SecurityManager",
"java.security.AccessControlException" "java.security.AccessControlException"
); );
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public ProblemType getProblemType() {
boolean isCompleteAst) throws RequiredCompleteAstException { return Boot3JavaProblemType.JAVA_TYPE_NOT_SUPPORTED;
cu.accept(new ASTVisitor() { }
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docURI, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(ImportDeclaration node) { public boolean visit(ImportDeclaration node) {
@@ -57,10 +72,10 @@ public class Boot3NotSupportedTypeReconciler implements JdtAstReconciler {
return super.visit(node); return super.visit(node);
} }
}); };
} }
private String processType(CompilationUnit cu, String name) { private static String processType(CompilationUnit cu, String name) {
if (TYPE_FQNAMES.contains(name)) { if (TYPE_FQNAMES.contains(name)) {
return name; return name;
} else { } else {
@@ -73,7 +88,7 @@ public class Boot3NotSupportedTypeReconciler implements JdtAstReconciler {
return null; return null;
} }
private List<String> createFqNamesFromWildcardImports(CompilationUnit cu, String name) { private static List<String> createFqNamesFromWildcardImports(CompilationUnit cu, String name) {
List<String> fqNames = new ArrayList<>(); List<String> fqNames = new ArrayList<>();
for (Object im : cu.imports()) { for (Object im : cu.imports()) {
ImportDeclaration importDecl = (ImportDeclaration) im; ImportDeclaration importDecl = (ImportDeclaration) im;
@@ -84,16 +99,6 @@ public class Boot3NotSupportedTypeReconciler implements JdtAstReconciler {
return fqNames; return fqNames;
} }
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return Boot3JavaProblemType.JAVA_TYPE_NOT_SUPPORTED;
}
private static String createLabel(String type) { private static String createLabel(String type) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("'"); sb.append("'");

View File

@@ -0,0 +1,143 @@
/*******************************************************************************
* Copyright (c) 2024 Broadcom
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Broadcom - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.reconcilers;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SimpleType;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.jdt.core.dom.TypeDeclaration;
public class CompositeASTVisitor extends ASTVisitor {
List<ASTVisitor> visitors = new ArrayList<>();
public void add(ASTVisitor visitor) {
visitors.add(visitor);
}
@Override
public boolean visit(TypeDeclaration node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(MethodInvocation node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(MethodDeclaration node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public void endVisit(MethodDeclaration node) {
for (ASTVisitor astVisitor : visitors) {
astVisitor.endVisit(node);
}
}
@Override
public boolean visit(FieldDeclaration node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(SingleMemberAnnotation node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(NormalAnnotation node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(MarkerAnnotation node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(ImportDeclaration node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(SimpleType node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(QualifiedName node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
@Override
public boolean visit(ReturnStatement node) {
boolean result = true;
for (ASTVisitor astVisitor : visitors) {
result &= astVisitor.visit(node);
}
return result;
}
}

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -55,12 +55,31 @@ public class EntityIdForRepoReconciler implements JdtAstReconciler {
Double.class.getName(), Double.class.getName(),
Byte.class.getName() Byte.class.getName()
); );
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public ProblemType getProblemType() {
boolean isCompleteAst) throws RequiredCompleteAstException { return Boot2JavaProblemType.DOMAIN_ID_FOR_REPOSITORY;
final boolean considerIdField = project.getClasspath().findBinaryLibrary("spring-data-mongodb-").isPresent(); }
cu.accept(new ASTVisitor() {
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
if (visitor != null) {
cu.accept(visitor);
}
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docURI, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
final boolean considerIdField = project.getClasspath().findBinaryLibrary("spring-data-mongodb-").isPresent();
@Override @Override
public boolean visit(TypeDeclaration typeDecl) { public boolean visit(TypeDeclaration typeDecl) {
@@ -216,22 +235,6 @@ public class EntityIdForRepoReconciler implements JdtAstReconciler {
} }
} }
private ITypeBinding getTypeFromAnnotationParameter(IAnnotationBinding a, String param) {
for (IMemberValuePairBinding pair : a.getDeclaredMemberValuePairs()) {
if (pair.getName().equals(param)) {
if (pair.getValue() instanceof ITypeBinding) {
return (ITypeBinding) pair.getValue();
} else if (pair.getValue() instanceof Object[]) {
Object[] arr = (Object[]) pair.getValue();
if (arr.length > 0 && arr[0] instanceof ITypeBinding) {
return (ITypeBinding) arr[0];
}
}
}
}
return null;
}
private List<ITypeBinding> findIdType(ITypeBinding type) { private List<ITypeBinding> findIdType(ITypeBinding type) {
List<ITypeBinding> idTypes = findAnnotatedIdTypes(type, new HashSet<>()); List<ITypeBinding> idTypes = findAnnotatedIdTypes(type, new HashSet<>());
if (idTypes.isEmpty() && considerIdField) { if (idTypes.isEmpty() && considerIdField) {
@@ -243,40 +246,47 @@ public class EntityIdForRepoReconciler implements JdtAstReconciler {
return idTypes; return idTypes;
} }
private boolean isValidRepoIdType(ITypeBinding repoIdType, ITypeBinding idType) { };
if (NUMBER_CLASS_NAMES.contains(repoIdType.getQualifiedName()) && NUMBER_CLASS_NAMES.contains(idType.getQualifiedName())) {
return true; }
private static boolean isValidRepoIdType(ITypeBinding repoIdType, ITypeBinding idType) {
if (NUMBER_CLASS_NAMES.contains(repoIdType.getQualifiedName()) && NUMBER_CLASS_NAMES.contains(idType.getQualifiedName())) {
return true;
}
return repoIdType.isCastCompatible(idType) || idType.isCastCompatible(repoIdType);
}
private static ITypeBinding getTypeFromAnnotationParameter(IAnnotationBinding a, String param) {
for (IMemberValuePairBinding pair : a.getDeclaredMemberValuePairs()) {
if (pair.getName().equals(param)) {
if (pair.getValue() instanceof ITypeBinding) {
return (ITypeBinding) pair.getValue();
} else if (pair.getValue() instanceof Object[]) {
Object[] arr = (Object[]) pair.getValue();
if (arr.length > 0 && arr[0] instanceof ITypeBinding) {
return (ITypeBinding) arr[0];
}
} }
return repoIdType.isCastCompatible(idType) || idType.isCastCompatible(repoIdType);
} }
});
}
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.DOMAIN_ID_FOR_REPOSITORY;
}
public static void findSuperTypeBindings(ITypeBinding binding, Set<ITypeBinding> superTypes) {
// superclasses
ITypeBinding superclass = binding.getSuperclass();
if (superclass != null) {
superTypes.add(superclass);
findSuperTypeBindings(superclass, superTypes);
}
// interfaces
for (ITypeBinding i : binding.getInterfaces()) {
superTypes.add(i);
findSuperTypeBindings(i, superTypes);
} }
return null;
} }
// public static void findSuperTypeBindings(ITypeBinding binding, Set<ITypeBinding> superTypes) {
// // superclasses
// ITypeBinding superclass = binding.getSuperclass();
// if (superclass != null) {
// superTypes.add(superclass);
// findSuperTypeBindings(superclass, superTypes);
// }
// // interfaces
// for (ITypeBinding i : binding.getInterfaces()) {
// superTypes.add(i);
// findSuperTypeBindings(i, superTypes);
// }
// }
//
private static @Nullable List<ITypeBinding> findRepoTypeChain(ITypeBinding type, List<ITypeBinding> visited) { private static @Nullable List<ITypeBinding> findRepoTypeChain(ITypeBinding type, List<ITypeBinding> visited) {
if (visited.stream().anyMatch(b -> b.isEqualTo(type))) { if (visited.stream().anyMatch(b -> b.isEqualTo(type))) {
return null; return null;
@@ -404,7 +414,7 @@ public class EntityIdForRepoReconciler implements JdtAstReconciler {
return true; return true;
} }
private List<ASTNode> findParamTypes(List<?> typeParams, ITypeBinding idType) { private static List<ASTNode> findParamTypes(List<?> typeParams, ITypeBinding idType) {
List<ASTNode> matchedParams = new ArrayList<>(); List<ASTNode> matchedParams = new ArrayList<>();
for (Object o : typeParams) { for (Object o : typeParams) {
if (o instanceof TypeParameter) { if (o instanceof TypeParameter) {
@@ -424,4 +434,5 @@ public class EntityIdForRepoReconciler implements JdtAstReconciler {
return matchedParams; return matchedParams;
} }
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -12,6 +12,7 @@ package org.springframework.ide.vscode.boot.java.reconcilers;
import java.net.URI; import java.net.URI;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.CompilationUnit;
import org.springframework.ide.vscode.commons.java.IJavaProject; import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector; import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
@@ -25,4 +26,6 @@ public interface JdtAstReconciler {
ProblemType getProblemType(); ProblemType getProblemType();
ASTVisitor createVisitor(IJavaProject project, URI docURI, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst);
} }

View File

@@ -17,6 +17,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.CompilationUnit;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -49,13 +50,19 @@ public class JdtReconciler implements JavaReconciler {
private final CompilationUnitCache compilationUnitCache; private final CompilationUnitCache compilationUnitCache;
private final JdtAstReconciler[] reconcilers; private final JdtAstReconciler[] reconcilers;
private BootJavaConfig config; private BootJavaConfig config;
private long stats_timer;
private long stats_counter;
public JdtReconciler(CompilationUnitCache compilationUnitCache, BootJavaConfig config, JdtAstReconciler[] reconcilers) { public JdtReconciler(CompilationUnitCache compilationUnitCache, BootJavaConfig config, JdtAstReconciler[] reconcilers) {
this.compilationUnitCache = compilationUnitCache; this.compilationUnitCache = compilationUnitCache;
this.config = config; this.config = config;
this.reconcilers = reconcilers; this.reconcilers = reconcilers;
this.stats_timer = 0;
this.stats_counter = 0;
} }
@Override @Override
public void reconcile(IJavaProject project, final IDocument doc, final IProblemCollector problemCollector) { public void reconcile(IJavaProject project, final IDocument doc, final IProblemCollector problemCollector) {
if (!config.isJavaSourceReconcileEnabled()) { if (!config.isJavaSourceReconcileEnabled()) {
@@ -76,20 +83,48 @@ public class JdtReconciler implements JavaReconciler {
return null; return null;
}); });
} }
public ASTVisitor createCompositeVisitor(IJavaProject project, URI docURI, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
CompositeASTVisitor compositeVisitor = new CompositeASTVisitor();
for (JdtAstReconciler reconciler : getApplicableReconcilers(project)) {
ASTVisitor visitor = reconciler.createVisitor(project, docURI, cu, problemCollector, isCompleteAst);
if (visitor != null) {
compositeVisitor.add(visitor);
}
}
return compositeVisitor;
}
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException { public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
long start = System.currentTimeMillis();
if (!config.isJavaSourceReconcileEnabled()) { if (!config.isJavaSourceReconcileEnabled()) {
return; return;
} }
for (JdtAstReconciler reconciler : getApplicableReconcilers(project)) {
try { try {
reconciler.reconcile(project, docUri, cu, problemCollector, isCompleteAst); ASTVisitor compositeVisitor = createCompositeVisitor(project, docUri, cu, problemCollector, isCompleteAst);
} catch (RequiredCompleteAstException e) { cu.accept(compositeVisitor);
throw e;
} catch (Exception e) { // for (JdtAstReconciler reconciler : getApplicableReconcilers(project)) {
log.error("", e); // try {
} // reconciler.reconcile(project, docUri, cu, problemCollector, isCompleteAst);
// } catch (RequiredCompleteAstException e) {
// throw e;
// } catch (Exception e) {
// log.error("", e);
// }
// }
}
finally {
long end = System.currentTimeMillis();
stats_counter++;
stats_timer += (end - start);
} }
} }
@@ -120,5 +155,13 @@ public class JdtReconciler implements JavaReconciler {
return Collections.emptyMap(); return Collections.emptyMap();
} }
public long getStatsTimer() {
return stats_timer;
}
public long getStatsCounter() {
return stats_counter;
}
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -35,19 +35,44 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.Reconcile
public class ModulithTypeReferenceViolationReconciler implements JdtAstReconciler, ApplicationContextAware { public class ModulithTypeReferenceViolationReconciler implements JdtAstReconciler, ApplicationContextAware {
private ApplicationContext appContext; private ApplicationContext appContext;
@Override
public boolean isApplicable(IJavaProject project) {
return ModulithService.isModulithDependentProject(project);
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public ProblemType getProblemType() {
boolean isCompleteAst) throws RequiredCompleteAstException { return Boot3JavaProblemType.MODULITH_TYPE_REF_VIOLATION;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.appContext = applicationContext;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
if (visitor != null) {
cu.accept(visitor);
}
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
Path sourceFile = Paths.get(docUri); Path sourceFile = Paths.get(docUri);
if (IClasspathUtil.getProjectJavaSourceFoldersWithoutTests(project.getClasspath()) if (IClasspathUtil.getProjectJavaSourceFoldersWithoutTests(project.getClasspath())
.anyMatch(f -> sourceFile.startsWith(f.toPath()))) { .anyMatch(f -> sourceFile.startsWith(f.toPath()))) {
ModulithService modulithService = appContext.getBean(ModulithService.class); ModulithService modulithService = appContext.getBean(ModulithService.class);
AppModules appModules = modulithService.getModulesData(project); AppModules appModules = modulithService.getModulesData(project);
if (appModules != null) { if (appModules != null) {
final String packageName = cu.getPackage().getName().getFullyQualifiedName(); final String packageName = cu.getPackage().getName().getFullyQualifiedName();
cu.accept(new ASTVisitor() {
return new ASTVisitor() {
@Override @Override
public boolean visit(QualifiedName node) { public boolean visit(QualifiedName node) {
@@ -71,25 +96,11 @@ public class ModulithTypeReferenceViolationReconciler implements JdtAstReconcile
} }
} }
}); };
} }
} }
}
return null;
@Override
public boolean isApplicable(IJavaProject project) {
return ModulithService.isModulithDependentProject(project);
}
@Override
public ProblemType getProblemType() {
return Boot3JavaProblemType.MODULITH_TYPE_REF_VIOLATION;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.appContext = applicationContext;
} }
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -45,9 +45,25 @@ public class NoAutowiredOnConstructorReconciler implements JdtAstReconciler {
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public boolean isApplicable(IJavaProject project) {
boolean isCompleteAst) throws RequiredCompleteAstException { return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
cu.accept(new ASTVisitor() { }
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_AUTOWIRED_CONSTRUCTOR;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(TypeDeclaration typeDecl) { public boolean visit(TypeDeclaration typeDecl) {
@@ -86,17 +102,7 @@ public class NoAutowiredOnConstructorReconciler implements JdtAstReconciler {
return super.visit(typeDecl); return super.visit(typeDecl);
} }
}); };
}
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_AUTOWIRED_CONSTRUCTOR;
} }
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -44,10 +44,25 @@ public class NoRepoAnnotationReconciler implements JdtAstReconciler {
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public boolean isApplicable(IJavaProject project) {
boolean isCompleteAst) throws RequiredCompleteAstException { return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
cu.accept(new ASTVisitor() { }
@Override
public Boot2JavaProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_REPOSITORY;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(TypeDeclaration typeDecl) { public boolean visit(TypeDeclaration typeDecl) {
@@ -80,46 +95,35 @@ public class NoRepoAnnotationReconciler implements JdtAstReconciler {
} }
return super.visit(typeDecl); return super.visit(typeDecl);
} }
};
private boolean isApplicableRepoAnnotation(Annotation a) { }
if (a instanceof MarkerAnnotation || (a.isNormalAnnotation() && ((NormalAnnotation) a).properties().isEmpty())) {
String typeName = a.getTypeName().getFullyQualifiedName(); private static boolean isApplicableRepoAnnotation(Annotation a) {
if (Annotations.REPOSITORY.equals(typeName)) { if (a instanceof MarkerAnnotation || (a.isNormalAnnotation() && ((NormalAnnotation) a).properties().isEmpty())) {
return true; String typeName = a.getTypeName().getFullyQualifiedName();
} else if (typeName.endsWith("Repository")) { if (Annotations.REPOSITORY.equals(typeName)) {
ITypeBinding type = a.resolveTypeBinding(); return true;
if (type != null && Annotations.REPOSITORY.equals(type.getQualifiedName())) { } else if (typeName.endsWith("Repository")) {
return true; ITypeBinding type = a.resolveTypeBinding();
} if (type != null && Annotations.REPOSITORY.equals(type.getQualifiedName())) {
}
}
return false;
}
private boolean isRepo(ITypeBinding t) {
if (INTERFACE_REPOSITORY.equals(t.getQualifiedName())) {
return true; return true;
} else {
for (ITypeBinding st : t.getInterfaces()) {
if (isRepo(st)) {
return true;
}
}
} }
return false;
} }
}
}); return false;
} }
@Override private static boolean isRepo(ITypeBinding t) {
public boolean isApplicable(IJavaProject project) { if (INTERFACE_REPOSITORY.equals(t.getQualifiedName())) {
return springBootVersionGreaterOrEqual(2, 0, 0).test(project); return true;
} } else {
for (ITypeBinding st : t.getInterfaces()) {
@Override if (isRepo(st)) {
public Boot2JavaProblemType getProblemType() { return true;
return Boot2JavaProblemType.JAVA_REPOSITORY; }
}
}
return false;
} }
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -57,11 +57,27 @@ public class NoRequestMappingAnnotationReconciler implements JdtAstReconciler {
public NoRequestMappingAnnotationReconciler(QuickfixRegistry registry) { public NoRequestMappingAnnotationReconciler(QuickfixRegistry registry) {
this.registry = registry; this.registry = registry;
} }
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public ProblemType getProblemType() {
boolean isCompleteAst) throws RequiredCompleteAstException { return Boot2JavaProblemType.JAVA_PRECISE_REQUEST_MAPPING;
cu.accept(new ASTVisitor() { }
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(MarkerAnnotation node) { public boolean visit(MarkerAnnotation node) {
@@ -109,7 +125,7 @@ public class NoRequestMappingAnnotationReconciler implements JdtAstReconciler {
} }
} }
}); };
} }
private static FixDescriptor createFixDescriptor(String uri, Range range, String requestMethod) { private static FixDescriptor createFixDescriptor(String uri, Range range, String requestMethod) {
@@ -162,14 +178,4 @@ public class NoRequestMappingAnnotationReconciler implements JdtAstReconciler {
return SUPPORTED_REQUEST_METHODS.contains(requestMethod) ? requestMethod : UNSUPPORTED_REQUEST_METHOD; return SUPPORTED_REQUEST_METHODS.contains(requestMethod) ? requestMethod : UNSUPPORTED_REQUEST_METHOD;
} }
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_PRECISE_REQUEST_MAPPING;
}
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2204 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -64,14 +64,34 @@ public class NotRegisteredBeansReconciler implements JdtAstReconciler, Applicati
private QuickfixRegistry registry; private QuickfixRegistry registry;
public NotRegisteredBeansReconciler(QuickfixRegistry registry) { public NotRegisteredBeansReconciler(QuickfixRegistry registry) {
this.registry = registry; this.registry = registry;
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public boolean isApplicable(IJavaProject project) {
boolean isCompleteAst) throws RequiredCompleteAstException { return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
cu.accept(new ASTVisitor() { }
@Override
public ProblemType getProblemType() {
return SpringAotJavaProblemType.JAVA_BEAN_NOT_REGISTERED_IN_AOT;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(TypeDeclaration node) { public boolean visit(TypeDeclaration node) {
@@ -146,24 +166,9 @@ public class NotRegisteredBeansReconciler implements JdtAstReconciler, Applicati
return super.visit(node); return super.visit(node);
} }
}); };
} }
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return SpringAotJavaProblemType.JAVA_BEAN_NOT_REGISTERED_IN_AOT;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
private static Set<String> allFQTypes(IBinding binding) { private static Set<String> allFQTypes(IBinding binding) {
ImmutableSet.Builder<String> b = ImmutableSet.builder(); ImmutableSet.Builder<String> b = ImmutableSet.builder();
if (binding instanceof IMethodBinding) { if (binding instanceof IMethodBinding) {

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -17,7 +17,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.CompilationUnit;
@@ -45,14 +44,28 @@ public class PreciseBeanTypeReconciler implements JdtAstReconciler {
public PreciseBeanTypeReconciler(QuickfixRegistry registry) { public PreciseBeanTypeReconciler(QuickfixRegistry registry) {
this.registry = registry; this.registry = registry;
}
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public ProblemType getProblemType() {
boolean isCompleteAst) throws RequiredCompleteAstException { return SpringAotJavaProblemType.JAVA_CONCRETE_BEAN_TYPE;
AtomicBoolean requiresCompleteAst = new AtomicBoolean(false); }
cu.accept(new ASTVisitor() {
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
private MethodDeclaration currentMethod; private MethodDeclaration currentMethod;
@@ -72,7 +85,7 @@ public class PreciseBeanTypeReconciler implements JdtAstReconciler {
return true; return true;
} }
} else { } else {
requiresCompleteAst.set(true); throw new RequiredCompleteAstException();
} }
} }
} }
@@ -124,21 +137,7 @@ public class PreciseBeanTypeReconciler implements JdtAstReconciler {
return super.visit(node); return super.visit(node);
} }
}); };
if (requiresCompleteAst.get()) {
throw new RequiredCompleteAstException();
}
}
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(3, 0, 0).test(project);
}
@Override
public ProblemType getProblemType() {
return SpringAotJavaProblemType.JAVA_CONCRETE_BEAN_TYPE;
} }
} }

View File

@@ -10,7 +10,7 @@
*******************************************************************************/ *******************************************************************************/
package org.springframework.ide.vscode.boot.java.reconcilers; package org.springframework.ide.vscode.boot.java.reconcilers;
public class RequiredCompleteAstException extends Exception { public class RequiredCompleteAstException extends RuntimeException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -61,13 +61,28 @@ public class UnnecessarySpringExtensionReconciler implements JdtAstReconciler {
public UnnecessarySpringExtensionReconciler(QuickfixRegistry registry) { public UnnecessarySpringExtensionReconciler(QuickfixRegistry registry) {
this.registry = registry; this.registry = registry;
} }
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 1, 0).test(project);
}
@Override
public Boot2JavaProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_TEST_SPRING_EXTENSION;
}
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector,
boolean isCompleteAst) throws RequiredCompleteAstException { boolean isCompleteAst) throws RequiredCompleteAstException {
cu.accept(new ASTVisitor() { ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(TypeDeclaration typeDecl) { public boolean visit(TypeDeclaration typeDecl) {
@@ -94,50 +109,40 @@ public class UnnecessarySpringExtensionReconciler implements JdtAstReconciler {
} }
return super.visit(typeDecl); return super.visit(typeDecl);
} }
};
private boolean isApplicableExtendsWith(Annotation a) { }
if (FQN_EXTEND_WITH.endsWith(a.getTypeName().getFullyQualifiedName())) {
IAnnotationBinding annotationBinding = a.resolveAnnotationBinding(); private static boolean isApplicableExtendsWith(Annotation a) {
if (annotationBinding != null && FQN_EXTEND_WITH.equals(annotationBinding.getAnnotationType().getQualifiedName()) && annotationBinding.getDeclaredMemberValuePairs().length == 1) { if (FQN_EXTEND_WITH.endsWith(a.getTypeName().getFullyQualifiedName())) {
IMemberValuePairBinding pair = annotationBinding.getDeclaredMemberValuePairs()[0]; IAnnotationBinding annotationBinding = a.resolveAnnotationBinding();
if ("value".equals(pair.getName())) { if (annotationBinding != null && FQN_EXTEND_WITH.equals(annotationBinding.getAnnotationType().getQualifiedName()) && annotationBinding.getDeclaredMemberValuePairs().length == 1) {
ITypeBinding typeBinding = null; IMemberValuePairBinding pair = annotationBinding.getDeclaredMemberValuePairs()[0];
if (pair.getValue() instanceof ITypeBinding) { if ("value".equals(pair.getName())) {
typeBinding = (ITypeBinding) pair.getValue(); ITypeBinding typeBinding = null;
} else if (pair.getValue() instanceof Object[]) { if (pair.getValue() instanceof ITypeBinding) {
Object[] arr = (Object[]) pair.getValue(); typeBinding = (ITypeBinding) pair.getValue();
if (arr.length > 0 && arr[0] instanceof ITypeBinding) { } else if (pair.getValue() instanceof Object[]) {
typeBinding = (ITypeBinding) arr[0]; Object[] arr = (Object[]) pair.getValue();
} if (arr.length > 0 && arr[0] instanceof ITypeBinding) {
} typeBinding = (ITypeBinding) arr[0];
return typeBinding != null && FQN_SPRING_EXT.equals(typeBinding.getQualifiedName());
} }
} }
return typeBinding != null && FQN_SPRING_EXT.equals(typeBinding.getQualifiedName());
} }
return false;
} }
}
private boolean isApplicableTestAnnotation(Annotation a) { return false;
String annotationTypeFqn = a.getTypeName().getFullyQualifiedName(); }
if (SPRING_BOOT_TEST_ANNOTATIONS.stream().anyMatch(fqn -> fqn.endsWith(annotationTypeFqn))) {
IAnnotationBinding annotationBinding = a.resolveAnnotationBinding(); private static boolean isApplicableTestAnnotation(Annotation a) {
if (annotationBinding != null && SPRING_BOOT_TEST_ANNOTATIONS.contains(annotationBinding.getAnnotationType().getQualifiedName())) { String annotationTypeFqn = a.getTypeName().getFullyQualifiedName();
return true; if (SPRING_BOOT_TEST_ANNOTATIONS.stream().anyMatch(fqn -> fqn.endsWith(annotationTypeFqn))) {
} IAnnotationBinding annotationBinding = a.resolveAnnotationBinding();
} if (annotationBinding != null && SPRING_BOOT_TEST_ANNOTATIONS.contains(annotationBinding.getAnnotationType().getQualifiedName())) {
return false; return true;
} }
}); }
} return false;
@Override
public boolean isApplicable(IJavaProject project) {
return springBootVersionGreaterOrEqual(2, 1, 0).test(project);
}
@Override
public Boot2JavaProblemType getProblemType() {
return Boot2JavaProblemType.JAVA_TEST_SPRING_EXTENSION;
} }
} }

View File

@@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2023 VMware, Inc. * Copyright (c) 2023, 2024 VMware, Inc.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@@ -36,11 +36,8 @@ import org.springframework.ide.vscode.commons.rewrite.java.FixDescriptor;
public class WebSecurityConfigurerAdapterReconciler implements JdtAstReconciler { public class WebSecurityConfigurerAdapterReconciler implements JdtAstReconciler {
private static final String WEB_SECURITY_CONFIGURER_ADAPTER = "WebSecurityConfigurerAdapter"; private static final String WEB_SECURITY_CONFIGURER_ADAPTER = "WebSecurityConfigurerAdapter";
private static final String FQN_WEB_SECURITY_CONFIGURER_ADAPTER = "org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter"; private static final String FQN_WEB_SECURITY_CONFIGURER_ADAPTER = "org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter";
private static final String PROBLEM_LABEL = "Class extends 'WebSecurityConfigurerAdapter' which is removed in Spring-Security 6.x"; private static final String PROBLEM_LABEL = "Class extends 'WebSecurityConfigurerAdapter' which is removed in Spring-Security 6.x";
private static final String FIX_LABEL = "Refactor class into a Configuration bean not extending 'WebSecurityConfigurerAdapter'"; private static final String FIX_LABEL = "Refactor class into a Configuration bean not extending 'WebSecurityConfigurerAdapter'";
private static final String STUB_WEB_SECURITY_CONFIG_ADAPTER = """ private static final String STUB_WEB_SECURITY_CONFIG_ADAPTER = """
@@ -73,13 +70,28 @@ public class WebSecurityConfigurerAdapterReconciler implements JdtAstReconciler
public WebSecurityConfigurerAdapterReconciler(QuickfixRegistry registry) { public WebSecurityConfigurerAdapterReconciler(QuickfixRegistry registry) {
this.registry = registry; this.registry = registry;
} }
@Override @Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, public boolean isApplicable(IJavaProject project) {
boolean isCompleteAst) throws RequiredCompleteAstException { Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
cu.accept(new ASTVisitor() { return version != null && version.compareTo(new Version(5, 7, 0, null)) >= 0 && version.compareTo(new Version(6, 1, 0, null)) < 0;
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.WEB_SECURITY_CONFIGURER_ADAPTER;
}
@Override
public void reconcile(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) throws RequiredCompleteAstException {
ASTVisitor visitor = createVisitor(project, docUri, cu, problemCollector, isCompleteAst);
cu.accept(visitor);
}
@Override
public ASTVisitor createVisitor(IJavaProject project, URI docUri, CompilationUnit cu, IProblemCollector problemCollector, boolean isCompleteAst) {
return new ASTVisitor() {
@Override @Override
public boolean visit(TypeDeclaration typeDecl) { public boolean visit(TypeDeclaration typeDecl) {
@@ -108,7 +120,7 @@ public class WebSecurityConfigurerAdapterReconciler implements JdtAstReconciler
return super.visit(typeDecl); return super.visit(typeDecl);
} }
}); };
} }
private static boolean isWebSecurityConfigurerAdapter(CompilationUnit cu, Type type) { private static boolean isWebSecurityConfigurerAdapter(CompilationUnit cu, Type type) {
@@ -133,15 +145,4 @@ public class WebSecurityConfigurerAdapterReconciler implements JdtAstReconciler
return false; return false;
} }
@Override
public boolean isApplicable(IJavaProject project) {
Version version = SpringProjectUtil.getDependencyVersion(project, "spring-security-config");
return version != null && version.compareTo(new Version(5, 7, 0, null)) >= 0 && version.compareTo(new Version(6, 1, 0, null)) < 0;
}
@Override
public ProblemType getProblemType() {
return Boot2JavaProblemType.WEB_SECURITY_CONFIGURER_ADAPTER;
}
} }

View File

@@ -541,6 +541,9 @@ public class SpringIndexerJava implements SpringIndexer {
addEmptyDiagnostics(diagnosticsByDoc, javaFiles); addEmptyDiagnostics(diagnosticsByDoc, javaFiles);
symbolHandler.addSymbols(project, enhancedSymbols, allBeans, diagnosticsByDoc); symbolHandler.addSymbols(project, enhancedSymbols, allBeans, diagnosticsByDoc);
} }
System.out.println("reconciling stats - counter: " + reconciler.getStatsCounter());
System.out.println("reconciling stats - timer: " + reconciler.getStatsTimer());
} }
private String[] scanFiles(IJavaProject project, String[] javaFiles, List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans, private String[] scanFiles(IJavaProject project, String[] javaFiles, List<CachedSymbol> generatedSymbols, List<CachedBean> generatedBeans,
@@ -606,6 +609,7 @@ public class SpringIndexerJava implements SpringIndexer {
catch (Exception e) { catch (Exception e) {
log.error("error extracting symbol information in project '" + context.getProject().getElementName() + "' - for docURI '" + context.getDocURI() + "' - on node: " + node.toString(), e); log.error("error extracting symbol information in project '" + context.getProject().getElementName() + "' - for docURI '" + context.getDocURI() + "' - on node: " + node.toString(), e);
} }
return super.visit(node); return super.visit(node);
} }