Skip to content

Commit 9a7397e

Browse files
SONARPY-1753 Introduce a new symbol model decoupled from types
1 parent 18db8e6 commit 9a7397e

File tree

14 files changed

+964
-1
lines changed

14 files changed

+964
-1
lines changed

python-frontend/src/main/java/org/sonar/plugins/python/api/tree/Name.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
*/
2020
package org.sonar.plugins.python.api.tree;
2121

22+
import org.sonar.python.semantic.v2.SymbolV2;
23+
2224
/**
2325
* See https://docs.python.org/3/reference/expressions.html#atom-identifiers
2426
*/
@@ -28,4 +30,6 @@ public interface Name extends Expression, HasSymbol {
2830

2931
// FIXME: we should create a separate tree for Variables
3032
boolean isVariable();
33+
34+
SymbolV2 symbolV2();
3135
}

python-frontend/src/main/java/org/sonar/python/semantic/SymbolUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public static List<Expression> assignmentsLhs(AssignmentStatement assignmentStat
148148
.toList();
149149
}
150150

151-
static List<Name> boundNamesFromExpression(@CheckForNull Tree tree) {
151+
public static List<Name> boundNamesFromExpression(@CheckForNull Tree tree) {
152152
List<Name> names = new ArrayList<>();
153153
if (tree == null) {
154154
return names;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
package org.sonar.python.semantic.v2;public class ProjectLevelTypeTable {
2+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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.semantic.v2;
21+
22+
import java.util.ArrayList;
23+
import java.util.HashMap;
24+
import java.util.HashSet;
25+
import java.util.List;
26+
import java.util.Map;
27+
import java.util.Set;
28+
import javax.annotation.CheckForNull;
29+
import javax.annotation.Nullable;
30+
import org.sonar.plugins.python.api.tree.Name;
31+
import org.sonar.plugins.python.api.tree.Parameter;
32+
import org.sonar.plugins.python.api.tree.Tree;
33+
34+
public class ScopeV2 {
35+
private final ScopeV2 parent;
36+
private final Tree rootTree;
37+
38+
private final List<ScopeV2> childrenScopes;
39+
40+
final Map<String, SymbolV2> symbolsByName = new HashMap<>();
41+
private final Set<SymbolV2> symbols = new HashSet<>();
42+
43+
public ScopeV2(ScopeV2 parent, Tree rootTree) {
44+
this.parent = parent;
45+
this.rootTree = rootTree;
46+
this.childrenScopes = new ArrayList<>();
47+
}
48+
49+
public ScopeV2 parent() {
50+
return parent;
51+
}
52+
53+
public Tree root() {
54+
return rootTree;
55+
}
56+
57+
void addBindingUsage(Name nameTree, UsageV2.Kind kind, @Nullable String fullyQualifiedName) {
58+
String symbolName = nameTree.name();
59+
if (!isExistingSymbol(symbolName)) {
60+
SymbolV2 symbol = new SymbolV2(symbolName);
61+
symbols.add(symbol);
62+
symbolsByName.put(symbolName, symbol);
63+
}
64+
SymbolV2 symbol = resolve(symbolName);
65+
if (symbol != null) {
66+
symbol.addUsage(nameTree, kind);
67+
}
68+
}
69+
70+
@CheckForNull
71+
SymbolV2 resolve(String symbolName) {
72+
SymbolV2 symbol = symbolsByName.get(symbolName);
73+
if (parent == null || symbol != null) {
74+
return symbol;
75+
}
76+
// parent scope of a symbol inside of a class its the classes parent scope
77+
if (parent.rootTree.is(Tree.Kind.CLASSDEF)) {
78+
return parent.parent.resolve(symbolName);
79+
}
80+
return parent.resolve(symbolName);
81+
}
82+
83+
private boolean isExistingSymbol(String symbolName) {
84+
//return symbolsByName.containsKey(symbolName) || globalNames.contains(symbolName) || nonlocalNames.contains(symbolName);
85+
return symbolsByName.containsKey(symbolName);
86+
}
87+
88+
void createSelfParameter(Parameter parameter) {
89+
Name nameTree = parameter.name();
90+
if (nameTree == null) {
91+
return;
92+
}
93+
String symbolName = nameTree.name();
94+
//TODO: Check with SelfSymbolImpl
95+
SymbolV2 symbol = new SymbolV2(symbolName);
96+
symbols.add(symbol);
97+
symbolsByName.put(symbolName, symbol);
98+
symbol.addUsage(nameTree, UsageV2.Kind.PARAMETER);
99+
}
100+
101+
public Map<String, SymbolV2> symbols() {
102+
return symbolsByName;
103+
}
104+
105+
public List<ScopeV2> childrenScopes() {
106+
return childrenScopes;
107+
}
108+
}

0 commit comments

Comments
 (0)