/**
  * 中断接受节点
  *
  * @param node : 函数调用
  */
 public void interruptAcceptNodeHandle(MethodInvocation node) {
   int lineNumber = compilationUnit.getLineNumber(node.getStartPosition());
   Node interruptedNode = new Node(filePath, lineNumber);
   String threadKey;
   Expression expression = node.getExpression();
   ITypeBinding iTypeBinding = castHelper.getResolveTypeBinding(expression);
   if (expression == null || iTypeBinding == null) {
     System.out.println(filePath);
     System.out.println(compilationUnit.getLineNumber(node.getStartPosition()));
     System.out.println("interrupt iTypeBinding error!");
     return;
   }
   // 普通变量
   if (expression instanceof SimpleName && ((SimpleName) expression).resolveBinding() != null) {
     SimpleName simpleName = (SimpleName) expression;
     if (castHelper.getDecNode(simpleName) == null) {
       return;
     }
     int decLineNumber =
         compilationUnit.getLineNumber(castHelper.getDecNode(simpleName).getStartPosition());
     String varKey =
         filePath
             + "_"
             + decLineNumber
             + "_"
             + iTypeBinding.getName()
             + "_"
             + simpleName.getIdentifier();
     System.out.println(varKey);
     if (threadVarHashMap.containsKey(varKey)) {
       threadKey = threadVarHashMap.get(varKey).getThreadInfoKey();
       if (threadInfo.get(threadKey).getInterruptNodes() != null) {
         threadInfo.get(threadKey).getInterruptNodes().add(interruptedNode);
       }
     } else {
       System.out.println("ERROR: didn't contains the varKey");
     }
   }
   // 其它调用
   else if (((SimpleName) expression).resolveBinding() != null) {
     threadKey = iTypeBinding.getBinaryName();
     if (threadInfo.get(threadKey).getInterruptNodes() != null) {
       threadInfo.get(threadKey).getInterruptNodes().add(interruptedNode);
     }
   }
 }
 public void traverse(ArrayList<CompileUnit> compileUnits) {
   System.out.println("Traverse...............................");
   castHelper = CASTHelper.getInstance();
   for (CompileUnit compileUnit : compileUnits) {
     this.filePath = compileUnit.getFilePath();
     this.compilationUnit = compileUnit.getCompilationUnit();
     compilationUnit.accept(this);
   }
 }
  /**
   * 中断通知节点
   *
   * @param node :函数调用
   * @param threadInterruptNode :中断节点类
   */
  public void interruptNotifyNodeHandle(
      MethodInvocation node, ThreadInterruptNode threadInterruptNode) {
    String threadKey;
    Expression expression = node.getExpression();
    ITypeBinding iTypeBinding = castHelper.getResolveTypeBinding(expression);
    if (expression == null || iTypeBinding == null) {
      System.out.println(filePath);
      System.out.println(compilationUnit.getLineNumber(node.getStartPosition()));
      System.out.println("interrupt iTypeBinding error!");
      return;
    }
    // 普通变量,从变量集中获取线程key
    if (expression instanceof SimpleName && ((SimpleName) expression).resolveBinding() != null) {
      SimpleName simpleName = (SimpleName) expression;

      int lineNumber =
          compilationUnit.getLineNumber(castHelper.getDecNode(simpleName).getStartPosition());
      String varKey =
          filePath
              + "_"
              + lineNumber
              + "_"
              + iTypeBinding.getName()
              + "_"
              + simpleName.getIdentifier();
      System.out.println(varKey);
      if (threadVarHashMap.containsKey(varKey)) {
        threadKey = threadVarHashMap.get(varKey).getThreadInfoKey();
        threadInterruptNode.getThreadKeyList().add(threadKey);
        // 添加至中断通知节点集合
        threadInterruptNodes.add(threadInterruptNode);
      } else {
        System.out.println("ERROR: didn't contains the varKey");
      }
    }
    // 其它调用(函数返回值等):直接从返回值类型推断具体线程key
    else {
      threadKey = iTypeBinding.getBinaryName();
      threadInterruptNode.getThreadKeyList().add(threadKey);
    }
  }
 @Override
 public boolean visit(MethodInvocation node) {
   String methodKey = castHelper.methodKey(node);
   String methodName = node.getName().toString();
   int lineNumber = compilationUnit.getLineNumber(node.getStartPosition());
   // 函数调用在线程调用到的函数中(单个函数可能牵扯到多个线程)
   if (threadMethodMapTable.containsKey(methodKey) && node.resolveMethodBinding() != null) {
     IMethodBinding iMethodBinding = node.resolveMethodBinding();
     // 1.中断判断函数(中断接受节点)
     if ((methodName.equals("interrupted") || methodName.equals("isInterrupted"))) {
       if (iMethodBinding.getDeclaringClass() != null
           && iMethodBinding.getDeclaringClass().getBinaryName().equals("java.lang.Thread")) {
         System.out.println(node);
         System.out.println("interrupted judge");
         HashSet<String> threads = threadMethodMapTable.get(methodKey);
         // (1)添加到每个线程的中断接受节点集合
         for (String thread : threads) {
           ThreadInformation threadInformation = threadInfo.get(thread);
           Node interruptedNode = new Node(filePath, lineNumber);
           threadInformation.getInterruptNodes().add(interruptedNode);
         }
         // (2)变量自身判断(根据自己所绑定的线程类型而添加中断接受节点)
         interruptAcceptNodeHandle(node);
       }
     }
     // 2.引发中断的函数调用(中断通知节点)
     else if (methodName.equals("interrupt")) {
       ThreadInterruptNode threadInterruptNode = new ThreadInterruptNode(filePath, lineNumber);
       // (1)自中断
       if (node.getExpression() instanceof MethodInvocation
           && ((MethodInvocation) node.getExpression())
               .getName()
               .getIdentifier()
               .equals("currentThread")) {
         // 对有可能调用该自中断的线程添加到中断通知节点中
         HashSet<String> threads = threadMethodMapTable.get(methodKey);
         for (String thread : threads) {
           threadInterruptNode.getThreadKeyList().add(thread);
         }
         threadInterruptNodes.add(threadInterruptNode);
       }
       // (2)调用中断,通过变量来定位threadKey
       else if (iMethodBinding.getDeclaringClass() != null
           && iMethodBinding.getDeclaringClass().getBinaryName().equals("java.lang.Thread")) {
         interruptNotifyNodeHandle(node, threadInterruptNode);
       }
     }
     // 3.会抛出中断异常的函数(中断接受节点)
     else {
       ITypeBinding[] typeBindings = node.resolveMethodBinding().getExceptionTypes();
       for (ITypeBinding iTypeBinding : typeBindings) {
         if (iTypeBinding.getBinaryName().equals("java.lang.InterruptedException")) {
           System.out.println(node);
           System.out.println("interrupted exception");
           HashSet<String> threads = threadMethodMapTable.get(methodKey);
           // (1)添加到每个线程的中断接受节点集合
           for (String thread : threads) {
             ThreadInformation threadInformation = threadInfo.get(thread);
             Node interruptedNode = new Node(filePath, lineNumber);
             threadInformation.getInterruptNodes().add(interruptedNode);
           }
           // (2)变量自身判断(根据自己所绑定的线程类型而添加中断接受节点)
           interruptAcceptNodeHandle(node);
         }
       }
     }
   }
   return super.visit(node);
 }