|
Lines 1-5
Link Here
|
| 1 |
/******************************************************************************* |
1 |
/******************************************************************************* |
| 2 |
* Copyright (c) 2000, 2008 IBM Corporation and others. |
2 |
* Copyright (c) 2000, 2010 IBM Corporation and others. |
| 3 |
* All rights reserved. This program and the accompanying materials |
3 |
* All rights reserved. This program and the accompanying materials |
| 4 |
* are made available under the terms of the Eclipse Public License v1.0 |
4 |
* are made available under the terms of the Eclipse Public License v1.0 |
| 5 |
* which accompanies this distribution, and is available at |
5 |
* which accompanies this distribution, and is available at |
|
Lines 11-21
Link Here
|
| 11 |
package org.eclipse.jdt.internal.compiler.ast; |
11 |
package org.eclipse.jdt.internal.compiler.ast; |
| 12 |
|
12 |
|
| 13 |
import org.eclipse.jdt.internal.compiler.ASTVisitor; |
13 |
import org.eclipse.jdt.internal.compiler.ASTVisitor; |
| 14 |
import org.eclipse.jdt.internal.compiler.impl.*; |
|
|
| 15 |
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
14 |
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; |
| 16 |
import org.eclipse.jdt.internal.compiler.codegen.*; |
15 |
import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; |
| 17 |
import org.eclipse.jdt.internal.compiler.flow.*; |
16 |
import org.eclipse.jdt.internal.compiler.codegen.CodeStream; |
| 18 |
import org.eclipse.jdt.internal.compiler.lookup.*; |
17 |
import org.eclipse.jdt.internal.compiler.flow.FlowContext; |
|
|
18 |
import org.eclipse.jdt.internal.compiler.flow.FlowInfo; |
| 19 |
import org.eclipse.jdt.internal.compiler.impl.Constant; |
| 20 |
import org.eclipse.jdt.internal.compiler.impl.BooleanConstant; |
| 21 |
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; |
| 22 |
import org.eclipse.jdt.internal.compiler.lookup.BlockScope; |
| 23 |
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; |
| 24 |
import org.eclipse.jdt.internal.compiler.lookup.TypeIds; |
| 19 |
|
25 |
|
| 20 |
public class BinaryExpression extends OperatorExpression { |
26 |
public class BinaryExpression extends OperatorExpression { |
| 21 |
|
27 |
|
|
Lines 64-69
Link Here
|
| 64 |
this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()) |
70 |
this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()) |
| 65 |
.unconditionalInits(); |
71 |
.unconditionalInits(); |
| 66 |
} else { |
72 |
} else { |
|
|
73 |
if ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == OR) { |
| 74 |
Constant cst = this.left.optimizedBooleanConstant(); |
| 75 |
if (cst instanceof BooleanConstant) { |
| 76 |
boolean isLeftOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false; |
| 77 |
if (isLeftOptimizedFalse) { |
| 78 |
// FALSE | anything |
| 79 |
FlowInfo mergedInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); |
| 80 |
mergedInfo = this.right.analyseCode(currentScope, flowContext, mergedInfo); |
| 81 |
return mergedInfo; |
| 82 |
} |
| 83 |
} |
| 84 |
this.left.checkNPE(currentScope, flowContext, flowInfo); |
| 85 |
FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo); |
| 86 |
this.right.checkNPE(currentScope, flowContext, leftInfo); |
| 87 |
FlowInfo rightInfo = leftInfo.unconditionalCopy(); |
| 88 |
FlowInfo rightInfoWhenExpressionFalse = leftInfo.initsWhenFalse().unconditionalCopy(); |
| 89 |
rightInfoWhenExpressionFalse = this.right.analyseCode(currentScope, flowContext, rightInfoWhenExpressionFalse); |
| 90 |
rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo); |
| 91 |
|
| 92 |
FlowInfo leftInfoWhenTrue = leftInfo.initsWhenTrue().unconditionalCopy(); |
| 93 |
FlowInfo leftInfoWhenFalse = leftInfo.initsWhenFalse().unconditionalCopy(); |
| 94 |
|
| 95 |
//following steps are needed to ensure the initializations of rightInfo are not lost while merging |
| 96 |
leftInfoWhenTrue.addPotentialInitializationsFrom(rightInfo.unconditionalInitsWithoutSideEffect()); |
| 97 |
leftInfoWhenFalse.addPotentialInitializationsFrom(rightInfo.unconditionalInitsWithoutSideEffect()); |
| 98 |
/* Merging as follows: |
| 99 |
* For the whole expression to be true, conditions: |
| 100 |
* 1. left is false, right is true |
| 101 |
* 2. left is true, right is false |
| 102 |
* 3. left is true, right is true |
| 103 |
* For the whole expression to be false, condition: |
| 104 |
* left is false, right is false. |
| 105 |
*/ |
| 106 |
FlowInfo mergedInfo = FlowInfo.conditional( |
| 107 |
leftInfoWhenTrue.unconditionalInits().mergedWith( |
| 108 |
rightInfo.initsWhenTrue().unconditionalInits()).mergedWith( |
| 109 |
leftInfoWhenTrue.unconditionalInits().mergedWith( |
| 110 |
rightInfo.initsWhenFalse().unconditionalInits())).mergedWith( |
| 111 |
leftInfoWhenFalse.unconditionalInits().mergedWith( |
| 112 |
rightInfo.initsWhenTrue().unconditionalInits())), |
| 113 |
rightInfoWhenExpressionFalse.initsWhenFalse()); |
| 114 |
return mergedInfo; |
| 115 |
} else if ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT == AND) { |
| 116 |
Constant cst = this.left.optimizedBooleanConstant(); |
| 117 |
if (cst instanceof BooleanConstant) { |
| 118 |
boolean isLeftOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true; |
| 119 |
if (isLeftOptimizedTrue) { |
| 120 |
// TRUE & anything |
| 121 |
FlowInfo mergedInfo = this.left.analyseCode(currentScope, flowContext, flowInfo) |
| 122 |
.unconditionalInits(); |
| 123 |
mergedInfo = this.right.analyseCode(currentScope, flowContext, mergedInfo); |
| 124 |
return mergedInfo; |
| 125 |
} |
| 126 |
} |
| 127 |
this.left.checkNPE(currentScope, flowContext, flowInfo); |
| 128 |
FlowInfo leftInfo = this.left.analyseCode(currentScope, flowContext, flowInfo); |
| 129 |
this.right.checkNPE(currentScope, flowContext, leftInfo); |
| 130 |
FlowInfo rightInfo = leftInfo.initsWhenTrue().unconditionalCopy(); |
| 131 |
rightInfo = this.right.analyseCode(currentScope, flowContext, rightInfo); |
| 132 |
FlowInfo leftInfoWhenFalse = leftInfo.initsWhenFalse(); |
| 133 |
// The following step is to make sure that while merging and creating mergedInfo |
| 134 |
// we don't miss out potentially null candidates in rightInfo |
| 135 |
// This is because if a variable is definitely null in rightInfo.initsWhenFalse, and its nullness |
| 136 |
// is not known in leftInfo.initsWhenFalse, the merging will leave it out while taking |
| 137 |
// intersection of definitely null variables. So we just need to make sure that leftInfo.initsWhenFalse |
| 138 |
// also knows about it. |
| 139 |
leftInfoWhenFalse.addPotentialInitializationsFrom(rightInfo.unconditionalInitsWithoutSideEffect()); |
| 140 |
/* Merging as follows: |
| 141 |
* For the whole expression to be true, conditions: |
| 142 |
* left is false, right is false. |
| 143 |
* For the whole expression to be false, condition: |
| 144 |
* 1. left is false, right is true |
| 145 |
* 2. left is true, right is false |
| 146 |
* 3. left is false, right is false |
| 147 |
*/ |
| 148 |
FlowInfo mergedInfo = FlowInfo.conditional( |
| 149 |
rightInfo.safeInitsWhenTrue(), |
| 150 |
leftInfo.initsWhenTrue().unconditionalInits().mergedWith( |
| 151 |
rightInfo.initsWhenFalse().unconditionalInits()).mergedWith( |
| 152 |
leftInfoWhenFalse.unconditionalInits().mergedWith( |
| 153 |
rightInfo.initsWhenFalse().unconditionalInits())).mergedWith( |
| 154 |
leftInfoWhenFalse.unconditionalInits().mergedWith( |
| 155 |
rightInfo.initsWhenTrue().unconditionalInits()))); |
| 156 |
return mergedInfo; |
| 157 |
} |
| 67 |
this.left.checkNPE(currentScope, flowContext, flowInfo); |
158 |
this.left.checkNPE(currentScope, flowContext, flowInfo); |
| 68 |
flowInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); |
159 |
flowInfo = this.left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); |
| 69 |
this.right.checkNPE(currentScope, flowContext, flowInfo); |
160 |
this.right.checkNPE(currentScope, flowContext, flowInfo); |