/**
   * @param locateNode
   * @return true if the given path indicates a trait
   */
  private static boolean isTraitName(ASTNode locateNode) {
    assert locateNode != null;

    ASTNode parent = null;
    if (locateNode.getType() == ASTNode.CLASS_DECLARATION) {
      parent = locateNode;
    } else if (locateNode.getType() == ASTNode.IDENTIFIER) {
      parent = locateNode.getParent();
    } else {
      return false;
    }

    if (parent.getType() == ASTNode.NAMESPACE_NAME) {
      locateNode = parent;
      parent = parent.getParent();
    }

    final int parentType = parent.getType();
    if (parentType == ASTNode.CLASS_DECLARATION
        || parentType == ASTNode.TRAIT_USE_STATEMENT
        || parentType == ASTNode.FULLY_QUALIFIED_TRAIT_METHOD_REFERENCE) {
      if (parentType == ASTNode.FULLY_QUALIFIED_TRAIT_METHOD_REFERENCE) {
        FullyQualifiedTraitMethodReference reference = (FullyQualifiedTraitMethodReference) parent;
        if (reference.getFunctionName() == locateNode) {
          return false;
        }
      }
      return true;
    }

    return false;
  }
  public static boolean isGlobalConstant(ASTNode locateNode) {
    assert locateNode != null;

    // check if it is an identifier
    if (locateNode.getType() != ASTNode.IDENTIFIER) {
      return false;
    }

    ASTNode parent = locateNode.getParent();
    if (parent.getType() != ASTNode.NAMESPACE_NAME) {
      return false;
    }

    final NamespaceName namespaceName = (NamespaceName) parent;
    parent = namespaceName.getParent();
    if (parent.getType() == ASTNode.FUNCTION_NAME
        || parent.getType() == ASTNode.CLASS_NAME
        || parent.getType() == ASTNode.NAMESPACE
        || parent.getType() == ASTNode.USE_STATEMENT_PART
        || parent.getType() == ASTNode.TRAIT_USE_STATEMENT) {
      return false;
    }

    return true;
  }
  /**
   * @param locateNode
   * @return true if the given path indicates a function
   */
  private static boolean isFunction(ASTNode locateNode) {
    assert locateNode != null;
    ASTNode parent = null;
    Identifier targetIdentifier = null;

    if (locateNode.getType() == ASTNode.FUNCTION_DECLARATION) {
      parent = ((FunctionDeclaration) locateNode);
      targetIdentifier = ((FunctionDeclaration) locateNode).getFunctionName();
    } else if (locateNode instanceof Identifier
        && !"define".equals(((Identifier) locateNode).getName())) { // $NON-NLS-1$
      targetIdentifier = (Identifier) locateNode;
      parent = targetIdentifier.getParent();
      if (parent != null && parent.getType() == ASTNode.NAMESPACE_NAME) {
        parent = targetIdentifier.getParent().getParent();
      }
    } else {
      return false;
    }

    // check if it is a function
    if (parent == null
        || parent.getType() != ASTNode.FUNCTION_DECLARATION
            && parent.getType() != ASTNode.FUNCTION_NAME
        || parent.getParent().getType() == ASTNode.METHOD_DECLARATION
        || parent.getType() == ASTNode.FULLY_QUALIFIED_TRAIT_METHOD_REFERENCE) {
      return false;
    }

    if (parent instanceof TraitAlias) {
      return false;
    }
    // check if it is a method
    final int type = parent.getParent().getType();
    if (type == ASTNode.FUNCTION_INVOCATION) {
      final int parentParentType = parent.getParent().getParent().getType();
      if (parentParentType == ASTNode.METHOD_DECLARATION
          || parentParentType == ASTNode.STATIC_METHOD_INVOCATION) {
        return false;
      }
    } else if (type == ASTNode.METHOD_DECLARATION) {
      return false;
    }

    return true;
  }
 public ITypeBinding getDeclaringClass() {
   ASTNode parent = this.variableDeclaration.getParent();
   while (parent != null && parent.getNodeType() != ASTNode.TYPE_DECLARATION) {
     parent = parent.getParent();
   }
   if (parent != null) {
     return ((TypeDeclaration) parent).resolveBinding();
   }
   return null;
 }
 public IFunctionBinding getDeclaringMethod() {
   ASTNode parent = this.variableDeclaration.getParent();
   while (parent != null && parent.getNodeType() != ASTNode.FUNCTION_DECLARATION) {
     parent = parent.getParent();
   }
   if (parent != null) {
     return ((FunctionDeclaration) parent).resolveBinding();
   }
   return null;
 }
  /**
   * @param locateNode
   * @return true if the given path indicates a function
   */
  private static boolean isClassName(ASTNode locateNode) {
    assert locateNode != null;

    ASTNode parent = null;
    if (locateNode.getType() == ASTNode.CLASS_DECLARATION
        || locateNode.getType() == ASTNode.INTERFACE_DECLARATION) {
      parent = locateNode;
    } else if (locateNode.getType() == ASTNode.IDENTIFIER) {
      parent = locateNode.getParent();
    } else {
      return false;
    }

    if (parent.getType() == ASTNode.NAMESPACE_NAME) {
      locateNode = parent;
      parent = parent.getParent();
    }

    if (parent instanceof TraitDeclaration) {
      return false;
    }
    final int parentType = parent.getType();
    if (parentType == ASTNode.CLASS_NAME
        || parentType == ASTNode.CLASS_DECLARATION
        || parentType == ASTNode.INTERFACE_DECLARATION
        || parentType == ASTNode.CATCH_CLAUSE
        || parentType == ASTNode.FORMAL_PARAMETER
        || parentType == ASTNode.USE_STATEMENT_PART) {
      return true;
    }

    if (parentType == ASTNode.STATIC_METHOD_INVOCATION
        || parentType == ASTNode.STATIC_FIELD_ACCESS
        || parentType == ASTNode.STATIC_CONSTANT_ACCESS) {
      StaticDispatch staticDispatch = (StaticDispatch) parent;
      if (staticDispatch.getClassName() == locateNode) {
        return true;
      }
    }
    return false;
  }
  public void test_addAll() {
    ASTNode parent = argumentList();
    ArrayList<ASTNode> firstNodes = new ArrayList<ASTNode>();
    ASTNode firstNode = booleanLiteral(true);
    ASTNode secondNode = booleanLiteral(false);
    firstNodes.add(firstNode);
    firstNodes.add(secondNode);
    NodeList<ASTNode> list = new NodeList<ASTNode>(parent);
    list.addAll(firstNodes);
    assertSize(2, list);
    assertSame(firstNode, list.get(0));
    assertSame(secondNode, list.get(1));
    assertSame(parent, firstNode.getParent());
    assertSame(parent, secondNode.getParent());

    ArrayList<ASTNode> secondNodes = new ArrayList<ASTNode>();
    ASTNode thirdNode = booleanLiteral(true);
    ASTNode fourthNode = booleanLiteral(false);
    secondNodes.add(thirdNode);
    secondNodes.add(fourthNode);
    list.addAll(secondNodes);
    assertSize(4, list);
    assertSame(firstNode, list.get(0));
    assertSame(secondNode, list.get(1));
    assertSame(thirdNode, list.get(2));
    assertSame(fourthNode, list.get(3));
    assertSame(parent, firstNode.getParent());
    assertSame(parent, secondNode.getParent());
    assertSame(parent, thirdNode.getParent());
    assertSame(parent, fourthNode.getParent());
  }
  private void markAsMoveOrCopyTarget(ASTNode node, ASTNode newChild) {
    if (this.cloneDepth == 0) {
      while (node != null && this.clonedNodes.containsKey(node)) {
        /*
         * A modified node cannot be considered as cloned any more.
         * we can't copy the original formatting/comments and at the same time modify the node.
         *
         * Workaround for https://bugs.eclipse.org/405699 is to remove such nodes from clonedNodes
         * and instead mark all children as cloned (or skip them if they are not in clonedNodes).
         */
        ASTNode orig = (ASTNode) this.clonedNodes.remove(node);
        if (orig != null) {
          List properties = node.structuralPropertiesForType();
          for (int i = 0; i < properties.size(); i++) {
            StructuralPropertyDescriptor property =
                (StructuralPropertyDescriptor) properties.get(i);
            Object child = node.getStructuralProperty(property);
            if (child instanceof ASTNode) {
              markAsMoveOrCopyTarget(node, (ASTNode) child);
            } else if (child instanceof List) {
              List children = (List) child;
              for (int j = 0; j < children.size(); j++) {
                ASTNode clonedChild = (ASTNode) children.get(j);
                markAsMoveOrCopyTarget(node, clonedChild);
              }
            }
          }
        }

        node = node.getParent();
      }
    }

    ASTNode source = (ASTNode) this.clonedNodes.get(newChild);
    if (source != null) {
      if (this.cloneDepth == 0) {
        PropertyLocation propertyLocation =
            this.eventStore.getPropertyLocation(source, RewriteEventStore.ORIGINAL);
        CopySourceInfo sourceInfo =
            this.eventStore.markAsCopySource(
                propertyLocation.getParent(), propertyLocation.getProperty(), source, false);
        this.nodeStore.markAsCopyTarget(newChild, sourceInfo);
      }
    } else if ((newChild.getFlags() & ASTNode.ORIGINAL) != 0) {
      PropertyLocation propertyLocation =
          this.eventStore.getPropertyLocation(newChild, RewriteEventStore.ORIGINAL);
      CopySourceInfo sourceInfo =
          this.eventStore.markAsCopySource(
              propertyLocation.getParent(), propertyLocation.getProperty(), newChild, true);
      this.nodeStore.markAsCopyTarget(newChild, sourceInfo);
    }
  }
  public void test_add() {
    ASTNode parent = argumentList();
    ASTNode firstNode = booleanLiteral(true);
    ASTNode secondNode = booleanLiteral(false);
    NodeList<ASTNode> list = new NodeList<ASTNode>(parent);
    list.add(0, secondNode);
    list.add(0, firstNode);
    assertSize(2, list);
    assertSame(firstNode, list.get(0));
    assertSame(secondNode, list.get(1));
    assertSame(parent, firstNode.getParent());
    assertSame(parent, secondNode.getParent());

    ASTNode thirdNode = booleanLiteral(false);
    list.add(1, thirdNode);
    assertSize(3, list);
    assertSame(firstNode, list.get(0));
    assertSame(thirdNode, list.get(1));
    assertSame(secondNode, list.get(2));
    assertSame(parent, firstNode.getParent());
    assertSame(parent, secondNode.getParent());
    assertSame(parent, thirdNode.getParent());
  }
  private static boolean isLocalVariable(ASTNode locateNode) {
    assert locateNode != null;
    Variable parent = null;
    // check if it is an identifier
    if (locateNode instanceof Identifier
        && ((Identifier) locateNode).getParent() instanceof Variable) {
      parent = (Variable) ((Identifier) locateNode).getParent();
    } else if (locateNode.getType() == ASTNode.VARIABLE) {
      parent = (Variable) locateNode;
    } else {
      return false;
    }

    // check for not variables / or $this / or field declaration
    if (!parent.isDollared()
        || isThisVariable(parent)
        || parent.getType() == ASTNode.FIELD_DECLARATION) {
      return false;
    }

    // check for static variables
    if (parent.isDollared()
        && parent.getParent() != null
        && parent.getParent().getType() == ASTNode.STATIC_FIELD_ACCESS) {
      return false;
    }

    // check for static array variables
    if (parent.isDollared()
        && parent.getParent() != null
        && parent.getParent().getType() == ASTNode.ARRAY_ACCESS
        && parent != ((ArrayAccess) parent.getParent()).getIndex()
        && parent.getParent().getParent().getType() == ASTNode.STATIC_FIELD_ACCESS) {
      return false;
    }
    ASTNode node = parent;
    while (node != null) {
      final int type = node.getType();
      if (type == ASTNode.FUNCTION_DECLARATION) {
        return true;
      }
      node = node.getParent();
    }
    return false;
  }
Example #11
0
    public void endVisitNode(ASTNode node) {

      // Look if a child node is waiting for trailing comments computing
      ASTNode sibling =
          this.topSiblingParent == node ? (ASTNode) this.siblings[this.siblingPtr] : null;
      if (sibling != null) {
        try {
          storeTrailingComments(
              sibling, node.getEnd() - 1, true, this.parentLineRange[this.siblingPtr]);
        } catch (Exception ex) {
          // Give up extended ranges at this level if unexpected
          // exception happens...
        }
      }
      // Remove sibling if needed
      if (this.topSiblingParent != null /* not a CompilationUnit */
          && this.topSiblingParent == node) {
        this.siblingPtr--;
        this.topSiblingParent = node.getParent();
      }
    }
Example #12
0
    protected boolean apply(ASTNode node) {

      // Get default previous end
      ASTNode parent = node.getParent();
      int previousEnd = parent.getStart();

      // Look for sibling node
      ASTNode sibling =
          parent == this.topSiblingParent ? (ASTNode) this.siblings[this.siblingPtr] : null;
      if (sibling != null) {
        // Found one previous sibling, so compute its trailing comments
        // using current node start position
        try {
          previousEnd =
              storeTrailingComments(
                  sibling, node.getStart(), false, this.parentLineRange[this.siblingPtr]);
        } catch (Exception ex) {
          // Give up extended ranges at this level if unexpected
          // exception happens...
        }
      }

      // Stop visit for malformed node (see bug
      // https://bugs.eclipse.org/bugs/show_bug.cgi?id=84049)
      if (node.getType() == ASTNode.AST_ERROR) {
        return false;
      }

      // Compute leading comments for current node
      int[] previousLineRange =
          this.siblingPtr > -1
              ? this.parentLineRange[this.siblingPtr]
              : new int[] {1, DefaultCommentMapper.this.document.getNumberOfLines()};
      try {
        storeLeadingComments(node, previousEnd, previousLineRange);
      } catch (Exception ex) {
        // Give up extended ranges at this level if unexpected exception
        // happens...
      }

      // Store current node as waiting sibling for its parent
      if (this.topSiblingParent != parent) {
        if (this.siblings.length == ++this.siblingPtr) {
          System.arraycopy(
              this.siblings,
              0,
              this.siblings = new ASTNode[this.siblingPtr * 2],
              0,
              this.siblingPtr);
          System.arraycopy(
              this.parentLineRange,
              0,
              this.parentLineRange = new int[this.siblingPtr * 2][],
              0,
              this.siblingPtr);
        }
        if (this.topSiblingParent == null) {
          // node is a CompilationUnit
          this.parentLineRange[this.siblingPtr] = previousLineRange;
        } else {
          int parentStart = parent.getStart();
          int firstLine = getLineNumber(parentStart, previousLineRange);
          int lastLine = getLineNumber(parentStart + parent.getLength() - 1, previousLineRange);
          if (this.parentLineRange[this.siblingPtr] == null) {
            this.parentLineRange[this.siblingPtr] = new int[] {firstLine, lastLine};
          } else {
            int[] lineRange = this.parentLineRange[this.siblingPtr];
            lineRange[0] = firstLine;
            lineRange[1] = lastLine;
          }
        }
        this.topSiblingParent = parent;
      }
      this.siblings[this.siblingPtr] = node;

      // We're always ok to visit sub-levels
      return true;
    }
Example #13
0
  /**
   * Search and store node trailing comments. Comments are searched in position range from node end
   * position to specified next start. If one or several comment are found, returns last comment end
   * position, otherwise returns node end position.
   *
   * <p>Starts to search for first comment after node end position and return if none was found...
   *
   * <p>When first comment is found after node, goes down in comment list until one of following
   * conditions becomes true:
   *
   * <ol>
   *   <li>comment start is after next start
   *   <li>there's other than white characters between current node and comment
   *   <li>TODO there's more than 1 line between current node and comment
   * </ol>
   *
   * If at least potential comments have been found, then all of them has to be separated from
   * following node. So, remove all comments which do not verify this assumption. Note that this
   * verification is not applicable on last node.
   *
   * <p>If finally there's still trailing comments, then stores indexes of the first and last one in
   * trailing comments table.
   */
  int storeTrailingComments(ASTNode node, int nextStart, boolean lastChild, int[] parentLineRange) {

    // Init extended position
    int nodeEnd = node.getEnd() - 1;
    if (nodeEnd == nextStart) {
      // special case for last child of its parent
      if (++this.trailingPtr == 0) {
        this.trailingNodes = new ASTNode[STORAGE_INCREMENT];
        this.trailingIndexes = new long[STORAGE_INCREMENT];
        this.lastTrailingPtr = -1;
      } else if (this.trailingPtr == this.trailingNodes.length) {
        int newLength = (this.trailingPtr * 3 / 2) + STORAGE_INCREMENT;
        System.arraycopy(
            this.trailingNodes,
            0,
            this.trailingNodes = new ASTNode[newLength],
            0,
            this.trailingPtr);
        System.arraycopy(
            this.trailingIndexes,
            0,
            this.trailingIndexes = new long[newLength],
            0,
            this.trailingPtr);
      }
      this.trailingNodes[this.trailingPtr] = node;
      this.trailingIndexes[this.trailingPtr] = -1;
      return nodeEnd;
    }
    int extended = nodeEnd;

    // Get line number
    int nodeEndLine = getLineNumber(nodeEnd, parentLineRange);

    // Find comments range index
    int idx = getCommentIndex(0, nodeEnd, 1);
    if (idx == -1) {
      return nodeEnd;
    }

    // Look after potential comments
    int startIdx = idx;
    int endIdx = -1;
    int length = this.comments.length;
    int commentStart = extended + 1;
    int previousEnd = nodeEnd + 1;
    int sameLineIdx = -1;
    while (idx < length && commentStart < nextStart) {
      // get comment and leave if next starting position has been reached
      Comment comment = this.comments[idx];
      commentStart = comment.getStart();
      // verify that there's nothing else than white spaces between
      // node/comments
      if (commentStart >= nextStart) {
        // stop search on condition 1)
        break;
      } else if (previousEnd < commentStart) {
        try {
          resetTo(previousEnd, commentStart);
          this.scanner.next_token();
          String token = this.scanner.yytext();
          if (token != null && token.trim().length() > 0) {
            // stop search on condition 2)
            // if first index fails, then there's no extended
            // position in fact...
            if (idx == startIdx) {
              return nodeEnd;
            }
            // otherwise we get the last index of trailing comment
            // => break
            break;
          }
        } catch (Exception e) {
          // Should not happen, but return no extended position...
          assert false;
          return nodeEnd;
        }
      }
      // Store index if we're on the same line than node end
      int commentLine = getLineNumber(commentStart, parentLineRange);
      if (commentLine == nodeEndLine) {
        sameLineIdx = idx;
      }
      // Store previous infos
      previousEnd = commentStart + comment.getLength();
      endIdx = idx++;
    }
    if (endIdx != -1) {
      // Verify that following node start is separated
      if (!lastChild) {
        int nextLine = getLineNumber(nextStart, parentLineRange);
        int previousLine = getLineNumber(previousEnd, parentLineRange);
        if ((nextLine - previousLine) <= 1) {
          if (sameLineIdx == -1) return nodeEnd;
          endIdx = sameLineIdx;
        }
      }
      // Store trailing comments indexes
      if (++this.trailingPtr == 0) {
        this.trailingNodes = new ASTNode[STORAGE_INCREMENT];
        this.trailingIndexes = new long[STORAGE_INCREMENT];
        this.lastTrailingPtr = -1;
      } else if (this.trailingPtr == this.trailingNodes.length) {
        int newLength = (this.trailingPtr * 3 / 2) + STORAGE_INCREMENT;
        System.arraycopy(
            this.trailingNodes,
            0,
            this.trailingNodes = new ASTNode[newLength],
            0,
            this.trailingPtr);
        System.arraycopy(
            this.trailingIndexes,
            0,
            this.trailingIndexes = new long[newLength],
            0,
            this.trailingPtr);
      }
      this.trailingNodes[this.trailingPtr] = node;
      long nodeRange = (((long) startIdx) << 32) + endIdx;
      this.trailingIndexes[this.trailingPtr] = nodeRange;
      // Compute new extended end
      extended = this.comments[endIdx].getEnd() - 1;
      // Look for children unresolved extended end
      ASTNode previousNode = node;
      int ptr = this.trailingPtr - 1; // children extended end were stored
      // before
      while (ptr >= 0) {
        long range = this.trailingIndexes[ptr];
        if (range != -1) break; // there's no more unresolved nodes
        ASTNode unresolved = this.trailingNodes[ptr];
        if (previousNode != unresolved.getParent())
          break; // we're no longer in node ancestor hierarchy
        this.trailingIndexes[ptr] = nodeRange;
        previousNode = unresolved;
        ptr--; // get previous node
      }
      // Remove remaining unresolved nodes
      if (ptr > this.lastTrailingPtr) {
        int offset = ptr - this.lastTrailingPtr;
        for (int i = ptr + 1; i <= this.trailingPtr; i++) {
          this.trailingNodes[i - offset] = this.trailingNodes[i];
          this.trailingIndexes[i - offset] = this.trailingIndexes[i];
        }
        this.trailingPtr -= offset;
      }
      this.lastTrailingPtr = this.trailingPtr;
    }
    return extended;
  }
  /**
   * Identifies a dispatch usage
   *
   * @param locateNode
   */
  private static boolean isDispatch(ASTNode locateNode) {
    assert locateNode != null;

    ASTNode parent = null;
    // check if it is an identifier
    final int type = locateNode.getType();
    if (locateNode instanceof Identifier
        && ((Identifier) locateNode).getParent() instanceof Variable) {
      parent = (Variable) ((Identifier) locateNode).getParent();
      parent = parent.getParent();
    } else if (type == ASTNode.SINGLE_FIELD_DECLARATION
        || type == ASTNode.FIELD_DECLARATION
        || type == ASTNode.METHOD_DECLARATION) {
      parent = locateNode;
    } else {
      parent = locateNode.getParent();
    }

    if (parent instanceof TraitAlias) {
      // TraitAlias ta = (TraitAlias) parent;
      // return locateNode == ta.getTraitMethod();
      return true;
    }
    // check if it is a method declaration
    if (parent.getType() == ASTNode.FUNCTION_DECLARATION) {
      // check if it is a method declaration
      if (parent.getParent() != null) {
        parent = parent.getParent();
        if (parent.getType() == ASTNode.METHOD_DECLARATION) {
          return true;
        }
      }
      return false;
    }

    if (parent.getType() == ASTNode.FULLY_QUALIFIED_TRAIT_METHOD_REFERENCE) {
      FullyQualifiedTraitMethodReference reference = (FullyQualifiedTraitMethodReference) parent;
      if (reference.getFunctionName() == locateNode) {
        return true;
      }
      return false;
    }

    if (parent.getType() == ASTNode.SINGLE_FIELD_DECLARATION) {
      // check for $this variable
      if (parent.getParent().getType() == ASTNode.FIELD_DECLARATION
          || parent.getParent().getType() == ASTNode.SINGLE_FIELD_DECLARATION) {
        return true;
      }
    }

    if (parent.getType() == ASTNode.FIELD_DECLARATION
        || parent.getType() == ASTNode.METHOD_DECLARATION) {
      return true;
    }

    if (parent.getType() == ASTNode.VARIABLE) {
      if (parent.getParent().getType() == ASTNode.FIELD_DECLARATION
          || parent.getParent().getType() == ASTNode.SINGLE_FIELD_DECLARATION) {
        return true;
      }
    }

    if (parent.getType() == ASTNode.CONSTANT_DECLARATION) return true;

    // check if it is a dispatch
    while (parent != null) {
      if (parent instanceof Dispatch || parent instanceof StaticDispatch) {
        return true;
      }
      parent = parent.getParent();
    }
    return false;
  }
  public JavaRefactoringDescriptor buildEclipseDescriptor() throws Exception {
    System.err.println("[eclipse-rename] Building descriptor...");
    IJavaElement element = location.getIJavaElement();
    String kind = getRenameKind(element);
    // [1] BUGFIX was needed:  The scripting interface didn't allow VariableDeclarationFragments as
    // IJavaElements
    // and thus had to be extended

    // [2] WORKAROUND for scripting interface bug (see below)
    if (kind.equals(IJavaRefactorings.RENAME_METHOD)) {
      IMethod m = (IMethod) element;
      if (m.isConstructor()) {
        // Rename the type instead (as the UI would do-- the scripting interface will only rename
        // the constructor, which is broken)
        kind = IJavaRefactorings.RENAME_TYPE;
        element = m.getDeclaringType();
      }
    }

    System.err.println("[eclipse-rename] Kind = " + kind + ",  element = " + element);

    // [3] Don't test for package fragments now
    if (kind.equals(IJavaRefactorings.RENAME_PACKAGE)) return null; // don't bother with this now

    if (element == null) {
      System.err.println("!!! ABORT: No IJavaElement to represent location");
      throw new RuntimeException("!!! ABORT: No IJavaElement for location");
    }

    if (element instanceof ILocalVariable) {
      System.err.println("element is of type " + element.getClass());
      final ILocalVariable fLocalVariable = (ILocalVariable) element;
      final ISourceRange sourceRange = fLocalVariable.getNameRange();
      final CompilationUnit fCompilationUnitNode = location.getCompilationUnit();
      ASTNode name = NodeFinder.perform(fCompilationUnitNode, sourceRange);
      System.err.println("node is of type " + name.getClass());
      if (name == null) System.err.println("!!! ILV doesn't have associated name!");
      if (name.getParent() instanceof VariableDeclaration)
        System.err.println("ILV has parent : " + (VariableDeclaration) name.getParent());
      else
        System.err.println(
            "!!! ILV doesn't have var declaration parent, instead " + name.getParent().getClass());
    }

    System.err.println("Trying to rename a " + kind + ": " + element);
    if (element instanceof SimpleName)
      System.err.println("  Name = '" + ((SimpleName) element).getIdentifier() + "'");

    if (kind.equals(IJavaRefactorings.RENAME_TYPE)) {
      System.err.println("(Possibly need a new launch configuration)");
      tproject.renameClass((IType) element, new_name);
    }

    final RenameJavaElementDescriptor descriptor =
        (RenameJavaElementDescriptor) getDescriptor(kind);
    descriptor.setJavaElement(element);
    descriptor.setNewName(this.new_name);

    if (element.getElementType() == IJavaElement.TYPE
        || element.getElementType() == IJavaElement.PACKAGE_FRAGMENT)
      descriptor.setUpdateQualifiedNames(true);
    else descriptor.setUpdateQualifiedNames(false);

    descriptor.setUpdateReferences(true);
    descriptor.setDeprecateDelegate(false);
    descriptor.setRenameGetters(false);
    descriptor.setRenameSetters(false);
    descriptor.setKeepOriginal(false);
    descriptor.setUpdateHierarchy(false);
    descriptor.setUpdateSimilarDeclarations(false);

    // [3] Fix:  Eclipse will complain if the transformation is a no-op, but we don't want that:
    if (element.getElementName().equals(this.new_name)) throw new NOPException();

    System.err.println("[eclipse-rename] Computed descriptor.");
    return descriptor;
  }
  private static boolean checkGlobalIdentifier(ASTNode locateNode) {
    // check if it is a GLOBALS['a'] direction
    if (locateNode.getType() == ASTNode.SCALAR) {
      Scalar scalar = (Scalar) locateNode;
      return checkGLOBALS(scalar);
    }

    // check if it is an identifier
    if (locateNode.getType() != ASTNode.IDENTIFIER) {
      return false;
    }

    final Identifier targetIdentifier = ((Identifier) locateNode);

    ASTNode parent = locateNode.getParent();
    if (parent == null || parent.getType() != ASTNode.VARIABLE) {
      return false;
    }

    final Variable variable = (Variable) parent;
    // if it is not a dollared variable - it is not a global one
    if (!variable.isDollared() || variable.getParent().getType() == ASTNode.FIELD_DECLARATION) {
      return false;
    }

    // ignore static memeber call
    if (parent.getParent().getType() == ASTNode.STATIC_FIELD_ACCESS) {
      final StaticFieldAccess staticFieldAccess = (StaticFieldAccess) parent.getParent();
      if (staticFieldAccess.getMember() == variable) {
        return false;
      }
    }

    if (parent.getParent().getLocationInParent() == FieldsDeclaration.FIELDS_PROPERTY) {
      return false;
    }

    // check if declared global in function
    while (parent != null) {
      // if the variable was used inside a function
      if (parent.getType() == ASTNode.FUNCTION_DECLARATION) {
        // global declaration detection
        final int end = parent.getEnd();
        class GlobalSeacher extends ApplyAll {
          public int offset = end;

          public boolean apply(ASTNode node) {
            if (offset != end) {
              return false;
            }

            if (node.getType() == ASTNode.GLOBAL_STATEMENT) {
              GlobalStatement globalStatement = (GlobalStatement) node;
              if (checkGlobal(targetIdentifier, globalStatement)) {
                offset = globalStatement.getStart();
              }
            }

            return true;
          }
        }
        GlobalSeacher searchGlobal = new GlobalSeacher();
        parent.accept(searchGlobal);
        return searchGlobal.offset <= targetIdentifier.getStart();
      }
      parent = parent.getParent();
    }
    return true;
  }
  /**
   * Identifies a constant use
   *
   * @param locateNode
   * @return
   */
  private static boolean isConstant(ASTNode locateNode) {
    assert locateNode != null;
    Scalar scalar = null;
    // check if it is an identifier
    if (locateNode.getType() != ASTNode.SCALAR) {
      ASTNode parent = locateNode.getParent();
      ASTNode node = null;
      // php 5.3, the parent is NamespaceName
      if (parent instanceof NamespaceName) {
        node = parent.getParent().getParent();
      } else { // non-php 5.3
        node = parent.getParent();
      }

      // check if the node is 'define'
      if ((locateNode instanceof Identifier)
          && "define".equals(((Identifier) locateNode).getName()) // $NON-NLS-1$
          && node instanceof FunctionInvocation) {
        FunctionInvocation inv = (FunctionInvocation) node;
        List<Expression> parameters = inv.parameters();
        if (parameters != null && parameters.size() > 0) {
          Expression param = parameters.get(0);
          if (param instanceof Scalar) {
            scalar = (Scalar) param;
          } else {
            return false;
          }
        }
      } else {
        return false;
      }
    } else {
      scalar = (Scalar) locateNode;
    }

    // if it is not a dollared variable - it is not a global one
    if (scalar == null
        || scalar.getScalarType() != Scalar.TYPE_STRING
        || scalar.getStringValue() == null) {
      return false;
    }

    final int length = scalar.getStringValue().length() - 1;
    final char charAtBegining = scalar.getStringValue().charAt(0);
    final char charAtEnd = scalar.getStringValue().charAt(length);
    if (!detectString(charAtEnd) && !detectString(charAtBegining)) {
      return true;
    }

    // check if it is part of define
    ASTNode previous = locateNode.getParent();
    if (previous instanceof NamespaceName) {
      previous = previous.getParent();
    }
    if (previous.getType() == ASTNode.FUNCTION_NAME) {
      previous = previous.getParent();
    }

    if (previous.getType() != ASTNode.FUNCTION_INVOCATION) {
      return false;
    }

    final FunctionInvocation functionInvocation = (FunctionInvocation) previous;
    if (!(functionInvocation.getFunctionName().getName() instanceof Identifier)) {
      return false;
    }

    final Identifier identifier = (Identifier) functionInvocation.getFunctionName().getName();
    return "define".equalsIgnoreCase(identifier.getName())
        || "constant".equalsIgnoreCase(identifier.getName()); // $NON-NLS-1$ //$NON-NLS-2$
  }