View | Details | Raw Unified | Return to bug 265142 | Differences between
and this patch

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/MessageSend.java (-2 / +2 lines)
Lines 378-384 Link Here
378
						}
378
						}
379
						this.binding = closestMatch;
379
						this.binding = closestMatch;
380
						MethodBinding closestMatchOriginal = closestMatch.original();
380
						MethodBinding closestMatchOriginal = closestMatch.original();
381
						if ((closestMatchOriginal.isPrivate() || closestMatchOriginal.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatchOriginal)) {
381
						if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
382
							// ignore cases where method is used from within inside itself (e.g. direct recursions)
382
							// ignore cases where method is used from within inside itself (e.g. direct recursions)
383
							closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
383
							closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
384
						}
384
						}
Lines 426-432 Link Here
426
		if (closestMatch != null) {
426
		if (closestMatch != null) {
427
			this.binding = closestMatch;
427
			this.binding = closestMatch;
428
			MethodBinding closestMatchOriginal = closestMatch.original();
428
			MethodBinding closestMatchOriginal = closestMatch.original();
429
			if ((closestMatchOriginal.isPrivate() || closestMatchOriginal.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatchOriginal)) {
429
			if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
430
				// ignore cases where method is used from within inside itself (e.g. direct recursions)
430
				// ignore cases where method is used from within inside itself (e.g. direct recursions)
431
				closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
431
				closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
432
			}
432
			}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedAllocationExpression.java (-1 / +1 lines)
Lines 343-349 Link Here
343
							}
343
							}
344
							this.binding = closestMatch;
344
							this.binding = closestMatch;
345
							MethodBinding closestMatchOriginal = closestMatch.original();
345
							MethodBinding closestMatchOriginal = closestMatch.original();
346
							if ((closestMatchOriginal.isPrivate() || closestMatchOriginal.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatchOriginal)) {
346
							if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
347
								// ignore cases where method is used from within inside itself (e.g. direct recursions)
347
								// ignore cases where method is used from within inside itself (e.g. direct recursions)
348
								closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
348
								closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
349
							}
349
							}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/AllocationExpression.java (-1 / +1 lines)
Lines 321-327 Link Here
321
						}
321
						}
322
						this.binding = closestMatch;
322
						this.binding = closestMatch;
323
						MethodBinding closestMatchOriginal = closestMatch.original();
323
						MethodBinding closestMatchOriginal = closestMatch.original();
324
						if ((closestMatchOriginal.isPrivate() || closestMatchOriginal.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatchOriginal)) {
324
						if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
325
							// ignore cases where method is used from within inside itself (e.g. direct recursions)
325
							// ignore cases where method is used from within inside itself (e.g. direct recursions)
326
							closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
326
							closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
327
						}
327
						}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java (-1 / +18 lines)
Lines 59-66 Link Here
59
		if (constructorBinding.isPrivate()) {
59
		if (constructorBinding.isPrivate()) {
60
			if ((this.binding.declaringClass.tagBits & TagBits.HasNonPrivateConstructor) == 0)
60
			if ((this.binding.declaringClass.tagBits & TagBits.HasNonPrivateConstructor) == 0)
61
				break checkUnused; // tolerate as known pattern to block instantiation
61
				break checkUnused; // tolerate as known pattern to block instantiation
62
		} else if ((this.binding.declaringClass.tagBits & (TagBits.IsAnonymousType|TagBits.IsLocalType)) != TagBits.IsLocalType) {
62
		} else if (!constructorBinding.isOrEnclosedByPrivateType()) {
63
			break checkUnused;
63
			break checkUnused;
64
 		}
65
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=264991, Don't complain about this
66
		// constructor being unused if the base class doesn't have a no-arg constructor.
67
		// See that a seemingly unused constructor that chains to another constructor with a
68
		// this(...) can be flagged as being unused without hesitation.
69
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=265142
70
		if (this.constructorCall.accessMode != ExplicitConstructorCall.This) {
71
			ReferenceBinding superClass = constructorBinding.declaringClass.superclass();
72
			if (superClass == null)
73
				break checkUnused;
74
			// see if there is a no-arg super constructor
75
			MethodBinding methodBinding = superClass.getExactConstructor(Binding.NO_PARAMETERS);
76
			if (methodBinding == null || !methodBinding.isValidBinding())
77
				break checkUnused;
78
			if (!methodBinding.canBeSeenBy(SuperReference.implicitSuperConstructorCall(), this.scope))
79
				break checkUnused;
80
			// otherwise default super constructor exists, so go ahead and complain unused.
64
		}
81
		}
65
		// complain unused
82
		// complain unused
66
		this.scope.problemReporter().unusedPrivateConstructor(this);
83
		this.scope.problemReporter().unusedPrivateConstructor(this);
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ExplicitConstructorCall.java (-2 / +2 lines)
Lines 376-382 Link Here
376
							}
376
							}
377
							this.binding = closestMatch;
377
							this.binding = closestMatch;
378
							MethodBinding closestMatchOriginal = closestMatch.original();
378
							MethodBinding closestMatchOriginal = closestMatch.original();
379
							if ((closestMatchOriginal.isPrivate() || closestMatchOriginal.declaringClass.isLocalType()) && !scope.isDefinedInMethod(closestMatchOriginal)) {
379
							if (closestMatchOriginal.isOrEnclosedByPrivateType() && !scope.isDefinedInMethod(closestMatchOriginal)) {
380
								// ignore cases where method is used from within inside itself (e.g. direct recursions)
380
								// ignore cases where method is used from within inside itself (e.g. direct recursions)
381
								closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
381
								closestMatchOriginal.modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
382
							}
382
							}
Lines 403-409 Link Here
403
				if (checkInvocationArguments(scope, null, receiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
403
				if (checkInvocationArguments(scope, null, receiverType, this.binding, this.arguments, argumentTypes, argsContainCast, this)) {
404
					this.bits |= ASTNode.Unchecked;
404
					this.bits |= ASTNode.Unchecked;
405
				}
405
				}
406
				if (this.binding.isPrivate() || receiverType.isLocalType()) {
406
				if (this.binding.isOrEnclosedByPrivateType()) {
407
					this.binding.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
407
					this.binding.original().modifiers |= ExtraCompilerModifiers.AccLocallyUsed;
408
				}
408
				}
409
				if (this.typeArguments != null
409
				if (this.typeArguments != null
(-)src/org/eclipse/jdt/core/tests/compiler/regression/InnerEmulationTest.java (-30 / +10 lines)
Lines 2996-3013 Link Here
2996
			"	      ^\n" +
2996
			"	      ^\n" +
2997
			"The type B is never used locally\n" +
2997
			"The type B is never used locally\n" +
2998
			"----------\n" +
2998
			"----------\n" +
2999
			"2. WARNING in X.java (at line 8)\n" +
2999
			"2. ERROR in X.java (at line 9)\n" +
3000
			"	B() {	\n" +
3001
			"	^^^\n" +
3002
			"The constructor B() is never used locally\n" +
3003
			"----------\n" +
3004
			"3. ERROR in X.java (at line 9)\n" +
3005
			"	super(new A(){	\n" +
3000
			"	super(new A(){	\n" +
3006
			"				});	\n" +
3001
			"				});	\n" +
3007
			"	      ^^^^^^^^^^^^^^^\n" +
3002
			"	      ^^^^^^^^^^^^^^^\n" +
3008
			"No enclosing instance of type X is available due to some intermediate constructor invocation\n" +
3003
			"No enclosing instance of type X is available due to some intermediate constructor invocation\n" +
3009
			"----------\n" +
3004
			"----------\n" +
3010
			"4. WARNING in X.java (at line 9)\n" +
3005
			"3. WARNING in X.java (at line 9)\n" +
3011
			"	super(new A(){	\n" +
3006
			"	super(new A(){	\n" +
3012
			"	          ^^^\n" +
3007
			"	          ^^^\n" +
3013
			"Access to enclosing constructor A() is emulated by a synthetic accessor method\n" +
3008
			"Access to enclosing constructor A() is emulated by a synthetic accessor method\n" +
Lines 3039-3050 Link Here
3039
			"	      ^\n" +
3034
			"	      ^\n" +
3040
			"The type B is never used locally\n" +
3035
			"The type B is never used locally\n" +
3041
			"----------\n" +
3036
			"----------\n" +
3042
			"2. WARNING in X.java (at line 8)\n" +
3037
			"2. ERROR in X.java (at line 9)\n" +
3043
			"	B() {	\n" +
3044
			"	^^^\n" +
3045
			"The constructor B() is never used locally\n" +
3046
			"----------\n" +
3047
			"3. ERROR in X.java (at line 9)\n" +
3048
			"	super(new A(){	\n" +
3038
			"	super(new A(){	\n" +
3049
			"				});	\n" +
3039
			"				});	\n" +
3050
			"	      ^^^^^^^^^^^^^^^\n" +
3040
			"	      ^^^^^^^^^^^^^^^\n" +
Lines 3136-3164 Link Here
3136
			"	      ^\n" +
3126
			"	      ^\n" +
3137
			"The type B is never used locally\n" +
3127
			"The type B is never used locally\n" +
3138
			"----------\n" +
3128
			"----------\n" +
3139
			"2. WARNING in X.java (at line 8)\n" +
3129
			"2. ERROR in X.java (at line 9)\n" +
3140
			"	B() {	\n" +
3141
			"	^^^\n" +
3142
			"The constructor B() is never used locally\n" +
3143
			"----------\n" +
3144
			"3. ERROR in X.java (at line 9)\n" +
3145
			"	super(new A(){	\n" +
3130
			"	super(new A(){	\n" +
3146
			"					void foo() { System.out.println(X.this);	} \n" +
3131
			"					void foo() { System.out.println(X.this);	} \n" +
3147
			"				});	\n" +
3132
			"				});	\n" +
3148
			"	      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
3133
			"	      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
3149
			"No enclosing instance of type X is available due to some intermediate constructor invocation\n" +
3134
			"No enclosing instance of type X is available due to some intermediate constructor invocation\n" +
3150
			"----------\n" +
3135
			"----------\n" +
3151
			"4. WARNING in X.java (at line 9)\n" +
3136
			"3. WARNING in X.java (at line 9)\n" +
3152
			"	super(new A(){	\n" +
3137
			"	super(new A(){	\n" +
3153
			"	          ^^^\n" +
3138
			"	          ^^^\n" +
3154
			"Access to enclosing constructor A() is emulated by a synthetic accessor method\n" +
3139
			"Access to enclosing constructor A() is emulated by a synthetic accessor method\n" +
3155
			"----------\n" +
3140
			"----------\n" +
3156
			"5. WARNING in X.java (at line 10)\n" +
3141
			"4. WARNING in X.java (at line 10)\n" +
3157
			"	void foo() { System.out.println(X.this);	} \n" +
3142
			"	void foo() { System.out.println(X.this);	} \n" +
3158
			"	     ^^^^^\n" +
3143
			"	     ^^^^^\n" +
3159
			"The method foo() from the type new A(){} is never used locally\n" +
3144
			"The method foo() from the type new A(){} is never used locally\n" +
3160
			"----------\n" +
3145
			"----------\n" +
3161
			"6. ERROR in X.java (at line 10)\n" +
3146
			"5. ERROR in X.java (at line 10)\n" +
3162
			"	void foo() { System.out.println(X.this);	} \n" +
3147
			"	void foo() { System.out.println(X.this);	} \n" +
3163
			"	                                ^^^^^^\n" +
3148
			"	                                ^^^^^^\n" +
3164
			"No enclosing instance of the type X is accessible in scope\n" +
3149
			"No enclosing instance of the type X is accessible in scope\n" +
Lines 3191-3214 Link Here
3191
			"	      ^\n" +
3176
			"	      ^\n" +
3192
			"The type B is never used locally\n" +
3177
			"The type B is never used locally\n" +
3193
			"----------\n" +
3178
			"----------\n" +
3194
			"2. WARNING in X.java (at line 8)\n" +
3179
			"2. ERROR in X.java (at line 9)\n" +
3195
			"	B() {	\n" +
3196
			"	^^^\n" +
3197
			"The constructor B() is never used locally\n" +
3198
			"----------\n" +
3199
			"3. ERROR in X.java (at line 9)\n" +
3200
			"	super(new A(){	\n" +
3180
			"	super(new A(){	\n" +
3201
			"					void foo() { System.out.println(X.this);	} \n" +
3181
			"					void foo() { System.out.println(X.this);	} \n" +
3202
			"				});	\n" +
3182
			"				});	\n" +
3203
			"	      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
3183
			"	      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" +
3204
			"No enclosing instance of type X is available due to some intermediate constructor invocation\n" +
3184
			"No enclosing instance of type X is available due to some intermediate constructor invocation\n" +
3205
			"----------\n" +
3185
			"----------\n" +
3206
			"4. WARNING in X.java (at line 10)\n" +
3186
			"3. WARNING in X.java (at line 10)\n" +
3207
			"	void foo() { System.out.println(X.this);	} \n" +
3187
			"	void foo() { System.out.println(X.this);	} \n" +
3208
			"	     ^^^^^\n" +
3188
			"	     ^^^^^\n" +
3209
			"The method foo() from the type new A(){} is never used locally\n" +
3189
			"The method foo() from the type new A(){} is never used locally\n" +
3210
			"----------\n" +
3190
			"----------\n" +
3211
			"5. ERROR in X.java (at line 10)\n" +
3191
			"4. ERROR in X.java (at line 10)\n" +
3212
			"	void foo() { System.out.println(X.this);	} \n" +
3192
			"	void foo() { System.out.println(X.this);	} \n" +
3213
			"	                                ^^^^^^\n" +
3193
			"	                                ^^^^^^\n" +
3214
			"No enclosing instance of the type X is accessible in scope\n" +
3194
			"No enclosing instance of the type X is accessible in scope\n" +
(-)src/org/eclipse/jdt/core/tests/compiler/regression/ProblemConstructorTest.java (-2 / +107 lines)
Lines 177-188 Link Here
177
			"	           ^^^^^^^^^^^^^^\n" + 
177
			"	           ^^^^^^^^^^^^^^\n" + 
178
			"The method unusedMethod() from the type X.M is never used locally\n" + 
178
			"The method unusedMethod() from the type X.M is never used locally\n" + 
179
			"----------\n" + 
179
			"----------\n" + 
180
			"2. WARNING in X.java (at line 6)\n" + 
180
			"2. WARNING in X.java (at line 5)\n" + 
181
			"	public M (int state) { this.state = state;} \n" + 
182
			"	       ^^^^^^^^^^^^^\n" + 
183
			"The constructor X.M(int) is never used locally\n" + 
184
			"----------\n" + 
185
			"3. WARNING in X.java (at line 6)\n" + 
181
			"	public int unusedField = 0;\n" + 
186
			"	public int unusedField = 0;\n" + 
182
			"	           ^^^^^^^^^^^\n" + 
187
			"	           ^^^^^^^^^^^\n" + 
183
			"The field X.M.unusedField is never read locally\n" + 
188
			"The field X.M.unusedField is never read locally\n" + 
184
			"----------\n" + 
189
			"----------\n" + 
185
			"3. WARNING in X.java (at line 7)\n" + 
190
			"4. WARNING in X.java (at line 7)\n" + 
186
			"	public class N {}\n" + 
191
			"	public class N {}\n" + 
187
			"	             ^\n" + 
192
			"	             ^\n" + 
188
			"The type X.M.N is never used locally\n" + 
193
			"The type X.M.N is never used locally\n" + 
Lines 217-220 Link Here
217
			"Access to enclosing method test() from the type A.B is emulated by a synthetic accessor method\n" + 
222
			"Access to enclosing method test() from the type A.B is emulated by a synthetic accessor method\n" + 
218
			"----------\n");
223
			"----------\n");
219
}
224
}
225
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265142, wrong unused warning reported. Test to ensure that
226
//we DO complain about the constructor of B not being used when its base class has a no-arg constructor
227
public void test006() {
228
	this.runNegativeTest(
229
		new String[] {
230
				"A.java",
231
				"public class A {\n" +
232
			    "    public A(String s) {\n" +
233
			    "            B.test();\n" +
234
			    "    }\n" +
235
			    "    public A() {}\n" +
236
			    "\n" +
237
			    "    private static class B extends A {\n" +
238
			    "       public B () { super(\"\"); }\n" +
239
			    "\n" +
240
			    "            private static void test() {\n" +
241
			    "            };\n" +
242
			    "   }\n" +
243
				"}\n"
244
			},
245
			"----------\n" + 
246
			"1. WARNING in A.java (at line 3)\n" + 
247
			"	B.test();\n" + 
248
			"	^^^^^^^^\n" + 
249
			"Access to enclosing method test() from the type A.B is emulated by a synthetic accessor method\n" + 
250
			"----------\n" + 
251
			"2. WARNING in A.java (at line 8)\n" + 
252
			"	public B () { super(\"\"); }\n" + 
253
			"	       ^^^^\n" + 
254
			"The constructor A.B() is never used locally\n" + 
255
			"----------\n");
256
}
257
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265142, wrong unused warning reported. Test to ensure that
258
//we can compile the program successfully after deleting the unused constructor.
259
public void test007() {
260
	this.runConformTest(
261
		new String[] {
262
				"A.java",
263
				"public class A {\n" +
264
			    "    public A(String s) {\n" +
265
			    "            B.test();\n" +
266
			    "    }\n" +
267
			    "    public A() {}\n" +
268
			    "\n" +
269
			    "    private static class B extends A {\n" +
270
			    "            private static void test() {\n" +
271
			    "            };\n" +
272
			    "   }\n" +
273
				"}\n"
274
			});
275
}
276
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265142, wrong unused warning reported. Test to ensure that
277
//we DON'T complain about unused constructor when the super class's default constructor is not visible.
278
public void test008() {
279
	this.runNegativeTest(
280
		new String[] {
281
				"A.java",
282
				"public class A {\n" +
283
				" public A(String s) {}\n" +
284
				" public A() {}\n" +
285
				"}\n" +
286
				"class C {\n" +
287
				"	private static class B extends A {\n" +
288
				"		public B () { super(\"\"); }\n" +
289
				"       static void foo() {}\n" +
290
				"	}\n" +
291
				"	C() {\n" +
292
				"	B.foo();\n" +
293
				"	}\n" +
294
				"}\n"
295
				},
296
				"----------\n" + 
297
				"1. WARNING in A.java (at line 7)\n" + 
298
				"	public B () { super(\"\"); }\n" + 
299
				"	       ^^^^\n" + 
300
				"The constructor C.B() is never used locally\n" + 
301
				"----------\n");
302
}
303
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=265142, wrong unused warning reported. Test to ensure that
304
//we DO complain about unused constructor when the super class's default constructor is visible.
305
public void test009() {
306
	this.runNegativeTest(
307
		new String[] {
308
				"A.java",
309
				"public class A {\n" +
310
				" public A(String s) {this();}\n" +
311
				" private A() {}\n" +
312
				"}\n" +
313
				"class C {\n" +
314
				"	private static class B extends A {\n" +
315
				"		public B () { super(\"\"); }\n" +
316
				"       static void foo() {}\n" +
317
				"	}\n" +
318
				"	C() {\n" +
319
				"	B.foo();\n" +
320
				"	}\n" +
321
				"}\n"
322
				},
323
				"");
324
}
220
}
325
}

Return to bug 265142