Skip to content

Commit bc637b2

Browse files
committed
Java Error subclasses fix; adds this.this$0
1 parent 8f0dd73 commit bc637b2

File tree

5 files changed

+299
-197
lines changed

5 files changed

+299
-197
lines changed

sources/net.sf.j2s.core/src/net/sf/j2s/core/astvisitors/ASTKeywordVisitor.java

Lines changed: 107 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.eclipse.jdt.core.dom.SimpleType;
5858
import org.eclipse.jdt.core.dom.Statement;
5959
import org.eclipse.jdt.core.dom.StringLiteral;
60+
import org.eclipse.jdt.core.dom.SuperFieldAccess;
6061
import org.eclipse.jdt.core.dom.ThisExpression;
6162
import org.eclipse.jdt.core.dom.Type;
6263
import org.eclipse.jdt.core.dom.TypeLiteral;
@@ -113,7 +114,17 @@ private static final String getPrimitiveTYPE(String name) {
113114
private boolean isArray = false;
114115
protected int blockLevel = 0;
115116
protected int currentBlockForVisit = -1;
117+
118+
public String parentClassName;
119+
120+
121+
/**
122+
* used in case we are applying a private outer class method
123+
*
124+
*/
116125
protected String b$name;
126+
127+
117128
protected Stack<String> methodDeclareNameStack = new Stack<String>();
118129

119130
/**
@@ -979,8 +990,8 @@ private String simpleNameInMethodBinding(SimpleName node, boolean isQualified, I
979990
ASTNode parent = node.getParent();
980991
boolean checkNameViolation = false;
981992
if (parent != null && !(parent instanceof FieldAccess)) {
982-
IMethodBinding variableDeclaration = mBinding.getMethodDeclaration();
983-
ITypeBinding declaringClass = variableDeclaration.getDeclaringClass();
993+
IMethodBinding methodDeclaration = mBinding.getMethodDeclaration();
994+
ITypeBinding declaringClass = methodDeclaration.getDeclaringClass();
984995
if (!isQualified && declaringClass != null && getUnqualifiedClassName() != null) {
985996
String className = declaringClass.getQualifiedName();
986997
checkNameViolation = !("java.lang.String".equals(className) && "valueOf".equals(name));
@@ -1015,15 +1026,15 @@ private String simpleNameInVarBinding(SimpleName node, char ch, IVariableBinding
10151026
name = assureQualifiedName(name);
10161027
if (name.length() != 0) {
10171028
ret = getQualifiedStaticName(null, name, true, true, false) + ".";
1018-
ch = '.';
1029+
//ch = '.';
10191030
}
10201031
}
10211032
} else {
10221033
ASTNode parent = node.getParent();
10231034
if (parent != null && !(parent instanceof FieldAccess)) {
10241035
if (declaringClass != null && getUnqualifiedClassName() != null && ch != '.') {
10251036
ret = getClassNameAndDot(parent, declaringClass, false);
1026-
ch = '.';
1037+
//ch = '.';
10271038
}
10281039
}
10291040
String fieldVar = null;
@@ -1068,6 +1079,53 @@ public boolean visit(StringLiteral node) {
10681079
return false;
10691080
}
10701081

1082+
/**
1083+
* SuperFieldAccess:
1084+
*
1085+
*[ ClassName . ] super . Identifier
1086+
*
1087+
*/
1088+
public boolean visit(SuperFieldAccess node) {
1089+
ITypeBinding classBinding = resolveAbstractOrAnonymousBinding(node);
1090+
String fieldName = J2SMapAdapter.getJ2SName(node.getName());
1091+
buffer.append("this.");
1092+
if (isInheritedFieldName(classBinding, fieldName)) {
1093+
if (classBinding != null) {
1094+
IVariableBinding[] declaredFields = classBinding.getDeclaredFields();
1095+
for (int i = 0; i < declaredFields.length; i++) {
1096+
String superFieldName = J2SMapAdapter.getJ2SName(declaredFields[i]);
1097+
if (fieldName.equals(superFieldName)) {
1098+
buffer.append(getValidFieldName$Qualifier(fieldName, false));
1099+
buffer.append(J2SMapAdapter.getFieldName$Appended(classBinding.getSuperclass(), fieldName));
1100+
return false;
1101+
}
1102+
}
1103+
}
1104+
}
1105+
buffer.append(getValidFieldName$Qualifier(fieldName, true));
1106+
return false;
1107+
}
1108+
1109+
/**
1110+
* this or ClassName.this
1111+
*
1112+
*/
1113+
public boolean visit(ThisExpression node) {
1114+
Name className = node.getQualifier();
1115+
if (className != null) {
1116+
ASTNode classNode = getAbstractOrAnonymousParentForNode(node);
1117+
if (classNode != null && classNode.getParent() != null // CompilationUnit
1118+
&& classNode.getParent().getParent() != null) {
1119+
// just checking for top level?
1120+
buffer.append(getSyntheticReference(node.resolveTypeBinding().getQualifiedName()));
1121+
return false;
1122+
}
1123+
}
1124+
buffer.append("this");
1125+
return false;
1126+
}
1127+
1128+
10711129
public boolean visit(TypeLiteral node) {
10721130
// Class x = Foo.class
10731131
Type type = node.getType();
@@ -1670,35 +1728,49 @@ protected void addVariable(FinalVariable f, String identifier, IBinding binding)
16701728
finalVars.add(f);
16711729
}
16721730

1673-
protected String getClassNameAndDot(ASTNode parent, ITypeBinding declaringClass, boolean isPrivate) {
1731+
/**
1732+
* Determine the qualifier for a method or variable.
1733+
*
1734+
* In the case of private methods, this is "p$.";
1735+
* for general fields, this will be "this."; for fields in outer classes, we need a synthetic
1736+
* references, this.b$[className] that points to the outer object, which may be one or more levels
1737+
* higher than this one.
1738+
*
1739+
* Anonymous inner classes may reference either a superclass method/field or one in its declaring class
1740+
* stack.
1741+
*
1742+
* @param node either a method or field or local variable
1743+
* @param declaringClass the class that declares this variable
1744+
* @param isPrivate
1745+
* @return qualifier for method or variable
1746+
*/
1747+
protected String getClassNameAndDot(ASTNode node, ITypeBinding declaringClass, boolean isPrivate) {
1748+
16741749
String name = declaringClass.getQualifiedName();
16751750
String ret = "";
16761751
int superLevel = 0;
1677-
ITypeBinding originalType = null;
16781752
boolean isThis = false;
1679-
while (parent != null) {
1680-
boolean isAnonymous = (parent instanceof AnonymousClassDeclaration);
1681-
ITypeBinding typeBinding = (isAnonymous ? ((AnonymousClassDeclaration) parent).resolveBinding()
1682-
: parent instanceof AbstractTypeDeclaration ? ((AbstractTypeDeclaration) parent).resolveBinding()
1753+
1754+
// Search parents of this node for an anonymous or abstract class declaration
1755+
while (node != null) {
1756+
boolean isAnonymous = (node instanceof AnonymousClassDeclaration);
1757+
ITypeBinding typeBinding = (isAnonymous ? ((AnonymousClassDeclaration) node).resolveBinding()
1758+
: node instanceof AbstractTypeDeclaration ? ((AbstractTypeDeclaration) node).resolveBinding()
16831759
: null);
16841760
if (typeBinding != null) {
1685-
if (originalType == null) {
1686-
originalType = typeBinding;
1687-
}
16881761
superLevel++;
16891762
if (Bindings.isSuperType(declaringClass, typeBinding)) {
16901763
if (superLevel == 1) {
16911764
ret = (isPrivate ? "p$." : "this.");
16921765
isThis = true;
16931766
}
16941767
name = typeBinding.getQualifiedName();
1695-
if (!isAnonymous)
1696-
break;
1697-
name = ensureNameIfLocal(name, typeBinding, parent);
1768+
if (isAnonymous)
1769+
name = ensureNameIfLocal(name, typeBinding, node);
16981770
break;
16991771
}
17001772
}
1701-
parent = parent.getParent();
1773+
node = node.getParent();
17021774
}
17031775
return (isThis ? ret : getSyntheticReference(name) + ".");
17041776
}
@@ -1757,8 +1829,8 @@ protected void appendShortenedQualifiedName(String packageName, String name, boo
17571829
}
17581830
}
17591831

1760-
protected String getSyntheticReference(String name) {
1761-
b$name = ".b$['" + assureQualifiedNameNoC$(null, name) + "']";
1832+
protected String getSyntheticReference(String className) {
1833+
b$name = (className.equals(parentClassName) ? ".this$0" : ".b$['" + assureQualifiedNameNoC$(null, className) + "']");
17621834
return "this" + b$name;
17631835
}
17641836

@@ -2040,6 +2112,22 @@ private static void checkMethodsWithGenericParams(String topClassKey, ITypeBindi
20402112

20412113
}
20422114

2115+
private static ASTNode getAbstractOrAnonymousParentForNode(ASTNode node) {
2116+
ASTNode parent = node.getParent();
2117+
while (parent != null && !(parent instanceof AbstractTypeDeclaration)
2118+
&& !(parent instanceof AnonymousClassDeclaration)) {
2119+
parent = parent.getParent();
2120+
}
2121+
return parent;
2122+
}
2123+
2124+
protected static ITypeBinding resolveAbstractOrAnonymousBinding(ASTNode node) {
2125+
node = getAbstractOrAnonymousParentForNode(node);
2126+
return (node instanceof AbstractTypeDeclaration ? ((AbstractTypeDeclaration) node).resolveBinding()
2127+
: node instanceof AnonymousClassDeclaration ? ((AnonymousClassDeclaration) node).resolveBinding()
2128+
: null);
2129+
}
2130+
20432131
/**
20442132
* Create a map of the class type arguments for an implemented generic class
20452133
*

0 commit comments

Comments
 (0)