Skip to content

Commit e343412

Browse files
authored
Merge pull request #21 from neilccbrown/import-as
Added support for "import x as y" in .pyi files
2 parents 5d6a54b + 9a2f29b commit e343412

15 files changed

Lines changed: 19749 additions & 19560 deletions

File tree

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import sbtcrossproject.CrossPlugin.autoImport.{crossProject, CrossType}
22

33
val useScalaVersion = "2.13.14"
4-
val releaseVersion = "1.1.0"
4+
val releaseVersion = "1.1.1"
55

66
val sharedSettings = Seq(
77
scalaVersion := useScalaVersion,

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
{
33
"name": "tigerpython-parser",
4-
"version": "1.1.0",
4+
"version": "1.1.1",
55
"description": "Enhanced error recognition in Python ",
66
"main": "release/tigerpython-parser.mjs",
77
"types": "tpParser/js/types/index.d.ts",

release/tigerpython-parser.js

Lines changed: 2217 additions & 2216 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

release/tigerpython-parser.mjs

Lines changed: 17425 additions & 17338 deletions
Large diffs are not rendered by default.

tpParser/shared/src/main/scala/tigerpython/utilities/completer/PyiModuleParser.scala

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@ package tigerpython.utilities.completer
33
import tigerpython.utilities.fastparse._
44
import tigerpython.utilities.types._
55

6+
import scala.collection.mutable
67
import scala.collection.mutable.ArrayBuffer
78

89
/**
910
* This takes a Pyi-file and defines a TigerPython-module from it.
1011
*/
11-
class PyiModuleParser(val module: Module) extends PyiParser {
12+
class PyiModuleParser(val module: Module, val moduleLookup: mutable.Map[String, DataType]) extends PyiParser {
13+
14+
// Maps an alias to a module, imported either as:
15+
// import math # produces "math" -> <math Module>
16+
// import math as m # produces "m" -> <math Module>
17+
private val fullModuleImports: mutable.Map[String, Module] = mutable.Map()
1218

1319
private var currentClass: PythonClass = _
1420

@@ -36,6 +42,17 @@ class PyiModuleParser(val module: Module) extends PyiParser {
3642
for (el <- elts.tail)
3743
tp = DataType.getCompatibleType(tp, convertToType(el))
3844
tp
45+
case AttributeNode(base, name) =>
46+
val baseDotted = PyiModuleParser.toDotted(base)
47+
if (baseDotted != null && fullModuleImports.contains(baseDotted))
48+
fullModuleImports(baseDotted).findField(name) match {
49+
case Some (tp) =>
50+
tp
51+
case _ =>
52+
BuiltinTypes.ANY_TYPE
53+
}
54+
else
55+
BuiltinTypes.ANY_TYPE
3956
case _ =>
4057
BuiltinTypes.ANY_TYPE
4158
}
@@ -113,8 +130,56 @@ class PyiModuleParser(val module: Module) extends PyiParser {
113130
}
114131

115132
override protected
116-
def importModule(module: String, alias: String): Boolean = false
133+
def importModule(module: String, alias: String): Boolean = {
134+
val segments = module.split("\\.")
135+
if (segments.isEmpty) return false
136+
137+
// Start with the outermost module
138+
var currentOpt = moduleLookup.get(segments.head) match {
139+
case Some(m: Module) if m != null => Some(m)
140+
case _ => None
141+
}
142+
143+
// Traverse nested modules
144+
for (name <- segments.tail if currentOpt.isDefined) {
145+
currentOpt = currentOpt match {
146+
case Some(mod) =>
147+
mod.getFields(name) match {
148+
case m: Module if m != null => Some(m)
149+
case _ => None
150+
}
151+
case None => None
152+
}
153+
}
154+
155+
currentOpt match {
156+
case Some(finalModule) =>
157+
if (alias == null)
158+
fullModuleImports(module) = finalModule
159+
else
160+
fullModuleImports(alias) = finalModule
161+
true
162+
case None =>
163+
false
164+
}
165+
}
166+
117167

118168
override protected
119169
def importNameFromModule(module: String, name: String, alias: String): Boolean = false
120170
}
171+
172+
object PyiModuleParser {
173+
private def toDotted(exprAst: ExprAst): String = {
174+
exprAst match {
175+
case NameNode(name) =>
176+
name
177+
case AttributeNode(base, name) =>
178+
val prefix = toDotted(base)
179+
if (prefix == null) null
180+
else s"$prefix.$name"
181+
case _ =>
182+
null
183+
}
184+
}
185+
}

tpParser/shared/src/main/scala/tigerpython/utilities/scopes/ModuleLoader.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ object ModuleLoader {
227227
val names = name.split('.')
228228
val lastName = names(names.length - 1)
229229
val module = new Module(lastName)
230-
val parser = new PyiModuleParser(module)
230+
val parser = new PyiModuleParser(module, modules)
231231
parser.parse(body)
232232
if (names.length == 1) {
233233
modules(name) = module

tpParser/shared/src/main/scala/tigerpython/utilities/types/BuiltinTypes.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ package tigerpython.utilities.types
99
object BuiltinTypes {
1010
val builtins: collection.mutable.Map[String, DataType] = collection.mutable.Map[String, DataType]()
1111

12+
def add(types: Instance*): Unit =
13+
for (t <- types)
14+
builtins(t.baseType.name) = t.baseType
15+
16+
1217
def fromString(s: String): DataType = {
1318
val result = builtins.getOrElse(s, ExceptionTypes.byName(s))
1419
if (result != null)
@@ -294,6 +299,8 @@ object BuiltinTypes {
294299
val STRING = new Instance(STRING_TYPE)
295300
val TUPLE = new Instance(TUPLE_TYPE)
296301

302+
add(BOOLEAN, BUFFER, BYTEARRAY, COMPLEX, DICT, FILE, FLOAT, FROZENSET, GENERATOR, INTEGER, ITERATOR, LIST, LONG, NONE, SET, STRING, TUPLE);
303+
297304
def appyTigerPythonModifications(): Unit = {
298305
LIST_TYPE.addFields(
299306
PrimitiveType("first"),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 6
2+
# capitalize;center;count;decode;encode;endswith;expandtabs;find;format;index;isalnum;isalpha;isdigit;islower;isspace;istitle;isupper;join;ljust;lower;lstrip;partition;replace;rfind;rindex;rjust;rpartition;rsplit;rstrip;split;splitlines;startswith;strip;swapcase;title;translate;upper;zfill
3+
"foo".
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 14
2+
# capitalize;center;count;decode;encode;endswith;expandtabs;find;format;index;isalnum;isalpha;isdigit;islower;isspace;istitle;isupper;join;ljust;lower;lstrip;partition;replace;rfind;rindex;rjust;rpartition;rsplit;rstrip;split;splitlines;startswith;strip;swapcase;title;translate;upper;zfill
3+
"foo".upper().

0 commit comments

Comments
 (0)