Пример #1
0
 /**
  * Returns the extended start position of the given node. Unlike {@link ASTNode#getStart()} and
  * {@link ASTNode#getLength()}, the extended source range may include comments and whitespace
  * immediately before or after the normal source range for the node.
  *
  * @param node the node
  * @return the 0-based character index, or <code>-1</code> if no source position information is
  *     recorded for this node
  * @see #getExtendedLength(ASTNode)
  * @since 3.0
  */
 public int getExtendedStartPosition(ASTNode node) {
   if (this.leadingPtr >= 0) {
     long range = -1;
     for (int i = 0; range < 0 && i <= this.leadingPtr; i++) {
       if (this.leadingNodes[i] == node) range = this.leadingIndexes[i];
     }
     if (range >= 0) {
       return this.comments[(int) (range >> 32)].getStart();
     }
   }
   return node.getStart();
 }
Пример #2
0
  @Override
  public Object getReducedValue(
      final Object ctx, final Object thisValue, final VariableResolverFactory factory) {
    try {
      final String i = String.valueOf(soundslike.getReducedValue(ctx, thisValue, factory));
      if (i == null) {
        throw new ClassCastException();
      }

      final String x = (String) stmt.getReducedValue(ctx, thisValue, factory);
      if (x == null) {
        throw new CompileException("not a string: " + stmt.getName(), stmt.getExpr(), getStart());
      }

      return similarity(i, x);
    } catch (final ClassCastException e) {
      throw new CompileException(
          "not a string: " + soundslike.getName(), soundslike.getExpr(), soundslike.getStart());
    }
  }
  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
    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;
    }
Пример #5
0
  /**
   * Search and store node leading comments. Comments are searched in position range from previous
   * extended position to node start position. If one or several comment are found, returns first
   * comment start position, otherwise returns node start position.
   *
   * <p>Starts to search for first comment before node start position and return if none was
   * found...
   *
   * <p>When first comment is found before node, goes up in comment list until one of following
   * conditions becomes true:
   *
   * <ol>
   *   <li>comment end is before previous end
   *   <li>comment start and previous end is on the same line but not on same line of node 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 some comment have been found, then no token should be on on the same line before, so remove
   * all comments which do not verify this assumption.
   *
   * <p>If finally there's leading still comments, then stores indexes of the first and last one in
   * leading comments table.
   */
  int storeLeadingComments(ASTNode node, int previousEnd, int[] parentLineRange) {
    // Init extended position
    int nodeStart = node.getStart();
    int extended = nodeStart;

    // Get line of node start position
    int previousEndLine = getLineNumber(previousEnd, parentLineRange);
    int nodeStartLine = getLineNumber(nodeStart, parentLineRange);

    // Find first comment index
    int idx = getCommentIndex(0, nodeStart, -1);
    if (idx == -1) {
      return nodeStart;
    }

    // Look after potential comments
    int startIdx = -1;
    int endIdx = idx;
    int previousStart = nodeStart;
    while (idx >= 0 && previousStart >= previousEnd) {
      // Verify for each comment that there's only white spaces between
      // end and start of {following comment|node}
      Comment comment = this.comments[idx];
      int commentStart = comment.getStart();
      int end = commentStart + comment.getLength() - 1;
      int commentLine = getLineNumber(commentStart, parentLineRange);
      if (end <= previousEnd || (commentLine == previousEndLine && commentLine != nodeStartLine)) {
        // stop search on condition 1) and 2)
        break;
      } else if ((end + 1) < previousStart) { // may be equals => then no
        // scan is necessary
        try {
          resetTo(end + 1, previousStart);
          this.scanner.next_token();
          String token = this.scanner.yytext();
          if (token != null && token.trim().length() > 0) {
            // stop search on condition 3)
            // if first comment fails, then there's no extended
            // position in fact
            if (idx == endIdx) {
              return nodeStart;
            }
            break;
          }
        } catch (Exception e) {
          // Should not happen, but return no extended position...
          assert false;
          return nodeStart;
        }
      }
      // Store previous infos
      previousStart = commentStart;
      startIdx = idx--;
    }
    if (startIdx != -1) {
      // Store leading comments indexes
      if (startIdx <= endIdx) {
        if (++this.leadingPtr == 0) {
          this.leadingNodes = new ASTNode[STORAGE_INCREMENT];
          this.leadingIndexes = new long[STORAGE_INCREMENT];
        } else if (this.leadingPtr == this.leadingNodes.length) {
          int newLength = (this.leadingPtr * 3 / 2) + STORAGE_INCREMENT;
          System.arraycopy(
              this.leadingNodes, 0, this.leadingNodes = new ASTNode[newLength], 0, this.leadingPtr);
          System.arraycopy(
              this.leadingIndexes,
              0,
              this.leadingIndexes = new long[newLength],
              0,
              this.leadingPtr);
        }
        this.leadingNodes[this.leadingPtr] = node;
        this.leadingIndexes[this.leadingPtr] = (((long) startIdx) << 32) + endIdx;
        extended = this.comments[endIdx].getStart();
      }
    }
    return extended;
  }