### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core.tests.model Index: src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java,v retrieving revision 1.18 diff -u -r1.18 RunConverterTests.java --- src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java 29 Mar 2006 04:03:06 -0000 1.18 +++ src/org/eclipse/jdt/core/tests/dom/RunConverterTests.java 13 Nov 2007 12:27:18 -0000 @@ -25,8 +25,9 @@ } public static Class[] getAllTestClasses() { return new Class[] { - ASTConverterTest.class, + ASTConverterTest.class, ASTConverterTest2.class, + ASTConverterBugsTest.class, ASTConverterJavadocTest.class, ASTConverter15Test.class, ASTConverterAST3Test.class, Index: src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java =================================================================== RCS file: src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java diff -N src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/jdt/core/tests/dom/ASTConverterBugsTest.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.core.tests.dom; + +import java.io.IOException; + +import junit.framework.Test; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.Type; + +public class ASTConverterBugsTest extends ConverterTestSetup { + + public void setUpSuite() throws Exception { + PROJECT_SETUP = true; // do not copy Converter* directories + super.setUpSuite(); + setUpJCLClasspathVariables("1.4"); + waitUntilIndexesReady(); + } + + public ASTConverterBugsTest(String name) { + super(name); + } + + public static Test suite() { + return buildModelTestSuite(ASTConverterBugsTest.class); + } + + /** + * @bug 186410: [dom] StackOverflowError due to endless superclass bindings hierarchy + * @test Ensures that the superclass of "java.lang.Object" class is null even when it's a recovered binding + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=186410" + */ + public void testBug186410() throws CoreException, IOException { + try { + createJavaProject("P", new String[] {""}, new String[0], ""); + createFile("P/A.java", + "public class A {\n" + + " void method(){}\n" + + "}" + ); + ICompilationUnit cuA = getCompilationUnit("P/A.java"); + CompilationUnit unitA = (CompilationUnit) runConversion(AST.JLS3, cuA, true, false, true); + AbstractTypeDeclaration typeA = (AbstractTypeDeclaration)unitA.types().get(0); + ITypeBinding objectType = typeA.resolveBinding().getSuperclass(); + assertEquals("Unexpected superclass", "Object", objectType .getName()); + ITypeBinding objectSuperclass = objectType.getSuperclass(); + assertNull("java.lang.Object should not have any superclass", objectSuperclass); + } finally { + deleteProject("P"); + } + } + public void testBug186410b() throws CoreException, IOException { + try { + createJavaProject("P", new String[] {""}, new String[0], ""); + createFile("P/A.java", + "public class A {\n" + + " Object field;\n" + + "}" + ); + ICompilationUnit cuA = getCompilationUnit("P/A.java"); + CompilationUnit unitA = (CompilationUnit) runConversion(AST.JLS3, cuA, true, false, true); + AbstractTypeDeclaration type = (AbstractTypeDeclaration)unitA.types().get(0); + FieldDeclaration field = (FieldDeclaration) type.bodyDeclarations().get(0); + Type fieldType = field.getType(); + ITypeBinding typeBinding = fieldType.resolveBinding(); + ITypeBinding objectType = typeBinding.createArrayType(2).getElementType(); + assertEquals("Unexpected superclass", "Object", objectType.getName()); + ITypeBinding objectSuperclass = objectType.getSuperclass(); + assertNull("java.lang.Object should not have any superclass", objectSuperclass); + } finally { + deleteProject("P"); + } + } + + /** + * @bug 209510: [dom] Recovered type binding for "java.lang.Object" information are not complete + * @test Ensures that getPackage() and getQualifiedName() works properly for the "java.lang.Object" recovered binding + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=209510" + */ + public void testBug209510a() throws CoreException, IOException { + try { + createJavaProject("P", new String[] {""}, new String[0], ""); + createFile("P/A.java", + "public class A {\n" + + " void method(){}\n" + + "}" + ); + ICompilationUnit cuA = getCompilationUnit("P/A.java"); + CompilationUnit unitA = (CompilationUnit) runConversion(AST.JLS3, cuA, true, false, true); + AbstractTypeDeclaration typeA = (AbstractTypeDeclaration)unitA.types().get(0); + ITypeBinding objectType = typeA.resolveBinding().getSuperclass(); + assertTrue("'java.lang.Object' should be recovered!", objectType.isRecovered()); + assertEquals("Unexpected package for recovered 'java.lang.Object'", "java.lang", objectType .getPackage().getName()); + assertEquals("Unexpected qualified name for recovered 'java.lang.Object'", "java.lang.Object", objectType .getQualifiedName()); + } finally { + deleteProject("P"); + } + } + public void testBug209510b() throws CoreException, IOException { + try { + createJavaProject("P", new String[] {""}, new String[0], ""); + createFile("P/A.java", + "public class A {\n" + + " Object field;\n" + + "}" + ); + ICompilationUnit cuA = getCompilationUnit("P/A.java"); + CompilationUnit unitA = (CompilationUnit) runConversion(AST.JLS3, cuA, true, false, true); + AbstractTypeDeclaration type = (AbstractTypeDeclaration)unitA.types().get(0); + FieldDeclaration field = (FieldDeclaration) type.bodyDeclarations().get(0); + Type fieldType = field.getType(); + ITypeBinding typeBinding = fieldType.resolveBinding(); + ITypeBinding arrayType = typeBinding.createArrayType(2); + assertTrue("'java.lang.Object' should be recovered!", arrayType.isRecovered()); + assertNull("Unexpected package for recovered 'array of java.lang.Object'", arrayType .getPackage()); + assertEquals("Unexpected qualified name for recovered 'java.lang.Object'", "java.lang.Object[][]", arrayType .getQualifiedName()); + } finally { + deleteProject("P"); + } + } + public void testBug209510c() throws CoreException, IOException { + try { + createJavaProject("P", new String[] {""}, new String[0], ""); + createFile("P/A.java", + "public class A {\n" + + " Object[] array;\n" + + "}" + ); + ICompilationUnit cuA = getCompilationUnit("P/A.java"); + CompilationUnit unitA = (CompilationUnit) runConversion(AST.JLS3, cuA, true, false, true); + AbstractTypeDeclaration type = (AbstractTypeDeclaration)unitA.types().get(0); + FieldDeclaration field = (FieldDeclaration) type.bodyDeclarations().get(0); + Type fieldType = field.getType(); + ITypeBinding arrayType = fieldType.resolveBinding(); + assertTrue("'java.lang.Object' should be recovered!", arrayType.isRecovered()); + assertNull("Unexpected package for recovered 'array of java.lang.Object'", arrayType .getPackage()); + assertEquals("Unexpected qualified name for recovered 'java.lang.Object'", "java.lang.Object[]", arrayType .getQualifiedName()); + } finally { + deleteProject("P"); + } + } + +} #P org.eclipse.jdt.core Index: dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java,v retrieving revision 1.5.2.1 diff -u -r1.5.2.1 RecoveredTypeBinding.java --- dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java 27 Aug 2007 19:18:56 -0000 1.5.2.1 +++ dom/org/eclipse/jdt/core/dom/RecoveredTypeBinding.java 13 Nov 2007 12:27:19 -0000 @@ -15,8 +15,11 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; +import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; +import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.util.Util; import org.eclipse.jdt.internal.core.CompilationUnit; import org.eclipse.jdt.internal.core.PackageFragment; @@ -32,7 +35,7 @@ private int dimensions; private RecoveredTypeBinding innerTypeBinding; private ITypeBinding[] typeArguments; - private org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding; + private org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding; RecoveredTypeBinding(BindingResolver resolver, VariableDeclaration variableDeclaration) { this.variableDeclaration = variableDeclaration; @@ -44,10 +47,10 @@ } } - RecoveredTypeBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding) { + RecoveredTypeBinding(BindingResolver resolver, org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding) { this.resolver = resolver; - this.dimensions = referenceBinding.dimensions(); - this.referenceBinding = referenceBinding; + this.dimensions = typeBinding.dimensions(); + this.binding = typeBinding; } RecoveredTypeBinding(BindingResolver resolver, Type type) { @@ -147,12 +150,12 @@ * @see org.eclipse.jdt.core.dom.ITypeBinding#getElementType() */ public ITypeBinding getElementType() { - if (this.referenceBinding != null) { - if (this.referenceBinding.isArrayType()) { - ArrayBinding arrayBinding = (ArrayBinding) this.referenceBinding; + if (this.binding != null) { + if (this.binding.isArrayType()) { + ArrayBinding arrayBinding = (ArrayBinding) this.binding; return new RecoveredTypeBinding(this.resolver, arrayBinding.leafComponentType); } else { - return new RecoveredTypeBinding(this.resolver, this.referenceBinding); + return new RecoveredTypeBinding(this.resolver, this.binding); } } if (this.innerTypeBinding != null) { @@ -205,17 +208,10 @@ private String getInternalName() { if (this.innerTypeBinding != null) { return this.innerTypeBinding.getInternalName(); - } else if (this.referenceBinding != null) { - org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding typeBinding = null; - if (this.referenceBinding.isArrayType()) { - ArrayBinding arrayBinding = (ArrayBinding) this.referenceBinding; - if (arrayBinding.leafComponentType instanceof org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) { - typeBinding = (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) arrayBinding.leafComponentType; - } - } else if (this.referenceBinding instanceof org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) { - typeBinding = (org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) this.referenceBinding; - } - return new String(typeBinding.compoundName[typeBinding.compoundName.length - 1]); + } + ReferenceBinding referenceBinding = getReferenceBinding(); + if (referenceBinding != null) { + return new String(referenceBinding.compoundName[referenceBinding.compoundName.length - 1]); } return this.getTypeNameFrom(getType()); } @@ -224,6 +220,20 @@ * @see org.eclipse.jdt.core.dom.ITypeBinding#getPackage() */ public IPackageBinding getPackage() { + if (this.binding != null) { + switch (this.binding.kind()) { + case Binding.BASE_TYPE : + case Binding.ARRAY_TYPE : + case Binding.TYPE_PARAMETER : // includes capture scenario + case Binding.WILDCARD_TYPE : + return null; + } + IPackageBinding packageBinding = this.resolver.getPackageBinding(this.binding.getPackage()); + if (packageBinding != null) return packageBinding; + } + if (this.innerTypeBinding != null && this.dimensions > 0) { + return null; + } CompilationUnitScope scope = this.resolver.scope(); if (scope != null) { return this.resolver.getPackageBinding(scope.getCurrentPackage()); @@ -235,13 +245,45 @@ * @see org.eclipse.jdt.core.dom.ITypeBinding#getQualifiedName() */ public String getQualifiedName() { - return this.getName(); + ReferenceBinding referenceBinding = getReferenceBinding(); + if (referenceBinding != null) { + StringBuffer buffer = new StringBuffer(); + char[] brackets = new char[this.dimensions * 2]; + for (int i = this.dimensions * 2 - 1; i >= 0; i -= 2) { + brackets[i] = ']'; + brackets[i - 1] = '['; + } + buffer.append(CharOperation.toString(referenceBinding.compoundName)); + buffer.append(brackets); + return String.valueOf(buffer); + } else { + return getName(); + } + } + + private ReferenceBinding getReferenceBinding() { + if (this.binding != null) { + if (this.binding.isArrayType()) { + ArrayBinding arrayBinding = (ArrayBinding) this.binding; + if (arrayBinding.leafComponentType instanceof ReferenceBinding) { + return (ReferenceBinding) arrayBinding.leafComponentType; + } + } else if (this.binding instanceof ReferenceBinding) { + return (ReferenceBinding) this.binding; + } + } else if (this.innerTypeBinding != null) { + return this.innerTypeBinding.getReferenceBinding(); + } + return null; } /* (non-Javadoc) * @see org.eclipse.jdt.core.dom.ITypeBinding#getSuperclass() */ public ITypeBinding getSuperclass() { + if (getQualifiedName().equals("java.lang.Object")) { //$NON-NLS-1$ + return null; + } return this.resolver.resolveWellKnownType("java.lang.Object"); //$NON-NLS-1$ } @@ -249,7 +291,7 @@ * @see org.eclipse.jdt.core.dom.ITypeBinding#getTypeArguments() */ public ITypeBinding[] getTypeArguments() { - if (this.referenceBinding != null) { + if (this.binding != null) { return this.typeArguments = TypeBinding.NO_TYPE_BINDINGS; } if (this.typeArguments != null) { @@ -521,9 +563,9 @@ } else if (this.currentType != null) { buffer.append("currentType") //$NON-NLS-1$ .append(this.currentType.toString()); - } else if (this.referenceBinding != null) { - buffer.append("referenceBinding") //$NON-NLS-1$ - .append(this.referenceBinding.computeUniqueKey()); + } else if (this.binding != null) { + buffer.append("typeBinding") //$NON-NLS-1$ + .append(this.binding.computeUniqueKey()); } else if (variableDeclaration != null) { buffer .append("variableDeclaration") //$NON-NLS-1$ Index: dom/org/eclipse/jdt/core/dom/ITypeBinding.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ITypeBinding.java,v retrieving revision 1.68 diff -u -r1.68 ITypeBinding.java --- dom/org/eclipse/jdt/core/dom/ITypeBinding.java 10 May 2007 00:16:04 -0000 1.68 +++ dom/org/eclipse/jdt/core/dom/ITypeBinding.java 13 Nov 2007 12:27:19 -0000 @@ -370,10 +370,12 @@ /** * Returns the binding for the package in which this type is declared. - * - *

The package of a recovered type reference binding is the package of the - * enclosing type.

* + *

The package of a recovered type reference binding is either + * the package of the enclosing type, or, if the type name is the name of a + * {@linkplain AST#resolveWellKnownType(String) well-known type}, + * the package of the matching well-known type.

+ * * @return the binding for the package in which this class, interface, * enum, or annotation type is declared, or null if this type * binding represents a primitive type, an array type, the null type,