/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.wst.jsdt.internal.compiler.ast; import org.eclipse.wst.jsdt.core.ast.IAND_AND_Expression; import org.eclipse.wst.jsdt.core.ast.IASTNode; import org.eclipse.wst.jsdt.internal.compiler.ASTVisitor; import org.eclipse.wst.jsdt.internal.compiler.flow.FlowContext; import org.eclipse.wst.jsdt.internal.compiler.flow.FlowInfo; import org.eclipse.wst.jsdt.internal.compiler.impl.Constant; import org.eclipse.wst.jsdt.internal.compiler.lookup.BlockScope; //dedicated treatment for the && public class AND_AND_Expression extends BinaryExpression implements IAND_AND_Expression { int rightInitStateIndex = -1; int mergedInitStateIndex = -1; public AND_AND_Expression(Expression left, Expression right, int operator) { super(left, right, operator); } public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { Constant cst = this.left.optimizedBooleanConstant(); boolean isLeftOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true; boolean isLeftOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false; if (isLeftOptimizedTrue) { // TRUE && anything // need to be careful of scenario: // (x && y) && !z, if passing the left info to the right, it would // be swapped by the ! FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo) .unconditionalInits(); mergedInfo = right.analyseCode(currentScope, flowContext, mergedInfo); // mergedInitStateIndex = currentScope.methodScope() // .recordInitializationStates(mergedInfo); return mergedInfo; } FlowInfo leftInfo = left.analyseCode(currentScope, flowContext, flowInfo); // need to be careful of scenario: // (x && y) && !z, if passing the left info to the right, it would be // swapped by the ! FlowInfo rightInfo = leftInfo.initsWhenTrue().unconditionalCopy(); // rightInitStateIndex = currentScope.methodScope().recordInitializationStates(rightInfo); int previousMode = rightInfo.reachMode(); if (isLeftOptimizedFalse) { rightInfo.setReachMode(FlowInfo.UNREACHABLE); } rightInfo = right.analyseCode(currentScope, flowContext, rightInfo); FlowInfo mergedInfo = FlowInfo.conditional( rightInfo.safeInitsWhenTrue(), leftInfo.initsWhenFalse().unconditionalInits().mergedWith( rightInfo.initsWhenFalse().setReachMode(previousMode).unconditionalInits())); // reset after trueMergedInfo got extracted // mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo); return mergedInfo; } public boolean isCompactableOperation() { return false; } public void traverse(ASTVisitor visitor, BlockScope scope) { if (visitor.visit(this, scope)) { left.traverse(visitor, scope); right.traverse(visitor, scope); } visitor.endVisit(this, scope); } public int getASTType() { return IASTNode.AND_AND_EXPRESSION; } }