📄 nonstaticmethodcallnode.java
字号:
* QUERY_INVARIANT - invariant within the life of a query * (constant expressions) * * @return The variant type for the underlying expression. */ protected int getOrderableVariantType() throws StandardException { int receiverVariant = receiver.getOrderableVariantType(); if (receiverVariant > Qualifier.SCAN_INVARIANT) { // If the method call is related to a trigger then the return // values are SCAN_INVARIANT even though their calls look QUERY_INVARIANT // because they take no parameters. if (receiver.getJavaTypeName().equals("org.apache.derby.iapi.db.TriggerExecutionContext")) receiverVariant = Qualifier.SCAN_INVARIANT; } int thisVariant = super.getOrderableVariantType(); if (receiverVariant < thisVariant) //return the more variant one return receiverVariant; return thisVariant; } /** * Remap all ColumnReferences in this tree to be clones of the * underlying expression. * * @return JavaValueNode The remapped expression tree. * * @exception StandardException Thrown on error */ public JavaValueNode remapColumnReferencesToExpressions() throws StandardException { if (receiver != null) { receiver.remapColumnReferencesToExpressions(); } return super.remapColumnReferencesToExpressions(); } /** * Prints the sub-nodes of this object. See QueryTreeNode.java for * how tree printing is supposed to work. * * @param depth The depth of this node in the tree * * @return Nothing */ public void printSubNodes(int depth) { if (SanityManager.DEBUG) { int parm; super.printSubNodes(depth); if (receiver != null) { printLabel(depth, "receiver :"); receiver.treePrint(depth + 1); } } } /** * Preprocess an expression tree. We do a number of transformations * here (including subqueries, IN lists, LIKE and BETWEEN) plus * subquery flattening. * NOTE: This is done before the outer ResultSetNode is preprocessed. * * @param numTables Number of tables in the DML Statement * @param outerFromList FromList from outer query block * @param outerSubqueryList SubqueryList from outer query block * @param outerPredicateList PredicateList from outer query block * * @return Nothing. * * @exception StandardException Thrown on error */ public void preprocess(int numTables, FromList outerFromList, SubqueryList outerSubqueryList, PredicateList outerPredicateList) throws StandardException { super.preprocess(numTables, outerFromList, outerSubqueryList, outerPredicateList); receiver.preprocess(numTables, outerFromList, outerSubqueryList, outerPredicateList); } /** * Do code generation for this method call * * @param acb The ExpressionClassBuilder for the class we're generating * @param mb The method the expression will go into * * * @exception StandardException Thrown on error */ public void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException { boolean inConditional = false; /* ** If this method returns its value to the Java domain, ** generate the receiver and put the value in a field (only if ** this method does not return a primitive type). If it ** returns its value to the SQL domain, it's up to the JavaToSQLNode ** to call generateReceiver(). ** ** Also, don't do this if the return value from this method ** call will be discarded. This is the case for a CALL statement. ** One reason we don't want to do this for a CALL statement ** is that the ?: operator cannot be made into a statement. */ if ( ( ! valueReturnedToSQLDomain()) && ( ! returnValueDiscarded())) { if (generateReceiver(acb, mb, receiver)) { /* ** If the above did generate the expression, let's test it for ** a null value. */ /* ** Generate the following to test for null: ** ** (receiverExpression == null) ? */ inConditional = true; mb.conditionalIfNull(); mb.pushNull(getJavaTypeName()); mb.startElseCode(); } } /* ** Generate the following: ** ** <receiver>.<method name>(<param> (, <param> )* ) ** ** for non-static calls. ** ** Refer to the field holding the receiver, if there is any. */ Class declaringClass = method.getDeclaringClass(); /* ** If it's an interface, generate an interface method call, if it's a static, ** generate a static method call, otherwise generate a regular method call. */ short methodType; if (declaringClass.isInterface()) methodType = VMOpcode.INVOKEINTERFACE; else if (isStatic) methodType = VMOpcode.INVOKESTATIC; else methodType = VMOpcode.INVOKEVIRTUAL; getReceiverExpression(acb, mb, receiver); if (isStatic) mb.endStatement(); // PUSHCOMPILER ??? int nargs = generateParameters(acb, mb); mb.callMethod(methodType, declaringClass.getName(), methodName, getJavaTypeName(), nargs); if (inConditional) mb.completeConditional(); } /** * Generate the expression that evaluates to the receiver. This is * for the case where a java expression is being returned to the SQL * domain, and we need to check whether the receiver is null (if so, * the SQL value should be set to null, and this Java expression * not evaluated). Instance method calls and field references have * receivers, while class method calls and calls to constructors do * not. If this Java expression does not have a receiver, this method * returns null. * * Only generate the receiver once and cache it in a field. This is * because there will be two references to the receiver, and we want * to evaluate it only once. * * * @param acb The ExpressionClassBuilder for the class being built * @param mb The method the expression will go into * * @return true if compiled receiver, false otherwise. * * @exception StandardException Thrown on error */ protected boolean generateReceiver(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException { /* ** Let's pretend that a call to a static method doesn't have a ** receiver, since the method call is actually to the class, ** and can be made even if the receiver is null (that is, we ** always want to call a static method, even if the receiver is null). */ if (isStatic) return false; return generateReceiver(acb, mb, receiver); } /** * Accept a visitor, and call v.visit() * on child nodes as necessary. * * @param v the visitor * * @exception StandardException on error */ public Visitable accept(Visitor v) throws StandardException { if (v.skipChildren(this)) { return v.visit(this); } Visitable returnNode = super.accept(v); if (receiver != null && !v.stopTraversal()) { receiver = (JavaValueNode)receiver.accept(v); } return returnNode; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -