예제 #1
0
 /*
  * Returns the extended end position of the given node.
  */
 public int getExtendedEnd(ASTNode node) {
   int end = node.getEnd();
   if (this.trailingPtr >= 0) {
     long range = -1;
     for (int i = 0; range < 0 && i <= this.trailingPtr; i++) {
       if (this.trailingNodes[i] == node) range = this.trailingIndexes[i];
     }
     if (range >= 0) {
       Comment lastComment = this.comments[(int) range];
       end = lastComment.getEnd();
     }
   }
   return end - 1;
 }
예제 #2
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();
      }
    }
  protected void addError(String msg, ASTNode expr) {
    int line = expr.getLineNumber();
    int col = expr.getColumnNumber();
    // GRECLIPSE
    int start = expr.getStart();
    int end = expr.getEnd() - 1;
    if (expr instanceof ClassNode) {
      // assume we have a class declaration
      ClassNode cn = (ClassNode) expr;
      if (cn.getNameEnd() > 0) {
        start = cn.getNameStart();
        end = cn.getNameEnd();
      } else if (cn.getComponentType() != null) {
        // avoid extra whitespace after closing ]
        end--;
      }

    } else if (expr instanceof DeclarationExpression) {
      // assume that we just want to underline the variable declaration
      DeclarationExpression decl = (DeclarationExpression) expr;
      Expression lhs = decl.getLeftExpression();
      start = lhs.getStart();
      // avoid extra space before = if a variable
      end =
          lhs instanceof VariableExpression ? start + lhs.getText().length() - 1 : lhs.getEnd() - 1;
    }
    // end

    SourceUnit source = getSourceUnit();
    source
        .getErrorCollector()
        .addErrorAndContinue(
            // GRECLIPSE: start
            new SyntaxErrorMessage(
                new PreciseSyntaxException(msg + '\n', line, col, start, end), source)
            // end
            );
  }
예제 #4
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;
  }
예제 #5
0
  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;
  }