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

Collapse All | Expand All

(-)compiler/org/eclipse/jdt/internal/compiler/ast/Assignment.java (-28 / +3 lines)
Lines 53-86 Link Here
53
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
53
		.analyseAssignment(currentScope, flowContext, flowInfo, this, false)
54
		.unconditionalInits();
54
		.unconditionalInits();
55
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
55
	if (local != null && (local.type.tagBits & TagBits.IsBaseType) == 0) {
56
		switch(nullStatus) {
56
		flowInfo.markNullStatus(local, nullStatus);
57
			case FlowInfo.NULL :
57
		if (flowContext.initsOnFinally != null)
58
				flowInfo.markAsDefinitelyNull(local);
58
			flowContext.initsOnFinally.markNullStatus(local, nullStatus);
59
				break;
60
			case FlowInfo.NON_NULL :
61
				flowInfo.markAsDefinitelyNonNull(local);
62
				break;
63
			case FlowInfo.POTENTIALLY_NULL :
64
				flowInfo.markAsPotentiallyNull(local);
65
				break;
66
			default:
67
				flowInfo.markAsDefinitelyUnknown(local);
68
		}
69
		if (flowContext.initsOnFinally != null) {
70
			switch(nullStatus) {
71
				case FlowInfo.NULL :
72
					flowContext.initsOnFinally.markAsDefinitelyNull(local);
73
					break;
74
				case FlowInfo.NON_NULL :
75
					flowContext.initsOnFinally.markAsDefinitelyNonNull(local);
76
					break;
77
				case FlowInfo.POTENTIALLY_NULL :
78
					flowContext.initsOnFinally.markAsPotentiallyNull(local);
79
					break;
80
				default:
81
					flowContext.initsOnFinally.markAsDefinitelyUnknown(local);
82
			}
83
		}
84
	}
59
	}
85
	return flowInfo;
60
	return flowInfo;
86
}
61
}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java (-12 / +11 lines)
Lines 319-338 Link Here
319
	if (ifTrueNullStatus == ifFalseNullStatus) {
319
	if (ifTrueNullStatus == ifFalseNullStatus) {
320
		return ifTrueNullStatus;
320
		return ifTrueNullStatus;
321
	}
321
	}
322
	// is there a chance of null? -> potentially null
322
	// is there a chance of null (or non-null)? -> potentially null etc.
323
	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
323
	// https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125
324
	switch (ifTrueNullStatus) {
324
	int status = 0;
325
		case FlowInfo.NULL:
325
	int combinedStatus = ifTrueNullStatus|ifFalseNullStatus;
326
		case FlowInfo.POTENTIALLY_NULL:
326
	if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0)
327
			return FlowInfo.POTENTIALLY_NULL;
327
		status |= FlowInfo.POTENTIALLY_NULL;
328
	}
328
	if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0)
329
	switch (ifFalseNullStatus) {
329
		status |= FlowInfo.POTENTIALLY_NON_NULL;
330
		case FlowInfo.NULL:
330
	if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0)
331
		case FlowInfo.POTENTIALLY_NULL:
331
		status |= FlowInfo.POTENTIALLY_UNKNOWN;
332
			return FlowInfo.POTENTIALLY_NULL;
332
	if (status > 0)
333
	}
333
		return status;
334
	return FlowInfo.UNKNOWN;
334
	return FlowInfo.UNKNOWN;
335
	// cannot decide which branch to take, and they disagree
336
}
335
}
337
336
338
	public Constant optimizedBooleanConstant() {
337
	public Constant optimizedBooleanConstant() {
(-)compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java (-9 / +2 lines)
Lines 837-851 Link Here
837
	return FlowInfo.NON_NULL; // constant expression cannot be null
837
	return FlowInfo.NON_NULL; // constant expression cannot be null
838
838
839
	LocalVariableBinding local = localVariableBinding();
839
	LocalVariableBinding local = localVariableBinding();
840
	if (local != null) {
840
	if (local != null)
841
		if (flowInfo.isDefinitelyNull(local))
841
		return flowInfo.nullStatus(local);
842
			return FlowInfo.NULL;
843
		if (flowInfo.isDefinitelyNonNull(local))
844
			return FlowInfo.NON_NULL;
845
		if (flowInfo.isPotentiallyNull(local))
846
			return FlowInfo.POTENTIALLY_NULL;
847
		return FlowInfo.UNKNOWN;
848
	}
849
	return FlowInfo.NON_NULL;
842
	return FlowInfo.NON_NULL;
850
}
843
}
851
844
(-)compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java (-13 / +1 lines)
Lines 57-75 Link Here
57
	}
57
	}
58
	flowInfo.markAsDefinitelyAssigned(this.binding);
58
	flowInfo.markAsDefinitelyAssigned(this.binding);
59
	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
59
	if ((this.binding.type.tagBits & TagBits.IsBaseType) == 0) {
60
		switch(nullStatus) {
60
		flowInfo.markNullStatus(this.binding, nullStatus);
61
			case FlowInfo.NULL :
62
				flowInfo.markAsDefinitelyNull(this.binding);
63
				break;
64
			case FlowInfo.NON_NULL :
65
				flowInfo.markAsDefinitelyNonNull(this.binding);
66
				break;
67
			case FlowInfo.POTENTIALLY_NULL :
68
				flowInfo.markAsPotentiallyNull(this.binding);
69
				break;
70
			default:
71
				flowInfo.markAsDefinitelyUnknown(this.binding);
72
		}
73
		// no need to inform enclosing try block since its locals won't get
61
		// no need to inform enclosing try block since its locals won't get
74
		// known by the finally block
62
		// known by the finally block
75
	}
63
	}
(-)compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java (-9 / +2 lines)
Lines 770-784 Link Here
770
			return FlowInfo.UNKNOWN;
770
			return FlowInfo.UNKNOWN;
771
		case Binding.LOCAL : // reading a local variable
771
		case Binding.LOCAL : // reading a local variable
772
			LocalVariableBinding local = (LocalVariableBinding) this.binding;
772
			LocalVariableBinding local = (LocalVariableBinding) this.binding;
773
			if (local != null) {
773
			if (local != null)
774
				if (flowInfo.isDefinitelyNull(local))
774
				return flowInfo.nullStatus(local);
775
					return FlowInfo.NULL;
776
				if (flowInfo.isDefinitelyNonNull(local))
777
					return FlowInfo.NON_NULL;
778
				if (flowInfo.isPotentiallyNull(local))
779
					return FlowInfo.POTENTIALLY_NULL;
780
				return FlowInfo.UNKNOWN;
781
			}
782
	}
775
	}
783
	return FlowInfo.NON_NULL; // never get there
776
	return FlowInfo.NON_NULL; // never get there
784
}
777
}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/ConditionalFlowInfo.java (+15 lines)
Lines 162-167 Link Here
162
	this.initsWhenFalse.markAsPotentiallyNull(local);
162
	this.initsWhenFalse.markAsPotentiallyNull(local);
163
}
163
}
164
164
165
public void markAsPotentiallyNonNull(LocalVariableBinding local) {
166
	this.initsWhenTrue.markAsPotentiallyNonNull(local);
167
	this.initsWhenFalse.markAsPotentiallyNonNull(local);
168
}
169
170
public void markAsPotentiallyNullOrNonNull(LocalVariableBinding local) {
171
	this.initsWhenTrue.markAsPotentiallyNullOrNonNull(local);
172
	this.initsWhenFalse.markAsPotentiallyNullOrNonNull(local);
173
}
174
175
public void addPotentiallyUnknownMark(LocalVariableBinding local) {
176
	this.initsWhenTrue.addPotentiallyUnknownMark(local);
177
	this.initsWhenFalse.addPotentiallyUnknownMark(local);
178
}
179
165
public void markAsDefinitelyUnknown(LocalVariableBinding local) {
180
public void markAsDefinitelyUnknown(LocalVariableBinding local) {
166
	this.initsWhenTrue.markAsDefinitelyUnknown(local);
181
	this.initsWhenTrue.markAsDefinitelyUnknown(local);
167
	this.initsWhenFalse.markAsDefinitelyUnknown(local);
182
	this.initsWhenFalse.markAsDefinitelyUnknown(local);
(-)compiler/org/eclipse/jdt/internal/compiler/flow/FlowInfo.java (-4 / +79 lines)
Lines 23-32 Link Here
23
	public final static int UNREACHABLE = 1;
23
	public final static int UNREACHABLE = 1;
24
	public final static int NULL_FLAG_MASK = 2;
24
	public final static int NULL_FLAG_MASK = 2;
25
25
26
	public final static int UNKNOWN = 0;
26
	public final static int UNKNOWN = 1;
27
	public final static int NULL = 1;
27
	public final static int NULL = 2;
28
	public final static int NON_NULL = -1;
28
	public final static int NON_NULL = 4;
29
	public final static int POTENTIALLY_NULL = 2;
29
	public final static int POTENTIALLY_UNKNOWN = 8;
30
	public final static int POTENTIALLY_NULL = 16;
31
	public final static int POTENTIALLY_NON_NULL = 32;
30
32
31
	public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
33
	public static final UnconditionalFlowInfo DEAD_END; // Represents a dead branch status of initialization
32
	static {
34
	static {
Lines 255-260 Link Here
255
	abstract public void markAsPotentiallyNull(LocalVariableBinding local);
257
	abstract public void markAsPotentiallyNull(LocalVariableBinding local);
256
258
257
	/**
259
	/**
260
	 * Record a local may have got assigned to non-null.
261
	 */
262
	abstract public void markAsPotentiallyNonNull(LocalVariableBinding local);
263
264
	/**
265
	 * Record a local may have got assigned to null or to non-null.
266
	 */
267
	abstract public void markAsPotentiallyNullOrNonNull(LocalVariableBinding local);
268
	
269
	/**
270
	 * Add the marker bit for potentially unknown.
271
	 * Assumes that at most pot.null and pot.non-null have been set for 'local'.
272
	 */
273
	abstract public void addPotentiallyUnknownMark(LocalVariableBinding local);
274
275
	/**
258
	 * Record a local got definitely assigned.
276
	 * Record a local got definitely assigned.
259
	 */
277
	 */
260
	abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
278
	abstract public void markAsDefinitelyAssigned(LocalVariableBinding local);
Lines 265-270 Link Here
265
abstract public void markAsDefinitelyUnknown(LocalVariableBinding local);
283
abstract public void markAsDefinitelyUnknown(LocalVariableBinding local);
266
284
267
/**
285
/**
286
 * Mark the null status of the given local according to the given status
287
 * @param local
288
 * @param nullStatus bitset of FLowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
289
 */
290
public void markNullStatus(LocalVariableBinding local, int nullStatus) {
291
	switch(nullStatus) {
292
		case NULL :
293
			markAsDefinitelyNull(local);
294
			break;
295
		case NON_NULL :
296
			markAsDefinitelyNonNull(local);
297
			break;
298
		default:
299
			switch (nullStatus & (POTENTIALLY_NULL|POTENTIALLY_NON_NULL)) {
300
				case POTENTIALLY_NULL:
301
					markAsPotentiallyNull(local);
302
					break;
303
				case POTENTIALLY_NON_NULL:
304
					markAsPotentiallyNonNull(local);
305
					break;
306
				case POTENTIALLY_NULL|POTENTIALLY_NON_NULL:
307
					markAsPotentiallyNullOrNonNull(local);
308
					break;
309
				default:
310
					markAsDefinitelyUnknown(local);
311
					return;
312
			}
313
			if ((nullStatus & POTENTIALLY_UNKNOWN) != 0)
314
				// add this point only null and non-null bits can be set
315
				addPotentiallyUnknownMark(local);
316
	}
317
}
318
319
/**
320
 * Answer the null status of the given local
321
 * @param local
322
 * @return bitset of FLowInfo.UNKNOWN ... FlowInfo.POTENTIALLY_NON_NULL
323
 */
324
public int nullStatus(LocalVariableBinding local) {
325
	if (isDefinitelyNull(local))
326
		return NULL;
327
	if (isDefinitelyNonNull(local))
328
		return NON_NULL;
329
	int status = 0;
330
	if (isPotentiallyNull(local))
331
		status |= POTENTIALLY_NULL;
332
	if (isPotentiallyNonNull(local))
333
		status |= POTENTIALLY_NON_NULL;
334
	if (isPotentiallyUnknown(local))
335
		status |= POTENTIALLY_UNKNOWN;
336
	if (status > 0)
337
		return status;
338
	return UNKNOWN;
339
}
340
341
/**
268
 * Merge branches using optimized boolean conditions
342
 * Merge branches using optimized boolean conditions
269
 */
343
 */
270
public static UnconditionalFlowInfo mergedOptimizedBranches(
344
public static UnconditionalFlowInfo mergedOptimizedBranches(
Lines 482-485 Link Here
482
 */
556
 */
483
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448
557
//https://bugs.eclipse.org/bugs/show_bug.cgi?id=303448
484
abstract public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding local);
558
abstract public boolean isMarkedAsNullOrNonNullInAssertExpression(LocalVariableBinding local);
559
485
}
560
}
(-)compiler/org/eclipse/jdt/internal/compiler/flow/UnconditionalFlowInfo.java (+97 lines)
Lines 11-16 Link Here
11
 *******************************************************************************/
11
 *******************************************************************************/
12
package org.eclipse.jdt.internal.compiler.flow;
12
package org.eclipse.jdt.internal.compiler.flow;
13
13
14
import org.eclipse.core.runtime.Assert;
14
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
15
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
15
import org.eclipse.jdt.internal.compiler.impl.Constant;
16
import org.eclipse.jdt.internal.compiler.impl.Constant;
16
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
17
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
Lines 1363-1368 Link Here
1363
	}
1364
	}
1364
}
1365
}
1365
1366
1367
public void markAsPotentiallyNonNull(LocalVariableBinding local) {
1368
	if (this != DEAD_END) {
1369
		this.tagBits |= NULL_FLAG_MASK;
1370
        int position;
1371
        long mask;
1372
        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
1373
            // use bits
1374
            this.nullBit1 &= ~(mask = 1L << position);
1375
            this.nullBit2 &= ~mask;
1376
            this.nullBit3 |= mask;
1377
            this.nullBit4 &= ~mask;
1378
            if (COVERAGE_TEST_FLAG) {
1379
				if(CoverageTestId == 42) {
1380
				  	this.nullBit4 = ~0;
1381
				}
1382
			}
1383
        } else {
1384
    		// use extra vector
1385
    		int vectorIndex ;
1386
    		this.extra[2][vectorIndex = (position / BitCacheSize) - 1]
1387
    		    &= ~(mask = 1L << (position % BitCacheSize));
1388
    		this.extra[3][vectorIndex] &= ~mask;
1389
    		this.extra[4][vectorIndex] |= mask;
1390
    		this.extra[5][vectorIndex] &= ~mask;
1391
    		if (COVERAGE_TEST_FLAG) {
1392
				if(CoverageTestId == 43) {
1393
					this.extra[5][vectorIndex] = ~0;
1394
				}
1395
			}
1396
    	}
1397
	}
1398
}
1399
1400
public void markAsPotentiallyNullOrNonNull(LocalVariableBinding local) {
1401
	if (this != DEAD_END) {
1402
		this.tagBits |= NULL_FLAG_MASK;
1403
        int position;
1404
        long mask;
1405
        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
1406
            // use bits
1407
            this.nullBit1 &= ~(mask = 1L << position);
1408
            this.nullBit2 |= mask;
1409
            this.nullBit3 |= mask;
1410
            this.nullBit4 &= ~mask;
1411
            if (COVERAGE_TEST_FLAG) {
1412
				if(CoverageTestId == 44) {
1413
				  	this.nullBit4 = ~0;
1414
				}
1415
			}
1416
        } else {
1417
    		// use extra vector
1418
    		int vectorIndex ;
1419
    		this.extra[2][vectorIndex = (position / BitCacheSize) - 1]
1420
    		    &= ~(mask = 1L << (position % BitCacheSize));
1421
    		this.extra[3][vectorIndex] |= mask;
1422
    		this.extra[4][vectorIndex] |= mask;
1423
    		this.extra[5][vectorIndex] &= ~mask;
1424
    		if (COVERAGE_TEST_FLAG) {
1425
				if(CoverageTestId == 45) {
1426
					this.extra[5][vectorIndex] = ~0;
1427
				}
1428
			}
1429
    	}
1430
	}
1431
}
1432
1433
public void addPotentiallyUnknownMark(LocalVariableBinding local) {
1434
	if (this != DEAD_END) {
1435
		this.tagBits |= NULL_FLAG_MASK;
1436
        int position;
1437
        long mask;
1438
        if ((position = local.id + this.maxFieldCount) < BitCacheSize) {
1439
            // use bits
1440
        	mask = 1L << position;
1441
        	Assert.isTrue((this.nullBit1 & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$
1442
            this.nullBit4 |= mask;
1443
            if (COVERAGE_TEST_FLAG) {
1444
				if(CoverageTestId == 46) {
1445
				  	this.nullBit4 = ~0;
1446
				}
1447
			}
1448
        } else {
1449
    		// use extra vector
1450
    		int vectorIndex = (position / BitCacheSize) - 1;
1451
    		mask = 1L << (position % BitCacheSize);
1452
    		Assert.isTrue((this.extra[2][vectorIndex] & mask) == 0, "Adding 'unknown' mark in unexpected state"); //$NON-NLS-1$
1453
    		this.extra[5][vectorIndex] |= mask;
1454
    		if (COVERAGE_TEST_FLAG) {
1455
				if(CoverageTestId == 47) {
1456
					this.extra[5][vectorIndex] = ~0;
1457
				}
1458
			}
1459
    	}
1460
	}
1461
}
1462
1366
public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
1463
public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
1367
	if ((otherInits.tagBits & UNREACHABLE) != 0 && this != DEAD_END) {
1464
	if ((otherInits.tagBits & UNREACHABLE) != 0 && this != DEAD_END) {
1368
		if (COVERAGE_TEST_FLAG) {
1465
		if (COVERAGE_TEST_FLAG) {
(-)src/org/eclipse/jdt/core/tests/compiler/regression/NullReferenceTest.java (-1 / +98 lines)
Lines 35-41 Link Here
35
// Only the highest compliance level is run; add the VM argument
35
// Only the highest compliance level is run; add the VM argument
36
// -Dcompliance=1.4 (for example) to lower it if needed
36
// -Dcompliance=1.4 (for example) to lower it if needed
37
static {
37
static {
38
//		TESTS_NAMES = new String[] { "testBug320414" };
38
//		TESTS_NAMES = new String[] { "testBug324762a" };
39
//		TESTS_NUMBERS = new int[] { 561 };
39
//		TESTS_NUMBERS = new int[] { 561 };
40
//		TESTS_RANGE = new int[] { 1, 2049 };
40
//		TESTS_RANGE = new int[] { 1, 2049 };
41
}
41
}
Lines 13222-13225 Link Here
13222
		"Potential null pointer access: The variable y may be null at this location\n" + 
13222
		"Potential null pointer access: The variable y may be null at this location\n" + 
13223
		"----------\n");
13223
		"----------\n");
13224
}
13224
}
13225
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478 -  Report potentially null across variable assignment
13226
// test regression reported in comment 8
13227
public void testBug292478e() {
13228
	this.runConformTest(
13229
		new String[] {
13230
			"Test.java",
13231
			"public class Test {\n" +
13232
			"	Object foo(int i, boolean b1, boolean b2) {\n" +
13233
			"		Object o1 = null;\n" +
13234
			"		done : while (true) { \n" +
13235
			"			switch (i) {\n" +
13236
			"				case 1 :\n" +
13237
			"					Object o2 = null;\n" +
13238
			"					if (b2)\n" +
13239
			"						o2 = new Object();\n" +
13240
			"					o1 = o2;\n" +
13241
			"					break;\n" +
13242
			"				case 2 :\n" +
13243
			"					break done;\n" +
13244
			"			}\n" +
13245
			"		}		\n" +
13246
			"		if (o1 != null)\n" +
13247
			"			return o1;\n" +
13248
			"		return null;\n" +
13249
			"	}\n" +
13250
			"}\n"
13251
		});
13252
}
13253
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=292478 -  Report potentially null across variable assignment
13254
// variant where regression occurred inside the while-switch structure
13255
public void testBug292478f() {
13256
	this.runConformTest(
13257
		new String[] {
13258
			"Test.java",
13259
			"public class Test {\n" +
13260
			"	Object foo(int i, boolean b1, boolean b2) {\n" +
13261
			"		Object o1 = null;\n" +
13262
			"		done : while (true) { \n" +
13263
			"			switch (i) {\n" +
13264
			"				case 1 :\n" +
13265
			"					Object o2 = null;\n" +
13266
			"					if (b2)\n" +
13267
			"						o2 = new Object();\n" +
13268
			"					o1 = o2;\n" +
13269
			"					if (o1 != null)\n" +
13270
			"						return o1;\n" +
13271
			"					break;\n" +
13272
			"				case 2 :\n" +
13273
			"					break done;\n" +
13274
			"			}\n" +
13275
			"		}		\n" +
13276
			"		return null;\n" +
13277
			"	}\n" +
13278
			"}\n"
13279
		});
13280
}
13281
13282
// Bug 324762 -  Compiler thinks there is deadcode and removes it!
13283
// regression caused by the fix for bug 133125
13284
// ternary is non-null or null
13285
public void testBug324762() {
13286
	this.runConformTest(
13287
		new String[] {
13288
			"Test.java",
13289
			"public class Test {\n" +
13290
			"	void zork(boolean b1) {\n" +
13291
			"		Object satisfied = null;\n" +
13292
			"		if (b1) {\n" +
13293
			"			String[] s = new String[] { \"a\", \"b\" };\n" +
13294
			"			for (int k = 0; k < s.length && satisfied == null; k++)\n" +
13295
			"				satisfied = s.length > 1 ? new Object() : null;\n" +
13296
			"		}\n" +
13297
			"	}\n" +
13298
			"}\n"
13299
		});
13300
}
13301
13302
// Bug 324762 -  Compiler thinks there is deadcode and removes it!
13303
// regression caused by the fix for bug 133125
13304
// ternary is unknown or null
13305
public void testBug324762a() {
13306
	this.runConformTest(
13307
		new String[] {
13308
			"Test.java",
13309
			"public class Test {\n" +
13310
			"	void zork(boolean b1) {\n" +
13311
			"		Object satisfied = null;\n" +
13312
			"		if (b1) {\n" +
13313
			"			String[] s = new String[] { \"a\", \"b\" };\n" +
13314
			"			for (int k = 0; k < s.length && satisfied == null; k++)\n" +
13315
			"				satisfied = s.length > 1 ? bar() : null;\n" +
13316
			"		}\n" +
13317
			"	}\n" +
13318
			"	Object bar() { return null; }\n" +
13319
			"}\n"
13320
		});
13321
}
13225
}
13322
}

Return to bug 292478