Use the source code position from core in javascript
This commit is contained in:
@ -3,10 +3,11 @@
|
||||
*/
|
||||
package net.sourceforge.pmd.lang.ecmascript.ast;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.AbstractNode;
|
||||
|
||||
import org.mozilla.javascript.ast.AstNode;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.AbstractNode;
|
||||
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;
|
||||
|
||||
public abstract class AbstractEcmascriptNode<T extends AstNode> extends AbstractNode implements EcmascriptNode<T> {
|
||||
|
||||
protected final T node;
|
||||
@ -22,9 +23,9 @@ public abstract class AbstractEcmascriptNode<T extends AstNode> extends Abstract
|
||||
int endOffset = startOffset + node.getLength();
|
||||
|
||||
this.beginLine = positioner.lineNumberFromOffset(startOffset);
|
||||
this.beginColumn = positioner.columnFromOffset(startOffset);
|
||||
this.beginColumn = positioner.columnFromOffset(this.beginLine, startOffset);
|
||||
this.endLine = positioner.lineNumberFromOffset(endOffset);
|
||||
this.endColumn = positioner.columnFromOffset(endOffset) - 1; // end column is inclusive
|
||||
this.endColumn = positioner.columnFromOffset(this.endLine, endOffset) - 1; // end column is inclusive
|
||||
if (this.endColumn < 0) {
|
||||
this.endColumn = 0;
|
||||
}
|
||||
|
@ -10,8 +10,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
|
||||
import org.mozilla.javascript.ast.ArrayComprehension;
|
||||
import org.mozilla.javascript.ast.ArrayComprehensionLoop;
|
||||
import org.mozilla.javascript.ast.ArrayLiteral;
|
||||
@ -66,6 +64,9 @@ import org.mozilla.javascript.ast.XmlExpression;
|
||||
import org.mozilla.javascript.ast.XmlMemberGet;
|
||||
import org.mozilla.javascript.ast.XmlString;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.ast.SourceCodePositioner;
|
||||
|
||||
public final class EcmascriptTreeBuilder implements NodeVisitor {
|
||||
|
||||
private static final Map<Class<? extends AstNode>, Constructor<? extends EcmascriptNode<?>>> NODE_TYPE_TO_NODE_ADAPTER_TYPE = new HashMap<>();
|
||||
|
@ -1,56 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
package net.sourceforge.pmd.lang.ecmascript.ast;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Calculates from an absolute offset in the source file the line/column coordinate.
|
||||
* This is needed as Rhino only offers absolute positions for each node.
|
||||
*
|
||||
* Idea from: http://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/javascript/jscomp/SourceFile.java
|
||||
*/
|
||||
public class SourceCodePositioner {
|
||||
|
||||
private int[] lineOffsets;
|
||||
|
||||
public SourceCodePositioner(String sourceCode) {
|
||||
analyzeLineOffsets(sourceCode);
|
||||
}
|
||||
|
||||
private void analyzeLineOffsets(String sourceCode) {
|
||||
String[] lines = sourceCode.split("\n");
|
||||
|
||||
int startOffset = 0;
|
||||
int lineNumber = 0;
|
||||
|
||||
lineOffsets = new int[lines.length];
|
||||
|
||||
for (String line : lines) {
|
||||
lineOffsets[lineNumber] = startOffset;
|
||||
lineNumber++;
|
||||
startOffset += line.length() + 1; // +1 for the "\n" character
|
||||
}
|
||||
}
|
||||
|
||||
public int lineNumberFromOffset(int offset) {
|
||||
int search = Arrays.binarySearch(lineOffsets, offset);
|
||||
int lineNumber;
|
||||
if (search >= 0) {
|
||||
lineNumber = search;
|
||||
} else {
|
||||
int insertionPoint = search;
|
||||
insertionPoint += 1;
|
||||
insertionPoint *= -1;
|
||||
lineNumber = insertionPoint - 1; // take the insertion point one before
|
||||
}
|
||||
return lineNumber + 1; // 1-based line numbers
|
||||
}
|
||||
|
||||
public int columnFromOffset(int offset) {
|
||||
int lineNumber = lineNumberFromOffset(offset);
|
||||
int columnOffset = offset - lineOffsets[lineNumber - 1];
|
||||
return columnOffset + 1; // 1-based column offsets
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
package net.sourceforge.pmd.lang.ecmascript.ast;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit test for {@link SourceCodePositioner}.
|
||||
*/
|
||||
public class SourceCodePositionerTest {
|
||||
|
||||
private final String SOURCE_CODE = "abcd\ndefghi\n\njklmn\nopq";
|
||||
|
||||
/**
|
||||
* Tests whether the lines and columns are calculated correctly.
|
||||
*/
|
||||
@Test
|
||||
public void testLineNumberFromOffset() {
|
||||
SourceCodePositioner positioner = new SourceCodePositioner(SOURCE_CODE);
|
||||
|
||||
int offset;
|
||||
|
||||
offset = SOURCE_CODE.indexOf('a');
|
||||
assertEquals(1, positioner.lineNumberFromOffset(offset));
|
||||
assertEquals(1, positioner.columnFromOffset(offset));
|
||||
|
||||
offset = SOURCE_CODE.indexOf('b');
|
||||
assertEquals(1, positioner.lineNumberFromOffset(offset));
|
||||
assertEquals(2, positioner.columnFromOffset(offset));
|
||||
|
||||
offset = SOURCE_CODE.indexOf('e');
|
||||
assertEquals(2, positioner.lineNumberFromOffset(offset));
|
||||
assertEquals(2, positioner.columnFromOffset(offset));
|
||||
|
||||
offset = SOURCE_CODE.indexOf('q');
|
||||
assertEquals(5, positioner.lineNumberFromOffset(offset));
|
||||
assertEquals(3, positioner.columnFromOffset(offset));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user