Skip to content

Commit

Permalink
Fix lack of type resolution issue due to lack of imports. #275
Browse files Browse the repository at this point in the history
The changes will add import statements for found types while traversing
symbols in the binary class definition so that the evaluation snippet
will properly compiled without needing to have FQN names.
  • Loading branch information
gayanper committed Jul 9, 2023
1 parent f6310db commit 00b5b08
Showing 1 changed file with 41 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
*******************************************************************************/
package org.eclipse.jdt.internal.debug.eval.ast.engine;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
Expand Down Expand Up @@ -85,26 +88,31 @@ public BinaryBasedSourceGenerator(String[] localTypesNames,
public void buildSource(JDIReferenceType referenceType) {
ReferenceType reference = (ReferenceType) referenceType
.getUnderlyingType();
fSource = buildTypeDeclaration(reference, buildRunMethod(reference),
null);
Set<String> importsEntries = new HashSet<>();
fSource = buildTypeDeclaration(reference, buildRunMethod(reference, importsEntries), null, importsEntries);
}

/**
* Build source for a class type (static context)
*/
public void buildSourceStatic(IJavaReferenceType type) {
Type underlyingType = ((JDIReferenceType) type).getUnderlyingType();
Set<String> importsEntries = new HashSet<>();
if (!(underlyingType instanceof ReferenceType)) {
return;
}
ReferenceType refType = (ReferenceType) underlyingType;
fSource = buildTypeDeclaration(refType, buildRunMethod(refType), null,
false);
fSource = buildTypeDeclaration(refType, buildRunMethod(refType, importsEntries), null, false, importsEntries);
String packageName = getPackageName(refType.name());
int packageStatementEnd = 0;
if (packageName != null) {
fSource.insert(0, "package " + packageName + ";\n"); //$NON-NLS-1$ //$NON-NLS-2$
fCodeSnippetPosition += 10 + packageName.length();
packageStatementEnd = 10 + packageName.length();
fCodeSnippetPosition += packageStatementEnd;
}
String importBlock = importsEntries.stream().collect(Collectors.joining("\\n", "import ", ";")).concat("\\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
fSource.insert(packageStatementEnd, importBlock);
fCodeSnippetPosition += importBlock.length();
fCompilationUnitName = getSimpleName(refType.name());
}

Expand All @@ -117,7 +125,7 @@ protected String getUniqueMethodName(String methodName, ReferenceType type) {
return methodName;
}

private StringBuilder buildRunMethod(ReferenceType type) {
private StringBuilder buildRunMethod(ReferenceType type, Set<String> importsEntries) {
StringBuilder source = new StringBuilder();

if (isInStaticMethod()) {
Expand All @@ -128,7 +136,9 @@ private StringBuilder buildRunMethod(ReferenceType type) {
source.append(getUniqueMethodName(RUN_METHOD_NAME, type));
source.append('(');
for (int i = 0, length = fLocalVariableNames.length; i < length; i++) {
source.append(getDotName(fLocalVariableTypeNames[i]));
String typeName = getDotName(fLocalVariableTypeNames[i]);
collectImport(importsEntries, typeName);
source.append(typeName);
source.append(' ');
source.append(fLocalVariableNames[i]);
if (i + 1 < length)
Expand All @@ -148,7 +158,7 @@ private StringBuilder buildRunMethod(ReferenceType type) {
}

private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
StringBuilder buffer, String nestedTypeName) {
StringBuilder buffer, String nestedTypeName, Set<String> importsEntries) {

Field thisField = null;

Expand All @@ -159,15 +169,19 @@ private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
}
}

StringBuilder source = buildTypeDeclaration(referenceType, buffer,
nestedTypeName, thisField != null);
StringBuilder source = buildTypeDeclaration(referenceType, buffer, nestedTypeName, thisField != null, importsEntries);

if (thisField == null) {
String packageName = getPackageName(referenceType.name());
int packageStatementEnd = 0;
if (packageName != null) {
source.insert(0, "package " + packageName + ";\n"); //$NON-NLS-1$ //$NON-NLS-2$
fCodeSnippetPosition += 10 + packageName.length();
packageStatementEnd = 10 + packageName.length();
fCodeSnippetPosition += packageStatementEnd;
}
String importBlock = importsEntries.stream().collect(Collectors.joining("\\n", "import ", ";")).concat("\\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
source.insert(packageStatementEnd, importBlock);
fCodeSnippetPosition += importBlock.length();
if (isAnonymousTypeName(referenceType.name())) {
fCompilationUnitName = ANONYMOUS_CLASS_NAME;
} else {
Expand All @@ -176,7 +190,7 @@ private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
} else {
try {
return buildTypeDeclaration((ReferenceType) thisField.type(),
source, referenceType.name());
source, referenceType.name(), importsEntries);
} catch (ClassNotLoadedException e) {
}
}
Expand All @@ -186,7 +200,7 @@ private StringBuilder buildTypeDeclaration(ReferenceType referenceType,

private StringBuilder buildTypeDeclaration(ReferenceType referenceType,
StringBuilder buffer, String nestedTypeName,
boolean hasEnclosingInstance) {
boolean hasEnclosingInstance, Set<String> importsEntries) {
StringBuilder source = new StringBuilder();

String typeName = referenceType.name();
Expand Down Expand Up @@ -337,7 +351,9 @@ && isSourceLevelGreaterOrEqual(1, 5)) {
for (Method method : referenceType.methods()) {
if (!method.isConstructor() && !method.isStaticInitializer()
&& !method.isBridge()) {
source.append(buildMethodDeclaration(method));
source.append(buildMethodDeclaration(method, null));
} else if (method.isConstructor()) {
source.append(buildMethodDeclaration(method, getSimpleName(typeName)));
}
}

Expand All @@ -346,15 +362,15 @@ && isSourceLevelGreaterOrEqual(1, 5)) {
for (ReferenceType nestedType : nestedTypes) {
if (isADirectInnerType(typeName, nestedType.name())) {
source.append(buildTypeDeclaration(nestedType, null, null,
true));
true, importsEntries));
}
}
} else {
for (ReferenceType nestedType : nestedTypes) {
if (!nestedTypeName.equals(nestedType.name())
&& isADirectInnerType(typeName, nestedType.name())) {
source.append(buildTypeDeclaration(nestedType, null, null,
true));
true, importsEntries));
}
}
}
Expand Down Expand Up @@ -393,7 +409,7 @@ private StringBuilder buildFieldDeclaration(Field field) {
return source;
}

private StringBuilder buildMethodDeclaration(Method method) {
private StringBuilder buildMethodDeclaration(Method method, String overrideMethodName) {
StringBuilder source = new StringBuilder();

if (method.isFinal()) {
Expand All @@ -419,6 +435,7 @@ private StringBuilder buildMethodDeclaration(Method method) {
}

String genericSignature = method.genericSignature();
String methodName = (overrideMethodName == null) ? method.name() : overrideMethodName;
if (genericSignature != null && isSourceLevelGreaterOrEqual(1, 5)) {
String[] typeParameters = Signature
.getTypeParameters(genericSignature);
Expand Down Expand Up @@ -449,6 +466,7 @@ private StringBuilder buildMethodDeclaration(Method method) {
Signature.getReturnType(genericSignature)).replace(
'/', '.')).append(' ').append(method.name())
.append('(');
source.append(methodName).append('(');

String[] parameterTypes = Signature
.getParameterTypes(genericSignature);
Expand Down Expand Up @@ -526,6 +544,12 @@ private StringBuilder buildMethodDeclaration(Method method) {
return source;
}

private void collectImport(Set<String> importsEntries, String typeName) {
if (typeName.contains(".")) { //$NON-NLS-1$
importsEntries.add(typeName);
}
}

private String getReturnStatement(String returnTypeName) {
String typeName = getSimpleName(returnTypeName);
if (typeName.charAt(typeName.length() - 1) == ']') {
Expand Down

0 comments on commit 00b5b08

Please sign in to comment.