INRIA / INRIA/spoon

[Bug]: Unable to parse `CtElement` from a JDK-runtime-element by `CtPath`

Open
#4,984 4 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
2k
Forks
392
Avg merge
11h 24m
Merged PRs (30d)
36

Description

### Describe the bug

Ideally, there's a one-to-one relationship between a `CtElement` and a specific complete `CtPath`.

It works well with user-defined classes, but not with a JDK-runtime element.

For example, I can't get `CtType` for `java.lang.System` from its `CtPath`:
#subPackage[name=java]#subPackage[name=lang]#containedType[name=System]

### Source code you are trying to analyze/transform

```Java
java.lang.System
```

### Source code for your Spoon processing

```Java
@Test
public void test() {
CtType ctType = new TypeFactory().get(java.lang.System.class);
System.out.println(ctType.getPath());

CtPath path = new CtPathStringBuilder().fromString("#subPackage[name=java]#subPackage[name=lang]#containedType[name=System]");
List l = path.evaluateOn(model.getRootPackage());
System.out.println(l);

assertTrue(l.iterator().hasNext());
assertEquals(l.iterator().next(), ctType);
}
```

### Actual output

```Java
#subPackage[name=java]#subPackage[name=lang]#containedType[name=System]
[]

java.lang.AssertionError
at org.junit.Assert.fail(Assert.java:86)
at org.junit.Assert.assertTrue(Assert.java:41)
at org.junit.Assert.assertTrue(Assert.java:52)
```

### Expected output

```Java
#subPackage[name=java]#subPackage[name=lang]#containedType[name=System]
[public final class System {
private System() {
}

private static void initPhase1() {
}

private static int initPhase2(boolean arg0, boolean arg1) {
}

private static void initPhase3() {
}

public static void exit(int arg0) {
}

public static void runFinalization() {
}

public static java.lang.String getProperty(java.lang.String arg0) {
}

public static java.lang.String getProperty(java.lang.String arg0, java.lang.String arg1) {
}

@jdk.internal.HotSpotIntrinsicCandidate
public static native int identityHashCode(java.lang.Object arg0) {
}

@jdk.internal.HotSpotIntrinsicCandidate
public static native long currentTimeMillis() {
}

@jdk.internal.HotSpotIntrinsicCandidate
public static native long nanoTime() {
}

@jdk.internal.HotSpotIntrinsicCandidate
public static native void arraycopy(java.lang.Object arg0, int arg1, java.lang.Object arg2, int arg3, int arg4) {
}

private static native void registerNatives() {
}

public static java.lang.SecurityManager getSecurityManager() {
}

@jdk.internal.reflect.CallerSensitive
public static void loadLibrary(java.lang.String arg0) {
}

public static native java.lang.String mapLibraryName(java.lang.String arg0) {
}

public static java.lang.String lineSeparator() {
}

public static void setIn(java.io.InputStream arg0) {
}

public static void setOut(java.io.PrintStream arg0) {
}

public static void setErr(java.io.PrintStream arg0) {
}

public static java.io.Console console() {
}

public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException {
}

private static void checkIO() {
}

private static native void setIn0(java.io.InputStream arg0) {
}

private static native void setOut0(java.io.PrintStream arg0) {
}

private static native void setErr0(java.io.PrintStream arg0) {
}

public static void setSecurityManager(java.lang.SecurityManager arg0) {
}

private static synchronized void setSecurityManager0(java.lang.SecurityManager arg0) {
}

private static native java.util.Properties initProperties(java.util.Properties arg0) {
}

public static java.util.Properties getProperties() {
}

public static void setProperties(java.util.Properties arg0) {
}

public static java.lang.String setProperty(java.lang.String arg0, java.lang.String arg1) {
}

public static java.lang.String clearProperty(java.lang.String arg0) {
}

private static void checkKey(java.lang.String arg0) {
}

public static java.lang.String getenv(java.lang.String arg0) {
}

public static java.util.Map getenv() {
}

@jdk.internal.reflect.CallerSensitive
public static java.lang.System.Logger getLogger(java.lang.String arg0, java.util.ResourceBundle arg1) {
}

@jdk.internal.reflect.CallerSensitive
public static java.lang.System.Logger getLogger(java.lang.String arg0) {
}

public static void gc() {
}

@jdk.internal.reflect.CallerSensitive
public static void load(java.lang.String arg0) {
}

private static java.io.PrintStream newPrintStream(java.io.FileOutputStream arg0, java.lang.String arg1) {
}

private static void logInitException(boolean arg0, boolean arg1, java.lang.String arg2, java.lang.Throwable arg3) {
}

private static void setJavaLangAccess() {
}

public static final java.io.InputStream in;

public static final java.io.PrintStream out;

public static final java.io.PrintStream err;

private static volatile java.io.Console cons;

private static java.util.Properties props;

private static java.lang.String lineSeparator;

static java.lang.ModuleLayer bootLayer;

public static abstract class LoggerFinder {
protected LoggerFinder() {
}

private LoggerFinder(java.lang.Void arg0) {
}

private static java.lang.Void checkPermission() {
}

public abstract java.lang.System.Logger getLogger(java.lang.String arg0, java.lang.Module arg1);

static java.lang.System.LoggerFinder accessProvider() {
}

public java.lang.System.Logger getLocalizedLogger(java.lang.String arg0, java.util.ResourceBundle arg1, java.lang.Module arg2) {
}

public static java.lang.System.LoggerFinder getLoggerFinder() {
}

static final java.lang.RuntimePermission LOGGERFINDER_PERMISSION;

private static volatile java.lang.System.LoggerFinder service;
}

public static abstract interface Logger {
public abstract java.lang.String getName();

public default void log(java.lang.System.Logger.Level arg0, java.lang.String arg1, java.lang.Object... arg2) {
}

public default void log(java.lang.System.Logger.Level arg0, java.util.function.Supplier arg1, java.lang.Throwable arg2) {
}

public default void log(java.lang.System.Logger.Level arg0, java.lang.String arg1, java.lang.Throwable arg2) {
}

public abstract void log(java.lang.System.Logger.Level arg0, java.util.ResourceBundle arg1, java.lang.String arg2, java.lang.Throwable arg3);

public abstract void log(java.lang.System.Logger.Level arg0, java.util.ResourceBundle arg1, java.lang.String arg2, java.lang.Object... arg3);

public default void log(java.lang.System.Logger.Level arg0, java.lang.String arg1) {
}

public default void log(java.lang.System.Logger.Level arg0, java.util.function.Supplier arg1) {
}

public default void log(java.lang.System.Logger.Level arg0, java.lang.Object arg1) {
}

public abstract boolean isLoggable(java.lang.System.Logger.Level arg0);

public static final enum Level {

ALL,
TRACE,
DEBUG,
INFO,
WARNING,
ERROR,
OFF;
private Level(int arg0) {
}

public final java.lang.String getName() {
}

public final int getSeverity() {
}

private final int severity;
}
}
}]
```

### Spoon Version

10.2.0-beta-21

### JVM Version

11

### What operating system are you using?

Windows 11

Contributor guide

Open the contributing guide

Research direction

Reproduce the test using TypeFactory().get(java.lang.System.class), CtPathStringBuilder.fromString(...), and path.evaluateOn(model.getRootPackage()). Start by tracing how the JDK runtime type and its CtPath are represented, then compare that with the user-defined class case. Done means the path returns the java.lang.System CtType as shown in the expected output.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.