### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java,v retrieving revision 1.335 diff -u -r1.335 ProblemReporter.java --- compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 22 Dec 2006 16:02:08 -0000 1.335 +++ compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java 9 Jan 2007 14:33:59 -0000 @@ -6344,9 +6344,6 @@ } public void unusedPrivateConstructor(ConstructorDeclaration constructorDecl) { - // no complaint for no-arg constructors (or default ones) - known pattern to block instantiation - if (constructorDecl.arguments == null || constructorDecl.arguments.length == 0) return; - int severity = computeSeverity(IProblem.UnusedPrivateConstructor); if (severity == ProblemSeverities.Ignore) return; Index: compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java,v retrieving revision 1.84 diff -u -r1.84 ConstructorDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 14 Nov 2006 19:44:11 -0000 1.84 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java 9 Jan 2007 14:33:56 -0000 @@ -51,10 +51,19 @@ int nonStaticFieldInfoReachMode = flowInfo.reachMode(); flowInfo.setReachMode(initialReachMode); - if (this.binding != null && !this.binding.isUsed() && (this.binding.isPrivate() || (this.binding.declaringClass.tagBits & (TagBits.IsAnonymousType|TagBits.IsLocalType)) == TagBits.IsLocalType)) { - if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError) { - this.scope.problemReporter().unusedPrivateConstructor(this); + checkUnused: { + MethodBinding constructorBinding; + if ((constructorBinding = this.binding) == null) break checkUnused; + if (this.isDefaultConstructor) break checkUnused; + if (constructorBinding.isUsed()) break checkUnused; + if (constructorBinding.isPrivate()) { + if ((this.binding.declaringClass.tagBits & TagBits.HasNonPrivateConstructor) == 0) + break checkUnused; // tolerate as known pattern to block instantiation + } else if ((this.binding.declaringClass.tagBits & (TagBits.IsAnonymousType|TagBits.IsLocalType)) != TagBits.IsLocalType) { + break checkUnused; } + // complain unused + this.scope.problemReporter().unusedPrivateConstructor(this); } // check constructor recursion, once all constructor got resolved @@ -412,28 +421,31 @@ * for recursive constructor invocations. */ public void resolveStatements() { - if (!CharOperation.equals(this.scope.enclosingSourceType().sourceName, this.selector)){ + SourceTypeBinding sourceType = this.scope.enclosingSourceType(); + if (!CharOperation.equals(sourceType.sourceName, this.selector)){ this.scope.problemReporter().missingReturnType(this); } - if (this.typeParameters != null) { for (int i = 0, length = this.typeParameters.length; i < length; i++) { this.typeParameters[i].resolve(this.scope); } } - - // if null ==> an error has occurs at parsing time .... - if (this.constructorCall != null) { - // e.g. using super() in java.lang.Object - if (this.binding != null - && this.binding.declaringClass.id == TypeIds.T_JavaLangObject - && this.constructorCall.accessMode != ExplicitConstructorCall.This) { - if (this.constructorCall.accessMode == ExplicitConstructorCall.Super) { - this.scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall); - } - this.constructorCall = null; - } else { - this.constructorCall.resolve(this.scope); + if (this.binding != null) { + if (!this.binding.isPrivate()) { + sourceType.tagBits |= TagBits.HasNonPrivateConstructor; + } + // if null ==> an error has occurs at parsing time .... + if (this.constructorCall != null) { + // e.g. using super() in java.lang.Object + if (sourceType.id == TypeIds.T_JavaLangObject + && this.constructorCall.accessMode != ExplicitConstructorCall.This) { + if (this.constructorCall.accessMode == ExplicitConstructorCall.Super) { + this.scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall); + } + this.constructorCall = null; + } else { + this.constructorCall.resolve(this.scope); + } } } if ((this.modifiers & ExtraCompilerModifiers.AccSemicolonBody) != 0) { Index: compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java,v retrieving revision 1.28 diff -u -r1.28 TagBits.java --- compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 23 Oct 2006 08:01:16 -0000 1.28 +++ compiler/org/eclipse/jdt/internal/compiler/lookup/TagBits.java 9 Jan 2007 14:33:56 -0000 @@ -106,4 +106,7 @@ long AllStandardAnnotationsMask = AnnotationTargetMASK | AnnotationRetentionMASK | AnnotationDeprecated | AnnotationDocumented | AnnotationInherited | AnnotationOverride | AnnotationSuppressWarnings; long DefaultValueResolved = ASTNode.Bit52L; + + // set when type contains non-private constructor(s) + long HasNonPrivateConstructor = ASTNode.Bit53L; } #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/ProblemConstructorTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ProblemConstructorTest.java,v retrieving revision 1.14 diff -u -r1.14 ProblemConstructorTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/ProblemConstructorTest.java 29 Mar 2006 03:50:23 -0000 1.14 +++ src/org/eclipse/jdt/core/tests/compiler/regression/ProblemConstructorTest.java 9 Jan 2007 14:34:00 -0000 @@ -98,4 +98,39 @@ "This method requires a body instead of a semicolon\n" + "----------\n"); } +//https://bugs.eclipse.org/bugs/show_bug.cgi?id=163443 +public void test003() { + this.runNegativeTest( + new String[] { + "Example.java", + "class Example {\n" + + " private Example() {\n" + + " }\n" + + " public Example(int i) {\n" + + " }\n" + + "}\n" + + "class E1 {\n" + + " private E1(int i) {}\n" + + " private E1(long l) {}\n" + + "}\n" + + "class E2 {\n" + + " private E2(int i) {}\n" + + "}\n" + + "class E3 {\n" + + " public E3(int i) {}\n" + + " Zork z;\n" + + "}\n" + }, + "----------\n" + + "1. WARNING in Example.java (at line 2)\n" + + " private Example() {\n" + + " ^^^^^^^^^\n" + + "The constructor Example() is never used locally\n" + + "----------\n" + + "2. ERROR in Example.java (at line 16)\n" + + " Zork z;\n" + + " ^^^^\n" + + "Zork cannot be resolved to a type\n" + + "----------\n"); +} }