Skip to content

Commit 4b09ae6

Browse files
joke1196ghislainpiot
authored andcommitted
SONARPY-1990: Map JSON locations to python locations in IPythonTreeMaker (#1884)
1 parent 039867a commit 4b09ae6

File tree

10 files changed

+323
-65
lines changed

10 files changed

+323
-65
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* SonarQube Python Plugin
3+
* Copyright (C) 2011-2024 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.python;
21+
22+
import java.util.Map;
23+
24+
public record IPythonLocation(int line, int column, Map<Integer, Integer> colOffset) {
25+
}

python-frontend/src/main/java/org/sonar/python/tree/IPythonTreeMaker.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import java.util.ArrayList;
2525
import java.util.Collection;
2626
import java.util.List;
27+
import java.util.Map;
2728
import java.util.stream.Collectors;
2829
import java.util.stream.Stream;
30+
import javax.annotation.Nullable;
2931
import org.sonar.plugins.python.api.tree.CellMagicStatement;
3032
import org.sonar.plugins.python.api.tree.DynamicObjectInfoStatement;
3133
import org.sonar.plugins.python.api.tree.Expression;
@@ -37,17 +39,38 @@
3739
import org.sonar.plugins.python.api.tree.Token;
3840
import org.sonar.plugins.python.api.tree.Tree;
3941
import org.sonar.python.DocstringExtractor;
42+
import org.sonar.python.IPythonLocation;
4043
import org.sonar.python.api.IPythonGrammar;
4144
import org.sonar.python.api.PythonGrammar;
4245

4346
public class IPythonTreeMaker extends PythonTreeMaker {
4447

48+
private Map<Integer, IPythonLocation> offsetMap;
49+
50+
public IPythonTreeMaker() {
51+
this(null);
52+
}
53+
public IPythonTreeMaker(@Nullable Map<Integer, IPythonLocation> offsetMap) {
54+
this.offsetMap = offsetMap;
55+
}
56+
57+
@Override
58+
protected Token toPyToken(@Nullable com.sonar.sslr.api.Token token) {
59+
if (token == null) {
60+
return null;
61+
}
62+
if (this.offsetMap != null) {
63+
return TokenEnricher.enrichToken(token, offsetMap);
64+
}
65+
return new TokenImpl(token);
66+
}
67+
4568
@Override
4669
public FileInput fileInput(AstNode astNode) {
4770
StatementList statementList = astNode.getChildren(IPythonGrammar.CELL, IPythonGrammar.MAGIC_CELL)
4871
.stream()
4972
.flatMap(this::getStatementsFromCell)
50-
.collect(Collectors.collectingAndThen(Collectors.toList(), l -> l.isEmpty()? null : new StatementListImpl(l)));
73+
.collect(Collectors.collectingAndThen(Collectors.toList(), l -> l.isEmpty() ? null : new StatementListImpl(l)));
5174
Token endOfFile = toPyToken(astNode.getFirstChild(GenericTokenType.EOF).getToken());
5275
FileInputImpl pyFileInputTree = new FileInputImpl(statementList, endOfFile, DocstringExtractor.extractDocstring(statementList));
5376
setParents(pyFileInputTree);
@@ -59,7 +82,7 @@ private Stream<Statement> getStatementsFromCell(AstNode cell) {
5982
if (cell.is(IPythonGrammar.CELL)) {
6083
return getStatements(cell).stream().map(this::statement);
6184
} else {
62-
return Stream.of(cell.getFirstChild(IPythonGrammar.CELL_MAGIC_STATEMENT)).map(IPythonTreeMaker::cellMagicStatement);
85+
return Stream.of(cell.getFirstChild(IPythonGrammar.CELL_MAGIC_STATEMENT)).map(this::cellMagicStatement);
6386
}
6487
}
6588

@@ -85,12 +108,12 @@ protected Expression annotatedRhs(AstNode annotatedRhs) {
85108
return super.annotatedRhs(annotatedRhs);
86109
}
87110

88-
private static CellMagicStatement cellMagicStatement(AstNode astNode) {
111+
private CellMagicStatement cellMagicStatement(AstNode astNode) {
89112
var tokens = astNode.getChildren()
90113
.stream()
91114
.map(AstNode::getTokens)
92115
.flatMap(Collection::stream)
93-
.map(IPythonTreeMaker::toPyToken)
116+
.map(this::toPyToken)
94117
.toList();
95118
return new CellMagicStatementImpl(tokens);
96119
}
@@ -121,7 +144,7 @@ protected DynamicObjectInfoStatement dynamicObjectInfoStatement(AstNode astNode)
121144
isQuestionMarksBefore = false;
122145
child.getTokens()
123146
.stream()
124-
.map(PythonTreeMaker::toPyToken)
147+
.map(this::toPyToken)
125148
.forEach(children::add);
126149
}
127150
}
@@ -137,9 +160,8 @@ protected LineMagic lineMagic(AstNode astNode) {
137160
.skip(2)
138161
.map(AstNode::getTokens)
139162
.flatMap(Collection::stream)
140-
.map(IPythonTreeMaker::toPyToken)
163+
.map(this::toPyToken)
141164
.toList();
142165
return new LineMagicImpl(percent, name, tokens);
143166
}
144-
145167
}

0 commit comments

Comments
 (0)