Use the source code position from core in javascript

This commit is contained in:
Andreas Dangel
2016-04-09 18:57:56 +02:00
parent 380fdcab54
commit 8bec393cf8
4 changed files with 13 additions and 67 deletions

View File

@ -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;
}

View File

@ -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<>();

View File

@ -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
}
}

View File

@ -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));
}
}