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
22package com.sun.org.apache.xalan.internal.xsltc.compiler;
23
24import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType;
25import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
26import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
27import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
28import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
29import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
30import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util;
31
32/**
33 * @author Jacek Ambroziak
34 * @author Santiago Pericas-Geertsen
35 * @author Morten Jorgensen
36 */
37final class When extends Instruction {
38
39    private Expression _test;
40    private boolean _ignore = false;
41
42    public void display(int indent) {
43        indent(indent);
44        Util.println("When");
45        indent(indent + IndentIncrement);
46        System.out.print("test ");
47        Util.println(_test.toString());
48        displayContents(indent + IndentIncrement);
49    }
50
51    public Expression getTest() {
52        return _test;
53    }
54
55    public boolean ignore() {
56        return(_ignore);
57    }
58
59    public void parseContents(Parser parser) {
60        _test = parser.parseExpression(this, "test", null);
61
62        // Ignore xsl:if when test is false (function-available() and
63        // element-available())
64        Object result = _test.evaluateAtCompileTime();
65        if (result != null && result instanceof Boolean) {
66            _ignore = !((Boolean) result).booleanValue();
67        }
68
69        parseChildren(parser);
70
71        // Make sure required attribute(s) have been set
72        if (_test.isDummy()) {
73            reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "test");
74        }
75    }
76
77    /**
78     * Type-check this when element. The test should always be type checked,
79     * while we do not bother with the contents if we know the test fails.
80     * This is important in cases where the "test" expression tests for
81     * the support of a non-available element, and the <xsl:when> body contains
82     * this non-available element.
83     */
84    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
85        // Type-check the test expression
86        if (_test.typeCheck(stable) instanceof BooleanType == false) {
87            _test = new CastExpr(_test, Type.Boolean);
88        }
89        // Type-check the contents (if necessary)
90        if (!_ignore) {
91            typeCheckContents(stable);
92        }
93
94        return Type.Void;
95    }
96
97    /**
98     * This method should never be called. An Otherwise object will explicitly
99     * translate the "test" expression and and contents of this element.
100     */
101    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
102        final ErrorMsg msg = new ErrorMsg(ErrorMsg.STRAY_WHEN_ERR, this);
103        getParser().reportError(Constants.ERROR, msg);
104    }
105}
106