Package lombok.ast.grammar

Source Code of lombok.ast.grammar.PositionCheckingFormatter

/*
* Copyright (C) 2010 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package lombok.ast.grammar;

import java.util.List;
import java.util.Stack;

import com.google.common.collect.Lists;

import lombok.ast.AstException;
import lombok.ast.Node;
import lombok.ast.Position;
import lombok.ast.printer.TextFormatter;

public class PositionCheckingFormatter extends TextFormatter {
  private Stack<Node> nodeStack = new Stack<Node>();
  private List<AstException> problems = Lists.newArrayList();
  private Source source;
 
  public PositionCheckingFormatter(Source source) {
    this.source = source;
    if ("\r\n".equals(System.getProperty("line.separator", "\n")) && source.getRawInput().contains("\r\n")) {
      setNewlineText("\r\n");
    }
  }
 
  public List<AstException> getProblems() {
    List<AstException> p = Lists.newArrayList(problems);
    if (!nodeStack.isEmpty()) p.add(new AstException(nodeStack.peek(), "This node was never closed"));
    return p;
  }
 
  private void registerNode(Node node) {
    nodeStack.add(node);
    if (node == null) return;
   
    Position p = node.getPosition();
    if (p.isUnplaced()) problems.add(new AstException(node, String.format(
        "this node is unplaced [%s]", node.getClass().getSimpleName())));
    else {
      int delta = p.getStart() - getCurrentPosition(true);
      if (delta != 0) {
        int actualPos = getCurrentPosition(true);
        int repPos = p.getStart();
        reportError(node, "start", actualPos, repPos);
      }
    }
  }
 
  @Override public void buildBlock(Node node) {
    super.buildBlock(node);
    registerNode(node);
  }
 
  @Override public void buildInline(Node node) {
    super.buildInline(node);
    registerNode(node);
  }
 
  @Override public void closeBlock() {
    super.closeBlock();
    checkNodeClose();
  }
 
  @Override public void closeInline() {
    super.closeInline();
    checkNodeClose();
  }
 
  private void checkNodeClose() {
    Node node = nodeStack.pop();
    if (node == null) return;
    Position p = node.getPosition();
    if (p.isUnplaced()) return//opener already generated error.
    if (p.getStart() > p.getEnd()) problems.add(new AstException(node, "Node ends before it starts."));
    int delta = p.getEnd() - Math.max(getCurrentPosition(false), p.getStart());
    if (delta != 0) {
      int actualPos = getCurrentPosition(false);
      int repPos = p.getEnd();
      reportError(node, "end", actualPos, repPos);
    }
  }
 
  private static final int RANGE = 12;
  private void reportError(Node node, String description, int actualPos, int repPos) {
    int delta = repPos - actualPos;
    String raw = source.getRawInput();
    String actualPrefix = getCharsBeforePosition(actualPos, raw);
    String actualPostfix = getCharsAfterPosition(actualPos, raw);
    String reportedPrefix = getCharsBeforePosition(repPos, raw);
    String reportedPostfix = getCharsAfterPosition(repPos, raw);
    problems.add(new AstException(node, String.format(
      "this[%s] node's " + description + " is misreported with %+d\nactual(%d): \"%s⊚%s\"\nreported(%d): \"%s⊚%s\"\n%s",
      node.getClass().getSimpleName(),
      delta, actualPos, actualPrefix, actualPostfix, repPos, reportedPrefix, reportedPostfix, node)));
  }
 
  private String getCharsAfterPosition(int pos, String raw) {
    int max = raw.length();
    if (pos < 0) pos = 0;
    return pos >= max ? "" : raw.substring(pos, Math.min(pos + RANGE, max));
  }
 
  private String getCharsBeforePosition(int pos, String raw) {
    int max = raw.length();
    return pos > RANGE ? raw.substring(
        Math.min(max, pos-RANGE), Math.min(max, pos)) :
        raw.substring(0, Math.min(max, pos));
  }
}
TOP

Related Classes of lombok.ast.grammar.PositionCheckingFormatter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.