-
Notifications
You must be signed in to change notification settings - Fork 164
Running Kotlin and Spock tests #1829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17,15 +17,33 @@ | |||||||||
| import com.microsoft.java.test.plugin.util.TestItemUtils; | ||||||||||
|
|
||||||||||
| import org.eclipse.core.resources.IProject; | ||||||||||
| import org.eclipse.core.resources.IResource; | ||||||||||
| import org.eclipse.core.resources.ResourcesPlugin; | ||||||||||
| import org.eclipse.core.runtime.IPath; | ||||||||||
| import org.eclipse.jdt.core.IClassFile; | ||||||||||
| import org.eclipse.jdt.core.IClasspathEntry; | ||||||||||
| import org.eclipse.jdt.core.IJavaElement; | ||||||||||
| import org.eclipse.jdt.core.IJavaProject; | ||||||||||
| import org.eclipse.jdt.core.IPackageFragment; | ||||||||||
| import org.eclipse.jdt.core.JavaModelException; | ||||||||||
| import org.eclipse.jdt.internal.core.BinaryMember; | ||||||||||
| import org.eclipse.jdt.internal.core.BinaryMethod; | ||||||||||
| import org.eclipse.jdt.internal.core.BinaryType; | ||||||||||
| import org.eclipse.jdt.internal.core.PackageFragmentRoot; | ||||||||||
| import org.eclipse.jdt.internal.core.manipulation.JavaElementLabelsCore; | ||||||||||
| import org.eclipse.jdt.ls.core.internal.JDTUtils; | ||||||||||
| import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; | ||||||||||
| import org.eclipse.jdt.ls.core.internal.ProjectUtils; | ||||||||||
| import org.eclipse.lsp4j.Position; | ||||||||||
| import org.eclipse.lsp4j.Range; | ||||||||||
| import org.objectweb.asm.ClassReader; | ||||||||||
| import org.objectweb.asm.ClassVisitor; | ||||||||||
| import org.objectweb.asm.Label; | ||||||||||
| import org.objectweb.asm.MethodVisitor; | ||||||||||
| import org.objectweb.asm.Opcodes; | ||||||||||
|
|
||||||||||
| import java.io.ByteArrayInputStream; | ||||||||||
| import java.io.InputStream; | ||||||||||
|
|
||||||||||
| /** | ||||||||||
| * Builder class to build {@link com.microsoft.java.test.plugin.model.JavaTestItem} | ||||||||||
|
|
@@ -36,6 +54,7 @@ public class JavaTestItemBuilder { | |||||||||
| private IJavaElement element; | ||||||||||
| private TestLevel level; | ||||||||||
| private TestKind kind; | ||||||||||
| private String displayName; | ||||||||||
|
|
||||||||||
| public JavaTestItemBuilder setJavaElement(IJavaElement element) { | ||||||||||
| this.element = element; | ||||||||||
|
|
@@ -52,34 +71,124 @@ public JavaTestItemBuilder setKind(TestKind kind) { | |||||||||
| return this; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| public JavaTestItemBuilder setDisplayName(String displayName) { | ||||||||||
| this.displayName = displayName; | ||||||||||
| return this; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| public JavaTestItem build() throws JavaModelException { | ||||||||||
| if (this.element == null || this.level == null || this.kind == null) { | ||||||||||
| throw new IllegalArgumentException("Failed to build Java test item due to missing arguments"); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| final String displayName; | ||||||||||
| String uri = null; | ||||||||||
| if (this.element instanceof IJavaProject) { | ||||||||||
| final IJavaProject javaProject = (IJavaProject) this.element; | ||||||||||
| final IProject project = javaProject.getProject(); | ||||||||||
| if (ProjectUtils.isVisibleProject(project)) { | ||||||||||
| displayName = project.getName(); | ||||||||||
| if (this.displayName == null) { | ||||||||||
| if (this.element instanceof IJavaProject) { | ||||||||||
| final IJavaProject javaProject = (IJavaProject) this.element; | ||||||||||
| final IProject project = javaProject.getProject(); | ||||||||||
| if (ProjectUtils.isVisibleProject(project)) { | ||||||||||
| displayName = project.getName(); | ||||||||||
| } else { | ||||||||||
| final IPath realPath = ProjectUtils.getProjectRealFolder(project); | ||||||||||
| displayName = realPath.lastSegment(); | ||||||||||
| uri = realPath.toFile().toURI().toString(); | ||||||||||
| } | ||||||||||
| } else if (this.element instanceof IPackageFragment && | ||||||||||
| ((IPackageFragment) this.element).isDefaultPackage()) { | ||||||||||
| displayName = DEFAULT_PACKAGE_NAME; | ||||||||||
| final IResource resource = getResource((IPackageFragment) this.element); | ||||||||||
| if (resource == null || !resource.exists()) { | ||||||||||
| return null; | ||||||||||
| } | ||||||||||
| uri = JDTUtils.getFileURI(resource); | ||||||||||
| } else { | ||||||||||
| final IPath realPath = ProjectUtils.getProjectRealFolder(project); | ||||||||||
| displayName = realPath.lastSegment(); | ||||||||||
| uri = realPath.toFile().toURI().toString(); | ||||||||||
| displayName = JavaElementLabelsCore.getElementLabel(this.element, JavaElementLabelsCore.ALL_DEFAULT); | ||||||||||
| } | ||||||||||
| } else if (this.element instanceof IPackageFragment && ((IPackageFragment) this.element).isDefaultPackage()) { | ||||||||||
| displayName = DEFAULT_PACKAGE_NAME; | ||||||||||
| } else { | ||||||||||
| displayName = JavaElementLabelsCore.getElementLabel(this.element, JavaElementLabelsCore.ALL_DEFAULT); | ||||||||||
| } | ||||||||||
| Range range = null; | ||||||||||
| final String fullName = TestItemUtils.parseFullName(this.element, this.level, this.kind); | ||||||||||
| if (uri == null) { | ||||||||||
| uri = JDTUtils.getFileURI(this.element.getResource()); | ||||||||||
| IResource resource = this.element.getResource(); | ||||||||||
| if (resource == null && this.element instanceof IPackageFragment) { | ||||||||||
| resource = getResource((IPackageFragment) this.element); | ||||||||||
| } | ||||||||||
| if (resource == null || !resource.exists()) { | ||||||||||
| return null; | ||||||||||
| } | ||||||||||
| if (element instanceof BinaryMember) { | ||||||||||
| final String[] sources = new String[1]; | ||||||||||
| final int[] lines = {-1}; | ||||||||||
| final IClassFile classFile = ((BinaryMember) element).getClassFile(); | ||||||||||
| try (InputStream is = new ByteArrayInputStream(classFile.getBytes())) { | ||||||||||
| final ClassReader cr = new ClassReader(is); | ||||||||||
| if (element instanceof BinaryType) { | ||||||||||
| cr.accept(new ClassVisitor(Opcodes.ASM9) { | ||||||||||
| @Override | ||||||||||
| public void visitSource(String source, String debug) { | ||||||||||
| sources[0] = source; | ||||||||||
| } | ||||||||||
| }, ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES); | ||||||||||
| } else if (element instanceof BinaryMethod) { | ||||||||||
| final String methodDescriptor = ((BinaryMethod) element).getSignature(); | ||||||||||
| cr.accept(new ClassVisitor(Opcodes.ASM9) { | ||||||||||
| @Override | ||||||||||
| public void visitSource(String source, String debug) { | ||||||||||
| sources[0] = source; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| public MethodVisitor visitMethod(int access, String name, String descriptor, | ||||||||||
| String signature, String[] exceptions) { | ||||||||||
| if (name.equals(element.getElementName()) && descriptor.equals(methodDescriptor)) { | ||||||||||
| return new MethodVisitor(Opcodes.ASM9) { | ||||||||||
|
Comment on lines
+131
to
+142
|
||||||||||
| @Override | ||||||||||
| public void visitLineNumber(int line, Label start) { | ||||||||||
| if (lines[0] < 0) { | ||||||||||
| lines[0] = line; | ||||||||||
| if (line > 0) { | ||||||||||
| lines[0]--; | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| }; | ||||||||||
| } | ||||||||||
| return null; | ||||||||||
| } | ||||||||||
| }, ClassReader.SKIP_FRAMES); | ||||||||||
| } | ||||||||||
| } catch (Exception e) { | ||||||||||
| JavaLanguageServerPlugin.logException(e); | ||||||||||
| } | ||||||||||
| if (sources[0] != null) { | ||||||||||
| final IPackageFragment packageFragment = (IPackageFragment) element | ||||||||||
| .getAncestor(IJavaElement.PACKAGE_FRAGMENT); | ||||||||||
| if (packageFragment != null) { | ||||||||||
| final String packageName = packageFragment.getElementName(); | ||||||||||
| final IJavaProject project = element.getJavaProject(); | ||||||||||
| final String packagePath = packageName.replace('.', '/'); | ||||||||||
| for (final IClasspathEntry entry : project.getRawClasspath()) { | ||||||||||
| if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) { | ||||||||||
| final IPath sourceFolderPath = entry.getPath(); | ||||||||||
| final IPath fullPath = sourceFolderPath.append(packagePath).append(sources[0]); | ||||||||||
| final IResource candidate = ResourcesPlugin.getWorkspace().getRoot() | ||||||||||
| .findMember(fullPath); | ||||||||||
| if (candidate != null && candidate.exists()) { | ||||||||||
| resource = candidate; | ||||||||||
| break; | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| if (lines[0] > 0) { | ||||||||||
| final Position line = new Position(lines[0] - 1, 0); | ||||||||||
|
Comment on lines
+182
to
+183
|
||||||||||
| if (lines[0] > 0) { | |
| final Position line = new Position(lines[0] - 1, 0); | |
| if (lines[0] >= 0) { | |
| final Position line = new Position(lines[0], 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file now relies on several
org.eclipse.jdt.internal.*types (BinaryMember,BinaryMethod,BinaryType,PackageFragmentRoot). Elsewhere in this codebase, files that touch internal Eclipse APIs are annotated with@SuppressWarnings("restriction")(e.g.,TestSearchUtils,TestItemUtils). Consider adding the same suppression (or refactoring to public JDT APIs) to avoid Tycho/Eclipse "Discouraged access" build warnings or failures.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback