예제 #1
0
 /** Method invocation. */
 public void visitInvokeInstruction(InvokeInstruction i) {
   Type[] argTypes = i.getArgumentTypes(cp);
   for (int j = 0; j < argTypes.length; j++) cv.registerCoupling(argTypes[j]);
   cv.registerCoupling(i.getReturnType(cp));
   /* Measuring decision: measure overloaded methods separately */
   cv.registerMethodInvocation(i.getClassName(cp), i.getMethodName(cp), argTypes);
 }
      private void checkForPossibleObligationTransfer(
          InvokeInstruction inv, InstructionHandle handle) throws ClassNotFoundException {
        //
        // We will assume that a method invocation might transfer
        // an obligation from one type to another if
        // 1. either
        // - it's a constructor where the constructed
        // type and exactly one param type
        // are obligation types, or
        // - it's a method where the return type and
        // exactly one param type are obligation types
        // 2. at least one instance of the resource "consumed"
        // by the transfer exists at the point of the transfer.
        // E.g., if we see a transfer of InputStream->Reader,
        // there must be an instance of InputStream at
        // the transfer point.
        //

        if (DEBUG_FP) {
          System.out.println("Checking " + handle + " as possible obligation transfer...:");
        }

        // Find the State which is a prefix of the error state
        // at the location of this (possible) transfer.
        State transferState = getTransferState(handle);
        if (transferState == null) {
          if (DEBUG_FP) {
            System.out.println("No transfer state???");
          }
          return;
        }

        String methodName = inv.getMethodName(cpg);
        Type producedType =
            methodName.equals("<init>") ? inv.getReferenceType(cpg) : inv.getReturnType(cpg);

        if (DEBUG_FP && !(producedType instanceof ObjectType)) {
          System.out.println("Produced type " + producedType + " not an ObjectType");
        }

        if (producedType instanceof ObjectType) {
          Obligation produced =
              database.getFactory().getObligationByType((ObjectType) producedType);

          if (DEBUG_FP && produced == null) {
            System.out.println("Produced type  " + producedType + " not an obligation type");
          }

          if (produced != null) {
            XMethod calledMethod = XFactory.createXMethod(inv, cpg);
            Obligation[] params = database.getFactory().getParameterObligationTypes(calledMethod);

            for (int i = 0; i < params.length; i++) {
              Obligation consumed = params[i];

              if (DEBUG_FP && consumed == null) {
                System.out.println("Param " + i + " not an obligation type");
              }

              if (DEBUG_FP && consumed != null && consumed.equals(produced)) {
                System.out.println("Consumed type is the same as produced type");
              }

              if (consumed != null && !consumed.equals(produced)) {
                // See if an instance of the consumed obligation
                // type
                // exists here.
                if (transferState.getObligationSet().getCount(consumed.getId()) > 0) {
                  transferList.add(new PossibleObligationTransfer(consumed, produced));
                  if (DEBUG_FP) {
                    System.out.println(
                        "===> Possible transfer of "
                            + consumed
                            + " to "
                            + produced
                            + " at "
                            + handle);
                  }
                } else if (DEBUG_FP) {
                  System.out.println(
                      handle
                          + " not a transfer "
                          + "of "
                          + consumed
                          + "->"
                          + produced
                          + " because no instances of "
                          + consumed);
                  System.out.println("I see " + transferState.getObligationSet());
                }
              }
            }
          }
        }
      }