Skip to content

Commit

Permalink
Merge pull request jMonkeyEngine#623 from neph1/fix_AppStateExplorer
Browse files Browse the repository at this point in the history
fix AppStateExplorer not finding AppStates extending BaseAppState
  • Loading branch information
neph1 authored Nov 29, 2024
2 parents 0e0e4f2 + ecde876 commit f87c55b
Showing 1 changed file with 62 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -82,57 +83,84 @@ private void scanControls() {
}

private List<String> getSources() {
Sources sources = proj.getLookup().lookup(Sources.class);
final List<String> list = new LinkedList<String>();
Sources sources = ProjectUtils.getSources(proj);
final List<String> 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<SearchScope> set = EnumSet.of(ClassIndex.SearchScope.SOURCE);
Set<ElementHandle<TypeElement>> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set);
for (Iterator<ElementHandle<TypeElement>> it = types.iterator(); it.hasNext();) {
final ElementHandle<TypeElement> elementHandle = it.next();
for (ElementHandle<TypeElement> elementHandle : types) {
JavaSource js = JavaSource.create(cpInfo);
try {
js.runUserActionTask(new Task<CompilationController>() {
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<? extends TypeMirror> 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();
Expand Down

0 comments on commit f87c55b

Please sign in to comment.