JPS mappings for incremental compilation refactoring: basic class parsing test and NPE fixes

GitOrigin-RevId: f88636ec9fb9b151dc716882b7eeba297dac41cb
This commit is contained in:
Eugene Zhuravlev
2023-10-04 13:59:42 +02:00
committed by intellij-monorepo-bot
parent 0742cf58d1
commit 647b9dde1c
7 changed files with 62 additions and 12 deletions

View File

@@ -178,6 +178,10 @@ public final class Iterators {
};
}
public static <T> Iterable<T> asIterable(final T[] elem) {
return elem == null? Collections.<T>emptyList() : Arrays.asList(elem);
}
public static <T> Iterator<T> asIterator(final T elem) {
return new BaseIterator<T>() {
private boolean available = true;

View File

@@ -10,6 +10,7 @@
<orderEntry type="module" module-name="intellij.platform.jps.build" exported="" />
<orderEntry type="module" module-name="intellij.java.testFramework" scope="TEST" />
<orderEntry type="module" module-name="intellij.platform.jps.model.serialization.tests" scope="TEST" />
<orderEntry type="module" module-name="intellij.java.compiler.instrumentationUtil" scope="TEST" />
<orderEntry type="library" scope="TEST" name="Eclipse" level="project" />
<orderEntry type="library" scope="TEST" name="kotlin-stdlib" level="project" />
<orderEntry type="library" scope="TEST" name="ASM" level="project" />

View File

@@ -50,6 +50,10 @@ public final class JvmClass extends JVMClassNode<JvmClass, JvmClass.Diff> {
return index >= 0? jvmClassName.substring(0, index) : "";
}
public boolean isInterface() {
return getFlags().isInterface();
}
public boolean isAnonymous() {
return getFlags().isAnonymous();
}

View File

@@ -306,7 +306,6 @@ final class JvmClassNodeBuilder extends ClassVisitor implements NodeBuilder {
}
};
private boolean myTakeIntoAccount = false;
private boolean myIsModule = false;
private final String myFileName;
private final boolean myIsGenerated;
@@ -314,7 +313,7 @@ final class JvmClassNodeBuilder extends ClassVisitor implements NodeBuilder {
private String myName;
private String myVersion; // for class contains a class bytecode version, for module contains a module version
private String mySuperClass;
private String[] myInterfaces;
private Iterable<String> myInterfaces;
private String mySignature;
private final Ref<String> myClassNameHolder = Ref.create();
@@ -341,7 +340,7 @@ final class JvmClassNodeBuilder extends ClassVisitor implements NodeBuilder {
myIsGenerated = isGenerated;
}
public static NodeBuilder create(String filePath, ClassReader cr, boolean isGenerated) {
public static JvmClassNodeBuilder create(String filePath, ClassReader cr, boolean isGenerated) {
JvmClassNodeBuilder builder = new JvmClassNodeBuilder(filePath, isGenerated);
try {
cr.accept(builder, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG);
@@ -362,6 +361,8 @@ final class JvmClassNodeBuilder extends ClassVisitor implements NodeBuilder {
myUsages.add(usage);
}
// todo: ignore private nodes on the client side
@Override
public JVMClassNode<? extends JVMClassNode<?, ?>, ? extends Proto.Diff<? extends JVMClassNode<?, ?>>> getResult() {
JVMFlags flags = new JVMFlags(myAccess);
@@ -377,7 +378,7 @@ final class JvmClassNodeBuilder extends ClassVisitor implements NodeBuilder {
if (myIsModule) {
return new JvmModule(flags, myVersion, myFileName, myName, myModuleRequires, myModuleExports, myUsages);
}
return new JvmClass(flags, mySignature, myName, myFileName, mySuperClass, myOuterClassName.get(), Arrays.asList(myInterfaces), myFields, myMethods, myAnnotations, myTargets, myRetentionPolicy, myUsages);
return new JvmClass(flags, mySignature, myName, myFileName, mySuperClass, myOuterClassName.get(), myInterfaces, myFields, myMethods, myAnnotations, myTargets, myRetentionPolicy, myUsages);
}
@Override
@@ -387,18 +388,16 @@ final class JvmClassNodeBuilder extends ClassVisitor implements NodeBuilder {
myVersion = String.valueOf(version);
mySignature = sig;
mySuperClass = superName;
myInterfaces = interfaces;
myInterfaces = Iterators.asIterable(interfaces);
myClassNameHolder.set(name);
if (mySuperClass != null) {
if (mySuperClass != null && !Utils.OBJECT_CLASS_NAME.equals(mySuperClass)) {
addUsage(new ClassUsage(mySuperClass));
}
if (myInterfaces != null) {
for (String ifaceName : myInterfaces) {
addUsage(new ClassUsage(ifaceName));
}
for (String ifaceName : myInterfaces) {
addUsage(new ClassUsage(ifaceName));
}
processSignature(sig);

View File

@@ -7,7 +7,6 @@ import org.jetbrains.jps.dependency.diff.Difference;
import org.jetbrains.jps.javac.Iterators;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@@ -24,7 +23,7 @@ public final class JvmMethod extends ProtoMember implements DiffCapable<JvmMetho
super(flags, signature, name, TypeRepr.getType(Type.getReturnType(descriptor)), annotations, defaultValue);
myParamAnnotations = parameterAnnotations;
myExceptions = Iterators.collect(Iterators.map(Arrays.asList(exceptions), s -> new TypeRepr.ClassType(s)), new HashSet<>());
myExceptions = Iterators.collect(Iterators.map(Iterators.asIterable(exceptions), s -> new TypeRepr.ClassType(s)), new HashSet<>());
myArgTypes = TypeRepr.getTypes(Type.getArgumentTypes(descriptor));
}

View File

@@ -0,0 +1,43 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.jps.dependency.java;
import com.intellij.compiler.instrumentation.FailSafeClassReader;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.util.io.FileUtil;
import junit.framework.TestCase;
import org.jetbrains.jps.javac.Iterators;
import org.jetbrains.org.objectweb.asm.ClassReader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Eugene Zhuravlev
*/
public class JvmClassNodeBuilderTest extends TestCase {
private final File myWorkDir;
public JvmClassNodeBuilderTest() {
myWorkDir = new File(PathManagerEx.getTestDataPath(getClass()) + File.separator + "compileServer" + File.separator + "dependency");
}
public void testClassParsing() throws IOException {
File dataFile = new File(myWorkDir, "I.class");
final ClassReader reader = new FailSafeClassReader(FileUtil.loadFileBytes(dataFile));
JvmClassNodeBuilder nodeBuilder = JvmClassNodeBuilder.create(dataFile.getPath(), reader, false);
JVMClassNode<?, ?> classNode = nodeBuilder.getResult();
assertTrue(classNode instanceof JvmClass);
JvmClass cls = (JvmClass)classNode;
assertTrue(cls.isInterface());
assertFalse(cls.isAnnotation());
List<JvmMethod> methods = Iterators.collect(cls.getMethods(), new ArrayList<>());
assertEquals(1, methods.size());
assertEquals("bar", methods.iterator().next().getName());
}
}