Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
alessiostalla committed Nov 7, 2024
2 parents f690431 + d80608b commit 54f94ae
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pylasu/model/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class internal_property(property):

def internal_properties(*props: str):
def decorate(cls: type):
cls.__internal_properties__ = [*Node.__internal_properties__, *props]
cls.__internal_properties__ = getattr(cls, "__internal_properties__", []) + [*Node.__internal_properties__, *props]
return cls
return decorate

Expand Down
35 changes: 31 additions & 4 deletions pylasu/model/naming.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass, field
from itertools import chain
from typing import TypeVar, Generic, Optional, List, Dict


Expand Down Expand Up @@ -33,14 +34,14 @@ def __hash__(self):
def resolved(self):
return self.referred is not None

def resolve(self, scope: 'Scope') -> bool:
self.referred = scope.lookup(symbol_name=self.name)
def resolve(self, scope: 'Scope', case_insensitive: bool = False) -> bool:
self.referred = scope.lookup(symbol_name=self.name, case_insensitive=case_insensitive)
return self.resolved()

def try_to_resolve(self, candidates: List[T], case_insensitive: bool = False) -> bool:
"""
Try to resolve the reference by finding a named element with a matching name.
The name match is performed in a case sensitive or insensitive way depending on the value of caseInsensitive.
The name match is performed in a case sensitive or insensitive way depending on the value of case_insensitive.
"""

def check_name(candidate: T) -> bool:
Expand All @@ -60,10 +61,36 @@ class Symbol(PossiblyNamed):
class Scope:
symbols: Dict[str, List[Symbol]] = field(default_factory=list)
parent: Optional['Scope'] = field(default=None)
insensitive_map: Optional[Dict[str, List[str]]] = field(default=None)

def lookup(self, symbol_name: str, symbol_type: type = Symbol, case_insensitive: bool = False) -> Optional[Symbol]:
if case_insensitive:
if self.insensitive_map is None:
self.insensitive_map = {}
for key in self.symbols.keys():
key_lower: str = key.lower()
self.insensitive_map[key_lower] = self.insensitive_map.get(key_lower, []) + [key]

symbol_name_lower: str = symbol_name.lower()

return next(
(
symbol
for symbol in chain.from_iterable(
self.symbols.get(orig_symbol_name, [])
for orig_symbol_name in self.insensitive_map[symbol_name_lower]
)
if isinstance(symbol, symbol_type)
),
self.parent.lookup(symbol_name, symbol_type) if self.parent is not None else None
)

def lookup(self, symbol_name: str, symbol_type: type = Symbol) -> Optional[Symbol]:
return next((symbol for symbol in self.symbols.get(symbol_name, []) if isinstance(symbol, symbol_type)),
self.parent.lookup(symbol_name, symbol_type) if self.parent is not None else None)

def add(self, symbol: Symbol):
self.symbols[symbol.name] = self.symbols.get(symbol.name, []) + [symbol]

if self.insensitive_map is not None:
symbol_name_lower: str = symbol.name.lower()
self.insensitive_map[symbol_name_lower] = self.insensitive_map.get(symbol_name_lower, []) + [symbol.name]
9 changes: 8 additions & 1 deletion tests/model/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ def test_scope_lookup_7(self):
result = scope.lookup(symbol_name='a', symbol_type=AnotherSymbol)
self.assertIsNone(result)

def test_scope_case_insensitive_lookup(self):
local_symbol = SomeSymbol(name='a', index=0)
scope = Scope(symbols={'a': [local_symbol]}, parent=Scope(symbols={'a': [SomeSymbol(name='a', index=1)]}))
result = scope.lookup(symbol_name='A', case_insensitive=True)
self.assertEqual(result, local_symbol)
self.assertIsInstance(result, Symbol)

def test_node_properties_meta(self):
pds = [pd for pd in sorted(SomeNode.node_properties, key=lambda x: x.name)]
self.assertEqual(5, len(pds))
Expand All @@ -149,4 +156,4 @@ def test_node_properties_meta(self):
self.assertEqual("name", pds[3].name)
self.assertFalse(pds[3].provides_nodes)
self.assertEqual("ref", pds[4].name)
self.assertTrue(pds[4].provides_nodes)
self.assertTrue(pds[4].provides_nodes)

0 comments on commit 54f94ae

Please sign in to comment.