Skip to content

Commit

Permalink
Code analysis for type vars.
Browse files Browse the repository at this point in the history
  • Loading branch information
fabioz committed Oct 19, 2024
1 parent fe4bfda commit 65c7c63
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ public Object visitClassDef(ClassDef node) throws Exception {

handleDecorators(node.decs);

// visit typed params. i.e.: class A[T]
if (node.type_params != null) {
node.type_params.accept(visitor);
}

//we want to visit the bases before actually starting the class scope (as it's as if they're attribute
//accesses).
if (node.bases != null) {
Expand Down Expand Up @@ -383,6 +388,11 @@ public Object visitFunctionDef(FunctionDef node) throws Exception {
addToNamesToIgnore(node, false, true);

AbstractScopeAnalyzerVisitor visitor = this;
// visit typed params. i.e.: def func[T](arg: t):
if (node.type_params != null) {
node.type_params.accept(visitor);
}

argumentsType args = node.args;

//visit the defaults first (before starting the scope, because this is where the load of variables from other scopes happens)
Expand Down Expand Up @@ -566,7 +576,7 @@ public Object visitLambda(org.python.pydev.parser.jython.ast.Lambda node) throws
@Override
public Object visitNameTok(NameTok nameTok) throws Exception {
unhandled_node(nameTok);
if (nameTok.ctx == NameTok.VarArg || nameTok.ctx == NameTok.KwArg) {
if (nameTok.ctx == NameTok.VarArg || nameTok.ctx == NameTok.KwArg || nameTok.ctx == NameTok.TypeVarName) {
SourceToken token = AbstractVisitor.makeToken(nameTok, moduleName, nature, this.current);
scope.addToken(token, token, (nameTok).id);
if (checkCurrentScopeForAssignmentsToBuiltins()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.python.pydev.analysis;

import org.eclipse.jface.text.Document;
import org.python.pydev.core.IPythonNature;
import org.python.pydev.parser.jython.ParseException;

public class OccurrencesAnalyzerPy312Test extends AnalysisTestsBase {

public static void main(String[] args) {
try {
OccurrencesAnalyzerPy312Test analyzer2 = new OccurrencesAnalyzerPy312Test();
analyzer2.setUp();
analyzer2.testTypeVarClassSimple();
analyzer2.tearDown();
System.out.println("finished");
junit.textui.TestRunner.run(OccurrencesAnalyzerPy312Test.class);
System.out.println("finished all");
} catch (Throwable e) {
e.printStackTrace();
}
System.exit(0);
}

private int initialGrammar;

@Override
public void setUp() throws Exception {
initialGrammar = GRAMMAR_TO_USE_FOR_PARSING;
GRAMMAR_TO_USE_FOR_PARSING = IPythonNature.GRAMMAR_PYTHON_VERSION_3_12;
super.setUp();
}

@Override
public void tearDown() throws Exception {
GRAMMAR_TO_USE_FOR_PARSING = initialGrammar;
ParseException.verboseExceptions = true;
super.tearDown();
}

@Override
protected boolean isPython3Test() {
return true;
}

public void testTypeVarMethodSimple() {
doc = new Document("""
def method[T](argument:T)->None:
print(argument)
""");
checkNoError();
}

public void testTypeVarClassSimple() {
doc = new Document("""
class ClassA[T1, T2, T3](list[T1]):
def method1(self, a: T2) -> None:
...
def method2(self) -> T3:
...
""");
checkNoError();
}

}

0 comments on commit 65c7c63

Please sign in to comment.