View | Details | Raw Unified | Return to bug 228109
Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/EnumTest.java (-27 / +348 lines)
Lines 3860-3879 Link Here
3860
		"	^^^^^\n" + 
3860
		"	^^^^^\n" + 
3861
		"Cannot refer to the static enum field X.VALUE within an initializer\n" + 
3861
		"Cannot refer to the static enum field X.VALUE within an initializer\n" + 
3862
		"----------\n" + 
3862
		"----------\n" + 
3863
		"2. ERROR in X.java (at line 8)\n" + 
3863
		"2. ERROR in X.java (at line 9)\n" + 
3864
		"	VALUE = null;\n" + 
3865
		"	^^^^^\n" + 
3866
		"The final field X.VALUE cannot be assigned\n" + 
3867
		"----------\n" + 
3868
		"3. ERROR in X.java (at line 9)\n" + 
3869
		"	ASD = 5;\n" + 
3864
		"	ASD = 5;\n" + 
3870
		"	^^^\n" + 
3865
		"	^^^\n" + 
3871
		"Cannot refer to the static enum field X.ASD within an initializer\n" + 
3866
		"Cannot refer to the static enum field X.ASD within an initializer\n" + 
3872
		"----------\n" + 
3867
		"----------\n" + 
3873
		"4. ERROR in X.java (at line 10)\n" + 
3868
		"3. ERROR in X.java (at line 10)\n" + 
3874
		"	X.VALUE = null;\n" + 
3869
		"	X.VALUE = null;\n" + 
3875
		"	  ^^^^^\n" + 
3870
		"	  ^^^^^\n" + 
3876
		"The final field X.VALUE cannot be assigned\n" + 
3871
		"Cannot refer to the static enum field X.VALUE within an initializer\n" + 
3872
		"----------\n" + 
3873
		"4. ERROR in X.java (at line 11)\n" + 
3874
		"	X.ASD = 5;\n" + 
3875
		"	  ^^^\n" + 
3876
		"Cannot refer to the static enum field X.ASD within an initializer\n" + 
3877
		"----------\n");
3877
		"----------\n");
3878
}	
3878
}	
3879
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=101713 - variation
3879
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=101713 - variation
Lines 3895-3905 Link Here
3895
		"	BLEU = null;\n" + 
3895
		"	BLEU = null;\n" + 
3896
		"	^^^^\n" + 
3896
		"	^^^^\n" + 
3897
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3897
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3898
		"----------\n" + 
3899
		"2. ERROR in X.java (at line 6)\n" + 
3900
		"	BLEU = null;\n" + 
3901
		"	^^^^\n" + 
3902
		"The final field X.BLEU cannot be assigned\n" + 
3903
		"----------\n");
3898
		"----------\n");
3904
}	
3899
}	
3905
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=101713 - variation
3900
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=101713 - variation
Lines 3933-3969 Link Here
3933
		"	      ^^^^\n" + 
3928
		"	      ^^^^\n" + 
3934
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3929
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3935
		"----------\n" + 
3930
		"----------\n" + 
3936
		"2. WARNING in X.java (at line 6)\n" + 
3931
		"2. ERROR in X.java (at line 6)\n" + 
3932
		"	X x = BLEU.BLANC; // ko\n" + 
3933
		"	           ^^^^^\n" + 
3934
		"Cannot refer to the static enum field X.BLANC within an initializer\n" + 
3935
		"----------\n" + 
3936
		"3. WARNING in X.java (at line 6)\n" + 
3937
		"	X x = BLEU.BLANC; // ko\n" + 
3937
		"	X x = BLEU.BLANC; // ko\n" + 
3938
		"	           ^^^^^\n" + 
3938
		"	           ^^^^^\n" + 
3939
		"The static field X.BLANC should be accessed in a static way\n" + 
3939
		"The static field X.BLANC should be accessed in a static way\n" + 
3940
		"----------\n" + 
3940
		"----------\n" + 
3941
		"3. ERROR in X.java (at line 7)\n" + 
3941
		"4. ERROR in X.java (at line 7)\n" + 
3942
		"	X x2 = BLEU; // ko\n" + 
3942
		"	X x2 = BLEU; // ko\n" + 
3943
		"	       ^^^^\n" + 
3943
		"	       ^^^^\n" + 
3944
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3944
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3945
		"----------\n" + 
3945
		"----------\n" + 
3946
		"4. WARNING in X.java (at line 10)\n" + 
3946
		"5. WARNING in X.java (at line 10)\n" + 
3947
		"	X x = BLEU.BLANC; // ok\n" + 
3947
		"	X x = BLEU.BLANC; // ok\n" + 
3948
		"	           ^^^^^\n" + 
3948
		"	           ^^^^^\n" + 
3949
		"The static field X.BLANC should be accessed in a static way\n" + 
3949
		"The static field X.BLANC should be accessed in a static way\n" + 
3950
		"----------\n" + 
3950
		"----------\n" + 
3951
		"5. ERROR in X.java (at line 13)\n" + 
3951
		"6. ERROR in X.java (at line 13)\n" + 
3952
		"	X dummy = BLEU; // ko\n" + 
3952
		"	X dummy = BLEU; // ko\n" + 
3953
		"	          ^^^^\n" + 
3953
		"	          ^^^^\n" + 
3954
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3954
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3955
		"----------\n" + 
3955
		"----------\n" + 
3956
		"6. ERROR in X.java (at line 16)\n" + 
3956
		"7. ERROR in X.java (at line 16)\n" + 
3957
		"	X x = BLEU.BLANC; // ko\n" + 
3957
		"	X x = BLEU.BLANC; // ko\n" + 
3958
		"	      ^^^^\n" + 
3958
		"	      ^^^^\n" + 
3959
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3959
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3960
		"----------\n" + 
3960
		"----------\n" + 
3961
		"7. WARNING in X.java (at line 16)\n" + 
3961
		"8. ERROR in X.java (at line 16)\n" + 
3962
		"	X x = BLEU.BLANC; // ko\n" + 
3963
		"	           ^^^^^\n" + 
3964
		"Cannot refer to the static enum field X.BLANC within an initializer\n" + 
3965
		"----------\n" + 
3966
		"9. WARNING in X.java (at line 16)\n" + 
3962
		"	X x = BLEU.BLANC; // ko\n" + 
3967
		"	X x = BLEU.BLANC; // ko\n" + 
3963
		"	           ^^^^^\n" + 
3968
		"	           ^^^^^\n" + 
3964
		"The static field X.BLANC should be accessed in a static way\n" + 
3969
		"The static field X.BLANC should be accessed in a static way\n" + 
3965
		"----------\n" + 
3970
		"----------\n" + 
3966
		"8. ERROR in X.java (at line 17)\n" + 
3971
		"10. ERROR in X.java (at line 17)\n" + 
3967
		"	X x2 = BLEU; // ko\n" + 
3972
		"	X x2 = BLEU; // ko\n" + 
3968
		"	       ^^^^\n" + 
3973
		"	       ^^^^\n" + 
3969
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
3974
		"Cannot refer to the static enum field X.BLEU within an initializer\n" + 
Lines 4063-4069 Link Here
4063
		"	             ^\n" + 
4068
		"	             ^\n" + 
4064
		"Cannot refer to the static enum field X.B within an initializer\n" + 
4069
		"Cannot refer to the static enum field X.B within an initializer\n" + 
4065
		"----------\n" + 
4070
		"----------\n" + 
4066
		"3. WARNING in X.java (at line 5)\n" + 
4071
		"3. ERROR in X.java (at line 5)\n" + 
4072
		"	final X a2 = B.A;\n" + 
4073
		"	               ^\n" + 
4074
		"Cannot refer to the static enum field X.A within an initializer\n" + 
4075
		"----------\n" + 
4076
		"4. WARNING in X.java (at line 5)\n" + 
4067
		"	final X a2 = B.A;\n" + 
4077
		"	final X a2 = B.A;\n" + 
4068
		"	               ^\n" + 
4078
		"	               ^\n" + 
4069
		"The static field X.A should be accessed in a static way\n" + 
4079
		"The static field X.A should be accessed in a static way\n" + 
Lines 4087-4098 Link Here
4087
			"}\n",
4097
			"}\n",
4088
		},
4098
		},
4089
		"----------\n" + 
4099
		"----------\n" + 
4090
		"1. WARNING in X.java (at line 5)\n" + 
4100
		"1. ERROR in X.java (at line 8)\n" + 
4091
		"	private static String error;\n" + 
4092
		"	                      ^^^^^\n" + 
4093
		"The field X.error is never read locally\n" + 
4094
		"----------\n" + 
4095
		"2. ERROR in X.java (at line 8)\n" + 
4096
		"	error = \"error\";\n" + 
4101
		"	error = \"error\";\n" + 
4097
		"	^^^^^\n" + 
4102
		"	^^^^^\n" + 
4098
		"Cannot refer to the static enum field X.error within an initializer\n" + 
4103
		"Cannot refer to the static enum field X.error within an initializer\n" + 
Lines 5262-5265 Link Here
5262
		false,
5267
		false,
5263
		null);
5268
		null);
5264
}
5269
}
5270
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109
5271
public void test153() {
5272
	this.runNegativeTest(
5273
		new String[] {
5274
				"TestEnum.java",
5275
				"public enum TestEnum {\n" + 
5276
				"	RED, GREEN, BLUE; \n" + 
5277
				"    static int test = 0;  \n" + 
5278
				"\n" + 
5279
				"    TestEnum() {\n" + 
5280
				"        TestEnum.test=10;\n" + 
5281
				"    }\n" + 
5282
				"}\n"
5283
		},
5284
		"----------\n" + 
5285
		"1. ERROR in TestEnum.java (at line 6)\n" + 
5286
		"	TestEnum.test=10;\n" + 
5287
		"	         ^^^^\n" + 
5288
		"Cannot refer to the static enum field TestEnum.test within an initializer\n" + 
5289
		"----------\n");
5290
}
5291
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5292
public void test154() {
5293
	this.runNegativeTest(
5294
		new String[] {
5295
				"TestEnum2.java",
5296
				"public enum TestEnum2 {\n" + 
5297
				"	; \n" + 
5298
				"   static int test = 0;  \n" + 
5299
				"	TestEnum2() {\n" + 
5300
				"        TestEnum2.test=11;\n" + 
5301
				"   }\n" + 
5302
				"}\n" +
5303
				"class X {\n" + 
5304
				"	static int test = 0;\n" + 
5305
				"	X() {\n" + 
5306
				"		X.test = 13;\n" + 
5307
				"	}\n" + 
5308
				"}\n"
5309
		},
5310
		"----------\n" + 
5311
		"1. ERROR in TestEnum2.java (at line 5)\n" + 
5312
		"	TestEnum2.test=11;\n" + 
5313
		"	          ^^^^\n" + 
5314
		"Cannot refer to the static enum field TestEnum2.test within an initializer\n" + 
5315
		"----------\n");
5316
}
5317
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5318
public void test155() {
5319
	this.runConformTest(
5320
		new String[] {
5321
				"TestEnum.java",
5322
				"public enum TestEnum {\n" + 
5323
				"	RED, GREEN, BLUE; \n" + 
5324
				"    static int test = 0;  \n" + 
5325
				"}\n" + 
5326
				"\n" + 
5327
				"enum TestEnum2 {\n" + 
5328
				"	; \n" + 
5329
				"    TestEnum2() {\n" + 
5330
				"        TestEnum.test=12;\n" + 
5331
				"    }\n" + 
5332
				"}\n"
5333
		},
5334
		"");
5335
}
5336
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5337
public void test156() {
5338
	this.runConformTest(
5339
		new String[] {
5340
				"TestEnum.java",
5341
				"public enum TestEnum {\n" + 
5342
				"	RED, GREEN, BLUE; \n" + 
5343
				"    static int test = 0;  \n" + 
5344
				"\n" + 
5345
				"    TestEnum() {\n" + 
5346
				"        new Object() {\n" +
5347
				"			{ TestEnum.test=10; }\n" + 
5348
				"		};\n" +
5349
				"    }\n" + 
5350
				"}\n"
5351
		},
5352
		"");
5353
}
5354
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5355
public void test157() {
5356
	this.runNegativeTest(
5357
		new String[] {
5358
				"Foo.java",
5359
				"enum Foo {\n" + 
5360
				"	ONE, TWO, THREE;\n" + 
5361
				"	static int val = 10;\n" + 
5362
				"	Foo () {\n" + 
5363
				"		this(Foo.val);\n" +
5364
				"		System.out.println(Foo.val);\n" + 
5365
				"	}\n" + 
5366
				"	Foo(int i){}\n" +
5367
				"	{\n" + 
5368
				"		System.out.println(Foo.val);\n" + 
5369
				"	}\n" + 
5370
				"	int field = Foo.val;\n" + 
5371
				"}\n"
5372
		},
5373
		"----------\n" + 
5374
		"1. ERROR in Foo.java (at line 5)\n" + 
5375
		"	this(Foo.val);\n" + 
5376
		"	         ^^^\n" + 
5377
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5378
		"----------\n" + 
5379
		"2. ERROR in Foo.java (at line 6)\n" + 
5380
		"	System.out.println(Foo.val);\n" + 
5381
		"	                       ^^^\n" + 
5382
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5383
		"----------\n" + 
5384
		"3. ERROR in Foo.java (at line 10)\n" + 
5385
		"	System.out.println(Foo.val);\n" + 
5386
		"	                       ^^^\n" + 
5387
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5388
		"----------\n" + 
5389
		"4. ERROR in Foo.java (at line 12)\n" + 
5390
		"	int field = Foo.val;\n" + 
5391
		"	                ^^^\n" + 
5392
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5393
		"----------\n");
5394
}
5395
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5396
public void test158() {
5397
	this.runNegativeTest(
5398
		new String[] {
5399
				"Foo.java",
5400
				"enum Foo {\n" + 
5401
				"	ONE, TWO, THREE;\n" + 
5402
				"	static int val = 10;\n" + 
5403
				"	Foo () {\n" + 
5404
				"		this(val);\n" +
5405
				"		System.out.println(val);\n" + 
5406
				"	}\n" + 
5407
				"	Foo(int i){}\n" +
5408
				"	{\n" + 
5409
				"		System.out.println(val);\n" + 
5410
				"	}\n" + 
5411
				"	int field = val;\n" + 
5412
				"}\n"
5413
		},
5414
		"----------\n" + 
5415
		"1. ERROR in Foo.java (at line 5)\n" + 
5416
		"	this(val);\n" + 
5417
		"	     ^^^\n" + 
5418
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5419
		"----------\n" + 
5420
		"2. ERROR in Foo.java (at line 6)\n" + 
5421
		"	System.out.println(val);\n" + 
5422
		"	                   ^^^\n" + 
5423
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5424
		"----------\n" + 
5425
		"3. ERROR in Foo.java (at line 10)\n" + 
5426
		"	System.out.println(val);\n" + 
5427
		"	                   ^^^\n" + 
5428
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5429
		"----------\n" + 
5430
		"4. ERROR in Foo.java (at line 12)\n" + 
5431
		"	int field = val;\n" + 
5432
		"	            ^^^\n" + 
5433
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5434
		"----------\n");
5435
}
5436
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5437
public void test159() {
5438
	this.runNegativeTest(
5439
		new String[] {
5440
				"Foo.java",
5441
				"enum Foo {\n" + 
5442
				"	ONE, TWO, THREE;\n" + 
5443
				"	static int val = 10;\n" + 
5444
				"	Foo () {\n" + 
5445
				"		this(get().val);\n" +
5446
				"		System.out.println(get().val);\n" + 
5447
				"	}\n" + 
5448
				"	Foo(int i){}\n" +
5449
				"	{\n" + 
5450
				"		System.out.println(get().val);\n" + 
5451
				"	}\n" + 
5452
				"	int field = get().val;\n" + 
5453
				"	Foo get() { return ONE; }\n" + 
5454
				"}\n"
5455
		},
5456
		"----------\n" + 
5457
		"1. ERROR in Foo.java (at line 5)\n" + 
5458
		"	this(get().val);\n" + 
5459
		"	     ^^^\n" + 
5460
		"Cannot refer to an instance method while explicitly invoking a constructor\n" + 
5461
		"----------\n" + 
5462
		"2. WARNING in Foo.java (at line 5)\n" + 
5463
		"	this(get().val);\n" + 
5464
		"	           ^^^\n" + 
5465
		"The static field Foo.val should be accessed in a static way\n" + 
5466
		"----------\n" + 
5467
		"3. ERROR in Foo.java (at line 5)\n" + 
5468
		"	this(get().val);\n" + 
5469
		"	           ^^^\n" + 
5470
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5471
		"----------\n" + 
5472
		"4. WARNING in Foo.java (at line 6)\n" + 
5473
		"	System.out.println(get().val);\n" + 
5474
		"	                         ^^^\n" + 
5475
		"The static field Foo.val should be accessed in a static way\n" + 
5476
		"----------\n" + 
5477
		"5. ERROR in Foo.java (at line 6)\n" + 
5478
		"	System.out.println(get().val);\n" + 
5479
		"	                         ^^^\n" + 
5480
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5481
		"----------\n" + 
5482
		"6. WARNING in Foo.java (at line 10)\n" + 
5483
		"	System.out.println(get().val);\n" + 
5484
		"	                         ^^^\n" + 
5485
		"The static field Foo.val should be accessed in a static way\n" + 
5486
		"----------\n" + 
5487
		"7. ERROR in Foo.java (at line 10)\n" + 
5488
		"	System.out.println(get().val);\n" + 
5489
		"	                         ^^^\n" + 
5490
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5491
		"----------\n" + 
5492
		"8. WARNING in Foo.java (at line 12)\n" + 
5493
		"	int field = get().val;\n" + 
5494
		"	                  ^^^\n" + 
5495
		"The static field Foo.val should be accessed in a static way\n" + 
5496
		"----------\n" + 
5497
		"9. ERROR in Foo.java (at line 12)\n" + 
5498
		"	int field = get().val;\n" + 
5499
		"	                  ^^^\n" + 
5500
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5501
		"----------\n");
5502
}
5503
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5504
public void test160() {
5505
	this.runNegativeTest(
5506
		new String[] {
5507
				"Foo.java",
5508
				"enum Foo {\n" + 
5509
				"	ONE, TWO, THREE;\n" + 
5510
				"	static int val = 10;\n" + 
5511
				"	Foo () {\n" + 
5512
				"		this(get().val = 1);\n" + 
5513
				"		System.out.println(get().val = 2);\n" + 
5514
				"	}\n" + 
5515
				"	Foo(int i){}\n" + 
5516
				"	{\n" + 
5517
				"		System.out.println(get().val = 3);\n" + 
5518
				"	}\n" + 
5519
				"	int field = get().val = 4;\n" + 
5520
				"	Foo get() { return ONE; }\n" + 
5521
				"}\n"
5522
		},
5523
		"----------\n" + 
5524
		"1. ERROR in Foo.java (at line 5)\n" + 
5525
		"	this(get().val = 1);\n" + 
5526
		"	     ^^^\n" + 
5527
		"Cannot refer to an instance method while explicitly invoking a constructor\n" + 
5528
		"----------\n" + 
5529
		"2. WARNING in Foo.java (at line 5)\n" + 
5530
		"	this(get().val = 1);\n" + 
5531
		"	           ^^^\n" + 
5532
		"The static field Foo.val should be accessed in a static way\n" + 
5533
		"----------\n" + 
5534
		"3. ERROR in Foo.java (at line 5)\n" + 
5535
		"	this(get().val = 1);\n" + 
5536
		"	           ^^^\n" + 
5537
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5538
		"----------\n" + 
5539
		"4. WARNING in Foo.java (at line 6)\n" + 
5540
		"	System.out.println(get().val = 2);\n" + 
5541
		"	                         ^^^\n" + 
5542
		"The static field Foo.val should be accessed in a static way\n" + 
5543
		"----------\n" + 
5544
		"5. ERROR in Foo.java (at line 6)\n" + 
5545
		"	System.out.println(get().val = 2);\n" + 
5546
		"	                         ^^^\n" + 
5547
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5548
		"----------\n" + 
5549
		"6. WARNING in Foo.java (at line 10)\n" + 
5550
		"	System.out.println(get().val = 3);\n" + 
5551
		"	                         ^^^\n" + 
5552
		"The static field Foo.val should be accessed in a static way\n" + 
5553
		"----------\n" + 
5554
		"7. ERROR in Foo.java (at line 10)\n" + 
5555
		"	System.out.println(get().val = 3);\n" + 
5556
		"	                         ^^^\n" + 
5557
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5558
		"----------\n" + 
5559
		"8. WARNING in Foo.java (at line 12)\n" + 
5560
		"	int field = get().val = 4;\n" + 
5561
		"	                  ^^^\n" + 
5562
		"The static field Foo.val should be accessed in a static way\n" + 
5563
		"----------\n" + 
5564
		"9. ERROR in Foo.java (at line 12)\n" + 
5565
		"	int field = get().val = 4;\n" + 
5566
		"	                  ^^^\n" + 
5567
		"Cannot refer to the static enum field Foo.val within an initializer\n" + 
5568
		"----------\n");
5569
}
5570
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=228109 - variation
5571
public void test161() {
5572
	this.runConformTest(
5573
		new String[] {
5574
				"EnumTest1.java",
5575
				"enum EnumTest1 {\n" + 
5576
				"	;\n" + 
5577
				"	static int foo = EnumTest2.bar;\n" + 
5578
				"}\n" + 
5579
				"enum EnumTest2 {\n" + 
5580
				"	;\n" + 
5581
				"	static int bar = EnumTest1.foo;\n" + 
5582
				"}\n"
5583
		},
5584
		"");
5585
}
5265
}
5586
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/FieldReference.java (-103 / +130 lines)
Lines 12-22 Link Here
12
12
13
import org.eclipse.jdt.core.compiler.CharOperation;
13
import org.eclipse.jdt.core.compiler.CharOperation;
14
import org.eclipse.jdt.internal.compiler.ASTVisitor;
14
import org.eclipse.jdt.internal.compiler.ASTVisitor;
15
import org.eclipse.jdt.internal.compiler.impl.*;
16
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
15
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
17
import org.eclipse.jdt.internal.compiler.codegen.*;
16
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
18
import org.eclipse.jdt.internal.compiler.flow.*;
17
import org.eclipse.jdt.internal.compiler.flow.FlowContext;
19
import org.eclipse.jdt.internal.compiler.lookup.*;
18
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
19
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
20
import org.eclipse.jdt.internal.compiler.impl.Constant;
21
import org.eclipse.jdt.internal.compiler.lookup.Binding;
22
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
23
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
24
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
25
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
26
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
27
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
28
import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
29
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
30
import org.eclipse.jdt.internal.compiler.lookup.Scope;
31
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
32
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
33
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
34
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
20
35
21
public class FieldReference extends Reference implements InvocationSite {
36
public class FieldReference extends Reference implements InvocationSite {
22
37
Lines 33-62 Link Here
33
	public TypeBinding genericCast;
48
	public TypeBinding genericCast;
34
	
49
	
35
public FieldReference(char[] source, long pos) {
50
public FieldReference(char[] source, long pos) {
36
	token = source;
51
	this.token = source;
37
	nameSourcePosition = pos;
52
	this.nameSourcePosition = pos;
38
	//by default the position are the one of the field (not true for super access)
53
	//by default the position are the one of the field (not true for super access)
39
	sourceStart = (int) (pos >>> 32);
54
	this.sourceStart = (int) (pos >>> 32);
40
	sourceEnd = (int) (pos & 0x00000000FFFFFFFFL);
55
	this.sourceEnd = (int) (pos & 0x00000000FFFFFFFFL);
41
	bits |= Binding.FIELD;
56
	this.bits |= Binding.FIELD;
42
57
43
}
58
}
44
59
45
public FlowInfo analyseAssignment(BlockScope currentScope, 	FlowContext flowContext, 	FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
60
public FlowInfo analyseAssignment(BlockScope currentScope, 	FlowContext flowContext, 	FlowInfo flowInfo, Assignment assignment, boolean isCompound) {
46
	// compound assignment extra work
61
	// compound assignment extra work
47
	if (isCompound) { // check the variable part is initialized if blank final
62
	if (isCompound) { // check the variable part is initialized if blank final
48
		if (binding.isBlankFinal()
63
		if (this.binding.isBlankFinal()
49
			&& receiver.isThis()
64
			&& this.receiver.isThis()
50
			&& currentScope.needBlankFinalFieldInitializationCheck(binding)
65
			&& currentScope.needBlankFinalFieldInitializationCheck(this.binding)
51
			&& (!flowInfo.isDefinitelyAssigned(binding))) {
66
			&& (!flowInfo.isDefinitelyAssigned(this.binding))) {
52
			currentScope.problemReporter().uninitializedBlankFinalField(binding, this);
67
			currentScope.problemReporter().uninitializedBlankFinalField(this.binding, this);
53
			// we could improve error msg here telling "cannot use compound assignment on final blank field"
68
			// we could improve error msg here telling "cannot use compound assignment on final blank field"
54
		}
69
		}
55
		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
70
		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
56
	}
71
	}
57
	flowInfo =
72
	flowInfo =
58
		receiver
73
		this.receiver
59
			.analyseCode(currentScope, flowContext, flowInfo, !binding.isStatic())
74
			.analyseCode(currentScope, flowContext, flowInfo, !this.binding.isStatic())
60
			.unconditionalInits();
75
			.unconditionalInits();
61
	if (assignment.expression != null) {
76
	if (assignment.expression != null) {
62
		flowInfo =
77
		flowInfo =
Lines 68-92 Link Here
68
	manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);
83
	manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);
69
84
70
	// check if assigning a final field 
85
	// check if assigning a final field 
71
	if (binding.isFinal()) {
86
	if (this.binding.isFinal()) {
72
		// in a context where it can be assigned?
87
		// in a context where it can be assigned?
73
		if (binding.isBlankFinal()
88
		if (this.binding.isBlankFinal()
74
			&& !isCompound
89
			&& !isCompound
75
			&& receiver.isThis()
90
			&& this.receiver.isThis()
76
			&& !(receiver instanceof QualifiedThisReference)
91
			&& !(this.receiver instanceof QualifiedThisReference)
77
			&& ((receiver.bits & ParenthesizedMASK) == 0) // (this).x is forbidden
92
			&& ((this.receiver.bits & ASTNode.ParenthesizedMASK) == 0) // (this).x is forbidden
78
			&& currentScope.allowBlankFinalFieldAssignment(binding)) {
93
			&& currentScope.allowBlankFinalFieldAssignment(this.binding)) {
79
			if (flowInfo.isPotentiallyAssigned(binding)) {
94
			if (flowInfo.isPotentiallyAssigned(this.binding)) {
80
				currentScope.problemReporter().duplicateInitializationOfBlankFinalField(
95
				currentScope.problemReporter().duplicateInitializationOfBlankFinalField(
81
					binding,
96
					this.binding,
82
					this);
97
					this);
83
			} else {
98
			} else {
84
				flowContext.recordSettingFinal(binding, this, flowInfo);
99
				flowContext.recordSettingFinal(this.binding, this, flowInfo);
85
			}
100
			}
86
			flowInfo.markAsDefinitelyAssigned(binding);
101
			flowInfo.markAsDefinitelyAssigned(this.binding);
87
		} else {
102
		} else {
88
			// assigning a final field outside an initializer or constructor or wrong reference
103
			// assigning a final field outside an initializer or constructor or wrong reference
89
			currentScope.problemReporter().cannotAssignToFinalField(binding, this);
104
			currentScope.problemReporter().cannotAssignToFinalField(this.binding, this);
90
		}
105
		}
91
	}
106
	}
92
	return flowInfo;
107
	return flowInfo;
Lines 97-106 Link Here
97
}
112
}
98
113
99
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
114
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
100
	boolean nonStatic = !binding.isStatic();
115
	boolean nonStatic = !this.binding.isStatic();
101
	receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic);
116
	this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic);
102
	if (nonStatic) {
117
	if (nonStatic) {
103
		receiver.checkNPE(currentScope, flowContext, flowInfo);
118
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
104
	}
119
	}
105
	
120
	
106
	if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
121
	if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
Lines 122-128 Link Here
122
	    // extra cast needed if method return type is type variable
137
	    // extra cast needed if method return type is type variable
123
		if (originalBinding != this.binding 
138
		if (originalBinding != this.binding 
124
				&& originalType != this.binding.type
139
				&& originalType != this.binding.type
125
				&& runtimeTimeType.id != T_JavaLangObject
140
				&& runtimeTimeType.id != TypeIds.T_JavaLangObject
126
				&& (originalType.tagBits & TagBits.HasTypeVariable) != 0) {
141
				&& (originalType.tagBits & TagBits.HasTypeVariable) != 0) {
127
	    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType()) 
142
	    	TypeBinding targetType = (!compileTimeType.isBaseType() && runtimeTimeType.isBaseType()) 
128
	    		? compileTimeType  // unboxing: checkcast before conversion
143
	    		? compileTimeType  // unboxing: checkcast before conversion
Lines 144-155 Link Here
144
}
159
}
145
160
146
public FieldBinding fieldBinding() {
161
public FieldBinding fieldBinding() {
147
	return binding;
162
	return this.binding;
148
}
163
}
149
164
150
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
165
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
151
	int pc = codeStream.position;
166
	int pc = codeStream.position;
152
	receiver.generateCode(
167
	this.receiver.generateCode(
153
		currentScope,
168
		currentScope,
154
		codeStream,
169
		codeStream,
155
		!this.codegenBinding.isStatic());
170
		!this.codegenBinding.isStatic());
Lines 158-164 Link Here
158
	fieldStore(
173
	fieldStore(
159
		codeStream,
174
		codeStream,
160
		this.codegenBinding,
175
		this.codegenBinding,
161
		syntheticAccessors == null ? null : syntheticAccessors[WRITE],
176
		this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE],
162
		valueRequired);
177
		valueRequired);
163
	if (valueRequired) {
178
	if (valueRequired) {
164
		codeStream.generateImplicitConversion(assignment.implicitConversion);
179
		codeStream.generateImplicitConversion(assignment.implicitConversion);
Lines 175-183 Link Here
175
 */
190
 */
176
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
191
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
177
	int pc = codeStream.position;
192
	int pc = codeStream.position;
178
	if (constant != Constant.NotAConstant) {
193
	if (this.constant != Constant.NotAConstant) {
179
		if (valueRequired) {
194
		if (valueRequired) {
180
			codeStream.generateConstant(constant, implicitConversion);
195
			codeStream.generateConstant(this.constant, this.implicitConversion);
181
		}
196
		}
182
		codeStream.recordPositionsFrom(pc, this.sourceStart);
197
		codeStream.recordPositionsFrom(pc, this.sourceStart);
183
		return;
198
		return;
Lines 187-236 Link Here
187
	Constant fieldConstant = this.codegenBinding.constant();
202
	Constant fieldConstant = this.codegenBinding.constant();
188
	if (fieldConstant != Constant.NotAConstant) {
203
	if (fieldConstant != Constant.NotAConstant) {
189
		if (!isThisReceiver) {
204
		if (!isThisReceiver) {
190
			receiver.generateCode(currentScope, codeStream, !isStatic);
205
			this.receiver.generateCode(currentScope, codeStream, !isStatic);
191
			if (!isStatic){
206
			if (!isStatic){
192
				codeStream.invokeObjectGetClass();
207
				codeStream.invokeObjectGetClass();
193
				codeStream.pop();
208
				codeStream.pop();
194
			}
209
			}
195
		}
210
		}
196
		if (valueRequired) {
211
		if (valueRequired) {
197
			codeStream.generateConstant(fieldConstant, implicitConversion);
212
			codeStream.generateConstant(fieldConstant, this.implicitConversion);
198
		}
213
		}
199
		codeStream.recordPositionsFrom(pc, this.sourceStart);
214
		codeStream.recordPositionsFrom(pc, this.sourceStart);
200
		return;
215
		return;
201
	}
216
	}
202
	if (valueRequired 
217
	if (valueRequired 
203
			|| (!isThisReceiver && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
218
			|| (!isThisReceiver && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
204
			|| ((implicitConversion & TypeIds.UNBOXING) != 0)
219
			|| ((this.implicitConversion & TypeIds.UNBOXING) != 0)
205
			|| (this.genericCast != null)) {
220
			|| (this.genericCast != null)) {
206
		receiver.generateCode(currentScope, codeStream, !isStatic);
221
		this.receiver.generateCode(currentScope, codeStream, !isStatic);
207
		pc = codeStream.position;
222
		pc = codeStream.position;
208
		if (this.codegenBinding.declaringClass == null) { // array length
223
		if (this.codegenBinding.declaringClass == null) { // array length
209
			codeStream.arraylength();
224
			codeStream.arraylength();
210
			if (valueRequired) {
225
			if (valueRequired) {
211
				codeStream.generateImplicitConversion(implicitConversion);
226
				codeStream.generateImplicitConversion(this.implicitConversion);
212
			} else {
227
			} else {
213
				// could occur if !valueRequired but compliance >= 1.4
228
				// could occur if !valueRequired but compliance >= 1.4
214
				codeStream.pop();
229
				codeStream.pop();
215
			}
230
			}
216
		} else {
231
		} else {
217
			if (syntheticAccessors == null || syntheticAccessors[READ] == null) {
232
			if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
218
				if (isStatic) {
233
				if (isStatic) {
219
					codeStream.getstatic(this.codegenBinding);
234
					codeStream.getstatic(this.codegenBinding);
220
				} else {
235
				} else {
221
					codeStream.getfield(this.codegenBinding);
236
					codeStream.getfield(this.codegenBinding);
222
				}
237
				}
223
			} else {
238
			} else {
224
				codeStream.invokestatic(syntheticAccessors[READ]);
239
				codeStream.invokestatic(this.syntheticAccessors[FieldReference.READ]);
225
			}
240
			}
226
			// required cast must occur even if no value is required
241
			// required cast must occur even if no value is required
227
			if (this.genericCast != null) codeStream.checkcast(this.genericCast);
242
			if (this.genericCast != null) codeStream.checkcast(this.genericCast);
228
			if (valueRequired) {
243
			if (valueRequired) {
229
				codeStream.generateImplicitConversion(implicitConversion);
244
				codeStream.generateImplicitConversion(this.implicitConversion);
230
			} else {
245
			} else {
231
				boolean isUnboxing = (implicitConversion & TypeIds.UNBOXING) != 0;
246
				boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
232
				// conversion only generated if unboxing
247
				// conversion only generated if unboxing
233
				if (isUnboxing) codeStream.generateImplicitConversion(implicitConversion);
248
				if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
234
				switch (isUnboxing ? postConversionType(currentScope).id : this.codegenBinding.type.id) {
249
				switch (isUnboxing ? postConversionType(currentScope).id : this.codegenBinding.type.id) {
235
					case T_long :
250
					case T_long :
236
					case T_double :
251
					case T_double :
Lines 246-252 Link Here
246
			if (isStatic){
261
			if (isStatic){
247
				// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
262
				// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
248
				if (this.binding.original().declaringClass != this.receiverType.erasure()) {
263
				if (this.binding.original().declaringClass != this.receiverType.erasure()) {
249
					MethodBinding accessor = syntheticAccessors == null ? null : syntheticAccessors[READ]; 
264
					MethodBinding accessor = this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.READ]; 
250
					if (accessor == null) {
265
					if (accessor == null) {
251
						codeStream.getstatic(this.codegenBinding);
266
						codeStream.getstatic(this.codegenBinding);
252
					} else {
267
					} else {
Lines 263-269 Link Here
263
				}
278
				}
264
			}
279
			}
265
		} else {
280
		} else {
266
			receiver.generateCode(currentScope, codeStream, !isStatic);				
281
			this.receiver.generateCode(currentScope, codeStream, !isStatic);				
267
			if (!isStatic){
282
			if (!isStatic){
268
				codeStream.invokeObjectGetClass(); // perform null check
283
				codeStream.invokeObjectGetClass(); // perform null check
269
				codeStream.pop();
284
				codeStream.pop();
Lines 275-300 Link Here
275
290
276
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
291
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
277
	boolean isStatic;
292
	boolean isStatic;
278
	receiver.generateCode(
293
	this.receiver.generateCode(
279
		currentScope,
294
		currentScope,
280
		codeStream,
295
		codeStream,
281
		!(isStatic = this.codegenBinding.isStatic()));
296
		!(isStatic = this.codegenBinding.isStatic()));
282
	if (isStatic) {
297
	if (isStatic) {
283
		if (syntheticAccessors == null || syntheticAccessors[READ] == null) {
298
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
284
			codeStream.getstatic(this.codegenBinding);
299
			codeStream.getstatic(this.codegenBinding);
285
		} else {
300
		} else {
286
			codeStream.invokestatic(syntheticAccessors[READ]);
301
			codeStream.invokestatic(this.syntheticAccessors[FieldReference.READ]);
287
		}
302
		}
288
	} else {
303
	} else {
289
		codeStream.dup();
304
		codeStream.dup();
290
		if (syntheticAccessors == null || syntheticAccessors[READ] == null) {
305
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
291
			codeStream.getfield(this.codegenBinding);
306
			codeStream.getfield(this.codegenBinding);
292
		} else {
307
		} else {
293
			codeStream.invokestatic(syntheticAccessors[READ]);
308
			codeStream.invokestatic(this.syntheticAccessors[FieldReference.READ]);
294
		}
309
		}
295
	}
310
	}
296
	int operationTypeID;
311
	int operationTypeID;
297
	switch(operationTypeID = (implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) {
312
	switch(operationTypeID = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) {
298
		case T_JavaLangString :
313
		case T_JavaLangString :
299
		case T_JavaLangObject :
314
		case T_JavaLangObject :
300
		case T_undefined :
315
		case T_undefined :
Lines 304-313 Link Here
304
			if (this.genericCast != null)
319
			if (this.genericCast != null)
305
				codeStream.checkcast(this.genericCast);				
320
				codeStream.checkcast(this.genericCast);				
306
			// promote the array reference to the suitable operation type
321
			// promote the array reference to the suitable operation type
307
			codeStream.generateImplicitConversion(implicitConversion);
322
			codeStream.generateImplicitConversion(this.implicitConversion);
308
			// generate the increment value (will by itself  be promoted to the operation value)
323
			// generate the increment value (will by itself  be promoted to the operation value)
309
			if (expression == IntLiteral.One) { // prefix operation
324
			if (expression == IntLiteral.One) { // prefix operation
310
				codeStream.generateConstant(expression.constant, implicitConversion);
325
				codeStream.generateConstant(expression.constant, this.implicitConversion);
311
			} else {
326
			} else {
312
				expression.generateCode(currentScope, codeStream, true);
327
				expression.generateCode(currentScope, codeStream, true);
313
			}
328
			}
Lines 319-347 Link Here
319
	fieldStore(
334
	fieldStore(
320
		codeStream,
335
		codeStream,
321
		this.codegenBinding,
336
		this.codegenBinding,
322
		syntheticAccessors == null ? null : syntheticAccessors[WRITE],
337
		this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE],
323
		valueRequired);
338
		valueRequired);
324
	// no need for generic cast as value got dupped
339
	// no need for generic cast as value got dupped
325
}
340
}
326
341
327
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
342
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
328
	boolean isStatic;
343
	boolean isStatic;
329
	receiver.generateCode(
344
	this.receiver.generateCode(
330
		currentScope,
345
		currentScope,
331
		codeStream,
346
		codeStream,
332
		!(isStatic = this.codegenBinding.isStatic()));
347
		!(isStatic = this.codegenBinding.isStatic()));
333
	if (isStatic) {
348
	if (isStatic) {
334
		if (syntheticAccessors == null || syntheticAccessors[READ] == null) {
349
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
335
			codeStream.getstatic(this.codegenBinding);
350
			codeStream.getstatic(this.codegenBinding);
336
		} else {
351
		} else {
337
			codeStream.invokestatic(syntheticAccessors[READ]);
352
			codeStream.invokestatic(this.syntheticAccessors[FieldReference.READ]);
338
		}
353
		}
339
	} else {
354
	} else {
340
		codeStream.dup();
355
		codeStream.dup();
341
		if (syntheticAccessors == null || syntheticAccessors[READ] == null) {
356
		if (this.syntheticAccessors == null || this.syntheticAccessors[FieldReference.READ] == null) {
342
			codeStream.getfield(this.codegenBinding);
357
			codeStream.getfield(this.codegenBinding);
343
		} else {
358
		} else {
344
			codeStream.invokestatic(syntheticAccessors[READ]);
359
			codeStream.invokestatic(this.syntheticAccessors[FieldReference.READ]);
345
		}
360
		}
346
	}
361
	}
347
	if (valueRequired) {
362
	if (valueRequired) {
Lines 367-376 Link Here
367
	codeStream.generateConstant(
382
	codeStream.generateConstant(
368
		postIncrement.expression.constant,
383
		postIncrement.expression.constant,
369
		this.implicitConversion);
384
		this.implicitConversion);
370
	codeStream.sendOperator(postIncrement.operator, this.implicitConversion & COMPILE_TYPE_MASK);
385
	codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK);
371
	codeStream.generateImplicitConversion(
386
	codeStream.generateImplicitConversion(
372
		postIncrement.preAssignImplicitConversion);
387
		postIncrement.preAssignImplicitConversion);
373
	fieldStore(codeStream, this.codegenBinding, syntheticAccessors == null ? null : syntheticAccessors[WRITE], false);
388
	fieldStore(codeStream, this.codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[FieldReference.WRITE], false);
374
}	
389
}	
375
390
376
/**
391
/**
Lines 380-390 Link Here
380
	return null;
395
	return null;
381
}
396
}
382
public boolean isSuperAccess() {
397
public boolean isSuperAccess() {
383
	return receiver.isSuper();
398
	return this.receiver.isSuper();
384
}
399
}
385
400
386
public boolean isTypeAccess() {
401
public boolean isTypeAccess() {
387
	return receiver != null && receiver.isTypeReference();
402
	return this.receiver != null && this.receiver.isTypeReference();
388
}
403
}
389
404
390
/*
405
/*
Lines 396-437 Link Here
396
	// if field from parameterized type got found, use the original field at codegen time
411
	// if field from parameterized type got found, use the original field at codegen time
397
	this.codegenBinding = this.binding.original();
412
	this.codegenBinding = this.binding.original();
398
	
413
	
399
	if (binding.isPrivate()) {
414
	if (this.binding.isPrivate()) {
400
		if ((currentScope.enclosingSourceType() != this.codegenBinding.declaringClass) 
415
		if ((currentScope.enclosingSourceType() != this.codegenBinding.declaringClass) 
401
				&& binding.constant() == Constant.NotAConstant) {
416
				&& this.binding.constant() == Constant.NotAConstant) {
402
			if (syntheticAccessors == null)
417
			if (this.syntheticAccessors == null)
403
				syntheticAccessors = new MethodBinding[2];
418
				this.syntheticAccessors = new MethodBinding[2];
404
			syntheticAccessors[isReadAccess ? READ : WRITE] = 
419
			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = 
405
				((SourceTypeBinding) this.codegenBinding.declaringClass).addSyntheticMethod(this.codegenBinding, isReadAccess);
420
				((SourceTypeBinding) this.codegenBinding.declaringClass).addSyntheticMethod(this.codegenBinding, isReadAccess);
406
			currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
421
			currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
407
			return;
422
			return;
408
		}
423
		}
409
424
410
	} else if (receiver instanceof QualifiedSuperReference) { // qualified super
425
	} else if (this.receiver instanceof QualifiedSuperReference) { // qualified super
411
426
412
		// qualified super need emulation always
427
		// qualified super need emulation always
413
		SourceTypeBinding destinationType =
428
		SourceTypeBinding destinationType =
414
			(SourceTypeBinding) (((QualifiedSuperReference) receiver)
429
			(SourceTypeBinding) (((QualifiedSuperReference) this.receiver)
415
				.currentCompatibleType);
430
				.currentCompatibleType);
416
		if (syntheticAccessors == null)
431
		if (this.syntheticAccessors == null)
417
			syntheticAccessors = new MethodBinding[2];
432
			this.syntheticAccessors = new MethodBinding[2];
418
		syntheticAccessors[isReadAccess ? READ : WRITE] = destinationType.addSyntheticMethod(this.codegenBinding, isReadAccess);
433
		this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = destinationType.addSyntheticMethod(this.codegenBinding, isReadAccess);
419
		currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
434
		currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
420
		return;
435
		return;
421
436
422
	} else if (binding.isProtected()) {
437
	} else if (this.binding.isProtected()) {
423
438
424
		SourceTypeBinding enclosingSourceType;
439
		SourceTypeBinding enclosingSourceType;
425
		if (((bits & DepthMASK) != 0)
440
		if (((this.bits & ASTNode.DepthMASK) != 0)
426
			&& binding.declaringClass.getPackage()
441
			&& this.binding.declaringClass.getPackage()
427
				!= (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()) {
442
				!= (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()) {
428
443
429
			SourceTypeBinding currentCompatibleType =
444
			SourceTypeBinding currentCompatibleType =
430
				(SourceTypeBinding) enclosingSourceType.enclosingTypeAt(
445
				(SourceTypeBinding) enclosingSourceType.enclosingTypeAt(
431
					(bits & DepthMASK) >> DepthSHIFT);
446
					(this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
432
			if (syntheticAccessors == null)
447
			if (this.syntheticAccessors == null)
433
				syntheticAccessors = new MethodBinding[2];
448
				this.syntheticAccessors = new MethodBinding[2];
434
			syntheticAccessors[isReadAccess ? READ : WRITE] = currentCompatibleType.addSyntheticMethod(this.codegenBinding, isReadAccess);
449
			this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] = currentCompatibleType.addSyntheticMethod(this.codegenBinding, isReadAccess);
435
			currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
450
			currentScope.problemReporter().needToEmulateFieldAccess(this.codegenBinding, this, isReadAccess);
436
			return;
451
			return;
437
		}
452
		}
Lines 446-453 Link Here
446
			&& this.binding.constant() == Constant.NotAConstant) {
461
			&& this.binding.constant() == Constant.NotAConstant) {
447
		CompilerOptions options = currentScope.compilerOptions();
462
		CompilerOptions options = currentScope.compilerOptions();
448
		if ((options.targetJDK >= ClassFileConstants.JDK1_2
463
		if ((options.targetJDK >= ClassFileConstants.JDK1_2
449
				&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(receiver.isImplicitThis() && this.codegenBinding.isStatic()))
464
				&& (options.complianceLevel >= ClassFileConstants.JDK1_4 || !(this.receiver.isImplicitThis() && this.codegenBinding.isStatic()))
450
				&& this.binding.declaringClass.id != T_JavaLangObject) // no change for Object fields
465
				&& this.binding.declaringClass.id != TypeIds.T_JavaLangObject) // no change for Object fields
451
			|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
466
			|| !this.binding.declaringClass.canBeSeenBy(currentScope)) {
452
467
453
			this.codegenBinding =
468
			this.codegenBinding =
Lines 479-485 Link Here
479
	TypeBinding convertedType = this.resolvedType;
494
	TypeBinding convertedType = this.resolvedType;
480
	if (this.genericCast != null) 
495
	if (this.genericCast != null) 
481
		convertedType = this.genericCast;
496
		convertedType = this.genericCast;
482
	int runtimeType = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4;
497
	int runtimeType = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4;
483
	switch (runtimeType) {
498
	switch (runtimeType) {
484
		case T_boolean :
499
		case T_boolean :
485
			convertedType = TypeBinding.BOOLEAN;
500
			convertedType = TypeBinding.BOOLEAN;
Lines 507-520 Link Here
507
			break;
522
			break;
508
		default :
523
		default :
509
	}		
524
	}		
510
	if ((this.implicitConversion & BOXING) != 0) {
525
	if ((this.implicitConversion & TypeIds.BOXING) != 0) {
511
		convertedType = scope.environment().computeBoxingType(convertedType);
526
		convertedType = scope.environment().computeBoxingType(convertedType);
512
	}
527
	}
513
	return convertedType;
528
	return convertedType;
514
}
529
}
515
530
516
public StringBuffer printExpression(int indent, StringBuffer output) {
531
public StringBuffer printExpression(int indent, StringBuffer output) {
517
	return receiver.printExpression(0, output).append('.').append(token);
532
	return this.receiver.printExpression(0, output).append('.').append(this.token);
518
}
533
}
519
534
520
public TypeBinding resolveType(BlockScope scope) {
535
public TypeBinding resolveType(BlockScope scope) {
Lines 525-536 Link Here
525
	//always ignore receiver cast, since may affect constant pool reference
540
	//always ignore receiver cast, since may affect constant pool reference
526
	boolean receiverCast = false;
541
	boolean receiverCast = false;
527
	if (this.receiver instanceof CastExpression) {
542
	if (this.receiver instanceof CastExpression) {
528
		this.receiver.bits |= DisableUnnecessaryCastCheck; // will check later on
543
		this.receiver.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on
529
		receiverCast = true;
544
		receiverCast = true;
530
	}
545
	}
531
	this.receiverType = this.receiver.resolveType(scope);
546
	this.receiverType = this.receiver.resolveType(scope);
532
	if (this.receiverType == null) {
547
	if (this.receiverType == null) {
533
		constant = Constant.NotAConstant;
548
		this.constant = Constant.NotAConstant;
534
		return null;
549
		return null;
535
	}
550
	}
536
	if (receiverCast) {
551
	if (receiverCast) {
Lines 540-548 Link Here
540
		}
555
		}
541
	}		
556
	}		
542
	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
557
	// the case receiverType.isArrayType and token = 'length' is handled by the scope API
543
	FieldBinding fieldBinding = this.codegenBinding = this.binding = scope.getField(this.receiverType, token, this);
558
	FieldBinding fieldBinding = this.codegenBinding = this.binding = scope.getField(this.receiverType, this.token, this);
544
	if (!fieldBinding.isValidBinding()) {
559
	if (!fieldBinding.isValidBinding()) {
545
		constant = Constant.NotAConstant;
560
		this.constant = Constant.NotAConstant;
546
		if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
561
		if (this.receiver.resolvedType instanceof ProblemReferenceBinding) {
547
			// problem already got signaled on receiver, do not report secondary problem
562
			// problem already got signaled on receiver, do not report secondary problem
548
			return null;
563
			return null;
Lines 557-583 Link Here
557
		}
572
		}
558
	}
573
	}
559
	this.receiver.computeConversion(scope, this.receiverType, this.receiverType);
574
	this.receiver.computeConversion(scope, this.receiverType, this.receiverType);
560
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & IsStrictlyAssigned) !=0)) {
575
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) !=0)) {
561
		scope.problemReporter().deprecatedField(fieldBinding, this);
576
		scope.problemReporter().deprecatedField(fieldBinding, this);
562
	}
577
	}
563
	boolean isImplicitThisRcv = receiver.isImplicitThis();
578
	boolean isImplicitThisRcv = this.receiver.isImplicitThis();
564
	constant = isImplicitThisRcv ? fieldBinding.constant() : Constant.NotAConstant;
579
	this.constant = isImplicitThisRcv ? fieldBinding.constant() : Constant.NotAConstant;
565
	if (fieldBinding.isStatic()) {
580
	if (fieldBinding.isStatic()) {
566
		// static field accessed through receiver? legal but unoptimal (optional warning)
581
		// static field accessed through receiver? legal but unoptimal (optional warning)
567
		if (!(isImplicitThisRcv
582
		if (!(isImplicitThisRcv
568
				|| (receiver instanceof NameReference 
583
				|| (this.receiver instanceof NameReference 
569
					&& (((NameReference) receiver).bits & Binding.TYPE) != 0))) {
584
					&& (((NameReference) this.receiver).bits & Binding.TYPE) != 0))) {
570
			scope.problemReporter().nonStaticAccessToStaticField(this, fieldBinding);
585
			scope.problemReporter().nonStaticAccessToStaticField(this, fieldBinding);
571
		}
586
		}
587
		ReferenceBinding declaringClass = this.binding.declaringClass;
572
		if (!isImplicitThisRcv
588
		if (!isImplicitThisRcv
573
				&& fieldBinding.declaringClass != receiverType
589
				&& declaringClass != this.receiverType
574
				&& fieldBinding.declaringClass.canBeSeenBy(scope)) {
590
				&& declaringClass.canBeSeenBy(scope)) {
575
			scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
591
			scope.problemReporter().indirectAccessToStaticField(this, fieldBinding);
576
		}
592
		}
593
		// check if accessing enum static field in initializer
594
		if (declaringClass.isEnum()) {
595
			MethodScope methodScope = scope.methodScope();
596
			SourceTypeBinding sourceType = scope.enclosingSourceType();
597
			if (this.constant == Constant.NotAConstant
598
					&& !methodScope.isStatic
599
					&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
600
					&& methodScope.isInsideInitializerOrConstructor()) {
601
				scope.problemReporter().enumStaticFieldUsedDuringInitialization(this.binding, this);
602
			}
603
		}		
577
	}
604
	}
578
	TypeBinding fieldType = fieldBinding.type;
605
	TypeBinding fieldType = fieldBinding.type;
579
	if (fieldType != null) {
606
	if (fieldType != null) {
580
		if ((this.bits & IsStrictlyAssigned) == 0) {
607
		if ((this.bits & ASTNode.IsStrictlyAssigned) == 0) {
581
			fieldType = fieldType.capture(scope, this.sourceEnd);	// perform capture conversion if read access
608
			fieldType = fieldType.capture(scope, this.sourceEnd);	// perform capture conversion if read access
582
		}
609
		}
583
		this.resolvedType = fieldType;
610
		this.resolvedType = fieldType;
Lines 594-602 Link Here
594
}
621
}
595
622
596
public void setDepth(int depth) {
623
public void setDepth(int depth) {
597
	bits &= ~DepthMASK; // flush previous depth if any			
624
	this.bits &= ~ASTNode.DepthMASK; // flush previous depth if any			
598
	if (depth > 0) {
625
	if (depth > 0) {
599
		bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits
626
		this.bits |= (depth & 0xFF) << ASTNode.DepthSHIFT; // encoded on 8 bits
600
	}
627
	}
601
}
628
}
602
629
Lines 606-612 Link Here
606
633
607
public void traverse(ASTVisitor visitor, BlockScope scope) {
634
public void traverse(ASTVisitor visitor, BlockScope scope) {
608
	if (visitor.visit(this, scope)) {
635
	if (visitor.visit(this, scope)) {
609
		receiver.traverse(visitor, scope);
636
		this.receiver.traverse(visitor, scope);
610
	}
637
	}
611
	visitor.endVisit(this, scope);
638
	visitor.endVisit(this, scope);
612
}
639
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (-36 / +19 lines)
Lines 89-109 Link Here
89
		case Binding.FIELD : // assigning to a field
89
		case Binding.FIELD : // assigning to a field
90
			manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);
90
			manageSyntheticAccessIfNecessary(currentScope, flowInfo, false /*write-access*/);
91
91
92
			FieldBinding fieldBinding = (FieldBinding) this.binding;
93
			ReferenceBinding declaringClass = fieldBinding.declaringClass;
94
			// check if accessing enum static field in initializer
95
			if (declaringClass.isEnum()) {
96
				MethodScope methodScope = currentScope.methodScope();
97
				SourceTypeBinding sourceType = currentScope.enclosingSourceType();
98
				if (fieldBinding.isStatic()
99
						&& this.constant == Constant.NotAConstant
100
						&& !methodScope.isStatic
101
						&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
102
						&& methodScope.isInsideInitializerOrConstructor()) {
103
					currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
104
				}
105
			}					
106
			// check if assigning a final field
92
			// check if assigning a final field
93
			FieldBinding fieldBinding = (FieldBinding) this.binding;
107
			if (fieldBinding.isFinal()) {
94
			if (fieldBinding.isFinal()) {
108
				// inside a context where allowed
95
				// inside a context where allowed
109
				if (!isCompound && fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
96
				if (!isCompound && fieldBinding.isBlankFinal() && currentScope.allowBlankFinalFieldAssignment(fieldBinding)) {
Lines 158-178 Link Here
158
			if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
145
			if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
159
				manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
146
				manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
160
			}
147
			}
161
			FieldBinding fieldBinding = (FieldBinding) this.binding;
162
			ReferenceBinding declaringClass = fieldBinding.declaringClass;
163
			// check if accessing enum static field in initializer
164
			if (declaringClass.isEnum()) {
165
				MethodScope methodScope = currentScope.methodScope();
166
				SourceTypeBinding sourceType = currentScope.enclosingSourceType();
167
				if (fieldBinding.isStatic()
168
						&& this.constant == Constant.NotAConstant
169
						&& !methodScope.isStatic
170
						&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
171
						&& methodScope.isInsideInitializerOrConstructor()) {
172
					currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
173
				}
174
			}				
175
			// check if reading a final blank field
148
			// check if reading a final blank field
149
			FieldBinding fieldBinding = (FieldBinding) this.binding;
176
			if (fieldBinding.isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
150
			if (fieldBinding.isBlankFinal() && currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
177
				if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
151
				if (!flowInfo.isDefinitelyAssigned(fieldBinding)) {
178
					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
152
					currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
Lines 198-217 Link Here
198
172
199
public TypeBinding checkFieldAccess(BlockScope scope) {
173
public TypeBinding checkFieldAccess(BlockScope scope) {
200
	FieldBinding fieldBinding = (FieldBinding) this.binding;
174
	FieldBinding fieldBinding = (FieldBinding) this.binding;
175
	this.constant = fieldBinding.constant();
201
	
176
	
202
	this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
177
	this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
203
	this.bits |= Binding.FIELD;
178
	this.bits |= Binding.FIELD;
204
	MethodScope methodScope = scope.methodScope();
179
	MethodScope methodScope = scope.methodScope();
205
	boolean isStatic = fieldBinding.isStatic();
180
	if (fieldBinding.isStatic()) {
206
	if (!isStatic) {
181
		// check if accessing enum static field in initializer
182
		ReferenceBinding declaringClass = fieldBinding.declaringClass;
183
		if (declaringClass.isEnum()) {
184
			SourceTypeBinding sourceType = scope.enclosingSourceType();
185
			if (this.constant == Constant.NotAConstant
186
					&& !methodScope.isStatic
187
					&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
188
					&& methodScope.isInsideInitializerOrConstructor()) {
189
				scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
190
			}
191
		}		
192
	} else {
193
		if (scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
194
			scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding);
195
		}		
207
		// must check for the static status....
196
		// must check for the static status....
208
		if (methodScope.isStatic) {
197
		if (methodScope.isStatic) {
209
			scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding);
198
			scope.problemReporter().staticFieldAccessToNonStaticVariable(this, fieldBinding);
210
			this.constant = Constant.NotAConstant;
211
			return fieldBinding.type;
199
			return fieldBinding.type;
212
		}
200
		}
213
	}
201
	}
214
	this.constant = fieldBinding.constant();
215
202
216
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) !=0))
203
	if (isFieldUseDeprecated(fieldBinding, scope, (this.bits & ASTNode.IsStrictlyAssigned) !=0))
217
		scope.problemReporter().deprecatedField(fieldBinding, this);
204
		scope.problemReporter().deprecatedField(fieldBinding, this);
Lines 858-867 Link Here
858
						this.constant = (this.bits & ASTNode.IsStrictlyAssigned) == 0 ? variable.constant() : Constant.NotAConstant;
845
						this.constant = (this.bits & ASTNode.IsStrictlyAssigned) == 0 ? variable.constant() : Constant.NotAConstant;
859
					} else {
846
					} else {
860
						// a field
847
						// a field
861
						FieldBinding field = (FieldBinding) this.binding;
862
						if (!field.isStatic() && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
863
							scope.problemReporter().unqualifiedFieldAccess(this, field);
864
						}
865
						variableType = checkFieldAccess(scope);
848
						variableType = checkFieldAccess(scope);
866
					}
849
					}
867
					// perform capture conversion if read access
850
					// perform capture conversion if read access
(-)compiler/org/eclipse/jdt/internal/compiler/ast/QualifiedNameReference.java (-36 / +27 lines)
Lines 70-90 Link Here
70
			if (needValue || complyTo14) {
70
			if (needValue || complyTo14) {
71
				manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, this.actualReceiverType, 0, flowInfo);
71
				manageSyntheticAccessIfNecessary(currentScope, lastFieldBinding, this.actualReceiverType, 0, flowInfo);
72
			}
72
			}
73
			if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
74
				ReferenceBinding declaringClass = lastFieldBinding.declaringClass;
75
				// check if accessing enum static field in initializer					
76
				if (declaringClass.isEnum()) {
77
					MethodScope methodScope = currentScope.methodScope();
78
					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
79
					if (lastFieldBinding.isStatic()
80
							&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
81
							&& lastFieldBinding.constant() == Constant.NotAConstant
82
							&& !methodScope.isStatic
83
							&& methodScope.isInsideInitializerOrConstructor()) {
84
						currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(lastFieldBinding, this);
85
					}
86
				}				
87
			}
88
			// check if final blank field
73
			// check if final blank field
89
			if (lastFieldBinding.isBlankFinal()
74
			if (lastFieldBinding.isBlankFinal()
90
				    && this.otherBindings != null // the last field binding is only assigned
75
				    && this.otherBindings != null // the last field binding is only assigned
Lines 225-243 Link Here
225
			}
210
			}
226
			if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
211
			if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
227
				FieldBinding fieldBinding = (FieldBinding) this.binding;
212
				FieldBinding fieldBinding = (FieldBinding) this.binding;
228
				ReferenceBinding declaringClass = fieldBinding.declaringClass;
229
				// check if accessing enum static field in initializer					
230
				if (declaringClass.isEnum()) {
231
					MethodScope methodScope = currentScope.methodScope();
232
					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
233
					if (fieldBinding.isStatic()
234
							&& (sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
235
							&& fieldBinding.constant() == Constant.NotAConstant
236
							&& !methodScope.isStatic
237
							&& methodScope.isInsideInitializerOrConstructor()) {
238
						currentScope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
239
					}
240
				}				
241
				// check if reading a final blank field
213
				// check if reading a final blank field
242
				if (fieldBinding.isBlankFinal()
214
				if (fieldBinding.isBlankFinal()
243
						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)
215
						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)
Lines 739-751 Link Here
739
				scope.problemReporter().staticFieldAccessToNonStaticVariable(this, field);
711
				scope.problemReporter().staticFieldAccessToNonStaticVariable(this, field);
740
				return null;
712
				return null;
741
			 }
713
			 }
742
		} else {
714
		} else if (this.indexOfFirstFieldBinding > 1 
743
			// indirect static reference ?
744
			if (this.indexOfFirstFieldBinding > 1 
745
					&& field.declaringClass != this.actualReceiverType
715
					&& field.declaringClass != this.actualReceiverType
746
					&& field.declaringClass.canBeSeenBy(scope)) {
716
					&& field.declaringClass.canBeSeenBy(scope)) {
747
				scope.problemReporter().indirectAccessToStaticField(this, field);
717
			scope.problemReporter().indirectAccessToStaticField(this, field);
748
			}
749
		}
718
		}
750
		// only last field is actually a write access if any
719
		// only last field is actually a write access if any
751
		if (isFieldUseDeprecated(field, scope, (this.bits & ASTNode.IsStrictlyAssigned) != 0 && this.indexOfFirstFieldBinding == length))
720
		if (isFieldUseDeprecated(field, scope, (this.bits & ASTNode.IsStrictlyAssigned) != 0 && this.indexOfFirstFieldBinding == length))
Lines 808-813 Link Here
808
			}
777
			}
809
778
810
			if (field.isStatic()) {
779
			if (field.isStatic()) {
780
				// check if accessing enum static field in initializer
781
				ReferenceBinding declaringClass = field.declaringClass;
782
				if (declaringClass.isEnum()) {
783
					MethodScope methodScope = scope.methodScope();
784
					SourceTypeBinding sourceType = methodScope.enclosingSourceType();
785
					if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
786
							&& field.constant() == Constant.NotAConstant
787
							&& !methodScope.isStatic
788
							&& methodScope.isInsideInitializerOrConstructor()) {
789
						scope.problemReporter().enumStaticFieldUsedDuringInitialization(field, this);
790
					}
791
				}					
811
				// static field accessed through receiver? legal but unoptimal (optional warning)
792
				// static field accessed through receiver? legal but unoptimal (optional warning)
812
				scope.problemReporter().nonStaticAccessToStaticField(this, field, index);
793
				scope.problemReporter().nonStaticAccessToStaticField(this, field, index);
813
				// indirect static reference ?
794
				// indirect static reference ?
Lines 1029-1037 Link Here
1029
							&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
1010
							&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
1030
						scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
1011
						scope.problemReporter().forwardReference(this, 0, methodScope.enclosingSourceType());
1031
					}
1012
					}
1032
					if (!fieldBinding.isStatic() 
1013
					if (fieldBinding.isStatic()) {
1033
							&& this.indexOfFirstFieldBinding == 1
1014
						ReferenceBinding declaringClass = fieldBinding.declaringClass;
1034
							&& scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
1015
						// check if accessing enum static field in initializer					
1016
						if (declaringClass.isEnum()) {
1017
							SourceTypeBinding sourceType = methodScope.enclosingSourceType();
1018
							if ((sourceType == declaringClass || sourceType.superclass == declaringClass) // enum constant body
1019
									&& fieldBinding.constant() == Constant.NotAConstant
1020
									&& !methodScope.isStatic
1021
									&& methodScope.isInsideInitializerOrConstructor()) {
1022
								scope.problemReporter().enumStaticFieldUsedDuringInitialization(fieldBinding, this);
1023
							}
1024
						}						
1025
					} else if (this.indexOfFirstFieldBinding == 1 && scope.compilerOptions().getSeverity(CompilerOptions.UnqualifiedFieldAccess) != ProblemSeverities.Ignore) {
1035
						scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding);
1026
						scope.problemReporter().unqualifiedFieldAccess(this, fieldBinding);
1036
					}
1027
					}
1037
					this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
1028
					this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits

Return to bug 228109