Search in sources :

Example 1 with Type

use of org.apache.xalan.xsltc.compiler.util.Type in project servicemix-bundles by apache.

the class FunctionCall method typeCheckConstructor.

public Type typeCheckConstructor(SymbolTable stable) throws TypeCheckError {
    final Vector constructors = findConstructors();
    if (constructors == null) {
        // Constructor not found in this class
        throw new TypeCheckError(ErrorMsg.CONSTRUCTOR_NOT_FOUND, _className);
    }
    final int nConstructors = constructors.size();
    final int nArgs = _arguments.size();
    final Vector argsType = typeCheckArgs(stable);
    // Try all constructors
    int bestConstrDistance = Integer.MAX_VALUE;
    // reset
    _type = null;
    for (int j, i = 0; i < nConstructors; i++) {
        // Check if all parameters to this constructor can be converted
        final Constructor constructor = (Constructor) constructors.elementAt(i);
        final Class[] paramTypes = constructor.getParameterTypes();
        Class extType = null;
        int currConstrDistance = 0;
        for (j = 0; j < nArgs; j++) {
            // Convert from internal (translet) type to external (Java) type
            extType = paramTypes[j];
            final Type intType = (Type) argsType.elementAt(j);
            Object match = _internal2Java.maps(intType, extType);
            if (match != null) {
                currConstrDistance += ((JavaType) match).distance;
            } else if (intType instanceof ObjectType) {
                ObjectType objectType = (ObjectType) intType;
                if (objectType.getJavaClass() == extType)
                    continue;
                else if (extType.isAssignableFrom(objectType.getJavaClass()))
                    currConstrDistance += 1;
                else {
                    currConstrDistance = Integer.MAX_VALUE;
                    break;
                }
            } else {
                // no mapping available
                currConstrDistance = Integer.MAX_VALUE;
                break;
            }
        }
        if (j == nArgs && currConstrDistance < bestConstrDistance) {
            _chosenConstructor = constructor;
            _isExtConstructor = true;
            bestConstrDistance = currConstrDistance;
            _type = (_clazz != null) ? Type.newObjectType(_clazz) : Type.newObjectType(_className);
        }
    }
    if (_type != null) {
        return _type;
    }
    throw new TypeCheckError(ErrorMsg.ARGUMENT_CONVERSION_ERR, getMethodSignature(argsType));
}
Also used : ObjectType(org.apache.xalan.xsltc.compiler.util.ObjectType) BooleanType(org.apache.xalan.xsltc.compiler.util.BooleanType) Type(org.apache.xalan.xsltc.compiler.util.Type) ObjectType(org.apache.xalan.xsltc.compiler.util.ObjectType) IntType(org.apache.xalan.xsltc.compiler.util.IntType) MethodType(org.apache.xalan.xsltc.compiler.util.MethodType) ReferenceType(org.apache.xalan.xsltc.compiler.util.ReferenceType) Constructor(java.lang.reflect.Constructor) Vector(java.util.Vector) TypeCheckError(org.apache.xalan.xsltc.compiler.util.TypeCheckError)

Example 2 with Type

use of org.apache.xalan.xsltc.compiler.util.Type in project servicemix-bundles by apache.

the class FunctionCall method getMethodSignature.

/**
 * Return the signature of the current method
 */
private String getMethodSignature(Vector argsType) {
    final StringBuffer buf = new StringBuffer(_className);
    buf.append('.').append(_fname.getLocalPart()).append('(');
    int nArgs = argsType.size();
    for (int i = 0; i < nArgs; i++) {
        final Type intType = (Type) argsType.elementAt(i);
        buf.append(intType.toString());
        if (i < nArgs - 1)
            buf.append(", ");
    }
    buf.append(')');
    return buf.toString();
}
Also used : BooleanType(org.apache.xalan.xsltc.compiler.util.BooleanType) Type(org.apache.xalan.xsltc.compiler.util.Type) ObjectType(org.apache.xalan.xsltc.compiler.util.ObjectType) IntType(org.apache.xalan.xsltc.compiler.util.IntType) MethodType(org.apache.xalan.xsltc.compiler.util.MethodType) ReferenceType(org.apache.xalan.xsltc.compiler.util.ReferenceType)

Example 3 with Type

use of org.apache.xalan.xsltc.compiler.util.Type in project servicemix-bundles by apache.

the class FunctionCall method translate.

/**
 * Translate a function call. The compiled code will leave the function's
 * return value on the JVM's stack.
 */
public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
    final int n = argumentCount();
    final ConstantPoolGen cpg = classGen.getConstantPool();
    final InstructionList il = methodGen.getInstructionList();
    final boolean isSecureProcessing = classGen.getParser().getXSLTC().isSecureProcessing();
    int index;
    // Translate calls to methods in the BasisLibrary
    if (isStandard() || isExtension()) {
        for (int i = 0; i < n; i++) {
            final Expression exp = argument(i);
            exp.translate(classGen, methodGen);
            exp.startIterator(classGen, methodGen);
        }
        // append "F" to the function's name
        final String name = _fname.toString().replace('-', '_') + "F";
        String args = Constants.EMPTYSTRING;
        // Special precautions for some method calls
        if (name.equals("sumF")) {
            args = DOM_INTF_SIG;
            il.append(methodGen.loadDOM());
        } else if (name.equals("normalize_spaceF")) {
            if (_chosenMethodType.toSignature(args).equals("()Ljava/lang/String;")) {
                args = "I" + DOM_INTF_SIG;
                il.append(methodGen.loadContextNode());
                il.append(methodGen.loadDOM());
            }
        }
        // Invoke the method in the basis library
        index = cpg.addMethodref(BASIS_LIBRARY_CLASS, name, _chosenMethodType.toSignature(args));
        il.append(new INVOKESTATIC(index));
    } else // run-time error message for unsupported external functions
    if (unresolvedExternal) {
        index = cpg.addMethodref(BASIS_LIBRARY_CLASS, "unresolved_externalF", "(Ljava/lang/String;)V");
        il.append(new PUSH(cpg, _fname.toString()));
        il.append(new INVOKESTATIC(index));
    } else if (_isExtConstructor) {
        if (isSecureProcessing)
            translateUnallowedExtension(cpg, il);
        final String clazz = _chosenConstructor.getDeclaringClass().getName();
        Class[] paramTypes = _chosenConstructor.getParameterTypes();
        LocalVariableGen[] paramTemp = new LocalVariableGen[n];
        for (int i = 0; i < n; i++) {
            final Expression exp = argument(i);
            Type expType = exp.getType();
            exp.translate(classGen, methodGen);
            // Convert the argument to its Java type
            exp.startIterator(classGen, methodGen);
            expType.translateTo(classGen, methodGen, paramTypes[i]);
            paramTemp[i] = methodGen.addLocalVariable("function_call_tmp" + i, expType.toJCType(), null, null);
            paramTemp[i].setStart(il.append(expType.STORE(paramTemp[i].getIndex())));
        }
        il.append(new NEW(cpg.addClass(_className)));
        il.append(InstructionConstants.DUP);
        for (int i = 0; i < n; i++) {
            final Expression arg = argument(i);
            paramTemp[i].setEnd(il.append(arg.getType().LOAD(paramTemp[i].getIndex())));
        }
        final StringBuffer buffer = new StringBuffer();
        buffer.append('(');
        for (int i = 0; i < paramTypes.length; i++) {
            buffer.append(getSignature(paramTypes[i]));
        }
        buffer.append(')');
        buffer.append("V");
        index = cpg.addMethodref(clazz, "<init>", buffer.toString());
        il.append(new INVOKESPECIAL(index));
        // Convert the return type back to our internal type
        (Type.Object).translateFrom(classGen, methodGen, _chosenConstructor.getDeclaringClass());
    } else // Invoke function calls that are handled in separate classes
    {
        if (isSecureProcessing)
            translateUnallowedExtension(cpg, il);
        final String clazz = _chosenMethod.getDeclaringClass().getName();
        Class[] paramTypes = _chosenMethod.getParameterTypes();
        // Push "this" if it is an instance method
        if (_thisArgument != null) {
            _thisArgument.translate(classGen, methodGen);
        }
        for (int i = 0; i < n; i++) {
            final Expression exp = argument(i);
            exp.translate(classGen, methodGen);
            // Convert the argument to its Java type
            exp.startIterator(classGen, methodGen);
            exp.getType().translateTo(classGen, methodGen, paramTypes[i]);
        }
        final StringBuffer buffer = new StringBuffer();
        buffer.append('(');
        for (int i = 0; i < paramTypes.length; i++) {
            buffer.append(getSignature(paramTypes[i]));
        }
        buffer.append(')');
        buffer.append(getSignature(_chosenMethod.getReturnType()));
        if (_thisArgument != null && _clazz.isInterface()) {
            index = cpg.addInterfaceMethodref(clazz, _fname.getLocalPart(), buffer.toString());
            il.append(new INVOKEINTERFACE(index, n + 1));
        } else {
            index = cpg.addMethodref(clazz, _fname.getLocalPart(), buffer.toString());
            il.append(_thisArgument != null ? (InvokeInstruction) new INVOKEVIRTUAL(index) : (InvokeInstruction) new INVOKESTATIC(index));
        }
        // Convert the return type back to our internal type
        _type.translateFrom(classGen, methodGen, _chosenMethod.getReturnType());
    }
}
Also used : INVOKESTATIC(org.apache.bcel.generic.INVOKESTATIC) NEW(org.apache.bcel.generic.NEW) InstructionList(org.apache.bcel.generic.InstructionList) LocalVariableGen(org.apache.bcel.generic.LocalVariableGen) INVOKESPECIAL(org.apache.bcel.generic.INVOKESPECIAL) ConstantPoolGen(org.apache.bcel.generic.ConstantPoolGen) InvokeInstruction(org.apache.bcel.generic.InvokeInstruction) BooleanType(org.apache.xalan.xsltc.compiler.util.BooleanType) Type(org.apache.xalan.xsltc.compiler.util.Type) ObjectType(org.apache.xalan.xsltc.compiler.util.ObjectType) IntType(org.apache.xalan.xsltc.compiler.util.IntType) MethodType(org.apache.xalan.xsltc.compiler.util.MethodType) ReferenceType(org.apache.xalan.xsltc.compiler.util.ReferenceType) INVOKEINTERFACE(org.apache.bcel.generic.INVOKEINTERFACE) INVOKEVIRTUAL(org.apache.bcel.generic.INVOKEVIRTUAL) PUSH(org.apache.bcel.generic.PUSH)

Example 4 with Type

use of org.apache.xalan.xsltc.compiler.util.Type in project servicemix-bundles by apache.

the class FunctionCall method translateDesynthesized.

/**
 * Compile the function call and treat as an expression
 * Update true/false-lists.
 */
public void translateDesynthesized(ClassGenerator classGen, MethodGenerator methodGen) {
    Type type = Type.Boolean;
    if (_chosenMethodType != null)
        type = _chosenMethodType.resultType();
    final InstructionList il = methodGen.getInstructionList();
    translate(classGen, methodGen);
    if ((type instanceof BooleanType) || (type instanceof IntType)) {
        _falseList.add(il.append(new IFEQ(null)));
    }
}
Also used : BooleanType(org.apache.xalan.xsltc.compiler.util.BooleanType) Type(org.apache.xalan.xsltc.compiler.util.Type) ObjectType(org.apache.xalan.xsltc.compiler.util.ObjectType) IntType(org.apache.xalan.xsltc.compiler.util.IntType) MethodType(org.apache.xalan.xsltc.compiler.util.MethodType) ReferenceType(org.apache.xalan.xsltc.compiler.util.ReferenceType) InstructionList(org.apache.bcel.generic.InstructionList) BooleanType(org.apache.xalan.xsltc.compiler.util.BooleanType) IFEQ(org.apache.bcel.generic.IFEQ) IntType(org.apache.xalan.xsltc.compiler.util.IntType)

Example 5 with Type

use of org.apache.xalan.xsltc.compiler.util.Type in project servicemix-bundles by apache.

the class FunctionCall method typeCheckExternal.

/**
 * Type check a call to an external (Java) method.
 * The method must be static an public, and a legal type conversion
 * must exist for all its arguments and its return type.
 * Every method of name <code>_fname</code> is inspected
 * as a possible candidate.
 */
public Type typeCheckExternal(SymbolTable stable) throws TypeCheckError {
    int nArgs = _arguments.size();
    final String name = _fname.getLocalPart();
    // check if function is a contructor 'new'
    if (_fname.getLocalPart().equals("new")) {
        return typeCheckConstructor(stable);
    } else // check if we are calling an instance method
    {
        boolean hasThisArgument = false;
        if (nArgs == 0)
            _isStatic = true;
        if (!_isStatic) {
            if (_namespace_format == NAMESPACE_FORMAT_JAVA || _namespace_format == NAMESPACE_FORMAT_PACKAGE)
                hasThisArgument = true;
            Expression firstArg = (Expression) _arguments.elementAt(0);
            Type firstArgType = (Type) firstArg.typeCheck(stable);
            if (_namespace_format == NAMESPACE_FORMAT_CLASS && firstArgType instanceof ObjectType && _clazz != null && _clazz.isAssignableFrom(((ObjectType) firstArgType).getJavaClass()))
                hasThisArgument = true;
            if (hasThisArgument) {
                _thisArgument = (Expression) _arguments.elementAt(0);
                _arguments.remove(0);
                nArgs--;
                if (firstArgType instanceof ObjectType) {
                    _className = ((ObjectType) firstArgType).getJavaClassName();
                } else
                    throw new TypeCheckError(ErrorMsg.NO_JAVA_FUNCT_THIS_REF, name);
            }
        } else if (_className.length() == 0) {
            /*
		 * Warn user if external function could not be resolved.
		 * Warning will _NOT_ be issued is the call is properly
		 * wrapped in an <xsl:if> or <xsl:when> element. For details
		 * see If.parserContents() and When.parserContents()
		 */
            final Parser parser = getParser();
            if (parser != null) {
                reportWarning(this, parser, ErrorMsg.FUNCTION_RESOLVE_ERR, _fname.toString());
            }
            unresolvedExternal = true;
            // use "Int" as "unknown"
            return _type = Type.Int;
        }
    }
    final Vector methods = findMethods();
    if (methods == null) {
        // Method not found in this class
        throw new TypeCheckError(ErrorMsg.METHOD_NOT_FOUND_ERR, _className + "." + name);
    }
    Class extType = null;
    final int nMethods = methods.size();
    final Vector argsType = typeCheckArgs(stable);
    // Try all methods to identify the best fit
    int bestMethodDistance = Integer.MAX_VALUE;
    // reset internal type
    _type = null;
    for (int j, i = 0; i < nMethods; i++) {
        // Check if all paramteters to this method can be converted
        final Method method = (Method) methods.elementAt(i);
        final Class[] paramTypes = method.getParameterTypes();
        int currMethodDistance = 0;
        for (j = 0; j < nArgs; j++) {
            // Convert from internal (translet) type to external (Java) type
            extType = paramTypes[j];
            final Type intType = (Type) argsType.elementAt(j);
            Object match = _internal2Java.maps(intType, extType);
            if (match != null) {
                currMethodDistance += ((JavaType) match).distance;
            } else {
                // the moment. The real type checking is performed at runtime.
                if (intType instanceof ReferenceType) {
                    currMethodDistance += 1;
                } else if (intType instanceof ObjectType) {
                    ObjectType object = (ObjectType) intType;
                    if (extType.getName().equals(object.getJavaClassName()))
                        currMethodDistance += 0;
                    else if (extType.isAssignableFrom(object.getJavaClass()))
                        currMethodDistance += 1;
                    else {
                        currMethodDistance = Integer.MAX_VALUE;
                        break;
                    }
                } else {
                    currMethodDistance = Integer.MAX_VALUE;
                    break;
                }
            }
        }
        if (j == nArgs) {
            // Check if the return type can be converted
            extType = method.getReturnType();
            _type = (Type) _java2Internal.get(extType);
            if (_type == null) {
                _type = Type.newObjectType(extType);
            }
            // Use this method if all parameters & return type match
            if (_type != null && currMethodDistance < bestMethodDistance) {
                _chosenMethod = method;
                bestMethodDistance = currMethodDistance;
            }
        }
    }
    // have a this argument.
    if (_chosenMethod != null && _thisArgument == null && !Modifier.isStatic(_chosenMethod.getModifiers())) {
        throw new TypeCheckError(ErrorMsg.NO_JAVA_FUNCT_THIS_REF, getMethodSignature(argsType));
    }
    if (_type != null) {
        if (_type == Type.NodeSet) {
            getXSLTC().setMultiDocument(true);
        }
        return _type;
    }
    throw new TypeCheckError(ErrorMsg.ARGUMENT_CONVERSION_ERR, getMethodSignature(argsType));
}
Also used : Method(java.lang.reflect.Method) ReferenceType(org.apache.xalan.xsltc.compiler.util.ReferenceType) ObjectType(org.apache.xalan.xsltc.compiler.util.ObjectType) BooleanType(org.apache.xalan.xsltc.compiler.util.BooleanType) Type(org.apache.xalan.xsltc.compiler.util.Type) ObjectType(org.apache.xalan.xsltc.compiler.util.ObjectType) IntType(org.apache.xalan.xsltc.compiler.util.IntType) MethodType(org.apache.xalan.xsltc.compiler.util.MethodType) ReferenceType(org.apache.xalan.xsltc.compiler.util.ReferenceType) Vector(java.util.Vector) TypeCheckError(org.apache.xalan.xsltc.compiler.util.TypeCheckError)

Aggregations

BooleanType (org.apache.xalan.xsltc.compiler.util.BooleanType)6 IntType (org.apache.xalan.xsltc.compiler.util.IntType)6 MethodType (org.apache.xalan.xsltc.compiler.util.MethodType)6 ObjectType (org.apache.xalan.xsltc.compiler.util.ObjectType)6 ReferenceType (org.apache.xalan.xsltc.compiler.util.ReferenceType)6 Type (org.apache.xalan.xsltc.compiler.util.Type)6 Vector (java.util.Vector)3 TypeCheckError (org.apache.xalan.xsltc.compiler.util.TypeCheckError)3 InstructionList (org.apache.bcel.generic.InstructionList)2 Constructor (java.lang.reflect.Constructor)1 Method (java.lang.reflect.Method)1 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)1 IFEQ (org.apache.bcel.generic.IFEQ)1 INVOKEINTERFACE (org.apache.bcel.generic.INVOKEINTERFACE)1 INVOKESPECIAL (org.apache.bcel.generic.INVOKESPECIAL)1 INVOKESTATIC (org.apache.bcel.generic.INVOKESTATIC)1 INVOKEVIRTUAL (org.apache.bcel.generic.INVOKEVIRTUAL)1 InvokeInstruction (org.apache.bcel.generic.InvokeInstruction)1 LocalVariableGen (org.apache.bcel.generic.LocalVariableGen)1 NEW (org.apache.bcel.generic.NEW)1