diff --git a/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java b/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java index 126a804b..84b8352d 100644 --- a/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java +++ b/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 jMonkeyEngine + * Copyright (c) 2009-2024 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,13 +31,15 @@ */ package com.jme3.gde.core.appstates; +import java.io.IOException; import java.util.EnumSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.lang.model.element.TypeElement; +import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; import javax.swing.JPanel; import org.netbeans.api.java.classpath.ClassPath; import org.netbeans.api.java.project.JavaProjectConstants; @@ -48,9 +50,8 @@ import org.netbeans.api.java.source.CompilationController; import org.netbeans.api.java.source.ElementHandle; import org.netbeans.api.java.source.JavaSource; -import org.netbeans.api.java.source.JavaSource.Phase; -import org.netbeans.api.java.source.Task; import org.netbeans.api.project.Project; +import org.netbeans.api.project.ProjectUtils; import org.netbeans.api.project.SourceGroup; import org.netbeans.api.project.Sources; import org.openide.util.Exceptions; @@ -82,57 +83,84 @@ private void scanControls() { } private List getSources() { - Sources sources = proj.getLookup().lookup(Sources.class); - final List list = new LinkedList(); + Sources sources = ProjectUtils.getSources(proj); + final List list = new LinkedList<>(); if (sources != null) { SourceGroup[] groups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); if (groups != null) { for (SourceGroup sourceGroup : groups) { - ClasspathInfo cpInfo = ClasspathInfo.create(ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.BOOT), + ClasspathInfo cpInfo = ClasspathInfo.create( + ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.BOOT), ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.COMPILE), - ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.SOURCE)); + ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.SOURCE) + ); Set set = EnumSet.of(ClassIndex.SearchScope.SOURCE); Set> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set); - for (Iterator> it = types.iterator(); it.hasNext();) { - final ElementHandle elementHandle = it.next(); + for (ElementHandle elementHandle : types) { JavaSource js = JavaSource.create(cpInfo); try { - js.runUserActionTask(new Task() { - public void run(CompilationController control) - throws Exception { - control.toPhase(Phase.RESOLVED); - //TODO: check with proper casting check.. gotta get TypeMirror of Control interface.. -// TypeUtilities util = control.getTypeUtilities();//.isCastable(Types., null) -// util.isCastable(null, null); - TypeElement elem = elementHandle.resolve(control); - if (elem != null) { - List interfaces = elem.getInterfaces(); - for (TypeMirror typeMirror : interfaces) { - String interfaceName = typeMirror.toString(); - if ("com.jme3.app.state.AppState".equals(interfaceName)) { - list.add(elem.getQualifiedName().toString()); - } - } - TypeMirror superClass = elem.getSuperclass(); - String superClassName = superClass.toString(); - if ("com.jme3.app.state.AbstractAppState".equals(superClassName)) { - list.add(elem.getQualifiedName().toString()); - } - } + js.runUserActionTask((CompilationController control) -> { + control.toPhase(JavaSource.Phase.RESOLVED); + TypeElement elem = elementHandle.resolve(control); + if (elem != null && doesInheritFromAppState(elem, control.getTypes())) { + list.add(elem.getQualifiedName().toString()); } }, false); - } catch (Exception ioe) { + } catch (IOException ioe) { Exceptions.printStackTrace(ioe); } } - } } } return list; } + /** + * Checks recursively if a type inherits from or implements any + * AppState-related class/interface. + */ + private boolean doesInheritFromAppState(TypeElement type, Types typeUtils) { + if (type == null) { + return false; + } + + // Check interfaces + for (TypeMirror iface : type.getInterfaces()) { + if (isAppStateType(iface)) { + return true; + } + if (doesInheritFromAppState((TypeElement) typeUtils.asElement(iface), typeUtils)) { + return true; + } + } + + // Check superclass + TypeMirror superClass = type.getSuperclass(); + if (superClass != null && superClass.getKind() != TypeKind.NONE) { + if (isAppStateType(superClass)) { + return true; + } + return doesInheritFromAppState((TypeElement) typeUtils.asElement(superClass), typeUtils); + } + + return false; + } + + /** + * Determines if a TypeMirror corresponds to an AppState-related type. + */ + private boolean isAppStateType(TypeMirror typeMirror) { + if (typeMirror == null) { + return false; + } + String className = typeMirror.toString(); + return "com.jme3.app.state.AppState".equals(className) + || "com.jme3.app.state.AbstractAppState".equals(className) + || "com.jme3.app.state.BaseAppState".equals(className); + } + public void load(Project proj) { this.proj = proj; scanControls();