View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.lang.ecmascript.ast;
    5
    6   import java.util.Arrays;
    7
    8   /**
    9    * Calculates from an absolute offset in the source file the line/column coordinate.
    10   * This is needed as Rhino only offers absolute positions for each node.
    11   *
    12   * Idea from: http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/SourceFile.java
    13   */
    14  public class SourceCodePositioner {
    15
    16      private int[] lineOffsets;
    17
    18      public SourceCodePositioner(String sourceCode) {
    19  	analyzeLineOffsets(sourceCode);
    20      }
    21
    22      private void analyzeLineOffsets(String sourceCode) {
    23  	String[] lines = sourceCode.split("\n");
    24
    25  	int startOffset = 0;
    26  	int lineNumber = 0;
    27
    28  	lineOffsets = new int[lines.length];
    29
    30  	for (String line : lines) {
    31  	    lineOffsets[lineNumber] = startOffset;
    32  	    lineNumber++;
    33  	    startOffset += line.length() + 1; // +1 for the "\n" character
    34  	}
    35      }
    36
    37      public int lineNumberFromOffset(int offset) {
    38  	int search = Arrays.binarySearch(lineOffsets, offset);
    39  	int lineNumber;
    40  	if (search >= 0) {
    41  	    lineNumber = search;
    42  	} else {
    43  	    int insertionPoint = search;
    44  	    insertionPoint += 1;
    45  	    insertionPoint *= -1;
    46  	    lineNumber = insertionPoint - 1; // take the insertion point one before
    47  	}
    48  	return lineNumber + 1; // 1-based line numbers
    49      }
    50
    51      public int columnFromOffset(int offset) {
    52  	int lineNumber = lineNumberFromOffset(offset);
    53  	int columnOffset = offset - lineOffsets[lineNumber - 1];
    54  	return columnOffset + 1; // 1-based column offsets
    55      }
    56  }