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

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/compiler/regression/FlowAnalysisTest.java (-36 / +297 lines)
Lines 34-39 Link Here
34
	return buildAllCompliancesTestSuite(testClass());
34
	return buildAllCompliancesTestSuite(testClass());
35
}
35
}
36
36
37
protected Map getCompilerOptions() {
38
	Map map = super.getCompilerOptions();
39
	map.put(CompilerOptions.OPTION_ReportDeadCode, CompilerOptions.WARNING);
40
	return map;		
41
}
37
public void test001() {
42
public void test001() {
38
	this.runNegativeTest(new String[] {
43
	this.runNegativeTest(new String[] {
39
		"X.java", // =================
44
		"X.java", // =================
Lines 48-58 Link Here
48
		"	}	\n" +
53
		"	}	\n" +
49
		"}\n",
54
		"}\n",
50
	},
55
	},
51
	"----------\n" +
56
	"----------\n" + 
52
	"1. ERROR in X.java (at line 2)\n" +
57
	"1. ERROR in X.java (at line 2)\n" + 
53
	"	public String foo(int i) {\n" +
58
	"	public String foo(int i) {\n" + 
54
	"	              ^^^^^^^^^^\n" +
59
	"	              ^^^^^^^^^^\n" + 
55
	"This method must return a result of type String\n" +
60
	"This method must return a result of type String\n" + 
61
	"----------\n" + 
62
	"2. WARNING in X.java (at line 6)\n" + 
63
	"	if (i > 0) {\n" + 
64
	"			return null;\n" + 
65
	"		}\n" + 
66
	"	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
67
	"Dead code\n" + 
56
	"----------\n");
68
	"----------\n");
57
}
69
}
58
70
Lines 712-722 Link Here
712
			"	}\n" +
724
			"	}\n" +
713
			"}"
725
			"}"
714
		},
726
		},
715
		"----------\n" +
727
		"----------\n" + 
716
		"1. ERROR in X.java (at line 10)\n" +
728
		"1. WARNING in X.java (at line 8)\n" + 
717
		"	x.foo();\n" +
729
		"	x = new X();\n" + 
718
		"	^\n" +
730
		"	^^^^^^^^^^^\n" + 
719
		"The local variable x may not have been initialized\n" +
731
		"Dead code\n" + 
732
		"----------\n" + 
733
		"2. ERROR in X.java (at line 10)\n" + 
734
		"	x.foo();\n" + 
735
		"	^\n" + 
736
		"The local variable x may not have been initialized\n" + 
720
		"----------\n",
737
		"----------\n",
721
		JavacTestOptions.JavacHasABug.JavacBugFixed_6_10);
738
		JavacTestOptions.JavacHasABug.JavacBugFixed_6_10);
722
}
739
}
Lines 1169-1179 Link Here
1169
			"  }\n" +
1186
			"  }\n" +
1170
			"}"
1187
			"}"
1171
		},
1188
		},
1172
		"----------\n" +
1189
		"----------\n" + 
1173
		"1. ERROR in X.java (at line 5)\n" +
1190
		"1. WARNING in X.java (at line 3)\n" + 
1174
		"	System.out.println(s);\n" +
1191
		"	if (false) {\n" + 
1175
		"	                   ^\n" +
1192
		"      String s;\n" + 
1176
		"The local variable s may not have been initialized\n" +
1193
		"      System.out.println(s);\n" + 
1194
		"    }\n" + 
1195
		"	           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
1196
		"Dead code\n" + 
1197
		"----------\n" + 
1198
		"2. ERROR in X.java (at line 5)\n" + 
1199
		"	System.out.println(s);\n" + 
1200
		"	                   ^\n" + 
1201
		"The local variable s may not have been initialized\n" + 
1177
		"----------\n");
1202
		"----------\n");
1178
}
1203
}
1179
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
1204
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
Lines 1210-1220 Link Here
1210
			"  }\n" +
1235
			"  }\n" +
1211
			"}"
1236
			"}"
1212
		},
1237
		},
1213
		"----------\n" +
1238
		"----------\n" + 
1214
		"1. ERROR in X.java (at line 6)\n" +
1239
		"1. WARNING in X.java (at line 3)\n" + 
1215
		"	System.out.println(s);\n" +
1240
		"	if (false) {\n" + 
1216
		"	                   ^\n" +
1241
		"      String s;\n" + 
1217
		"The local variable s may not have been initialized\n" +
1242
		"      if (System.out != null) {\n" + 
1243
		"        System.out.println(s);\n" + 
1244
		"      }\n" + 
1245
		"    }\n" + 
1246
		"	           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
1247
		"Dead code\n" + 
1248
		"----------\n" + 
1249
		"2. ERROR in X.java (at line 6)\n" + 
1250
		"	System.out.println(s);\n" + 
1251
		"	                   ^\n" + 
1252
		"The local variable s may not have been initialized\n" + 
1218
		"----------\n");
1253
		"----------\n");
1219
}
1254
}
1220
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
1255
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
Lines 1232-1242 Link Here
1232
			"  }\n" +
1267
			"  }\n" +
1233
			"}"
1268
			"}"
1234
		},
1269
		},
1235
		"----------\n" +
1270
		"----------\n" + 
1236
		"1. ERROR in X.java (at line 5)\n" +
1271
		"1. WARNING in X.java (at line 4)\n" + 
1237
		"	s = \"\";\n" +
1272
		"	if (false) {\n" + 
1238
		"	^\n" +
1273
		"      s = \"\";\n" + 
1239
		"The final local variable s cannot be assigned. It must be blank and not using a compound assignment\n" +
1274
		"    }\n" + 
1275
		"	           ^^^^^^^^^^^^^^^^^^^^^\n" + 
1276
		"Dead code\n" + 
1277
		"----------\n" + 
1278
		"2. ERROR in X.java (at line 5)\n" + 
1279
		"	s = \"\";\n" + 
1280
		"	^\n" + 
1281
		"The final local variable s cannot be assigned. It must be blank and not using a compound assignment\n" + 
1240
		"----------\n");
1282
		"----------\n");
1241
}
1283
}
1242
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
1284
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=166641
Lines 1273-1283 Link Here
1273
			"  }\n" +
1315
			"  }\n" +
1274
			"}"
1316
			"}"
1275
		},
1317
		},
1276
		"----------\n" +
1318
		"----------\n" + 
1277
		"1. ERROR in X.java (at line 7)\n" +
1319
		"1. WARNING in X.java (at line 4)\n" + 
1278
		"	s = \"\";\n" +
1320
		"	if (false) {\n" + 
1279
		"	^\n" +
1321
		"      s = \"\";\n" + 
1280
		"The final local variable s may already have been assigned\n" +
1322
		"    }\n" + 
1323
		"	           ^^^^^^^^^^^^^^^^^^^^^\n" + 
1324
		"Dead code\n" + 
1325
		"----------\n" + 
1326
		"2. ERROR in X.java (at line 7)\n" + 
1327
		"	s = \"\";\n" + 
1328
		"	^\n" + 
1329
		"The final local variable s may already have been assigned\n" + 
1281
		"----------\n");
1330
		"----------\n");
1282
}
1331
}
1283
// switch and definite assignment
1332
// switch and definite assignment
Lines 1421-1431 Link Here
1421
			"}\n"
1470
			"}\n"
1422
			},
1471
			},
1423
		false /* expectingCompilerErrors */,
1472
		false /* expectingCompilerErrors */,
1424
		"----------\n" +
1473
		"----------\n" + 
1425
		"1. WARNING in X.java (at line 5)\n" +
1474
		"1. WARNING in X.java (at line 4)\n" + 
1426
		"	label: while (bar()) {\n" +
1475
		"	if (b) {\n" + 
1427
		"	^^^^^\n" +
1476
		"      label: while (bar()) {\n" + 
1428
		"The label label is never explicitly referenced\n" +
1477
		"      }\n" + 
1478
		"      return null;\n" + 
1479
		"    }\n" + 
1480
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
1481
		"Dead code\n" + 
1482
		"----------\n" + 
1483
		"2. WARNING in X.java (at line 5)\n" + 
1484
		"	label: while (bar()) {\n" + 
1485
		"	^^^^^\n" + 
1486
		"The label label is never explicitly referenced\n" + 
1429
		"----------\n" /* expectedCompilerLog */,
1487
		"----------\n" /* expectedCompilerLog */,
1430
		"" /* expectedOutputString */,
1488
		"" /* expectedOutputString */,
1431
		"" /* expectedErrorString */,
1489
		"" /* expectedErrorString */,
Lines 1460-1466 Link Here
1460
			"}\n"
1518
			"}\n"
1461
			},
1519
			},
1462
		false /* expectingCompilerErrors */,
1520
		false /* expectingCompilerErrors */,
1463
		"" /* expectedCompilerLog */,
1521
		"----------\n" + 
1522
		"1. WARNING in X.java (at line 4)\n" + 
1523
		"	if (b) {\n" + 
1524
		"      while (bar()) {\n" + 
1525
		"      }\n" + 
1526
		"      return null;\n" + 
1527
		"    }\n" + 
1528
		"	       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
1529
		"Dead code\n" + 
1530
		"----------\n" /* expectedCompilerLog */,
1464
		"" /* expectedOutputString */,
1531
		"" /* expectedOutputString */,
1465
		"" /* expectedErrorString */,
1532
		"" /* expectedErrorString */,
1466
		false /* forceExecution */,
1533
		false /* forceExecution */,
Lines 1506-1511 Link Here
1506
		}
1573
		}
1507
	);
1574
	);
1508
}
1575
}
1576
public void test052() {
1577
	runNegativeTest(
1578
		new String[] { /* test files */
1579
			"X.java",
1580
			"public class X {\n" + 
1581
			"	void foo(boolean b) {\n" + 
1582
			"		if (b && false) {\n" + 
1583
			"			int i = 0; // deadcode\n" + 
1584
			"			return;  // 1\n" + 
1585
			"		}\n" + 
1586
			"		return;\n" +
1587
			"		return;\n" +
1588
			"	}\n" +
1589
			"}	\n"
1590
		},
1591
		"----------\n" + 
1592
		"1. WARNING in X.java (at line 3)\n" + 
1593
		"	if (b && false) {\n" + 
1594
		"			int i = 0; // deadcode\n" + 
1595
		"			return;  // 1\n" + 
1596
		"		}\n" + 
1597
		"	                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
1598
		"Dead code\n" + 
1599
		"----------\n" + 
1600
		"2. ERROR in X.java (at line 8)\n" + 
1601
		"	return;\n" + 
1602
		"	^^^^^^^\n" + 
1603
		"Unreachable code\n" + 
1604
		"----------\n");
1605
}
1606
public void test053() {
1607
	runNegativeTest(
1608
		new String[] { /* test files */
1609
			"X.java",
1610
			"public class X {\n" + 
1611
			"	void foo(boolean b) {\n" + 
1612
			"		if (false && b) {\n" + 
1613
			"			int j = 0; // deadcode\n" + 
1614
			"			return; // 2\n" + 
1615
			"		}\n" + 
1616
			"		return;\n" +
1617
			"		return;\n" +
1618
			"	}\n" +
1619
			"}	\n"
1620
		},
1621
		"----------\n" + 
1622
		"1. WARNING in X.java (at line 3)\n" + 
1623
		"	if (false && b) {\n" + 
1624
		"	             ^\n" + 
1625
		"Dead code\n" + 
1626
		"----------\n" + 
1627
		"2. WARNING in X.java (at line 3)\n" + 
1628
		"	if (false && b) {\n" + 
1629
		"			int j = 0; // deadcode\n" + 
1630
		"			return; // 2\n" + 
1631
		"		}\n" + 
1632
		"	                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" + 
1633
		"Dead code\n" + 
1634
		"----------\n" + 
1635
		"3. ERROR in X.java (at line 8)\n" + 
1636
		"	return;\n" + 
1637
		"	^^^^^^^\n" + 
1638
		"Unreachable code\n" + 
1639
		"----------\n");
1640
}
1641
public void test054() {
1642
	runNegativeTest(
1643
		new String[] { /* test files */
1644
			"X.java",
1645
			"public class X {\n" + 
1646
			"	void foo(boolean b) {\n" + 
1647
			"		while (true) {\n" + 
1648
			"			if (true) break;\n" + 
1649
			"			int k = 0; // deadcode\n" + 
1650
			"		}\n" + 
1651
			"		return;\n" +
1652
			"		return;\n" +
1653
			"	}\n" +
1654
			"}	\n"
1655
		},
1656
		"----------\n" + 
1657
		"1. WARNING in X.java (at line 5)\n" + 
1658
		"	int k = 0; // deadcode\n" + 
1659
		"	^^^^^^^^^^\n" + 
1660
		"Dead code\n" + 
1661
		"----------\n" + 
1662
		"2. ERROR in X.java (at line 8)\n" + 
1663
		"	return;\n" + 
1664
		"	^^^^^^^\n" + 
1665
		"Unreachable code\n" + 
1666
		"----------\n");
1667
}
1668
public void test055() {
1669
	runNegativeTest(
1670
		new String[] { /* test files */
1671
			"X.java",
1672
			"public class X {\n" + 
1673
			"	void foo(boolean b) {\n" + 
1674
			"		if (true || b) {\n" + 
1675
			"			int l = 0; // deadcode\n" + 
1676
			"			return; // 2a\n" + 
1677
			"		}		\n" + 
1678
			"		return;\n" +
1679
			"		return;\n" +
1680
			"	}\n" +
1681
			"}	\n"
1682
		},
1683
		"----------\n" + 
1684
		"1. WARNING in X.java (at line 3)\n" + 
1685
		"	if (true || b) {\n" + 
1686
		"	            ^\n" + 
1687
		"Dead code\n" + 
1688
		"----------\n" + 
1689
		"2. WARNING in X.java (at line 7)\n" + 
1690
		"	return;\n" + 
1691
		"	^^^^^^^\n" + 
1692
		"Dead code\n" + 
1693
		"----------\n" + 
1694
		"3. ERROR in X.java (at line 8)\n" + 
1695
		"	return;\n" + 
1696
		"	^^^^^^^\n" + 
1697
		"Unreachable code\n" + 
1698
		"----------\n");
1699
}
1700
public void test056() {
1701
	runNegativeTest(
1702
		new String[] { /* test files */
1703
			"X.java",
1704
			"public class X {\n" + 
1705
			"	void bar() {\n" + 
1706
			"		return;\n" + 
1707
			"		{\n" + 
1708
			"			return; // 3\n" + 
1709
			"		}\n" + 
1710
			"	}\n" + 
1711
			"	void baz() {\n" + 
1712
			"		return;\n" + 
1713
			"		{\n" + 
1714
			"		}\n" + 
1715
			"	}	\n" + 
1716
			"	void baz2() {\n" + 
1717
			"		return;\n" + 
1718
			"		; // 4\n" + 
1719
			"	}	\n" + 
1720
			"}	\n"
1721
		},
1722
		"----------\n" + 
1723
		"1. ERROR in X.java (at line 4)\n" + 
1724
		"	{\n" + 
1725
		"			return; // 3\n" + 
1726
		"		}\n" + 
1727
		"	^^^^^^^^^^^^^^^^^^^^^\n" + 
1728
		"Unreachable code\n" + 
1729
		"----------\n" + 
1730
		"2. ERROR in X.java (at line 10)\n" + 
1731
		"	{\n" + 
1732
		"		}\n" + 
1733
		"	^^^^^\n" + 
1734
		"Unreachable code\n" + 
1735
		"----------\n");
1736
}
1737
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=110544
1738
public void test057() {
1739
	runNegativeTest(
1740
		new String[] { /* test files */
1741
			"X.java",
1742
			"public class X {\n" + 
1743
			"	void foo(int x, int[] array) {\n" + 
1744
			"		for (int i = 0; \n" + 
1745
			"		     i < array.length; \n" + 
1746
			"		     i++) {//dead code\n" + 
1747
			"			if (x == array[i])\n" + 
1748
			"				return;\n" + 
1749
			"			else\n" + 
1750
			"				break;\n" + 
1751
			"		}\n" + 
1752
			"	}\n" + 
1753
			"}\n"
1754
		},
1755
		"----------\n" + 
1756
		"1. ERROR in X.java (at line 4)\n" + 
1757
		"	{\n" + 
1758
		"			return; // 3\n" + 
1759
		"		}\n" + 
1760
		"	^^^^^^^^^^^^^^^^^^^^^\n" + 
1761
		"Unreachable code\n" + 
1762
		"----------\n" + 
1763
		"2. ERROR in X.java (at line 10)\n" + 
1764
		"	{\n" + 
1765
		"		}\n" + 
1766
		"	^^^^^\n" + 
1767
		"Unreachable code\n" + 
1768
		"----------\n");
1769
}
1509
public static Class testClass() {
1770
public static Class testClass() {
1510
	return FlowAnalysisTest.class;
1771
	return FlowAnalysisTest.class;
1511
}
1772
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ConstructorDeclaration.java (-4 / +2 lines)
Lines 125-137 Link Here
125
125
126
		// propagate to statements
126
		// propagate to statements
127
		if (this.statements != null) {
127
		if (this.statements != null) {
128
			boolean didAlreadyComplain = false;
128
			int complaintLevel = Statement.NOT_COMPLAINED;
129
			for (int i = 0, count = this.statements.length; i < count; i++) {
129
			for (int i = 0, count = this.statements.length; i < count; i++) {
130
				Statement stat = this.statements[i];
130
				Statement stat = this.statements[i];
131
				if (!stat.complainIfUnreachable(flowInfo, this.scope, didAlreadyComplain)) {
131
				if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
132
					flowInfo = stat.analyseCode(this.scope, constructorContext, flowInfo);
132
					flowInfo = stat.analyseCode(this.scope, constructorContext, flowInfo);
133
				} else {
134
					didAlreadyComplain = true;
135
				}
133
				}
136
			}
134
			}
137
		}
135
		}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/AssertStatement.java (-1 / +4 lines)
Lines 60-66 Link Here
60
			unconditionalInits();
60
			unconditionalInits();
61
		UnconditionalFlowInfo assertInfo = assertRawInfo.unconditionalCopy();
61
		UnconditionalFlowInfo assertInfo = assertRawInfo.unconditionalCopy();
62
		if (isOptimizedTrueAssertion) {
62
		if (isOptimizedTrueAssertion) {
63
			assertInfo.setReachMode(FlowInfo.UNREACHABLE);
63
			if ((assertInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
64
				currentScope.problemReporter().fakeReachable(this.assertExpression);
65
				assertInfo.setReachMode(FlowInfo.UNREACHABLE);
66
			}
64
		}
67
		}
65
68
66
		if (this.exceptionArgument != null) {
69
		if (this.exceptionArgument != null) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Block.java (-97 / +81 lines)
Lines 22-142 Link Here
22
	// the number of explicit declaration , used to create scope
22
	// the number of explicit declaration , used to create scope
23
	public BlockScope scope;
23
	public BlockScope scope;
24
24
25
	public Block(int explicitDeclarations) {
25
public Block(int explicitDeclarations) {
26
		this.explicitDeclarations = explicitDeclarations;
26
	this.explicitDeclarations = explicitDeclarations;
27
	}
27
}
28
29
	public FlowInfo analyseCode(
30
		BlockScope currentScope,
31
		FlowContext flowContext,
32
		FlowInfo flowInfo) {
33
34
		// empty block
35
		if (this.statements == null)	return flowInfo;
36
		boolean didAlreadyComplain = false;
37
		for (int i = 0, max = this.statements.length; i < max; i++) {
38
			Statement stat = this.statements[i];
39
			if (!stat.complainIfUnreachable(flowInfo, this.scope, didAlreadyComplain)) {
40
				flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
41
			} else {
42
				didAlreadyComplain = true;
43
			}
44
		}
45
		return flowInfo;
46
	}
47
	/**
48
	 * Code generation for a block
49
	 */
50
	public void generateCode(BlockScope currentScope, CodeStream codeStream) {
51
28
52
		if ((this.bits & IsReachable) == 0) {
29
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
53
			return;
30
	// empty block
54
		}
31
	if (this.statements == null)	return flowInfo;
55
		int pc = codeStream.position;
32
	int complaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
56
		if (this.statements != null) {
33
	for (int i = 0, max = this.statements.length; i < max; i++) {
57
			for (int i = 0, max = this.statements.length; i < max; i++) {
34
		Statement stat = this.statements[i];
58
				this.statements[i].generateCode(this.scope, codeStream);
35
		if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
59
			}
36
			flowInfo = stat.analyseCode(this.scope, flowContext, flowInfo);
60
		} // for local variable debug attributes
61
		if (this.scope != currentScope) { // was really associated with its own scope
62
			codeStream.exitUserScope(this.scope);
63
		}
37
		}
64
		codeStream.recordPositionsFrom(pc, this.sourceStart);
65
	}
38
	}
66
39
	return flowInfo;
67
	public boolean isEmptyBlock() {
40
}
68
41
/**
69
		return this.statements == null;
42
 * Code generation for a block
43
 */
44
public void generateCode(BlockScope currentScope, CodeStream codeStream) {
45
	if ((this.bits & IsReachable) == 0) {
46
		return;
70
	}
47
	}
71
48
	int pc = codeStream.position;
72
	public StringBuffer printBody(int indent, StringBuffer output) {
49
	if (this.statements != null) {
73
50
		for (int i = 0, max = this.statements.length; i < max; i++) {
74
		if (this.statements == null) return output;
51
			this.statements[i].generateCode(this.scope, codeStream);
75
		for (int i = 0; i < this.statements.length; i++) {
76
			this.statements[i].printStatement(indent + 1, output);
77
			output.append('\n');
78
		}
52
		}
79
		return output;
53
	} // for local variable debug attributes
54
	if (this.scope != currentScope) { // was really associated with its own scope
55
		codeStream.exitUserScope(this.scope);
80
	}
56
	}
57
	codeStream.recordPositionsFrom(pc, this.sourceStart);
58
}
81
59
82
	public StringBuffer printStatement(int indent, StringBuffer output) {
60
public boolean isEmptyBlock() {
61
	return this.statements == null;
62
}
83
63
84
		printIndent(indent, output);
64
public StringBuffer printBody(int indent, StringBuffer output) {
85
		output.append("{\n"); //$NON-NLS-1$
65
	if (this.statements == null) return output;
86
		printBody(indent, output);
66
	for (int i = 0; i < this.statements.length; i++) {
87
		return printIndent(indent, output).append('}');
67
		this.statements[i].printStatement(indent + 1, output);
68
		output.append('\n');
88
	}
69
	}
70
	return output;
71
}
89
72
90
	public void resolve(BlockScope upperScope) {
73
public StringBuffer printStatement(int indent, StringBuffer output) {
74
	printIndent(indent, output);
75
	output.append("{\n"); //$NON-NLS-1$
76
	printBody(indent, output);
77
	return printIndent(indent, output).append('}');
78
}
91
79
92
		if ((this.bits & UndocumentedEmptyBlock) != 0) {
80
public void resolve(BlockScope upperScope) {
93
			upperScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd);
81
	if ((this.bits & UndocumentedEmptyBlock) != 0) {
94
		}
82
		upperScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd);
95
		if (this.statements != null) {
83
	}
96
			this.scope =
84
	if (this.statements != null) {
97
				this.explicitDeclarations == 0
85
		this.scope =
98
					? upperScope
86
			this.explicitDeclarations == 0
99
					: new BlockScope(upperScope, this.explicitDeclarations);
87
				? upperScope
100
			for (int i = 0, length = this.statements.length; i < length; i++) {
88
				: new BlockScope(upperScope, this.explicitDeclarations);
101
				this.statements[i].resolve(this.scope);
89
		for (int i = 0, length = this.statements.length; i < length; i++) {
102
			}
90
			this.statements[i].resolve(this.scope);
103
		}
91
		}
104
	}
92
	}
93
}
105
94
106
	public void resolveUsing(BlockScope givenScope) {
95
public void resolveUsing(BlockScope givenScope) {
107
96
	if ((this.bits & UndocumentedEmptyBlock) != 0) {
108
		if ((this.bits & UndocumentedEmptyBlock) != 0) {
97
		givenScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd);
109
			givenScope.problemReporter().undocumentedEmptyBlock(this.sourceStart, this.sourceEnd);
98
	}
110
		}
99
	// this optimized resolve(...) is sent only on none empty blocks
111
		// this optimized resolve(...) is sent only on none empty blocks
100
	this.scope = givenScope;
112
		this.scope = givenScope;
101
	if (this.statements != null) {
113
		if (this.statements != null) {
102
		for (int i = 0, length = this.statements.length; i < length; i++) {
114
			for (int i = 0, length = this.statements.length; i < length; i++) {
103
			this.statements[i].resolve(this.scope);
115
				this.statements[i].resolve(this.scope);
116
			}
117
		}
104
		}
118
	}
105
	}
106
}
119
107
120
	public void traverse(
108
public void traverse(ASTVisitor visitor, BlockScope blockScope) {
121
		ASTVisitor visitor,
109
	if (visitor.visit(this, blockScope)) {
122
		BlockScope blockScope) {
110
		if (this.statements != null) {
123
111
			for (int i = 0, length = this.statements.length; i < length; i++)
124
		if (visitor.visit(this, blockScope)) {
112
				this.statements[i].traverse(visitor, this.scope);
125
			if (this.statements != null) {
126
				for (int i = 0, length = this.statements.length; i < length; i++)
127
					this.statements[i].traverse(visitor, this.scope);
128
			}
129
		}
113
		}
130
		visitor.endVisit(this, blockScope);
131
	}
132
133
	/**
134
	 * Dispatch the call on its last statement.
135
	 */
136
	public void branchChainTo(BranchLabel label) {
137
		 if (this.statements != null) {
138
		 	this.statements[this.statements.length - 1].branchChainTo(label);
139
		 }
140
	}
114
	}
115
	visitor.endVisit(this, blockScope);
116
}
141
117
118
/**
119
 * Dispatch the call on its last statement.
120
 */
121
public void branchChainTo(BranchLabel label) {
122
	 if (this.statements != null) {
123
	 	this.statements[this.statements.length - 1].branchChainTo(label);
124
	 }
125
}
142
}
126
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/EmptyStatement.java (-3 / +3 lines)
Lines 29-41 Link Here
29
	}
29
	}
30
30
31
	// Report an error if necessary
31
	// Report an error if necessary
32
	public boolean complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, boolean didAlreadyComplain) {
32
	public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int complaintLevel) {
33
33
34
		// before 1.4, empty statements are tolerated anywhere
34
		// before 1.4, empty statements are tolerated anywhere
35
		if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
35
		if (scope.compilerOptions().complianceLevel < ClassFileConstants.JDK1_4) {
36
			return false;
36
			return complaintLevel;
37
		}
37
		}
38
		return super.complainIfUnreachable(flowInfo, scope, didAlreadyComplain);
38
		return super.complainIfUnreachable(flowInfo, scope, complaintLevel);
39
	}
39
	}
40
40
41
	public void generateCode(BlockScope currentScope, CodeStream codeStream){
41
	public void generateCode(BlockScope currentScope, CodeStream codeStream){
(-)compiler/org/eclipse/jdt/internal/compiler/ast/IfStatement.java (-17 / +9 lines)
Lines 53-66 Link Here
53
		this.sourceEnd = sourceEnd;
53
		this.sourceEnd = sourceEnd;
54
	}
54
	}
55
55
56
	public FlowInfo analyseCode(
56
	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
57
		BlockScope currentScope,
58
		FlowContext flowContext,
59
		FlowInfo flowInfo) {
60
61
		// process the condition
57
		// process the condition
62
		FlowInfo conditionFlowInfo =
58
		FlowInfo conditionFlowInfo = this.condition.analyseCode(currentScope, flowContext, flowInfo);
63
			this.condition.analyseCode(currentScope, flowContext, flowInfo);
59
		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
64
60
65
		Constant cst = this.condition.optimizedBooleanConstant();
61
		Constant cst = this.condition.optimizedBooleanConstant();
66
		boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
62
		boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
Lines 77-87 Link Here
77
		}
73
		}
78
		if (this.thenStatement != null) {
74
		if (this.thenStatement != null) {
79
			// Save info for code gen
75
			// Save info for code gen
80
			this.thenInitStateIndex =
76
			this.thenInitStateIndex = currentScope.methodScope().recordInitializationStates(thenFlowInfo);
81
				currentScope.methodScope().recordInitializationStates(thenFlowInfo);
77
			if (this.thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
82
			if (!this.thenStatement.complainIfUnreachable(thenFlowInfo, currentScope, false)) {
78
				thenFlowInfo = this.thenStatement.analyseCode(currentScope, flowContext, thenFlowInfo);
83
				thenFlowInfo =
84
					this.thenStatement.analyseCode(currentScope, flowContext, thenFlowInfo);
85
			}
79
			}
86
		}
80
		}
87
		// code gen: optimizing the jump around the ELSE part
81
		// code gen: optimizing the jump around the ELSE part
Lines 98-108 Link Here
98
		        currentScope.problemReporter().unnecessaryElse(this.elseStatement);
92
		        currentScope.problemReporter().unnecessaryElse(this.elseStatement);
99
		    }
93
		    }
100
			// Save info for code gen
94
			// Save info for code gen
101
			this.elseInitStateIndex =
95
			this.elseInitStateIndex = currentScope.methodScope().recordInitializationStates(elseFlowInfo);
102
				currentScope.methodScope().recordInitializationStates(elseFlowInfo);
96
			if (this.elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
103
			if (!this.elseStatement.complainIfUnreachable(elseFlowInfo, currentScope, false)) {
97
				elseFlowInfo = this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo);
104
				elseFlowInfo =
105
					this.elseStatement.analyseCode(currentScope, flowContext, elseFlowInfo);
106
			}
98
			}
107
		}
99
		}
108
100
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java (-7 / +20 lines)
Lines 52-58 Link Here
52
		// process the if-true part
52
		// process the if-true part
53
		FlowInfo trueFlowInfo = flowInfo.initsWhenTrue().copy();
53
		FlowInfo trueFlowInfo = flowInfo.initsWhenTrue().copy();
54
		if (isConditionOptimizedFalse) {
54
		if (isConditionOptimizedFalse) {
55
			trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
55
			if ((trueFlowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
56
				currentScope.problemReporter().fakeReachable(this.valueIfTrue);
57
				trueFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
58
			}
56
		}
59
		}
57
		this.trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo);
60
		this.trueInitStateIndex = currentScope.methodScope().recordInitializationStates(trueFlowInfo);
58
		trueFlowInfo = this.valueIfTrue.analyseCode(currentScope, flowContext, trueFlowInfo);
61
		trueFlowInfo = this.valueIfTrue.analyseCode(currentScope, flowContext, trueFlowInfo);
Lines 60-66 Link Here
60
		// process the if-false part
63
		// process the if-false part
61
		FlowInfo falseFlowInfo = flowInfo.initsWhenFalse().copy();
64
		FlowInfo falseFlowInfo = flowInfo.initsWhenFalse().copy();
62
		if (isConditionOptimizedTrue) {
65
		if (isConditionOptimizedTrue) {
63
			falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
66
			if ((falseFlowInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
67
				currentScope.problemReporter().fakeReachable(this.valueIfFalse);
68
				falseFlowInfo.setReachMode(FlowInfo.UNREACHABLE);
69
			}
64
		}
70
		}
65
		this.falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo);
71
		this.falseInitStateIndex = currentScope.methodScope().recordInitializationStates(falseFlowInfo);
66
		falseFlowInfo = this.valueIfFalse.analyseCode(currentScope, flowContext, falseFlowInfo);
72
		falseFlowInfo = this.valueIfFalse.analyseCode(currentScope, flowContext, falseFlowInfo);
Lines 85-95 Link Here
85
			UnconditionalFlowInfo falseInfoWhenTrue = falseFlowInfo.initsWhenTrue().unconditionalCopy();
91
			UnconditionalFlowInfo falseInfoWhenTrue = falseFlowInfo.initsWhenTrue().unconditionalCopy();
86
			UnconditionalFlowInfo trueInfoWhenFalse = trueFlowInfo.initsWhenFalse().unconditionalInits();
92
			UnconditionalFlowInfo trueInfoWhenFalse = trueFlowInfo.initsWhenFalse().unconditionalInits();
87
			UnconditionalFlowInfo falseInfoWhenFalse = falseFlowInfo.initsWhenFalse().unconditionalInits();
93
			UnconditionalFlowInfo falseInfoWhenFalse = falseFlowInfo.initsWhenFalse().unconditionalInits();
88
			if (isValueIfTrueOptimizedFalse) trueInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
94
			if (isValueIfTrueOptimizedFalse) {
89
			if (isValueIfFalseOptimizedFalse) falseInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);
95
				trueInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);				
90
			if (isValueIfTrueOptimizedTrue) trueInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
96
			}
91
			if (isValueIfFalseOptimizedTrue) falseInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);
97
			if (isValueIfFalseOptimizedFalse) {
92
98
				falseInfoWhenTrue.setReachMode(FlowInfo.UNREACHABLE);	
99
			}
100
			if (isValueIfTrueOptimizedTrue) {
101
				trueInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);	
102
			}
103
			if (isValueIfFalseOptimizedTrue) {
104
				falseInfoWhenFalse.setReachMode(FlowInfo.UNREACHABLE);	
105
			}
93
			mergedInfo =
106
			mergedInfo =
94
				FlowInfo.conditional(
107
				FlowInfo.conditional(
95
					trueInfoWhenTrue.mergedWith(falseInfoWhenTrue),
108
					trueInfoWhenTrue.mergedWith(falseInfoWhenTrue),
(-)compiler/org/eclipse/jdt/internal/compiler/ast/MethodDeclaration.java (-4 / +2 lines)
Lines 83-95 Link Here
83
			}
83
			}
84
			// propagate to statements
84
			// propagate to statements
85
			if (this.statements != null) {
85
			if (this.statements != null) {
86
				boolean didAlreadyComplain = false;
86
				int complaintLevel = Statement.NOT_COMPLAINED;
87
				for (int i = 0, count = this.statements.length; i < count; i++) {
87
				for (int i = 0, count = this.statements.length; i < count; i++) {
88
					Statement stat = this.statements[i];
88
					Statement stat = this.statements[i];
89
					if (!stat.complainIfUnreachable(flowInfo, this.scope, didAlreadyComplain)) {
89
					if ((complaintLevel = stat.complainIfUnreachable(flowInfo, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
90
						flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo);
90
						flowInfo = stat.analyseCode(this.scope, methodContext, flowInfo);
91
					} else {
92
						didAlreadyComplain = true;
93
					}
91
					}
94
				}
92
				}
95
			}
93
			}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java (-11 / +11 lines)
Lines 58-70 Link Here
58
		}
58
		}
59
	}
59
	}
60
60
61
	public FlowInfo analyseCode(
61
	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
62
		BlockScope currentScope,
63
		FlowContext flowContext,
64
		FlowInfo flowInfo) {
65
66
		this.breakLabel = new BranchLabel();
62
		this.breakLabel = new BranchLabel();
67
		this.continueLabel = new BranchLabel();
63
		this.continueLabel = new BranchLabel();
64
		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
68
65
69
		// process the initializations
66
		// process the initializations
70
		if (this.initializations != null) {
67
		if (this.initializations != null) {
Lines 82-88 Link Here
82
		cst = this.condition == null ? null : this.condition.optimizedBooleanConstant();
79
		cst = this.condition == null ? null : this.condition.optimizedBooleanConstant();
83
		boolean isConditionOptimizedTrue = cst == null ||  (cst != Constant.NotAConstant && cst.booleanValue() == true);
80
		boolean isConditionOptimizedTrue = cst == null ||  (cst != Constant.NotAConstant && cst.booleanValue() == true);
84
		boolean isConditionOptimizedFalse = cst != null && (cst != Constant.NotAConstant && cst.booleanValue() == false);
81
		boolean isConditionOptimizedFalse = cst != null && (cst != Constant.NotAConstant && cst.booleanValue() == false);
85
82
		
86
		// process the condition
83
		// process the condition
87
		LoopingFlowContext condLoopContext = null;
84
		LoopingFlowContext condLoopContext = null;
88
		FlowInfo condInfo = flowInfo.nullInfoLessUnconditionalCopy();
85
		FlowInfo condInfo = flowInfo.nullInfoLessUnconditionalCopy();
Lines 137-145 Link Here
137
						actionInfo.setReachMode(FlowInfo.UNREACHABLE);
134
						actionInfo.setReachMode(FlowInfo.UNREACHABLE);
138
					}
135
					}
139
				}
136
				}
140
			if (!this.action.complainIfUnreachable(actionInfo, this.scope, false)) {
137
			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
141
				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).
138
				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalInits();
142
					unconditionalInits();
143
			}
139
			}
144
140
145
			// code generation can be optimized when no need to continue in the loop
141
			// code generation can be optimized when no need to continue in the loop
Lines 179-187 Link Here
179
			}
175
			}
180
			exitBranch.addPotentialInitializationsFrom(actionInfo).
176
			exitBranch.addPotentialInitializationsFrom(actionInfo).
181
				addInitializationsFrom(condInfo.initsWhenFalse());
177
				addInitializationsFrom(condInfo.initsWhenFalse());
182
		}
178
		} else {
183
		else {
184
			exitBranch.addInitializationsFrom(condInfo.initsWhenFalse());
179
			exitBranch.addInitializationsFrom(condInfo.initsWhenFalse());
180
			if (this.increments != null) {
181
				if (initialComplaintLevel == Statement.NOT_COMPLAINED) {
182
					currentScope.problemReporter().fakeReachable(this.increments[0]);
183
				}
184
			}
185
		}
185
		}
186
		// nulls checks
186
		// nulls checks
187
		if (condLoopContext != null) {
187
		if (condLoopContext != null) {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/WhileStatement.java (-7 / +5 lines)
Lines 36-48 Link Here
36
		this.sourceEnd = e;
36
		this.sourceEnd = e;
37
	}
37
	}
38
38
39
	public FlowInfo analyseCode(
39
	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
40
		BlockScope currentScope,
41
		FlowContext flowContext,
42
		FlowInfo flowInfo) {
43
40
44
		this.breakLabel = new BranchLabel();
41
		this.breakLabel = new BranchLabel();
45
		this.continueLabel = new BranchLabel();
42
		this.continueLabel = new BranchLabel();
43
		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
46
44
47
		Constant cst = this.condition.constant;
45
		Constant cst = this.condition.constant;
48
		boolean isConditionTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
46
		boolean isConditionTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
Lines 52-61 Link Here
52
		boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
50
		boolean isConditionOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true;
53
		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
51
		boolean isConditionOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false;
54
52
55
		this.preCondInitStateIndex =
53
		this.preCondInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
56
			currentScope.methodScope().recordInitializationStates(flowInfo);
57
		LoopingFlowContext condLoopContext;
54
		LoopingFlowContext condLoopContext;
58
		FlowInfo condInfo =	flowInfo.nullInfoLessUnconditionalCopy();
55
		FlowInfo condInfo =	flowInfo.nullInfoLessUnconditionalCopy();
56
		
59
		// we need to collect the contribution to nulls of the coming paths through the
57
		// we need to collect the contribution to nulls of the coming paths through the
60
		// loop, be they falling through normally or branched to break, continue labels
58
		// loop, be they falling through normally or branched to break, continue labels
61
		// or catch blocks
59
		// or catch blocks
Lines 111-117 Link Here
111
				currentScope.methodScope().recordInitializationStates(
109
				currentScope.methodScope().recordInitializationStates(
112
					condInfo.initsWhenTrue());
110
					condInfo.initsWhenTrue());
113
111
114
			if (!this.action.complainIfUnreachable(actionInfo, currentScope, false)) {
112
			if (this.action.complainIfUnreachable(actionInfo, currentScope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
115
				actionInfo = this.action.analyseCode(currentScope, loopingContext, actionInfo);
113
				actionInfo = this.action.analyseCode(currentScope, loopingContext, actionInfo);
116
			}
114
			}
117
115
(-)compiler/org/eclipse/jdt/internal/compiler/ast/AND_AND_Expression.java (-1 / +4 lines)
Lines 54-60 Link Here
54
54
55
		int previousMode = rightInfo.reachMode();
55
		int previousMode = rightInfo.reachMode();
56
		if (isLeftOptimizedFalse) {
56
		if (isLeftOptimizedFalse) {
57
			rightInfo.setReachMode(FlowInfo.UNREACHABLE);
57
			if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
58
				currentScope.problemReporter().fakeReachable(this.right);
59
				rightInfo.setReachMode(FlowInfo.UNREACHABLE);
60
			}
58
		}
61
		}
59
		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
62
		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
60
		FlowInfo mergedInfo = FlowInfo.conditional(
63
		FlowInfo mergedInfo = FlowInfo.conditional(
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java (-17 / +9 lines)
Lines 44-54 Link Here
44
	int preSwitchInitStateIndex = -1;
44
	int preSwitchInitStateIndex = -1;
45
	int mergedInitStateIndex = -1;
45
	int mergedInitStateIndex = -1;
46
46
47
	public FlowInfo analyseCode(
47
	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
48
			BlockScope currentScope,
49
			FlowContext flowContext,
50
			FlowInfo flowInfo) {
51
52
	    try {
48
	    try {
53
			flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
49
			flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo);
54
			SwitchFlowContext switchContext =
50
			SwitchFlowContext switchContext =
Lines 58-68 Link Here
58
			// to the entry point)
54
			// to the entry point)
59
			FlowInfo caseInits = FlowInfo.DEAD_END;
55
			FlowInfo caseInits = FlowInfo.DEAD_END;
60
			// in case of statements before the first case
56
			// in case of statements before the first case
61
			this.preSwitchInitStateIndex =
57
			this.preSwitchInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
62
				currentScope.methodScope().recordInitializationStates(flowInfo);
63
			int caseIndex = 0;
58
			int caseIndex = 0;
64
			if (this.statements != null) {
59
			if (this.statements != null) {
65
				boolean didAlreadyComplain = false;
60
				int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
61
				int complaintLevel = initialComplaintLevel;
66
				int fallThroughState = CASE;
62
				int fallThroughState = CASE;
67
				for (int i = 0, max = this.statements.length; i < max; i++) {
63
				for (int i = 0, max = this.statements.length; i < max; i++) {
68
					Statement statement = this.statements[i];
64
					Statement statement = this.statements[i];
Lines 74-80 Link Here
74
							this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase);
70
							this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase);
75
						}
71
						}
76
						caseInits = caseInits.mergedWith(flowInfo.unconditionalInits());
72
						caseInits = caseInits.mergedWith(flowInfo.unconditionalInits());
77
						didAlreadyComplain = false; // reset complaint
73
						complaintLevel = initialComplaintLevel; // reset complaint
78
						fallThroughState = CASE;
74
						fallThroughState = CASE;
79
					} else if (statement == this.defaultCase) { // statement is the default case
75
					} else if (statement == this.defaultCase) { // statement is the default case
80
						this.scope.enclosingCase = this.defaultCase; // record entering in a switch case block
76
						this.scope.enclosingCase = this.defaultCase; // record entering in a switch case block
Lines 83-100 Link Here
83
							this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase);
79
							this.scope.problemReporter().possibleFallThroughCase(this.scope.enclosingCase);
84
						}
80
						}
85
						caseInits = caseInits.mergedWith(flowInfo.unconditionalInits());
81
						caseInits = caseInits.mergedWith(flowInfo.unconditionalInits());
86
						didAlreadyComplain = false; // reset complaint
82
						complaintLevel = initialComplaintLevel; // reset complaint
87
						fallThroughState = CASE;
83
						fallThroughState = CASE;
88
					} else {
84
					} else {
89
						fallThroughState = FALLTHROUGH; // reset below if needed
85
						fallThroughState = FALLTHROUGH; // reset below if needed
90
					}
86
					}
91
					if (!statement.complainIfUnreachable(caseInits, this.scope, didAlreadyComplain)) {
87
					if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel)) < Statement.COMPLAINED_UNREACHABLE) {
92
						caseInits = statement.analyseCode(this.scope, switchContext, caseInits);
88
						caseInits = statement.analyseCode(this.scope, switchContext, caseInits);
93
						if (caseInits == FlowInfo.DEAD_END) {
89
						if (caseInits == FlowInfo.DEAD_END) {
94
							fallThroughState = ESCAPING;
90
							fallThroughState = ESCAPING;
95
						}
91
						}
96
					} else {
97
						didAlreadyComplain = true;
98
					}
92
					}
99
				}
93
				}
100
			}
94
			}
Lines 107-116 Link Here
107
			// if no default case, then record it may jump over the block directly to the end
101
			// if no default case, then record it may jump over the block directly to the end
108
			if (this.defaultCase == null) {
102
			if (this.defaultCase == null) {
109
				// only retain the potential initializations
103
				// only retain the potential initializations
110
				flowInfo.addPotentialInitializationsFrom(
104
				flowInfo.addPotentialInitializationsFrom(caseInits.mergedWith(switchContext.initsOnBreak));
111
					caseInits.mergedWith(switchContext.initsOnBreak));
105
				this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo);
112
				this.mergedInitStateIndex =
113
					currentScope.methodScope().recordInitializationStates(flowInfo);
114
				return flowInfo;
106
				return flowInfo;
115
			}
107
			}
116
108
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java (-100 / +108 lines)
Lines 17-144 Link Here
17
17
18
public abstract class Statement extends ASTNode {
18
public abstract class Statement extends ASTNode {
19
19
20
	public abstract FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo);
20
public abstract FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo);
21
21
22
	/**
22
	public static final int NOT_COMPLAINED = 0;
23
	 * INTERNAL USE ONLY.
23
	public static final int COMPLAINED_FAKE_REACHABLE = 1;
24
	 * This is used to redirect inter-statements jumps.
24
	public static final int COMPLAINED_UNREACHABLE = 2;
25
	 */
25
	
26
	public void branchChainTo(BranchLabel label) {
26
/**
27
		// do nothing by default
27
 * INTERNAL USE ONLY.
28
	}
28
 * This is used to redirect inter-statements jumps.
29
29
 */
30
	// Report an error if necessary
30
public void branchChainTo(BranchLabel label) {
31
	public boolean complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, boolean didAlreadyComplain) {
31
	// do nothing by default
32
}
32
33
33
		if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) {
34
// Report an error if necessary (if even more unreachable than previously reported
34
			this.bits &= ~ASTNode.IsReachable;
35
// complaintLevel = 0 if was reachable up until now, 1 if fake reachable (deadcode), 2 if fatal unreachable (error)
35
			boolean reported = flowInfo == FlowInfo.DEAD_END;
36
public int complainIfUnreachable(FlowInfo flowInfo, BlockScope scope, int previousComplaintLevel) {
36
			if (!didAlreadyComplain && reported) {
37
	if ((flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0) {
38
		this.bits &= ~ASTNode.IsReachable;
39
		if (flowInfo == FlowInfo.DEAD_END) {
40
			if (previousComplaintLevel < COMPLAINED_UNREACHABLE) {
37
				scope.problemReporter().unreachableCode(this);
41
				scope.problemReporter().unreachableCode(this);
38
			}
42
			}
39
			return reported; // keep going for fake reachable
43
			return COMPLAINED_UNREACHABLE;
44
		} else {
45
			if (previousComplaintLevel < COMPLAINED_FAKE_REACHABLE) {
46
				scope.problemReporter().fakeReachable(this);
47
			}
48
			return COMPLAINED_FAKE_REACHABLE;
40
		}
49
		}
41
		return false;
42
	}
50
	}
51
	return previousComplaintLevel;
52
}
43
53
44
	/**
54
/**
45
	 * Generate invocation arguments, considering varargs methods
55
 * Generate invocation arguments, considering varargs methods
46
	 */
56
 */
47
	public void generateArguments(MethodBinding binding, Expression[] arguments, BlockScope currentScope, CodeStream codeStream) {
57
public void generateArguments(MethodBinding binding, Expression[] arguments, BlockScope currentScope, CodeStream codeStream) {
48
58
	if (binding.isVarargs()) {
49
		if (binding.isVarargs()) {
59
		// 5 possibilities exist for a call to the vararg method foo(int i, int ... value) :
50
			// 5 possibilities exist for a call to the vararg method foo(int i, int ... value) :
60
		//      foo(1), foo(1, null), foo(1, 2), foo(1, 2, 3, 4) & foo(1, new int[] {1, 2})
51
			//      foo(1), foo(1, null), foo(1, 2), foo(1, 2, 3, 4) & foo(1, new int[] {1, 2})
61
		TypeBinding[] params = binding.parameters;
52
			TypeBinding[] params = binding.parameters;
62
		int paramLength = params.length;
53
			int paramLength = params.length;
63
		int varArgIndex = paramLength - 1;
54
			int varArgIndex = paramLength - 1;
64
		for (int i = 0; i < varArgIndex; i++) {
55
			for (int i = 0; i < varArgIndex; i++) {
65
			arguments[i].generateCode(currentScope, codeStream, true);
66
		}
67
68
		ArrayBinding varArgsType = (ArrayBinding) params[varArgIndex]; // parameterType has to be an array type
69
		ArrayBinding codeGenVarArgsType = (ArrayBinding) binding.parameters[varArgIndex].erasure();
70
		int elementsTypeID = varArgsType.elementsType().id;
71
		int argLength = arguments == null ? 0 : arguments.length;
72
73
		if (argLength > paramLength) {
74
			// right number but not directly compatible or too many arguments - wrap extra into array
75
			// called with (argLength - lastIndex) elements : foo(1, 2) or foo(1, 2, 3, 4)
76
			// need to gen elements into an array, then gen each remaining element into created array
77
			codeStream.generateInlinedValue(argLength - varArgIndex);
78
			codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
79
			for (int i = varArgIndex; i < argLength; i++) {
80
				codeStream.dup();
81
				codeStream.generateInlinedValue(i - varArgIndex);
56
				arguments[i].generateCode(currentScope, codeStream, true);
82
				arguments[i].generateCode(currentScope, codeStream, true);
83
				codeStream.arrayAtPut(elementsTypeID, false);
57
			}
84
			}
58
85
		} else if (argLength == paramLength) {
59
			ArrayBinding varArgsType = (ArrayBinding) params[varArgIndex]; // parameterType has to be an array type
86
			// right number of arguments - could be inexact - pass argument as is
60
			ArrayBinding codeGenVarArgsType = (ArrayBinding) binding.parameters[varArgIndex].erasure();
87
			TypeBinding lastType = arguments[varArgIndex].resolvedType;
61
			int elementsTypeID = varArgsType.elementsType().id;
88
			if (lastType == TypeBinding.NULL
62
			int argLength = arguments == null ? 0 : arguments.length;
89
				|| (varArgsType.dimensions() == lastType.dimensions()
63
90
					&& lastType.isCompatibleWith(varArgsType))) {
64
			if (argLength > paramLength) {
91
				// foo(1, new int[]{2, 3}) or foo(1, null) --> last arg is passed as-is
92
				arguments[varArgIndex].generateCode(currentScope, codeStream, true);
93
			} else {
65
				// right number but not directly compatible or too many arguments - wrap extra into array
94
				// right number but not directly compatible or too many arguments - wrap extra into array
66
				// called with (argLength - lastIndex) elements : foo(1, 2) or foo(1, 2, 3, 4)
67
				// need to gen elements into an array, then gen each remaining element into created array
95
				// need to gen elements into an array, then gen each remaining element into created array
68
				codeStream.generateInlinedValue(argLength - varArgIndex);
96
				codeStream.generateInlinedValue(1);
69
				codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
97
				codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
70
				for (int i = varArgIndex; i < argLength; i++) {
98
				codeStream.dup();
71
					codeStream.dup();
72
					codeStream.generateInlinedValue(i - varArgIndex);
73
					arguments[i].generateCode(currentScope, codeStream, true);
74
					codeStream.arrayAtPut(elementsTypeID, false);
75
				}
76
			} else if (argLength == paramLength) {
77
				// right number of arguments - could be inexact - pass argument as is
78
				TypeBinding lastType = arguments[varArgIndex].resolvedType;
79
				if (lastType == TypeBinding.NULL
80
					|| (varArgsType.dimensions() == lastType.dimensions()
81
						&& lastType.isCompatibleWith(varArgsType))) {
82
					// foo(1, new int[]{2, 3}) or foo(1, null) --> last arg is passed as-is
83
					arguments[varArgIndex].generateCode(currentScope, codeStream, true);
84
				} else {
85
					// right number but not directly compatible or too many arguments - wrap extra into array
86
					// need to gen elements into an array, then gen each remaining element into created array
87
					codeStream.generateInlinedValue(1);
88
					codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
89
					codeStream.dup();
90
					codeStream.generateInlinedValue(0);
91
					arguments[varArgIndex].generateCode(currentScope, codeStream, true);
92
					codeStream.arrayAtPut(elementsTypeID, false);
93
				}
94
			} else { // not enough arguments - pass extra empty array
95
				// scenario: foo(1) --> foo(1, new int[0])
96
				// generate code for an empty array of parameterType
97
				codeStream.generateInlinedValue(0);
99
				codeStream.generateInlinedValue(0);
98
				codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
100
				arguments[varArgIndex].generateCode(currentScope, codeStream, true);
101
				codeStream.arrayAtPut(elementsTypeID, false);
99
			}
102
			}
100
		} else if (arguments != null) { // standard generation for method arguments
103
		} else { // not enough arguments - pass extra empty array
101
			for (int i = 0, max = arguments.length; i < max; i++)
104
			// scenario: foo(1) --> foo(1, new int[0])
102
				arguments[i].generateCode(currentScope, codeStream, true);
105
			// generate code for an empty array of parameterType
106
			codeStream.generateInlinedValue(0);
107
			codeStream.newArray(codeGenVarArgsType); // create a mono-dimensional array
103
		}
108
		}
109
	} else if (arguments != null) { // standard generation for method arguments
110
		for (int i = 0, max = arguments.length; i < max; i++)
111
			arguments[i].generateCode(currentScope, codeStream, true);
104
	}
112
	}
113
}
105
114
106
	public abstract void generateCode(BlockScope currentScope, CodeStream codeStream);
115
public abstract void generateCode(BlockScope currentScope, CodeStream codeStream);
107
108
	public boolean isEmptyBlock() {
109
		return false;
110
	}
111
116
112
	public boolean isValidJavaStatement() {
117
public boolean isEmptyBlock() {
113
		//the use of this method should be avoid in most cases
118
	return false;
114
		//and is here mostly for documentation purpose.....
119
}
115
		//while the parser is responsable for creating
116
		//welled formed expression statement, which results
117
		//in the fact that java-non-semantic-expression-used-as-statement
118
		//should not be parsable...thus not being built.
119
		//It sounds like the java grammar as help the compiler job in removing
120
		//-by construction- some statement that would have no effect....
121
		//(for example all expression that may do side-effects are valid statement
122
		// -this is an appromative idea.....-)
123
120
124
		return true;
121
public boolean isValidJavaStatement() {
125
	}
122
	//the use of this method should be avoid in most cases
123
	//and is here mostly for documentation purpose.....
124
	//while the parser is responsable for creating
125
	//welled formed expression statement, which results
126
	//in the fact that java-non-semantic-expression-used-as-statement
127
	//should not be parsable...thus not being built.
128
	//It sounds like the java grammar as help the compiler job in removing
129
	//-by construction- some statement that would have no effect....
130
	//(for example all expression that may do side-effects are valid statement
131
	// -this is an appromative idea.....-)
126
132
127
	public StringBuffer print(int indent, StringBuffer output) {
133
	return true;
128
		return printStatement(indent, output);
134
}
129
	}
130
	public abstract StringBuffer printStatement(int indent, StringBuffer output);
131
135
132
	public abstract void resolve(BlockScope scope);
136
public StringBuffer print(int indent, StringBuffer output) {
137
	return printStatement(indent, output);
138
}
133
139
134
	/**
140
public abstract StringBuffer printStatement(int indent, StringBuffer output);
135
	 * Returns case constant associated to this statement (NotAConstant if none)
136
	 */
137
	public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) {
138
		// statement within a switch that are not case are treated as normal statement....
139
141
140
		resolve(scope);
142
public abstract void resolve(BlockScope scope);
141
		return Constant.NotAConstant;
142
	}
143
143
144
/**
145
 * Returns case constant associated to this statement (NotAConstant if none)
146
 */
147
public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) {
148
	// statement within a switch that are not case are treated as normal statement....
149
	resolve(scope);
150
	return Constant.NotAConstant;
151
}
144
}
152
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java (-9 / +5 lines)
Lines 72-88 Link Here
72
		this.kind = -1;
72
		this.kind = -1;
73
	}
73
	}
74
74
75
	public FlowInfo analyseCode(
75
	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
76
		BlockScope currentScope,
77
		FlowContext flowContext,
78
		FlowInfo flowInfo) {
79
		// initialize break and continue labels
76
		// initialize break and continue labels
80
		this.breakLabel = new BranchLabel();
77
		this.breakLabel = new BranchLabel();
81
		this.continueLabel = new BranchLabel();
78
		this.continueLabel = new BranchLabel();
79
		int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;
82
80
83
		// process the element variable and collection
81
		// process the element variable and collection
84
		this.collection.checkNPE(currentScope, flowContext, flowInfo);
82
		this.collection.checkNPE(currentScope, flowContext, flowInfo);
85
		flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);
83
		flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);		
86
		FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy());
84
		FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy());
87
85
88
		// element variable will be assigned when iterating
86
		// element variable will be assigned when iterating
Lines 101-110 Link Here
101
		if (!(this.action == null || (this.action.isEmptyBlock()
99
		if (!(this.action == null || (this.action.isEmptyBlock()
102
		        	&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
100
		        	&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {
103
101
104
			if (!this.action.complainIfUnreachable(actionInfo, this.scope, false)) {
102
			if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel) < Statement.COMPLAINED_UNREACHABLE) {
105
				actionInfo = this.action.
103
				actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
106
					analyseCode(this.scope, loopingContext, actionInfo).
107
					unconditionalCopy();
108
			}
104
			}
109
105
110
			// code generation can be optimized when no need to continue in the loop
106
			// code generation can be optimized when no need to continue in the loop
(-)compiler/org/eclipse/jdt/internal/compiler/ast/OR_OR_Expression.java (-1 / +4 lines)
Lines 56-62 Link Here
56
56
57
		int previousMode = rightInfo.reachMode();
57
		int previousMode = rightInfo.reachMode();
58
		if (isLeftOptimizedTrue){
58
		if (isLeftOptimizedTrue){
59
			rightInfo.setReachMode(FlowInfo.UNREACHABLE);
59
			if ((rightInfo.reachMode() & FlowInfo.UNREACHABLE) == 0) {
60
				currentScope.problemReporter().fakeReachable(this.right);
61
				rightInfo.setReachMode(FlowInfo.UNREACHABLE);
62
			}
60
		}
63
		}
61
		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
64
		rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo);
62
		FlowInfo mergedInfo = FlowInfo.conditional(
65
		FlowInfo mergedInfo = FlowInfo.conditional(
(-)compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java (-8 / +28 lines)
Lines 42-51 Link Here
42
	  CONSTRUCTOR_ACCESS = 0x8,
42
	  CONSTRUCTOR_ACCESS = 0x8,
43
	  METHOD_ACCESS = 0xC;
43
	  METHOD_ACCESS = 0xC;
44
44
45
public ProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
46
	super(policy, options, problemFactory);
47
}
48
45
private static int getElaborationId (int leadProblemId, byte elaborationVariant) {
49
private static int getElaborationId (int leadProblemId, byte elaborationVariant) {
46
	return leadProblemId << 8 | elaborationVariant; // leadProblemId comes into the higher order bytes
50
	return leadProblemId << 8 | elaborationVariant; // leadProblemId comes into the higher order bytes
47
}
51
}
48
49
public static int getIrritant(int problemID) {
52
public static int getIrritant(int problemID) {
50
	switch(problemID){
53
	switch(problemID){
51
54
Lines 326-331 Link Here
326
329
327
		case IProblem.ShouldImplementHashcode:
330
		case IProblem.ShouldImplementHashcode:
328
			return CompilerOptions.ShouldImplementHashcode;
331
			return CompilerOptions.ShouldImplementHashcode;
332
			
333
		case IProblem.DeadCode:
334
			return CompilerOptions.DeadCode;
329
	}
335
	}
330
	return 0;
336
	return 0;
331
}
337
}
Lines 375-380 Link Here
375
			case CompilerOptions.ComparingIdentical :
381
			case CompilerOptions.ComparingIdentical :
376
			case CompilerOptions.MissingSynchronizedModifierInInheritedMethod :
382
			case CompilerOptions.MissingSynchronizedModifierInInheritedMethod :
377
			case CompilerOptions.ShouldImplementHashcode :
383
			case CompilerOptions.ShouldImplementHashcode :
384
			case CompilerOptions.DeadCode :
378
				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
385
				return CategorizedProblem.CAT_POTENTIAL_PROGRAMMING_PROBLEM;
379
			
386
			
380
			case CompilerOptions.OverriddenPackageDefaultMethod :
387
			case CompilerOptions.OverriddenPackageDefaultMethod :
Lines 394-400 Link Here
394
			case CompilerOptions.UnhandledWarningToken :
401
			case CompilerOptions.UnhandledWarningToken :
395
			case CompilerOptions.UnusedWarningToken :
402
			case CompilerOptions.UnusedWarningToken :
396
			case CompilerOptions.UnusedLabel :
403
			case CompilerOptions.UnusedLabel :
397
			case CompilerOptions.RedundantSuperinterface :				
404
			case CompilerOptions.RedundantSuperinterface :	
398
				return CategorizedProblem.CAT_UNNECESSARY_CODE;					
405
				return CategorizedProblem.CAT_UNNECESSARY_CODE;					
399
406
400
			case CompilerOptions.UsingDeprecatedAPI :
407
			case CompilerOptions.UsingDeprecatedAPI :
Lines 442-450 Link Here
442
	}
449
	}
443
	return CategorizedProblem.CAT_INTERNAL;
450
	return CategorizedProblem.CAT_INTERNAL;
444
}
451
}
445
public ProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
446
	super(policy, options, problemFactory);
447
}
448
public void abortDueToInternalError(String errorMessage) {
452
public void abortDueToInternalError(String errorMessage) {
449
	this.abortDueToInternalError(errorMessage, null);
453
	this.abortDueToInternalError(errorMessage, null);
450
}
454
}
Lines 1248-1253 Link Here
1248
		nodeSourceStart(field, location),
1252
		nodeSourceStart(field, location),
1249
		nodeSourceEnd(field, location));
1253
		nodeSourceEnd(field, location));
1250
}
1254
}
1255
1251
public void deprecatedMethod(MethodBinding method, ASTNode location) {
1256
public void deprecatedMethod(MethodBinding method, ASTNode location) {
1252
	boolean isConstructor = method.isConstructor();
1257
	boolean isConstructor = method.isConstructor();
1253
	int severity = computeSeverity(isConstructor ? IProblem.UsingDeprecatedConstructor : IProblem.UsingDeprecatedMethod);
1258
	int severity = computeSeverity(isConstructor ? IProblem.UsingDeprecatedConstructor : IProblem.UsingDeprecatedMethod);
Lines 1332-1338 Link Here
1332
		statement.sourceStart,
1337
		statement.sourceStart,
1333
		statement.sourceEnd);
1338
		statement.sourceEnd);
1334
}
1339
}
1335
1336
public void duplicateEnumSpecialMethod(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
1340
public void duplicateEnumSpecialMethod(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
1337
    MethodBinding method = methodDecl.binding;
1341
    MethodBinding method = methodDecl.binding;
1338
	this.handle(
1342
	this.handle(
Lines 1348-1353 Link Here
1348
		methodDecl.sourceStart,
1352
		methodDecl.sourceStart,
1349
		methodDecl.sourceEnd);
1353
		methodDecl.sourceEnd);
1350
}
1354
}
1355
1351
public void duplicateFieldInType(SourceTypeBinding type, FieldDeclaration fieldDecl) {
1356
public void duplicateFieldInType(SourceTypeBinding type, FieldDeclaration fieldDecl) {
1352
	this.handle(
1357
	this.handle(
1353
		IProblem.DuplicateField,
1358
		IProblem.DuplicateField,
Lines 1356-1362 Link Here
1356
		fieldDecl.sourceStart,
1361
		fieldDecl.sourceStart,
1357
		fieldDecl.sourceEnd);
1362
		fieldDecl.sourceEnd);
1358
}
1363
}
1359
1360
public void duplicateImport(ImportReference importRef) {
1364
public void duplicateImport(ImportReference importRef) {
1361
	String[] arguments = new String[] {CharOperation.toString(importRef.tokens)};
1365
	String[] arguments = new String[] {CharOperation.toString(importRef.tokens)};
1362
	this.handle(
1366
	this.handle(
Lines 1366-1371 Link Here
1366
		importRef.sourceStart,
1370
		importRef.sourceStart,
1367
		importRef.sourceEnd);
1371
		importRef.sourceEnd);
1368
}
1372
}
1373
1369
public void duplicateInheritedMethods(SourceTypeBinding type, MethodBinding inheritedMethod1, MethodBinding inheritedMethod2) {
1374
public void duplicateInheritedMethods(SourceTypeBinding type, MethodBinding inheritedMethod1, MethodBinding inheritedMethod2) {
1370
	this.handle(
1375
	this.handle(
1371
		IProblem.DuplicateParameterizedMethods,
1376
		IProblem.DuplicateParameterizedMethods,
Lines 1400-1406 Link Here
1400
		nodeSourceStart(local, location),
1405
		nodeSourceStart(local, location),
1401
		nodeSourceEnd(local, location));
1406
		nodeSourceEnd(local, location));
1402
}
1407
}
1403
1404
public void duplicateMethodInType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, boolean equalParameters) {
1408
public void duplicateMethodInType(SourceTypeBinding type, AbstractMethodDeclaration methodDecl, boolean equalParameters) {
1405
    MethodBinding method = methodDecl.binding;
1409
    MethodBinding method = methodDecl.binding;
1406
    if (equalParameters) {
1410
    if (equalParameters) {
Lines 1438-1443 Link Here
1438
			methodDecl.sourceEnd);
1442
			methodDecl.sourceEnd);
1439
    }
1443
    }
1440
}
1444
}
1445
1441
public void duplicateModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
1446
public void duplicateModifierForField(ReferenceBinding type, FieldDeclaration fieldDecl) {
1442
/* to highlight modifiers use:
1447
/* to highlight modifiers use:
1443
	this.handle(
1448
	this.handle(
Lines 1638-1643 Link Here
1638
		expression.sourceStart,
1643
		expression.sourceStart,
1639
		expression.sourceEnd);
1644
		expression.sourceEnd);
1640
}
1645
}
1646
public void fakeReachable(ASTNode location) {
1647
	int sourceStart = location.sourceStart;
1648
	int sourceEnd = location.sourceEnd;
1649
	if (location instanceof LocalDeclaration) {
1650
		LocalDeclaration declaration = (LocalDeclaration) location;
1651
		sourceStart = declaration.declarationSourceStart;
1652
		sourceEnd = declaration.declarationSourceEnd;
1653
	}	
1654
	this.handle(
1655
		IProblem.DeadCode,
1656
		NoArgument,
1657
		NoArgument,
1658
		sourceStart,
1659
		sourceEnd);
1660
}
1641
public void fieldHiding(FieldDeclaration fieldDecl, Binding hiddenVariable) {
1661
public void fieldHiding(FieldDeclaration fieldDecl, Binding hiddenVariable) {
1642
	FieldBinding field = fieldDecl.binding;
1662
	FieldBinding field = fieldDecl.binding;
1643
	if (CharOperation.equals(TypeConstants.SERIALVERSIONUID, field.name)
1663
	if (CharOperation.equals(TypeConstants.SERIALVERSIONUID, field.name)
(-)compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties (+1 lines)
Lines 122-127 Link Here
122
146 = Default constructor cannot handle exception type {0} thrown by implicit super constructor. Must define an explicit constructor
122
146 = Default constructor cannot handle exception type {0} thrown by implicit super constructor. Must define an explicit constructor
123
147 = Unhandled exception type {0} thrown by implicit super constructor
123
147 = Unhandled exception type {0} thrown by implicit super constructor
124
124
125
149 = Dead code
125
150 = The type of the expression must be an array type but it resolved to {0}
126
150 = The type of the expression must be an array type but it resolved to {0}
126
151 = Must explicitly convert the char[] to a String
127
151 = Must explicitly convert the char[] to a String
127
152 = String constant is exceeding the limit of 65535 bytes of UTF8 encoding
128
152 = String constant is exceeding the limit of 65535 bytes of UTF8 encoding
(-)batch/org/eclipse/jdt/internal/compiler/batch/Main.java (+5 lines)
Lines 3141-3146 Link Here
3141
					CompilerOptions.OPTION_ReportDiscouragedReference,
3141
					CompilerOptions.OPTION_ReportDiscouragedReference,
3142
					isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
3142
					isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
3143
				return;
3143
				return;
3144
			} else if (token.equals("deadCode")) { //$NON-NLS-1$
3145
				this.options.put(
3146
					CompilerOptions.OPTION_ReportDeadCode,
3147
					isEnabling ? CompilerOptions.WARNING : CompilerOptions.IGNORE);
3148
				return;
3144
			}
3149
			}
3145
			break;
3150
			break;
3146
		case 'e' :
3151
		case 'e' :
(-)compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java (-1 / +9 lines)
Lines 123-128 Link Here
123
	public static final String OPTION_ReportComparingIdentical =  "org.eclipse.jdt.core.compiler.problem.comparingIdentical"; //$NON-NLS-1$
123
	public static final String OPTION_ReportComparingIdentical =  "org.eclipse.jdt.core.compiler.problem.comparingIdentical"; //$NON-NLS-1$
124
	public static final String OPTION_ReportMissingSynchronizedOnInheritedMethod =  "org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"; //$NON-NLS-1$
124
	public static final String OPTION_ReportMissingSynchronizedOnInheritedMethod =  "org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod"; //$NON-NLS-1$
125
	public static final String OPTION_ReportMissingHashCodeMethod =  "org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod"; //$NON-NLS-1$
125
	public static final String OPTION_ReportMissingHashCodeMethod =  "org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod"; //$NON-NLS-1$
126
	public static final String OPTION_ReportDeadCode =  "org.eclipse.jdt.core.compiler.problem.deadCode"; //$NON-NLS-1$
126
127
127
	// Backward compatibility
128
	// Backward compatibility
128
	public static final String OPTION_ReportInvalidAnnotation = "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"; //$NON-NLS-1$
129
	public static final String OPTION_ReportInvalidAnnotation = "org.eclipse.jdt.core.compiler.problem.invalidAnnotation"; //$NON-NLS-1$
Lines 225-231 Link Here
225
	public static final int MissingSynchronizedModifierInInheritedMethod= IrritantSet.GROUP1 | ASTNode.Bit29;
226
	public static final int MissingSynchronizedModifierInInheritedMethod= IrritantSet.GROUP1 | ASTNode.Bit29;
226
227
227
	// group 2
228
	// group 2
228
	public static final int ShouldImplementHashcode= IrritantSet.GROUP2 | ASTNode.Bit1;
229
	public static final int ShouldImplementHashcode = IrritantSet.GROUP2 | ASTNode.Bit1;
230
	public static final int DeadCode = IrritantSet.GROUP2 | ASTNode.Bit2;
229
	
231
	
230
	// Map: String optionKey --> Long irritant>
232
	// Map: String optionKey --> Long irritant>
231
	private static Map OptionToIrritants;
233
	private static Map OptionToIrritants;
Lines 478-483 Link Here
478
				return OPTION_ReportMissingSynchronizedOnInheritedMethod;
480
				return OPTION_ReportMissingSynchronizedOnInheritedMethod;
479
			case ShouldImplementHashcode :
481
			case ShouldImplementHashcode :
480
				return OPTION_ReportMissingHashCodeMethod;
482
				return OPTION_ReportMissingHashCodeMethod;
483
			case DeadCode :
484
				return OPTION_ReportDeadCode;
481
		}
485
		}
482
		return null;
486
		return null;
483
	}
487
	}
Lines 580-585 Link Here
580
			OPTION_ReportAnnotationSuperInterface,
584
			OPTION_ReportAnnotationSuperInterface,
581
			OPTION_ReportAssertIdentifier,
585
			OPTION_ReportAssertIdentifier,
582
			OPTION_ReportAutoboxing,
586
			OPTION_ReportAutoboxing,
587
			OPTION_ReportDeadCode,
583
			OPTION_ReportDeprecation,
588
			OPTION_ReportDeprecation,
584
			OPTION_ReportDiscouragedReference,
589
			OPTION_ReportDiscouragedReference,
585
			OPTION_ReportEmptyStatement,
590
			OPTION_ReportEmptyStatement,
Lines 893-898 Link Here
893
		optionsMap.put(OPTION_ReportComparingIdentical, getSeverityString(ComparingIdentical));
898
		optionsMap.put(OPTION_ReportComparingIdentical, getSeverityString(ComparingIdentical));
894
		optionsMap.put(OPTION_ReportMissingSynchronizedOnInheritedMethod, getSeverityString(MissingSynchronizedModifierInInheritedMethod));
899
		optionsMap.put(OPTION_ReportMissingSynchronizedOnInheritedMethod, getSeverityString(MissingSynchronizedModifierInInheritedMethod));
895
		optionsMap.put(OPTION_ReportMissingHashCodeMethod, getSeverityString(ShouldImplementHashcode));
900
		optionsMap.put(OPTION_ReportMissingHashCodeMethod, getSeverityString(ShouldImplementHashcode));
901
		optionsMap.put(OPTION_ReportDeadCode, getSeverityString(DeadCode));
896
		return optionsMap;
902
		return optionsMap;
897
	}
903
	}
898
904
Lines 1264-1269 Link Here
1264
		if ((optionValue = optionsMap.get(OPTION_ReportComparingIdentical)) != null) updateSeverity(ComparingIdentical, optionValue);
1270
		if ((optionValue = optionsMap.get(OPTION_ReportComparingIdentical)) != null) updateSeverity(ComparingIdentical, optionValue);
1265
		if ((optionValue = optionsMap.get(OPTION_ReportMissingSynchronizedOnInheritedMethod)) != null) updateSeverity(MissingSynchronizedModifierInInheritedMethod, optionValue);
1271
		if ((optionValue = optionsMap.get(OPTION_ReportMissingSynchronizedOnInheritedMethod)) != null) updateSeverity(MissingSynchronizedModifierInInheritedMethod, optionValue);
1266
		if ((optionValue = optionsMap.get(OPTION_ReportMissingHashCodeMethod)) != null) updateSeverity(ShouldImplementHashcode, optionValue);
1272
		if ((optionValue = optionsMap.get(OPTION_ReportMissingHashCodeMethod)) != null) updateSeverity(ShouldImplementHashcode, optionValue);
1273
		if ((optionValue = optionsMap.get(OPTION_ReportDeadCode)) != null) updateSeverity(DeadCode, optionValue);
1267
1274
1268
		// Javadoc options
1275
		// Javadoc options
1269
		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
1276
		if ((optionValue = optionsMap.get(OPTION_DocCommentSupport)) != null) {
Lines 1461-1466 Link Here
1461
		buf.append("\n\t- comparing identical expr: ").append(getSeverityString(ComparingIdentical)); //$NON-NLS-1$
1468
		buf.append("\n\t- comparing identical expr: ").append(getSeverityString(ComparingIdentical)); //$NON-NLS-1$
1462
		buf.append("\n\t- missing synchronized on inherited method: ").append(getSeverityString(MissingSynchronizedModifierInInheritedMethod)); //$NON-NLS-1$
1469
		buf.append("\n\t- missing synchronized on inherited method: ").append(getSeverityString(MissingSynchronizedModifierInInheritedMethod)); //$NON-NLS-1$
1463
		buf.append("\n\t- should implement hashCode() method: ").append(getSeverityString(ShouldImplementHashcode)); //$NON-NLS-1$
1470
		buf.append("\n\t- should implement hashCode() method: ").append(getSeverityString(ShouldImplementHashcode)); //$NON-NLS-1$
1471
		buf.append("\n\t- dead code: ").append(getSeverityString(DeadCode)); //$NON-NLS-1$
1464
		return buf.toString();
1472
		return buf.toString();
1465
	}
1473
	}
1466
	
1474
	
(-)compiler/org/eclipse/jdt/core/compiler/IProblem.java (+1 lines)
Lines 425-430 Link Here
425
	int UnhandledExceptionInImplicitConstructorCall = TypeRelated + 147;
425
	int UnhandledExceptionInImplicitConstructorCall = TypeRelated + 147;
426
426
427
	// expressions
427
	// expressions
428
	int DeadCode = Internal + 149;
428
	int ArrayReferenceRequired = Internal + 150;
429
	int ArrayReferenceRequired = Internal + 150;
429
	int NoImplicitStringConversionForCharArrayExpression = Internal + 151;
430
	int NoImplicitStringConversionForCharArrayExpression = Internal + 151;
430
	// constant expressions
431
	// constant expressions

Return to bug 48399