Skip to content

Commit

Permalink
Filtering unqualified Stacktraces eclipse-jdt#115
Browse files Browse the repository at this point in the history
Using method signature to filter unqualified stacktraces generated in
java stacktrace console. + Includes code review changes

Fixes eclipse-jdt#115
  • Loading branch information
SougandhS committed Oct 31, 2024
1 parent 32d9ef8 commit f595ab8
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,87 @@ public void testLinkNavigationTrueForInnerClassMultilevel() throws Exception {
}
}

public void testLinkNavigationTrueForInnerClassParameters() throws Exception {
String projectName = "StackTest";
IJavaProject project = createProject(projectName, "testfiles/AmbiguityTest/", JavaProjectHelper.JAVA_SE_1_8_EE_NAME, false);
waitForBuild();
waitForJobs();
consoleDocumentWithText("MyScheduledExecutor(Worker).doWork(MyScheduledExecutor$Wor) line: 20");
IHyperlink[] hyperlinks = fConsole.getHyperlinks();
assertEquals("Wrong hyperlinks, listing all links: " + allLinks(), 2, hyperlinks.length);
String expectedText = "System.out.println(\"Expected_Result\");";
try {
for (IHyperlink hyperlink : hyperlinks) {
closeAllEditors();
hyperlink.linkActivated();
IEditorPart editor = waitForEditorOpen();
String[] selectedText = new String[1];
sync(() -> selectedText[0] = getSelectedText(editor));
selectedText[0] = selectedText[0].trim();
assertEquals("Wrong text selected after hyperlink navigation", expectedText, selectedText[0]);

}
} finally {
closeAllEditors();
boolean force = true;
project.getProject().delete(force, new NullProgressMonitor());
}
}

public void testLinkNavigationTrueForInnerClassMultiParameters() throws Exception {
String projectName = "StackTest";
IJavaProject project = createProject(projectName, "testfiles/AmbiguityTest/", JavaProjectHelper.JAVA_SE_1_8_EE_NAME, false);
waitForBuild();
waitForJobs();
consoleDocumentWithText("MyScheduledExecutor(Worker).doWorkParams(MyScheduledExecutor$Wor,MyScheduledExecutor$Ran) line: 23");
IHyperlink[] hyperlinks = fConsole.getHyperlinks();
assertEquals("Wrong hyperlinks, listing all links: " + allLinks(), 2, hyperlinks.length);
String expectedText = "System.out.println(\"Expected_Result\");";
try {
for (IHyperlink hyperlink : hyperlinks) {
closeAllEditors();
hyperlink.linkActivated();
IEditorPart editor = waitForEditorOpen();
String[] selectedText = new String[1];
sync(() -> selectedText[0] = getSelectedText(editor));
selectedText[0] = selectedText[0].trim();
assertEquals("Wrong text selected after hyperlink navigation", expectedText, selectedText[0]);

}
} finally {
closeAllEditors();
boolean force = true;
project.getProject().delete(force, new NullProgressMonitor());
}
}

public void testLinkNavigationTrueForLinksWithNoProperMethodSignature() throws Exception {
String projectName = "StackTest";
IJavaProject project = createProject(projectName, "testfiles/AmbiguityTest/", JavaProjectHelper.JAVA_SE_1_8_EE_NAME, false);
waitForBuild();
waitForJobs();
consoleDocumentWithText("Sample.testBlank(Sample.java:40)");
IHyperlink[] hyperlinks = fConsole.getHyperlinks();
assertEquals("Wrong hyperlinks, listing all links: " + allLinks(), 1, hyperlinks.length);
String expectedText = "System.out.println(\"Expected_No_Signature\");";
try {
for (IHyperlink hyperlink : hyperlinks) {
closeAllEditors();
hyperlink.linkActivated();
IEditorPart editor = waitForEditorOpen();
String[] selectedText = new String[1];
sync(() -> selectedText[0] = getSelectedText(editor));
selectedText[0] = selectedText[0].trim();
assertEquals("Wrong text selected after hyperlink navigation", expectedText, selectedText[0]);

}
} finally {
closeAllEditors();
boolean force = true;
project.getProject().delete(force, new NullProgressMonitor());
}
}

private void waitForJobs() throws Exception {
TestUtil.waitForJobs(getName(), 250, 10_000);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public static void main(String[] ar) {

}
class innerL1 {
void check() {
void check2() {
System.out.println("EXPECTED_INNERCLASS");
}
class innerL2 {
void check2() {
void check4() {
System.out.println("EXPECTED_INNER-INNER_CLASS");
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2024 IBM Corporation.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
public class MyScheduledExecutor {
public void executeTask() {
Wor worker = new Wor();
}
class Worker {
public void doWork2(Wor w) {

}
public void doWorkParams(Wor w,Ran r) {
System.out.println("Expected_Result");
}
}
class Wor {

}
class Ran {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2024 IBM Corporation.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
public class MyScheduledExecutor {
public void executeTask() {
Wor worker = new Wor();
}
class Worker {
public void doWork(Wor w) {
System.out.println("Expected_Result");
}
}
class Wor {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@ public void tes2() {
public static void tesComplex(String[] x, java.net.URL[] sx) {
System.out.println("Expected_One_normal_&_One_fully_qualified");
}

public void testBlank() {
System.out.println("Expected_No_Signature");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2024 IBM Corporation.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/**
* Test class
*/
class InnerClassTest {
public static void main(String[] ar) {

}
class innerL1 {
void check1() {
System.out.println("EXPECTED_INNERCLASS");
}
class innerL2 {
void check23() {
System.out.println("EXPECTED_INNER-INNER_CLASS");
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2024 IBM Corporation.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/**
* Test class
*/
class InnerClassTest {
public static void main(String[] ar) {

}
class innerL1 {
void check() {
System.out.println("EXPECTED_INNERCLASS");
}
class innerL2 {
void check2() {
System.out.println("EXPECTED_INNER-INNER_CLASS");
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,16 @@ public IStatus runInUIThread(IProgressMonitor monitor) {
if (generatedLink == null) { // Handles invalid links (without line number)
return openClipboard(matches, line, typeName);
}
int methodNameStartIndex = generatedLink.indexOf('.');
int methodNameStartIndex;
if (generatedLink.indexOf('.') != generatedLink.lastIndexOf('.')) {
int lastEndIndex = generatedLink.lastIndexOf('(');
String tempSubstring = generatedLink.substring(0, lastEndIndex);
methodNameStartIndex = tempSubstring.lastIndexOf('.');
} else {
methodNameStartIndex = generatedLink.indexOf('.');
}
int methodNameEndIndex = generatedLink.lastIndexOf(')');
if (methodNameStartIndex != -1 && methodNameEndIndex != -1) {
if ((methodNameStartIndex != -1 && methodNameEndIndex != -1) && (methodNameStartIndex < methodNameEndIndex)) {
List<Object> exactMatchesFiltered = new ArrayList<>();
String methodSignature = generatedLink.substring(methodNameStartIndex + 1, methodNameEndIndex + 1).replaceAll(" ", ""); //$NON-NLS-1$//$NON-NLS-2$
String methodNameExtracted = methodSignature.substring(0, methodSignature.indexOf('('));
Expand All @@ -213,10 +220,16 @@ public IStatus runInUIThread(IProgressMonitor monitor) {
processSearchResult(exactMatchesFiltered.get(0), typeName, lineNumber);
return Status.OK_STATUS;
} else if (exactMatchesFiltered.size() > 1) {
for(Object res : exactMatchesFiltered) {
if (res instanceof IType type) {
if (type.getFullyQualifiedName().startsWith("bin.")) { //$NON-NLS-1$
exactMatchesFiltered.remove(res);
}
}
}
return openClipboard(exactMatchesFiltered, line, typeName);
}
}

return openClipboard(matches, line, typeName);
} else {
processSearchResult(source, typeName, lineNumber);
Expand Down Expand Up @@ -288,18 +301,39 @@ private IStatus openClipboard(List<Object> results, int lineNumber, String type)
* @return returns <code>true</code> if a found an exact method inside the class, or <code>false</code> if there's no matching methods
*/
private boolean extractFromInnerClassResults(IType[] innerClass, String methodSignature, String methodNameExtracted) throws JavaModelException {
int innerClasslevel = innerClassLevels(this.generatedLink);
int levelTravelled = 0;
while (innerClass.length > 0) {
for (IType innerType : innerClass) {
if (innerClass.length > 0) {
innerClass = innerType.getTypes();
}
if (extractFromResults(innerType, methodSignature, methodNameExtracted)) {
levelTravelled++;
if (extractFromResults(innerType, methodSignature, methodNameExtracted) && levelTravelled == innerClasslevel) {
return true;
}
}
}
return false;
}

/**
* Checks the levels of inner class
*
* @param genLink
* Generated link
* @return returns <code>count of levels</code>
*/

private int innerClassLevels(String genLink) {
int level = 0;
for (Character c : genLink.toCharArray()) {
if (c == '$') {
level++;
}
}
return level;
}
/**
* Checks if there's any matching methods for the given IType
*
Expand All @@ -313,38 +347,46 @@ private boolean extractFromInnerClassResults(IType[] innerClass, String methodSi
* @return returns <code>true</code> if a found an exact method inside the class, or <code>false</code> if there's no matching methods
*/
private boolean extractFromResults(IType type, String methodSignature, String methodNameExtracted) throws JavaModelException {
IMethod[] methods = type.getMethods();
for (IMethod method : methods) {
int indexOfClosing = method.toString().indexOf(')');
int indexOfStart = method.toString().indexOf(method.getElementName());
String methodName = method.toString().substring(indexOfStart, indexOfClosing + 1).replaceAll(" ", ""); //$NON-NLS-1$//$NON-NLS-2$
int paramCount = methodSignature.substring(methodSignature.indexOf('(')
+ 1, methodSignature.lastIndexOf(')')).split(",").length; //$NON-NLS-1$
if (methodName.equals(methodSignature)) {
return true;
} else if (methodNameExtracted.equals(method.getElementName())
&& paramCount == method.getNumberOfParameters()) {
// Further mining from fully qualified parameter names in method signature
String methodSignatureGen = methodSignatureGenerator(method.getElementName(), methodName);
if (methodSignatureGen.equals(methodSignature)) {
boolean paramDetailsNotIncluded = methodSignature.substring(methodSignature.indexOf('(')).contains(".java:"); //$NON-NLS-1$
try {
IMethod[] methods = type.getMethods();
for (IMethod method : methods) {
if (paramDetailsNotIncluded && method.getElementName().equals(methodNameExtracted)) {
return true;
}
// If paramters includes innerclass
if (methodSignature.indexOf('$') != -1) {
String methodSignatureInnerClass = innerClassMethodSignatureGen(methodNameExtracted, methodSignature);
if (methodSignatureInnerClass.equals(methodSignatureGen)) {
String methodDetails = method.toString();
int indexOfClosing = methodDetails.indexOf(')');
int indexOfStart = methodDetails.indexOf(method.getElementName());
String methodName = methodDetails.substring(indexOfStart, indexOfClosing + 1).replaceAll(" ", ""); //$NON-NLS-1$//$NON-NLS-2$
int paramCount = methodSignature.substring(methodSignature.indexOf('(')
+ 1, methodSignature.lastIndexOf(')')).split(",").length; //$NON-NLS-1$
if (methodName.equals(methodSignature)) {
return true;
} else if (methodNameExtracted.equals(method.getElementName())
&& paramCount == method.getNumberOfParameters()) {
// Further mining from fully qualified parameter names in method signature
String methodSignatureGen = methodSignatureGenerator(method.getElementName(), methodName);
if (methodSignatureGen.equals(methodSignature)) {
return true;
}
String paramsExtracted = methodSignature.substring(methodSignature.indexOf('('));
String param = paramsExtracted.substring(paramsExtracted.indexOf('$') + 1);
methodSignatureInnerClass.concat(param);
methodSignatureInnerClass.concat(")"); //$NON-NLS-1$
if (methodSignatureInnerClass.toString().equals(methodSignatureGen)) {
return true;
// If paramters includes innerclass
if (methodSignature.indexOf('$') != -1) {
String methodSignatureInnerClass = innerClassMethodSignatureGen(methodNameExtracted, methodSignature);
if (methodSignatureInnerClass.equals(methodSignatureGen)) {
return true;
}
String paramsExtracted = methodSignature.substring(methodSignature.indexOf('('));
String param = paramsExtracted.substring(paramsExtracted.indexOf('$') + 1);
methodSignatureInnerClass = methodSignatureInnerClass.concat(param);
if (methodSignatureInnerClass.equals(methodSignatureGen)) {
return true;
}
}
return false;
}
return false;
}
} catch (Exception e) {
return false;
}
return false;
}
Expand Down

0 comments on commit f595ab8

Please sign in to comment.