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