1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Licensed to the Apache Software Foundation (ASF) under one or more 7 * contributor license agreements. See the NOTICE file distributed with 8 * this work for additional information regarding copyright ownership. 9 * The ASF licenses this file to You under the Apache License, Version 2.0 10 * (the "License"); you may not use this file except in compliance with 11 * the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22 package com.sun.org.apache.xalan.internal.xsltc.compiler; 23 24 import com.sun.org.apache.bcel.internal.generic.InstructionHandle; 25 import com.sun.org.apache.bcel.internal.generic.InstructionList; 26 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType; 27 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; 28 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; 29 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; 30 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; 31 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; 32 import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; 33 34 /** 35 * @author Jacek Ambroziak 36 * @author Santiago Pericas-Geertsen 37 * @author Morten Jorgensen 38 */ 39 final class If extends Instruction { 40 41 private Expression _test; 42 private boolean _ignore = false; 43 44 /** 45 * Display the contents of this element 46 */ 47 public void display(int indent) { 48 indent(indent); 49 Util.println("If"); 50 indent(indent + IndentIncrement); 51 System.out.print("test "); 52 Util.println(_test.toString()); 53 displayContents(indent + IndentIncrement); 54 } 55 56 /** 57 * Parse the "test" expression and contents of this element. 58 */ 59 public void parseContents(Parser parser) { 60 // Parse the "test" expression 61 _test = parser.parseExpression(this, "test", null); 62 63 // Make sure required attribute(s) have been set 64 if (_test.isDummy()) { 65 reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "test"); 66 return; 67 } 68 69 // Ignore xsl:if when test is false (function-available() and 70 // element-available()) 71 Object result = _test.evaluateAtCompileTime(); 72 if (result != null && result instanceof Boolean) { 73 _ignore = !((Boolean) result).booleanValue(); 74 } 75 76 parseChildren(parser); 77 } 78 79 /** 80 * Type-check the "test" expression and contents of this element. 81 * The contents will be ignored if we know the test will always fail. 82 */ 83 public Type typeCheck(SymbolTable stable) throws TypeCheckError { 84 // Type-check the "test" expression 85 if (_test.typeCheck(stable) instanceof BooleanType == false) { 86 _test = new CastExpr(_test, Type.Boolean); 87 } 88 // Type check the element contents 89 if (!_ignore) { 90 typeCheckContents(stable); 91 } 92 return Type.Void; 93 } 94 95 /** 96 * Translate the "test" expression and contents of this element. 97 * The contents will be ignored if we know the test will always fail. 98 */ 99 public void translate(ClassGenerator classGen, MethodGenerator methodGen) { 100 final InstructionList il = methodGen.getInstructionList(); 101 _test.translateDesynthesized(classGen, methodGen); 102 // remember end of condition 103 final InstructionHandle truec = il.getEnd(); 104 if (!_ignore) { 105 translateContents(classGen, methodGen); 106 } 107 _test.backPatchFalseList(il.append(NOP)); 108 _test.backPatchTrueList(truec.getNext()); 109 } 110 }