From 6db7bf508da3d0d71a4fcbf7d8e29587ad0531b2 Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Wed, 30 Oct 2024 10:58:55 -0400 Subject: [PATCH] Fix testCamelCaseTypePattern01_CamelCase and many others Signed-off-by: Rob Stryker --- .../internal/core/ClassFileWorkingCopy.java | 28 ++++++++ .../jdt/internal/core/CompilationUnit.java | 5 ++ .../eclipse/jdt/internal/core/util/Util.java | 44 ++++++++++++- .../core/search/matching/MatchLocator.java | 66 +++++++++++++++---- 4 files changed, 128 insertions(+), 15 deletions(-) diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java index 9c3cfc4b937..55b5c97c03e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileWorkingCopy.java @@ -17,14 +17,18 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IBuffer; +import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModelStatusConstants; +import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.ToolFactory; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.util.ClassFileBytesDisassembler; import org.eclipse.jdt.core.util.IClassFileReader; +import org.eclipse.jdt.internal.compiler.env.IDependent; import org.eclipse.jdt.internal.compiler.env.IElementInfo; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.core.util.Disassembler; @@ -79,6 +83,30 @@ public IPath getPath() { return this.classFile.getPath(); } +@Override +public char[] getFileName(){ + // BIG PROBLEM HERE!!! + // IJavaElement#getPath() has different specs than + // org.eclipse.jdt.internal.compiler.env.IDependent#getFileName() + //return getPath().toString().toCharArray(); + char[] ret = null; + PackageFragmentRoot root = getPackageFragmentRoot(); + if (root == null) + // working copy not in workspace + ret = new Path(getElementName()).toString().toCharArray(); + else if (root.isArchive()) { + String clazzFileName = this.classFile.getElementName(); + String parentPath = this.classFile.getParent().getPath().toString(); + IPackageFragment enclosingPackage = (IPackageFragment)getAncestor(IJavaElement.PACKAGE_FRAGMENT); + String pack = enclosingPackage == null ? "" : enclosingPackage.getElementName(); + String packReplaced = pack.length() > 0 ? pack.replaceAll("\\.", "/") + "/" : ""; + String goal = parentPath + IDependent.JAR_FILE_ENTRY_SEPARATOR + packReplaced + clazzFileName; + ret = goal.toCharArray(); + } else { + ret = getParent().getPath().append(getElementName()).toString().toCharArray(); + } + return ret; +} @Override public JavaElement getPrimaryElement(boolean checkOwner) { if (checkOwner && isPrimary()) return this; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java index a7ab47a2525..9621c6c1f69 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java @@ -327,6 +327,11 @@ public char[] getContents() { public CompilationUnit originalFromClone() { return CompilationUnit.this; } + @Override + public char[] getFileName(){ + return originalFromClone().getFileName(); + } + }; } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java index d64ef2a63bd..9718bb3f231 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java @@ -88,7 +88,9 @@ import org.eclipse.jdt.internal.core.Annotation; import org.eclipse.jdt.internal.core.ClassFile; import org.eclipse.jdt.internal.core.JavaElement; +import org.eclipse.jdt.internal.core.JavaModel; import org.eclipse.jdt.internal.core.JavaModelManager; +import org.eclipse.jdt.internal.core.JavaProject; import org.eclipse.jdt.internal.core.Member; import org.eclipse.jdt.internal.core.MemberValuePair; import org.eclipse.jdt.internal.core.PackageFragment; @@ -808,7 +810,8 @@ private static IClassFile getClassFile(char[] fileName) { IPackageFragment pkg = getPackageFragment(fileName, pkgEnd, jarSeparator); if (pkg == null) return null; int start; - return pkg.getClassFile(new String(fileName, start = pkgEnd + 1, fileName.length - start)); + IClassFile cz = pkg.getClassFile(new String(fileName, start = pkgEnd + 1, fileName.length - start)); + return cz; } private static ICompilationUnit getCompilationUnit(char[] fileName, WorkingCopyOwner workingCopyOwner) { @@ -1000,7 +1003,11 @@ private static String getLineSeparator(char[] text, char[] buffer) { public static IPackageFragment getPackageFragment(char[] fileName, int pkgEnd, int jarSeparator) { if (jarSeparator != -1) { String jarMemento = new String(fileName, 0, jarSeparator); + // TODO this is where shit is blowing up, PackageFragmentRoot root = (PackageFragmentRoot) JavaCore.create(jarMemento); + if( root == null ) { + root = getJarPkgFragmentRoot(new String(fileName), jarSeparator, jarMemento); + } if (pkgEnd == jarSeparator) return root.getPackageFragment(CharOperation.NO_STRINGS); char[] pkgName = CharOperation.subarray(fileName, jarSeparator+1, pkgEnd); @@ -1026,6 +1033,41 @@ public static IPackageFragment getPackageFragment(char[] fileName, int pkgEnd, i } } + // Copied from org.eclipse.jdt.internal.core.util.HandleFactory + private static PackageFragmentRoot getJarPkgFragmentRoot(String resourcePathString, int jarSeparatorIndex, String jarPathString) { + IPath jarPath= new Path(jarPathString); + Object target = JavaModel.getTarget(jarPath, false); + if (target instanceof IFile jarFile) { + // internal jar: is it on the classpath of its project? + // e.g. org.eclipse.swt.win32/ws/win32/swt.jar + // is NOT on the classpath of org.eclipse.swt.win32 + JavaProject javaProject = (JavaProject) JavaModelManager.getJavaModelManager().getJavaModel().getJavaProject(jarFile); + try { + IClasspathEntry entry = javaProject.getClasspathEntryFor(jarPath); + if (entry != null) { + return (PackageFragmentRoot) javaProject.getPackageFragmentRoot(jarFile); + } + } catch (JavaModelException e) { + // ignore and try to find another project + } + } else if( target instanceof File) { + try { + // Have to search, I guess. + IJavaProject[] javaProjects = JavaModelManager.getJavaModelManager().getJavaModel().getJavaProjects(); + for( int i = 0; i < javaProjects.length; i++ ) { + IClasspathEntry entry = javaProjects[i].getClasspathEntryFor(jarPath); + if (entry != null) { + return (PackageFragmentRoot) javaProjects[i].getPackageFragmentRoot(jarPathString); + } + } + } catch(JavaModelException jme) { + // TODO ignore + } + + } + return null; + } + /** * Returns the number of parameter types in a method signature. */ diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java index e50da0b8758..88206c70777 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/search/matching/MatchLocator.java @@ -36,6 +36,7 @@ import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.CharOperation; @@ -1339,17 +1340,55 @@ private boolean skipMatch(JavaProject javaProject, PossibleMatch possibleMatch) } return false; } + +private org.eclipse.jdt.core.ICompilationUnit findUnitForPossibleMatch(JavaProject jp, PossibleMatch match) { + if( !skipMatch(jp, match)) { + if( match.openable instanceof org.eclipse.jdt.core.ICompilationUnit cu) { + return cu; + } else if( match.openable instanceof ITypeRoot tr) { + ITypeRoot toOpen = tr; + try { + // If this is a nested class like p/X$Y, it won't work. When it gets to + // the bindings for p/X, it thinks it is in p/X$Y.class file. :| + String n = tr.getElementName(); + if( n.toLowerCase().endsWith(".class") && n.contains("$")) { + String enclosingSourceFile = n.substring(0, n.indexOf("$")) + ".class"; + IJavaElement parent = tr.getParent(); + if( parent instanceof IPackageFragment ipf) { + IOpenable open2 = ipf.getClassFile(enclosingSourceFile); + if( open2 instanceof ITypeRoot tr2 ) { + toOpen = tr2; + } + } + } + org.eclipse.jdt.core.ICompilationUnit ret = toOpen.getWorkingCopy(null, new NullProgressMonitor()); + return ret; + } catch(JavaModelException jme) { + // Ignore for now + } + } + } + return null; +} + protected void locateMatchesWithASTParser(JavaProject javaProject, PossibleMatch[] possibleMatches, int start, int length) throws CoreException { Map map = javaProject.getOptions(true); map.put(CompilerOptions.OPTION_TaskTags, org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING); this.options = new CompilerOptions(map); - org.eclipse.jdt.core.ICompilationUnit[] units = Arrays.stream(possibleMatches, start, start + length) - .filter(match -> !skipMatch(javaProject, match)) - .map(match -> match.openable) - .filter(org.eclipse.jdt.core.ICompilationUnit.class::isInstance) - .map(org.eclipse.jdt.core.ICompilationUnit.class::cast) - .toArray(org.eclipse.jdt.core.ICompilationUnit[]::new); + List unitCollector = new ArrayList<>(); + Map matchToCU = new HashMap<>(); + Map cuToMatch = new HashMap<>(); + for( int i = 0; i < possibleMatches.length; i++ ) { + if( !skipMatch(javaProject, possibleMatches[i])) { + org.eclipse.jdt.core.ICompilationUnit u = findUnitForPossibleMatch(javaProject, possibleMatches[i]); + unitCollector.add(u); + matchToCU.put(possibleMatches[i], u); + cuToMatch.put(u, possibleMatches[i]); + } + } + org.eclipse.jdt.core.ICompilationUnit[] units = unitCollector.toArray(new org.eclipse.jdt.core.ICompilationUnit[unitCollector.size()]); + if (units.length == 0) { return; } @@ -1377,10 +1416,13 @@ protected void locateMatchesWithASTParser(JavaProject javaProject, PossibleMatch astParser.createASTs(units, new String[0], new ASTRequestor() { @Override public void acceptAST(org.eclipse.jdt.core.ICompilationUnit source, org.eclipse.jdt.core.dom.CompilationUnit ast) { - Arrays.stream(possibleMatches, start, start + length) - .filter(match -> match.openable.equals(source)) - .findAny() - .ifPresent(match -> asts.put(match, ast)); + PossibleMatch pm = cuToMatch.get(source); + if( pm != null ) { + asts.put(pm, ast); + } + +// Arrays.stream(possibleMatches, start, start + length) .filter(match -> match.openable.equals(source)) +// .findAny() .ifPresent(match -> asts.put(match, ast)); } }, this.progressMonitor); // todo, use a subprogressmonitor or slice it asts.forEach((possibleMatch, ast) -> { @@ -1402,10 +1444,6 @@ public void acceptAST(org.eclipse.jdt.core.ICompilationUnit source, org.eclipse. } private SearchMatch toMatch(org.eclipse.jdt.core.dom.ASTNode node, int accuracy, PossibleMatch possibleMatch) { IResource resource = possibleMatch.resource; - org.eclipse.jdt.core.ICompilationUnit cu = possibleMatch.openable instanceof org.eclipse.jdt.core.ICompilationUnit ? (org.eclipse.jdt.core.ICompilationUnit)possibleMatch.openable : null; - WorkingCopyOwner owner = cu == null ? null : cu.getOwner(); - - boolean mustResolve = this.pattern.mustResolve; if (node instanceof MethodDeclaration || node instanceof AbstractTypeDeclaration || node instanceof VariableDeclaration) { IJavaElement javaElement = DOMASTNodeUtils.getDeclaringJavaElement(node); if (javaElement != null) {