@SuppressWarnings("rawtypes") // DOM AST API returns raw collections
  public SourcePosition getPosition() {
    final MirrorKind kind = _parent.kind();
    ASTNode astNode = null;
    switch (kind) {
      case ANNOTATION_MIRROR:
        final AnnotationMirrorImpl anno = (AnnotationMirrorImpl) _parent;
        astNode = anno.getASTNodeForElement(_name);
        break;
      case ANNOTATION_ELEMENT:
        final AnnotationElementDeclarationImpl element = (AnnotationElementDeclarationImpl) _parent;
        astNode = element.getAstNodeForDefault();
        break;
      default:
        throw new IllegalStateException(); // should never reach this point.
    }
    // did not come from source.
    if (astNode == null) return null;
    if (_index >= 0 && astNode.getNodeType() == ASTNode.ARRAY_INITIALIZER) {
      final ArrayInitializer arrayInit = (ArrayInitializer) astNode;
      final List exprs = arrayInit.expressions();
      if (exprs != null && _index < exprs.size()) astNode = (ASTNode) exprs.get(_index);
    }
    if (astNode == null) return null;

    final CompilationUnit unit = getCompilationUnit();
    if (unit == null) return null;
    final int offset = astNode.getStartPosition();
    return new SourcePositionImpl(
        astNode.getStartPosition(),
        astNode.getLength(),
        unit.getLineNumber(offset),
        unit.getColumnNumber(offset),
        this);
  }
 /**
  * 中断接受节点
  *
  * @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);
     }
   }
 }
  /**
   * 中断通知节点
   *
   * @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);
    }
  }
  protected ISourceLocation getSourceLocation(ASTNode node) {
    try {
      int nodeLength = compilUnit.getExtendedLength(node);

      if (nodeLength > 0) {
        int start = compilUnit.getExtendedStartPosition(node);
        int end = start + nodeLength - 1;

        if (end < start && ((node.getFlags() & 9) > 0)) {
          insert(
              messages,
              values.constructor(
                  DATATYPE_RASCAL_MESSAGE_ERROR_NODE_TYPE,
                  values.string("Recovered/Malformed node, guessing the length"),
                  values.sourceLocation(loc, 0, 0)));

          nodeLength = node.toString().length();
          end = start + nodeLength - 1;
        }

        return values.sourceLocation(
            loc,
            start,
            nodeLength,
            compilUnit.getLineNumber(start),
            compilUnit.getLineNumber(end),
            // TODO: only adding 1 at the end seems to work, need to test.
            compilUnit.getColumnNumber(start),
            compilUnit.getColumnNumber(end) + 1);
      }
    } catch (IllegalArgumentException e) {
      insert(
          messages,
          values.constructor(
              DATATYPE_RASCAL_MESSAGE_ERROR_NODE_TYPE,
              values.string("Most probably missing dependency"),
              values.sourceLocation(loc, 0, 0)));
    }
    return values.sourceLocation(loc, 0, 0, 0, 0, 0, 0);
  }
  /**
   * Adds the specified method binding to the search results.
   *
   * @param calledMethodBinding
   * @param node
   */
  protected void addMethodCall(IMethodBinding calledMethodBinding, ASTNode node) {
    try {
      if (calledMethodBinding != null) {
        fProgressMonitor.worked(1);

        ITypeBinding calledTypeBinding = calledMethodBinding.getDeclaringClass();
        IType calledType = null;

        if (!calledTypeBinding.isAnonymous()) {
          calledType = (IType) calledTypeBinding.getJavaElement();
        } else {
          if (!"java.lang.Object"
              .equals(calledTypeBinding.getSuperclass().getQualifiedName())) { // $NON-NLS-1$
            calledType = (IType) calledTypeBinding.getSuperclass().getJavaElement();
          } else {
            calledType = (IType) calledTypeBinding.getInterfaces()[0].getJavaElement();
          }
        }

        IMethod calledMethod =
            findIncludingSupertypes(calledMethodBinding, calledType, fProgressMonitor);

        IMember referencedMember = null;
        if (calledMethod == null) {
          if (calledMethodBinding.isConstructor()
              && calledMethodBinding.getParameterTypes().length == 0) {
            referencedMember = calledType;
          }
        } else {
          if (calledType.isInterface()) {
            calledMethod = findImplementingMethods(calledMethod);
          }

          if (!isIgnoredBySearchScope(calledMethod)) {
            referencedMember = calledMethod;
          }
        }
        final int position = node.getStartPosition();
        final int number = fCompilationUnit.getLineNumber(position);
        fSearchResults.addMember(
            fMember,
            referencedMember,
            position,
            position + node.getLength(),
            number < 1 ? 1 : number);
      }
    } catch (JavaModelException jme) {
      JavaPlugin.log(jme);
    }
  }
 private JavaElementLine getLineElement(
     CompilationUnit astRoot,
     OccurrenceLocation location,
     HashMap<Integer, JavaElementLine> lineToGroup) {
   int lineNumber = astRoot.getLineNumber(location.getOffset());
   if (lineNumber <= 0) {
     return null;
   }
   JavaElementLine lineElement = null;
   try {
     Integer key = new Integer(lineNumber);
     lineElement = lineToGroup.get(key);
     if (lineElement == null) {
       int lineStartOffset = astRoot.getPosition(lineNumber, 0);
       if (lineStartOffset >= 0) {
         lineElement = new JavaElementLine(astRoot.getTypeRoot(), lineNumber - 1, lineStartOffset);
         lineToGroup.put(key, lineElement);
       }
     }
   } catch (CoreException e) {
     // nothing
   }
   return lineElement;
 }
 @Override
 public int getLineNumber(int inputPosition) {
   Verify.verifyNotNull(unit, "Expected compilation unit to be set.");
   return unit.getLineNumber(inputPosition);
 }
 public int getRefactoringMarkerLine(ICompilationUnit unit) throws Exception {
   CompilationUnit tree = ASTreeManipulationMethods.parseICompilationUnit(unit);
   ASTNode node = ASTreeManipulationMethods.getASTNodeByIndex(tree, insertPlaceNodeIndex);
   int lineNo = tree.getLineNumber(node.getStartPosition());
   return lineNo + 1;
 }
 @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);
 }
  @Test
  public void testOneMethod() {
    System.out.println("filetypes in given file");
    System.out.println("inheritance " + resolver.getSuperType());
    System.out.println("interfaces " + resolver.getInterfaces());
    Map<String, String> types = resolver.getClassesInFile();
    for (MethodInvocationResolver.TypeDecl typeDeclaration : resolver.getTypeDeclarations()) {
      System.out.println(
          types.get(typeDeclaration.getClassName())
              + "   "
              + unit.getLineNumber(typeDeclaration.getLoc())
              + "  "
              + unit.getColumnNumber(typeDeclaration.getLoc()));
    }

    Map<ASTNode, String> typesAtPos = resolver.getVariableTypesAtPosition();
    System.out.println("~~~~~~variable Typeaatposition  ");
    for (Entry<ASTNode, String> e : typesAtPos.entrySet()) {
      Integer line = unit.getLineNumber(e.getKey().getStartPosition());
      Integer col = unit.getColumnNumber(e.getKey().getStartPosition());
      System.out.println(
          line + " , " + col + " , " + e.getKey().getLength() + " : " + e.getValue());
    }

    System.out.println("########  Import name position");
    for (Entry<ASTNode, String> e : resolver.getImportsDeclarationNode().entrySet()) {
      Integer line = unit.getLineNumber(e.getKey().getStartPosition());
      Integer col = unit.getColumnNumber(e.getKey().getStartPosition());
      System.out.println(
          line + " , " + col + " , " + e.getKey().getLength() + " : " + e.getValue());
    }

    System.out.println("--------------Type at positions ");
    for (Entry<ASTNode, String> e : resolver.getTypesAtPosition().entrySet()) {
      Integer line = unit.getLineNumber(e.getKey().getStartPosition());
      Integer col = unit.getColumnNumber(e.getKey().getStartPosition());
      System.out.println(
          line + " , " + col + " , " + e.getKey().getLength() + " : " + e.getValue());
    }

    for (Entry<ASTNode, ASTNode> e : resolver.getVariableDependencies().entrySet()) {
      ASTNode child = e.getKey();
      Integer chline = unit.getLineNumber(child.getStartPosition());
      Integer chcol = unit.getColumnNumber(child.getStartPosition());
      Integer chLength = child.getLength();
      ASTNode parent = e.getValue();
      Integer pline = unit.getLineNumber(parent.getStartPosition());
      Integer pcol = unit.getColumnNumber(parent.getStartPosition());
      Integer plength = parent.getLength();
      System.out.println(
          "**** "
              + child
              + "["
              + chline
              + ", "
              + chcol
              + ", "
              + chLength
              + "] ==> "
              + parent.toString()
              + "["
              + pline
              + ", "
              + pcol
              + ", "
              + plength
              + "]");
    }

    for (Entry<String, List<MethodInvokRef>> entry : resolver.getMethodInvoks().entrySet()) {
      System.out.println(" ~~~~~~~~~~~ For method " + entry.getKey() + " ~~~~~~~~~~~");
      for (MethodInvokRef m : entry.getValue()) {
        Integer loc = m.getLocation();
        Integer line = unit.getLineNumber(loc);
        Integer col = unit.getColumnNumber(loc);
        System.out.println("[" + line + ", " + col + ", " + m.getLength() + " ] ==> " + m);
      }
    }

    for (MethodDecl m : resolver.getDeclaredMethods()) {
      System.out.println("~~~~~~~~~~~~~~~~~ Declared Methods ~~~~~~~~~~~~~~~~~");
      System.out.println(m);
    }
    System.out.println(resolver.getVariableTypes());
  }