From 89fdddf8436903db07c182f0f34650efd0057b41 Mon Sep 17 00:00:00 2001 From: azerr Date: Mon, 29 Jul 2024 18:20:46 +0200 Subject: [PATCH] feat: Validate if a BuildItem is final or abstract Fixes #926 Signed-off-by: azerr --- .../maven/quarkus-builditems/.classpath | 40 ++++++ .../maven/quarkus-builditems/.gitignore | 43 +++++++ .../maven/quarkus-builditems/.project | 23 ++++ .../projects/maven/quarkus-builditems/pom.xml | 116 ++++++++++++++++++ .../org/acme/builditems/BadBuildItem.java | 6 + .../org/acme/builditems/GoodBuildItem.java | 6 + .../src/main/resources/application.properties | 0 .../jdt/quarkus/QuarkusMavenProjectName.java | 2 + .../QuarkusBuildItemASTVisitorTest.java | 54 ++++++++ .../META-INF/MANIFEST.MF | 1 + .../plugin.xml | 7 ++ .../internal/quarkus/QuarkusConstants.java | 11 +- .../builditems/QuarkusBuildItemErrorCode.java | 28 +++++ .../java/QuarkusBuildItemASTVisitor.java | 99 +++++++++++++++ 14 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.classpath create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.gitignore create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.project create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/pom.xml create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/BadBuildItem.java create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/GoodBuildItem.java create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/resources/application.properties create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/builditems/QuarkusBuildItemASTVisitorTest.java create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/QuarkusBuildItemErrorCode.java create mode 100644 quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/java/QuarkusBuildItemASTVisitor.java diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.classpath b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.classpath new file mode 100644 index 000000000..7a69f73fa --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.classpath @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.gitignore b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.gitignore new file mode 100644 index 000000000..726d8ae39 --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.gitignore @@ -0,0 +1,43 @@ +#Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +release.properties +.flattened-pom.xml + +# Eclipse +#.project +#.classpath +.settings/ +bin/ + +# IntelliJ +.idea +*.ipr +*.iml +*.iws + +# NetBeans +nb-configuration.xml + +# Visual Studio Code +.vscode +.factorypath + +# OSX +.DS_Store + +# Vim +*.swp +*.swo + +# patch +*.orig +*.rej + +# Local environment +.env + +# Plugin directory +/.quarkus/cli/plugins/ diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.project b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.project new file mode 100644 index 000000000..557480f1c --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/.project @@ -0,0 +1,23 @@ + + + quarkus-builditems + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/pom.xml b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/pom.xml new file mode 100644 index 000000000..cd6dfe7dd --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/pom.xml @@ -0,0 +1,116 @@ + + + 4.0.0 + org.acme + quarkus-builditems + 1.0.0-SNAPSHOT + + 3.11.0 + 17 + UTF-8 + UTF-8 + quarkus-bom + io.quarkus.platform + 3.3.1 + true + 3.1.2 + + + + + ${quarkus.platform.group-id} + ${quarkus.platform.artifact-id} + ${quarkus.platform.version} + pom + import + + + + + + io.quarkus + quarkus-core-deployment + + + io.quarkus + quarkus-arc + + + io.quarkus + quarkus-junit5 + test + + + + + + ${quarkus.platform.group-id} + quarkus-maven-plugin + ${quarkus.platform.version} + true + + + + build + generate-code + generate-code-tests + + + + + + maven-compiler-plugin + ${compiler-plugin.version} + + + -parameters + + + + + maven-surefire-plugin + ${surefire-plugin.version} + + + org.jboss.logmanager.LogManager + ${maven.home} + + + + + maven-failsafe-plugin + ${surefire-plugin.version} + + + + integration-test + verify + + + + ${project.build.directory}/${project.build.finalName}-runner + org.jboss.logmanager.LogManager + ${maven.home} + + + + + + + + + + native + + + native + + + + false + native + + + + diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/BadBuildItem.java b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/BadBuildItem.java new file mode 100644 index 000000000..85960e7bb --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/BadBuildItem.java @@ -0,0 +1,6 @@ +package org.acme.builditems; + +import io.quarkus.builder.item.MultiBuildItem; + +public class BadBuildItem extends MultiBuildItem { +} \ No newline at end of file diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/GoodBuildItem.java b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/GoodBuildItem.java new file mode 100644 index 000000000..8cf3a6604 --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/java/org/acme/builditems/GoodBuildItem.java @@ -0,0 +1,6 @@ +package org.acme.builditems; + +import io.quarkus.builder.item.SimpleBuildItem; + +public final class GoodBuildItem extends SimpleBuildItem { +} \ No newline at end of file diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/resources/application.properties b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/projects/maven/quarkus-builditems/src/main/resources/application.properties new file mode 100644 index 000000000..e69de29bb diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/QuarkusMavenProjectName.java b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/QuarkusMavenProjectName.java index 36619c90c..f1f1e0eee 100644 --- a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/QuarkusMavenProjectName.java +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/QuarkusMavenProjectName.java @@ -20,4 +20,6 @@ public class QuarkusMavenProjectName extends MicroProfileMavenProjectName { public static String scheduler_quickstart = "scheduler-quickstart"; public static String scheduler_diagnostic = "scheduler-diagnostic"; public static final String quarkus_route = "quarkus-route"; + + public static final String quarkus_builditems = "quarkus-builditems"; } \ No newline at end of file diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/builditems/QuarkusBuildItemASTVisitorTest.java b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/builditems/QuarkusBuildItemASTVisitorTest.java new file mode 100644 index 000000000..cd4a2c753 --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus.test/src/main/java/com/redhat/microprofile/jdt/quarkus/builditems/QuarkusBuildItemASTVisitorTest.java @@ -0,0 +1,54 @@ +package com.redhat.microprofile.jdt.quarkus.builditems; + +import static org.eclipse.lsp4mp.jdt.core.MicroProfileForJavaAssert.assertJavaDiagnostics; +import static org.eclipse.lsp4mp.jdt.core.MicroProfileForJavaAssert.d; + +import java.util.Arrays; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.lsp4j.Diagnostic; +import org.eclipse.lsp4j.DiagnosticSeverity; +import org.eclipse.lsp4mp.commons.DocumentFormat; +import org.eclipse.lsp4mp.commons.MicroProfileJavaDiagnosticsParams; +import org.eclipse.lsp4mp.jdt.core.BasePropertiesManagerTest; +import org.junit.Test; + +import com.redhat.microprofile.jdt.internal.quarkus.QuarkusConstants; +import com.redhat.microprofile.jdt.internal.quarkus.builditems.QuarkusBuildItemErrorCode; +import com.redhat.microprofile.jdt.quarkus.QuarkusMavenProjectName; + +public class QuarkusBuildItemASTVisitorTest extends BasePropertiesManagerTest { + + @Test + public void buildItemClassifier() throws Exception { + IJavaProject javaProject = loadMavenProject(QuarkusMavenProjectName.quarkus_builditems); + + { // Bad BuildItem shows error + MicroProfileJavaDiagnosticsParams diagnosticsParams = new MicroProfileJavaDiagnosticsParams(); + IFile javaFile = javaProject.getProject() + .getFile(new Path("src/main/java/org/acme/builditems/BadBuildItem.java")); + String uri = javaFile.getLocation().toFile().toURI().toASCIIString(); + diagnosticsParams.setUris(Arrays.asList(uri)); + diagnosticsParams.setDocumentFormat(DocumentFormat.Markdown); + + Diagnostic d = d(4, 13, 25, + "BuildItem class `org.acme.builditems.BadBuildItem` must either be declared final or abstract", + DiagnosticSeverity.Error, QuarkusConstants.QUARKUS_DIAGNOSTIC_SOURCE, + QuarkusBuildItemErrorCode.InvalidModifierBuildItem); + assertJavaDiagnostics(diagnosticsParams, JDT_UTILS, d); + } + + { // Good BuildItem shows no error + MicroProfileJavaDiagnosticsParams diagnosticsParams = new MicroProfileJavaDiagnosticsParams(); + IFile javaFile = javaProject.getProject() + .getFile(new Path("src/main/java/org/acme/builditems/GoodBuildItem.java")); + String uri = javaFile.getLocation().toFile().toURI().toASCIIString(); + diagnosticsParams.setUris(Arrays.asList(uri)); + diagnosticsParams.setDocumentFormat(DocumentFormat.Markdown); + assertJavaDiagnostics(diagnosticsParams, JDT_UTILS); + } + + } +} \ No newline at end of file diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/META-INF/MANIFEST.MF b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/META-INF/MANIFEST.MF index 2c4b53544..18f87b3a3 100644 --- a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/META-INF/MANIFEST.MF +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/META-INF/MANIFEST.MF @@ -18,6 +18,7 @@ Export-Package: com.redhat.microprofile.jdt.internal.quarkus;x-friends:="com.red com.redhat.microprofile.jdt.internal.quarkus.providers;x-friends:="com.redhat.microprofile.jdt.quarkus.test", com.redhat.microprofile.jdt.internal.quarkus.renarde.java;x-friends:="com.redhat.microprofile.jdt.quarkus.test", com.redhat.microprofile.jdt.internal.quarkus.scheduler;x-friends:="com.redhat.microprofile.jdt.quarkus.test", + com.redhat.microprofile.jdt.internal.quarkus.builditems;x-friends:="com.redhat.microprofile.jdt.quarkus.test", com.redhat.microprofile.jdt.internal.quarkus.utils;x-friends:="com.redhat.microprofile.jdt.quarkus.test", com.redhat.microprofile.jdt.quarkus, org.yaml.snakeyaml;x-friends:="com.redhat.microprofile.jdt.quarkus.test" diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/plugin.xml b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/plugin.xml index 5a0a50a01..36b961e0e 100644 --- a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/plugin.xml +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/plugin.xml @@ -19,6 +19,13 @@ + + + + + + + diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/QuarkusConstants.java b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/QuarkusConstants.java index 3f84dc801..4d784b62f 100644 --- a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/QuarkusConstants.java +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/QuarkusConstants.java @@ -56,10 +56,9 @@ public class QuarkusConstants { public static final String SCHEDULED_ANNOTATION_DELAY_UNIT = "delayUnit"; public static final String SCHEDULED_ANNOTATION_DELAYED = "delayed"; - public static final String[] SCHEDULED_SUPPORTED_PARTICIPANT_MEMBERS = { - SCHEDULED_ANNOTATION_CRON, SCHEDULED_ANNOTATION_EVERY, SCHEDULED_ANNOTATION_DELAY, - SCHEDULED_ANNOTATION_DELAYED, SCHEDULED_ANNOTATION_DELAY_UNIT - }; + public static final String[] SCHEDULED_SUPPORTED_PARTICIPANT_MEMBERS = { SCHEDULED_ANNOTATION_CRON, + SCHEDULED_ANNOTATION_EVERY, SCHEDULED_ANNOTATION_DELAY, SCHEDULED_ANNOTATION_DELAYED, + SCHEDULED_ANNOTATION_DELAY_UNIT }; public static final String SCHEDULED_ANNOTATION_CONCURRENT_EXECUTION = "concurrentExecution"; public static final String SCHEDULED_ANNOTATION_SKIP_EXECUTION_IF = "skipExecutionIf"; @@ -132,6 +131,10 @@ public class QuarkusConstants { public static final String QUARKUS_RUNTIME_CLASS_NAME = "io.quarkus.runtime.LaunchMode"; + public static final String QUARKUS_BUILD_ITEM_CLASS_NAME = "io.quarkus.builder.item.BuildItem"; + + public static final String QUARKUS_DIAGNOSTIC_SOURCE = "quarkus"; + private QuarkusConstants() { } } \ No newline at end of file diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/QuarkusBuildItemErrorCode.java b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/QuarkusBuildItemErrorCode.java new file mode 100644 index 000000000..5c26b2c75 --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/QuarkusBuildItemErrorCode.java @@ -0,0 +1,28 @@ +/******************************************************************************* +* Copyright (c) 2024 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 +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package com.redhat.microprofile.jdt.internal.quarkus.builditems; + +import org.eclipse.lsp4mp.jdt.core.java.diagnostics.IJavaErrorCode; + +/** + * Represents error codes for validation issues in classes inheriting + * io.quarkus.builder.item.BuildItem. + */ +public enum QuarkusBuildItemErrorCode implements IJavaErrorCode { + + InvalidModifierBuildItem; + + @Override + public String getCode() { + return name(); + } +} diff --git a/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/java/QuarkusBuildItemASTVisitor.java b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/java/QuarkusBuildItemASTVisitor.java new file mode 100644 index 000000000..5e96a520c --- /dev/null +++ b/quarkus.jdt.ext/com.redhat.microprofile.jdt.quarkus/src/main/java/com/redhat/microprofile/jdt/internal/quarkus/builditems/java/QuarkusBuildItemASTVisitor.java @@ -0,0 +1,99 @@ +/******************************************************************************* +* Copyright (c) 2024 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 +* +* SPDX-License-Identifier: EPL-2.0 +* +* Contributors: +* Red Hat Inc. - initial API and implementation +*******************************************************************************/ +package com.redhat.microprofile.jdt.internal.quarkus.builditems.java; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.TypeDeclaration; +import org.eclipse.lsp4j.DiagnosticSeverity; +import org.eclipse.lsp4mp.commons.DocumentFormat; +import org.eclipse.lsp4mp.jdt.core.java.diagnostics.JavaDiagnosticsContext; +import org.eclipse.lsp4mp.jdt.core.java.validators.JavaASTValidator; +import org.eclipse.lsp4mp.jdt.core.utils.JDTTypeUtils; + +import com.redhat.microprofile.jdt.internal.quarkus.QuarkusConstants; +import com.redhat.microprofile.jdt.internal.quarkus.builditems.QuarkusBuildItemErrorCode; + +/** + * Validates io.quarkus.builder.item.BuildItem subclasses. + *
    + *
  • checks if the BuildItem is final or abstract
  • + *
+ */ +public class QuarkusBuildItemASTVisitor extends JavaASTValidator { + + private static final String INVALID_MODIFIER = "BuildItem class %2$s%1$s%2$s must either be declared final or abstract"; + + @Override + public boolean isAdaptedForDiagnostics(JavaDiagnosticsContext context, IProgressMonitor monitor) + throws CoreException { + // Collection of diagnostics for Quarkus Build Items is done only if + // io.quarkus.builder.item.BuildItem is on the classpath + IJavaProject javaProject = context.getJavaProject(); + return JDTTypeUtils.findType(javaProject, QuarkusConstants.QUARKUS_BUILD_ITEM_CLASS_NAME) != null; + } + + @Override + public boolean visit(TypeDeclaration node) { + ITypeBinding typeBinding = node.resolveBinding(); + if (isBuildItem(typeBinding)) { + validateBuildItem(node, typeBinding, super.getContext()); + } + return super.visit(node); + } + + /** + * Returns true if the given type declaration extends + * 'io.quarkus.builder.item.BuildItem' class and false otherwise. + * + * @param typeBinding the type declaration. + * @return true if the given type declaration extends + * 'io.quarkus.builder.item.BuildItem' class and false otherwise. + */ + private static boolean isBuildItem(ITypeBinding typeBinding) { + return typeBinding != null && extendsClass(typeBinding, QuarkusConstants.QUARKUS_BUILD_ITEM_CLASS_NAME); + } + + private void validateBuildItem(TypeDeclaration typeDeclaration, ITypeBinding typeBinding, + JavaDiagnosticsContext context) { + if (isValidBuildItem(typeDeclaration)) { + return; + } + super.addDiagnostic(createDiagnosticMessage(typeBinding, context.getDocumentFormat()), + QuarkusConstants.QUARKUS_DIAGNOSTIC_SOURCE, typeDeclaration.getName(), + QuarkusBuildItemErrorCode.InvalidModifierBuildItem, DiagnosticSeverity.Error); + } + + private static boolean isValidBuildItem(TypeDeclaration typeDeclaration) { + int flags = typeDeclaration.getModifiers(); + return Modifier.isAbstract(flags) || Modifier.isFinal(flags); + } + + private static String createDiagnosticMessage(ITypeBinding typeBinding, DocumentFormat documentFormat) { + String quote = DocumentFormat.Markdown.equals(documentFormat) ? "`" : "'"; + return String.format(INVALID_MODIFIER, typeBinding.getQualifiedName(), quote); + } + + private static boolean extendsClass(ITypeBinding typeBinding, String classNameToCheck) { + ITypeBinding superClass = typeBinding.getSuperclass(); + while (superClass != null) { + if (superClass.getQualifiedName().equals(classNameToCheck)) { + return true; + } + superClass = superClass.getSuperclass(); + } + return false; + } +} \ No newline at end of file