IncludeCPP 3.8.3__py3-none-any.whl → 3.8.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -715,17 +715,60 @@ class CSSLRuntime:
715
715
 
716
716
  Parses class members and methods, creating a CSSLClass object
717
717
  that can be instantiated with 'new'.
718
+ Supports inheritance via 'extends' keyword and method overwriting via 'overwrites'.
718
719
  """
719
720
  class_info = node.value
720
721
  class_name = class_info.get('name')
722
+ extends_class_name = class_info.get('extends')
723
+ extends_is_python = class_info.get('extends_is_python', False)
724
+ overwrites_class_name = class_info.get('overwrites')
725
+ overwrites_is_python = class_info.get('overwrites_is_python', False)
726
+
727
+ # Resolve parent class if extends is specified
728
+ parent_class = None
729
+ if extends_class_name:
730
+ if extends_is_python:
731
+ # extends $PythonObject - look up in shared objects
732
+ from ..cssl_bridge import _live_objects, SharedObjectProxy
733
+ if extends_class_name in _live_objects:
734
+ parent_class = _live_objects[extends_class_name]
735
+ # Unwrap SharedObjectProxy if needed
736
+ if isinstance(parent_class, SharedObjectProxy):
737
+ parent_class = parent_class._obj
738
+ else:
739
+ # Also check scope with $ prefix
740
+ parent_class = self.global_scope.get(f'${extends_class_name}')
741
+ else:
742
+ # Try to resolve from scope (could be CSSL class or variable holding Python object)
743
+ parent_class = self.scope.get(extends_class_name)
744
+ if parent_class is None:
745
+ parent_class = self.global_scope.get(extends_class_name)
746
+
747
+ if parent_class is None:
748
+ raise ValueError(f"Cannot extend unknown class '{extends_class_name}'")
749
+
750
+ # Auto-wrap Python objects for inheritance
751
+ from .cssl_builtins import CSSLizedPythonObject
752
+ if not isinstance(parent_class, (CSSLClass, CSSLizedPythonObject)):
753
+ # Wrap raw Python object
754
+ parent_class = CSSLizedPythonObject(parent_class, self)
721
755
 
722
756
  members = {} # Member variable defaults/types
723
757
  methods = {} # Method AST nodes
724
- constructor = None
758
+ constructors = [] # List of constructors (multiple allowed with constr keyword)
759
+ constructor = None # Primary constructor (backward compatibility)
760
+
761
+ # Get class parameters and extends args
762
+ class_params = class_info.get('class_params', [])
763
+ extends_args = class_info.get('extends_args', [])
725
764
 
726
765
  for child in node.children:
727
- if child.type == 'function':
728
- # This is a method
766
+ if child.type == 'constructor':
767
+ # New-style constructor from 'constr' keyword
768
+ constructors.append(child)
769
+
770
+ elif child.type == 'function':
771
+ # This is a method or old-style constructor
729
772
  func_info = child.value
730
773
  method_name = func_info.get('name')
731
774
 
@@ -752,22 +795,156 @@ class CSSLRuntime:
752
795
  name=class_name,
753
796
  members=members,
754
797
  methods=methods,
755
- constructor=constructor
798
+ constructor=constructor,
799
+ parent=parent_class
756
800
  )
801
+ # Store additional constructor info
802
+ class_def.constructors = constructors # Multiple constructors from 'constr' keyword
803
+ class_def.class_params = class_params # Class-level constructor parameters
804
+ class_def.extends_args = extends_args # Arguments to pass to parent constructor
757
805
 
758
806
  # Register class in scope
759
807
  self.scope.set(class_name, class_def)
760
808
  self.global_scope.set(class_name, class_def)
761
809
 
810
+ # Handle class overwrites - replace methods in target class
811
+ if overwrites_class_name:
812
+ self._apply_class_overwrites(
813
+ class_def, overwrites_class_name, overwrites_is_python
814
+ )
815
+
762
816
  return class_def
763
817
 
818
+ def _apply_class_overwrites(self, new_class: CSSLClass, target_name: str, is_python: bool):
819
+ """Apply method overwrites from new_class to target class/object.
820
+
821
+ When a class has 'overwrites' specified, all methods defined in new_class
822
+ will replace the corresponding methods in the target.
823
+ """
824
+ from .cssl_builtins import CSSLizedPythonObject
825
+
826
+ # Resolve target
827
+ target = None
828
+ if is_python:
829
+ from ..cssl_bridge import _live_objects
830
+ if target_name in _live_objects:
831
+ target = _live_objects[target_name]
832
+ else:
833
+ target = self.scope.get(target_name)
834
+ if target is None:
835
+ target = self.global_scope.get(target_name)
836
+
837
+ if target is None:
838
+ return # Target not found, silently skip
839
+
840
+ # Get methods to overwrite
841
+ methods_to_overwrite = new_class.methods
842
+
843
+ if is_python and hasattr(target, '__class__'):
844
+ # Python object - overwrite methods on the object/class
845
+ for method_name, method_node in methods_to_overwrite.items():
846
+ # Create a Python-callable wrapper for the CSSL method
847
+ wrapper = self._create_method_wrapper(method_node, target)
848
+ # Set on the object
849
+ try:
850
+ setattr(target, method_name, wrapper)
851
+ except AttributeError:
852
+ # Try setting on class instead
853
+ try:
854
+ setattr(target.__class__, method_name, wrapper)
855
+ except:
856
+ pass
857
+ elif isinstance(target, CSSLClass):
858
+ # CSSL class - directly replace methods
859
+ for method_name, method_node in methods_to_overwrite.items():
860
+ target.methods[method_name] = method_node
861
+ elif isinstance(target, CSSLizedPythonObject):
862
+ # CSSLized Python object - get underlying object and overwrite
863
+ py_obj = target.get_python_obj()
864
+ for method_name, method_node in methods_to_overwrite.items():
865
+ wrapper = self._create_method_wrapper(method_node, py_obj)
866
+ try:
867
+ setattr(py_obj, method_name, wrapper)
868
+ except AttributeError:
869
+ try:
870
+ setattr(py_obj.__class__, method_name, wrapper)
871
+ except:
872
+ pass
873
+
874
+ def _create_method_wrapper(self, method_node: ASTNode, instance: Any):
875
+ """Create a Python-callable wrapper for a CSSL method that works with an instance."""
876
+ def wrapper(*args, **kwargs):
877
+ # Set up instance context for this->
878
+ old_instance = self._current_instance
879
+ # Create a fake CSSLInstance-like wrapper if needed
880
+ self._current_instance = instance
881
+ try:
882
+ return self._call_function(method_node, list(args), kwargs)
883
+ finally:
884
+ self._current_instance = old_instance
885
+ return wrapper
886
+
764
887
  def _exec_function(self, node: ASTNode) -> Any:
765
- """Execute function definition - just registers it"""
888
+ """Execute function definition - registers it and handles extends/overwrites.
889
+
890
+ Syntax:
891
+ define func() { ... }
892
+ define func : extends otherFunc() { ... } - Inherit local vars
893
+ define func : overwrites otherFunc() { ... } - Replace otherFunc
894
+ """
766
895
  func_info = node.value
767
896
  func_name = func_info.get('name')
897
+ extends_func = func_info.get('extends')
898
+ extends_is_python = func_info.get('extends_is_python', False)
899
+ overwrites_func = func_info.get('overwrites')
900
+ overwrites_is_python = func_info.get('overwrites_is_python', False)
901
+
902
+ # Store function extends info for runtime use
903
+ if extends_func:
904
+ node.value['_extends_resolved'] = self._resolve_function_target(
905
+ extends_func, extends_is_python
906
+ )
907
+
908
+ # Handle overwrites - replace the target function
909
+ if overwrites_func:
910
+ target = self._resolve_function_target(overwrites_func, overwrites_is_python)
911
+ if target is not None:
912
+ # Store original for reference
913
+ node.value['_overwrites_original'] = target
914
+ # Replace the target function with this one
915
+ if overwrites_is_python:
916
+ from ..cssl_bridge import _live_objects
917
+ if overwrites_func in _live_objects:
918
+ # Create a wrapper that calls the CSSL function
919
+ _live_objects[overwrites_func] = self._create_python_wrapper(node)
920
+ else:
921
+ # Replace in CSSL scope
922
+ self.scope.set(overwrites_func, node)
923
+ self.global_scope.set(overwrites_func, node)
924
+
925
+ # Register the function
768
926
  self.scope.set(func_name, node)
769
927
  return None
770
928
 
929
+ def _resolve_function_target(self, name: str, is_python: bool) -> Any:
930
+ """Resolve a function target for extends/overwrites."""
931
+ if is_python:
932
+ from ..cssl_bridge import _live_objects
933
+ if name in _live_objects:
934
+ return _live_objects[name]
935
+ return self.global_scope.get(f'${name}')
936
+ else:
937
+ target = self.scope.get(name)
938
+ if target is None:
939
+ target = self.global_scope.get(name)
940
+ return target
941
+
942
+ def _create_python_wrapper(self, func_node: ASTNode):
943
+ """Create a Python-callable wrapper for a CSSL function."""
944
+ def wrapper(*args, **kwargs):
945
+ return self._call_function(func_node, list(args), kwargs)
946
+ return wrapper
947
+
771
948
  def _exec_typed_declaration(self, node: ASTNode) -> Any:
772
949
  """Execute typed variable declaration: type<T> varName = value;
773
950
 
@@ -1031,6 +1208,9 @@ class CSSLRuntime:
1031
1208
  func_node: The function AST node
1032
1209
  args: List of positional arguments
1033
1210
  kwargs: Dict of named arguments (param_name -> value)
1211
+
1212
+ Supports:
1213
+ define func : extends otherFunc() { ... } - Inherit local vars from otherFunc
1034
1214
  """
1035
1215
  func_info = func_node.value
1036
1216
  params = func_info.get('params', [])
@@ -1043,6 +1223,34 @@ class CSSLRuntime:
1043
1223
  # Create new scope
1044
1224
  new_scope = Scope(parent=self.scope)
1045
1225
 
1226
+ # Handle function extends - inherit local vars from extended function
1227
+ extends_resolved = func_info.get('_extends_resolved')
1228
+ if extends_resolved:
1229
+ if callable(extends_resolved):
1230
+ # Python function - call it first to populate any state
1231
+ try:
1232
+ extends_resolved(*args, **kwargs)
1233
+ except:
1234
+ pass
1235
+ elif hasattr(extends_resolved, 'value'):
1236
+ # CSSL function - execute it in a temporary scope to get local vars
1237
+ old_scope = self.scope
1238
+ temp_scope = Scope(parent=self.scope)
1239
+ self.scope = temp_scope
1240
+ try:
1241
+ # Execute extended function body to populate local vars
1242
+ for child in extends_resolved.children:
1243
+ if not self._running:
1244
+ break
1245
+ self._execute(child)
1246
+ # Copy all local vars to new scope
1247
+ for name, value in temp_scope._vars.items():
1248
+ new_scope.set(name, value)
1249
+ except:
1250
+ pass
1251
+ finally:
1252
+ self.scope = old_scope
1253
+
1046
1254
  # Bind parameters - handle both positional and named arguments
1047
1255
  for i, param in enumerate(params):
1048
1256
  # Extract param name and type from dict format: {'name': 'a', 'type': 'int'}
@@ -1302,6 +1510,78 @@ class CSSLRuntime:
1302
1510
  """Execute continue statement"""
1303
1511
  raise CSSLContinue()
1304
1512
 
1513
+ def _exec_constructor(self, node: ASTNode) -> Any:
1514
+ """Execute constructor node - only called when encountered directly.
1515
+
1516
+ Normally constructors are executed through _call_constructor in _eval_new.
1517
+ This handles cases where a constructor node is executed in other contexts.
1518
+ """
1519
+ # Constructor nodes should be handled during class instantiation
1520
+ # If we reach here, it's in a context where the constructor is stored but not executed
1521
+ return None
1522
+
1523
+ def _exec_super_call(self, node: ASTNode) -> Any:
1524
+ """Execute super() call to invoke parent constructor or method.
1525
+
1526
+ Syntax:
1527
+ super() - Call parent constructor with no args
1528
+ super(arg1, arg2) - Call parent constructor with args
1529
+ super::method() - Call specific parent method
1530
+ super::method(args) - Call specific parent method with args
1531
+ """
1532
+ if self._current_instance is None:
1533
+ raise CSSLRuntimeError(
1534
+ "super() called outside of class context",
1535
+ node.line if hasattr(node, 'line') else 0,
1536
+ hint="super() can only be used inside class constructors and methods"
1537
+ )
1538
+
1539
+ instance = self._current_instance
1540
+ parent = getattr(instance, '_parent_class', None)
1541
+
1542
+ if parent is None:
1543
+ raise CSSLRuntimeError(
1544
+ "super() called but class has no parent",
1545
+ node.line if hasattr(node, 'line') else 0,
1546
+ hint="super() requires the class to extend another class"
1547
+ )
1548
+
1549
+ method_name = node.value.get('method')
1550
+ args = [self._evaluate(arg) for arg in node.value.get('args', [])]
1551
+
1552
+ from .cssl_builtins import CSSLizedPythonObject
1553
+
1554
+ if method_name:
1555
+ # super::method() - call specific parent method
1556
+ if isinstance(parent, CSSLClass):
1557
+ method = parent.methods.get(method_name)
1558
+ if method:
1559
+ return self._call_method(instance, method, args, {})
1560
+ else:
1561
+ raise CSSLRuntimeError(
1562
+ f"Parent class has no method '{method_name}'",
1563
+ node.line if hasattr(node, 'line') else 0
1564
+ )
1565
+ elif isinstance(parent, CSSLizedPythonObject):
1566
+ py_obj = parent.get_python_obj()
1567
+ if hasattr(py_obj, method_name):
1568
+ method = getattr(py_obj, method_name)
1569
+ return method(*args)
1570
+ else:
1571
+ raise CSSLRuntimeError(
1572
+ f"Parent Python object has no method '{method_name}'",
1573
+ node.line if hasattr(node, 'line') else 0
1574
+ )
1575
+ elif hasattr(parent, method_name):
1576
+ method = getattr(parent, method_name)
1577
+ return method(*args)
1578
+ else:
1579
+ # super() - call parent constructor
1580
+ self._call_parent_constructor(instance, args)
1581
+ instance._parent_constructor_called = True
1582
+
1583
+ return None
1584
+
1305
1585
  def _exec_try(self, node: ASTNode) -> Any:
1306
1586
  """Execute try/catch block"""
1307
1587
  try:
@@ -2887,6 +3167,8 @@ class CSSLRuntime:
2887
3167
  """Evaluate 'new ClassName(args)' expression.
2888
3168
 
2889
3169
  Creates a new instance of a CSSL class and calls its constructor.
3170
+ Supports multiple constructors (constr keyword), class parameters,
3171
+ and automatic parent constructor calling.
2890
3172
  """
2891
3173
  class_name = node.value.get('class')
2892
3174
  args = [self._evaluate(arg) for arg in node.value.get('args', [])]
@@ -2914,12 +3196,130 @@ class CSSLRuntime:
2914
3196
  # Create new instance
2915
3197
  instance = CSSLInstance(class_def)
2916
3198
 
2917
- # Call constructor if defined
3199
+ # Store parent class reference for super() calls
3200
+ instance._parent_class = class_def.parent
3201
+ instance._parent_constructor_called = False
3202
+
3203
+ # Get class params and extends args
3204
+ class_params = getattr(class_def, 'class_params', [])
3205
+ extends_args = getattr(class_def, 'extends_args', [])
3206
+ constructors = getattr(class_def, 'constructors', [])
3207
+
3208
+ # Bind class_params to instance scope (they receive values from constructor args)
3209
+ # These are the implicit constructor parameters defined in class declaration
3210
+ param_values = {}
3211
+ for i, param in enumerate(class_params):
3212
+ param_name = param.get('name') if isinstance(param, dict) else param
3213
+ if i < len(args):
3214
+ param_values[param_name] = args[i]
3215
+ else:
3216
+ param_values[param_name] = None
3217
+
3218
+ # Call parent constructor with extends_args if parent exists and args specified
3219
+ if class_def.parent and extends_args:
3220
+ evaluated_extends_args = [self._evaluate(arg) for arg in extends_args]
3221
+ self._call_parent_constructor(instance, evaluated_extends_args)
3222
+ instance._parent_constructor_called = True
3223
+
3224
+ # Execute all constructors defined with 'constr' keyword (in order)
3225
+ for constr in constructors:
3226
+ self._call_constructor(instance, constr, args, kwargs, param_values)
3227
+
3228
+ # Call primary constructor (old-style) if defined
2918
3229
  if class_def.constructor:
2919
3230
  self._call_method(instance, class_def.constructor, args, kwargs)
2920
3231
 
2921
3232
  return instance
2922
3233
 
3234
+ def _call_parent_constructor(self, instance: CSSLInstance, args: list, kwargs: dict = None):
3235
+ """Call the parent class constructor on an instance.
3236
+
3237
+ Used for automatic parent constructor calling and super() calls.
3238
+ """
3239
+ kwargs = kwargs or {}
3240
+ parent = instance._parent_class
3241
+
3242
+ if parent is None:
3243
+ return
3244
+
3245
+ from .cssl_builtins import CSSLizedPythonObject
3246
+
3247
+ if isinstance(parent, CSSLClass):
3248
+ # CSSL parent class
3249
+ if parent.constructor:
3250
+ self._call_method(instance, parent.constructor, args, kwargs)
3251
+ # Also call parent's constr constructors
3252
+ for constr in getattr(parent, 'constructors', []):
3253
+ self._call_constructor(instance, constr, args, kwargs, {})
3254
+ elif isinstance(parent, CSSLizedPythonObject):
3255
+ # Python parent - call __init__ if it's a class
3256
+ py_obj = parent.get_python_obj()
3257
+ if isinstance(py_obj, type):
3258
+ # It's a class - we need to initialize it
3259
+ try:
3260
+ py_obj.__init__(instance, *args, **kwargs)
3261
+ except TypeError:
3262
+ pass # Initialization might not be needed
3263
+ elif isinstance(parent, type):
3264
+ # Raw Python class
3265
+ try:
3266
+ parent.__init__(instance, *args, **kwargs)
3267
+ except TypeError:
3268
+ pass
3269
+
3270
+ def _call_constructor(self, instance: CSSLInstance, constr_node: ASTNode,
3271
+ args: list, kwargs: dict, param_values: dict):
3272
+ """Call a constructor defined with 'constr' keyword.
3273
+
3274
+ Handles constructor extends/overwrites and sets up the instance scope.
3275
+ """
3276
+ constr_info = constr_node.value
3277
+ constr_params = constr_info.get('params', [])
3278
+ extends_class = constr_info.get('extends_class')
3279
+ extends_method = constr_info.get('extends_method')
3280
+
3281
+ # Save previous instance context
3282
+ prev_instance = self._current_instance
3283
+ self._current_instance = instance
3284
+
3285
+ # Create new scope for constructor
3286
+ new_scope = Scope(parent=self.scope)
3287
+
3288
+ # Bind param_values (from class params) to constructor scope
3289
+ for name, value in param_values.items():
3290
+ new_scope.set(name, value)
3291
+
3292
+ # Bind constructor parameters
3293
+ for i, param in enumerate(constr_params):
3294
+ param_name = param.get('name') if isinstance(param, dict) else param
3295
+ if i < len(args):
3296
+ new_scope.set(param_name, args[i])
3297
+ elif param_name in kwargs:
3298
+ new_scope.set(param_name, kwargs[param_name])
3299
+ else:
3300
+ new_scope.set(param_name, None)
3301
+
3302
+ # If constructor extends another constructor, inherit its local vars
3303
+ if extends_class and extends_method:
3304
+ parent_class = self.scope.get(extends_class) or self.global_scope.get(extends_class)
3305
+ if parent_class and isinstance(parent_class, CSSLClass):
3306
+ for constr in getattr(parent_class, 'constructors', []):
3307
+ if constr.value.get('name') == extends_method:
3308
+ # Execute parent constructor first to get local vars
3309
+ self._call_constructor(instance, constr, args, kwargs, param_values)
3310
+ break
3311
+
3312
+ # Execute constructor body
3313
+ prev_scope = self.scope
3314
+ self.scope = new_scope
3315
+
3316
+ try:
3317
+ for stmt in constr_node.children:
3318
+ self._execute(stmt)
3319
+ finally:
3320
+ self.scope = prev_scope
3321
+ self._current_instance = prev_instance
3322
+
2923
3323
  def _eval_this_access(self, node: ASTNode) -> Any:
2924
3324
  """Evaluate 'this->member' access.
2925
3325
 
@@ -2957,6 +3357,10 @@ class CSSLRuntime:
2957
3357
  if instance.has_method(member):
2958
3358
  # Return a callable that will invoke the method with instance context
2959
3359
  method_node = instance.get_method(member)
3360
+ # Check if this is an inherited Python method
3361
+ if isinstance(method_node, tuple) and method_node[0] == 'python_method':
3362
+ python_method = method_node[1]
3363
+ return lambda *args, **kwargs: python_method(*args, **kwargs)
2960
3364
  return lambda *args, **kwargs: self._call_method(instance, method_node, list(args), kwargs)
2961
3365
 
2962
3366
  raise CSSLRuntimeError(
@@ -3038,6 +3442,10 @@ class CSSLRuntime:
3038
3442
  # Check for method
3039
3443
  if obj.has_method(member):
3040
3444
  method_node = obj.get_method(member)
3445
+ # Check if this is an inherited Python method
3446
+ if isinstance(method_node, tuple) and method_node[0] == 'python_method':
3447
+ python_method = method_node[1]
3448
+ return lambda *args, **kwargs: python_method(*args, **kwargs)
3041
3449
  return lambda *args, **kwargs: self._call_method(obj, method_node, list(args), kwargs)
3042
3450
  raise CSSLRuntimeError(f"'{obj._class.name}' has no member or method '{member}'")
3043
3451
 
@@ -1448,17 +1448,62 @@ class CSSLClass:
1448
1448
 
1449
1449
  Stores class name, member variables, methods, and constructor.
1450
1450
  Used by the runtime to instantiate CSSLInstance objects.
1451
+ Supports inheritance via the 'parent' attribute.
1451
1452
  """
1452
1453
 
1453
1454
  def __init__(self, name: str, members: Dict[str, Any] = None,
1454
- methods: Dict[str, Any] = None, constructor: Any = None):
1455
+ methods: Dict[str, Any] = None, constructor: Any = None,
1456
+ parent: Any = None):
1455
1457
  self.name = name
1456
1458
  self.members = members or {} # Default member values/types
1457
1459
  self.methods = methods or {} # Method AST nodes
1458
1460
  self.constructor = constructor # Constructor AST node
1461
+ self.parent = parent # Parent class (CSSLClass or CSSLizedPythonObject)
1462
+
1463
+ def get_all_members(self) -> Dict[str, Any]:
1464
+ """Get all members including inherited ones."""
1465
+ all_members = {}
1466
+ # First add parent members (can be overridden)
1467
+ if self.parent:
1468
+ if hasattr(self.parent, 'get_all_members'):
1469
+ all_members.update(self.parent.get_all_members())
1470
+ elif hasattr(self.parent, 'members'):
1471
+ all_members.update(self.parent.members)
1472
+ elif hasattr(self.parent, '_python_obj'):
1473
+ # CSSLizedPythonObject - get attributes from Python object
1474
+ py_obj = self.parent._python_obj
1475
+ if hasattr(py_obj, '__dict__'):
1476
+ for key, val in py_obj.__dict__.items():
1477
+ if not key.startswith('_'):
1478
+ all_members[key] = {'type': 'dynamic', 'default': val}
1479
+ # Then add own members (override parent)
1480
+ all_members.update(self.members)
1481
+ return all_members
1482
+
1483
+ def get_all_methods(self) -> Dict[str, Any]:
1484
+ """Get all methods including inherited ones."""
1485
+ all_methods = {}
1486
+ # First add parent methods (can be overridden)
1487
+ if self.parent:
1488
+ if hasattr(self.parent, 'get_all_methods'):
1489
+ all_methods.update(self.parent.get_all_methods())
1490
+ elif hasattr(self.parent, 'methods'):
1491
+ all_methods.update(self.parent.methods)
1492
+ elif hasattr(self.parent, '_python_obj'):
1493
+ # CSSLizedPythonObject - get methods from Python object
1494
+ py_obj = self.parent._python_obj
1495
+ for name in dir(py_obj):
1496
+ if not name.startswith('_'):
1497
+ attr = getattr(py_obj, name, None)
1498
+ if callable(attr):
1499
+ all_methods[name] = ('python_method', attr)
1500
+ # Then add own methods (override parent)
1501
+ all_methods.update(self.methods)
1502
+ return all_methods
1459
1503
 
1460
1504
  def __repr__(self):
1461
- return f"<CSSLClass '{self.name}' with {len(self.methods)} methods>"
1505
+ parent_info = f" extends {self.parent.name}" if self.parent and hasattr(self.parent, 'name') else ""
1506
+ return f"<CSSLClass '{self.name}'{parent_info} with {len(self.methods)} methods>"
1462
1507
 
1463
1508
 
1464
1509
  class CSSLInstance:
@@ -1471,8 +1516,9 @@ class CSSLInstance:
1471
1516
  def __init__(self, class_def: CSSLClass):
1472
1517
  self._class = class_def
1473
1518
  self._members: Dict[str, Any] = {}
1474
- # Initialize members with defaults from class definition
1475
- for name, default in class_def.members.items():
1519
+ # Initialize members with defaults from class definition (including inherited)
1520
+ all_members = class_def.get_all_members() if hasattr(class_def, 'get_all_members') else class_def.members
1521
+ for name, default in all_members.items():
1476
1522
  if isinstance(default, dict):
1477
1523
  # Type declaration with optional default
1478
1524
  member_type = default.get('type')
@@ -1541,14 +1587,17 @@ class CSSLInstance:
1541
1587
  return name in self._members
1542
1588
 
1543
1589
  def get_method(self, name: str) -> Any:
1544
- """Get method AST node by name"""
1545
- if name in self._class.methods:
1546
- return self._class.methods[name]
1590
+ """Get method AST node by name (including inherited methods)"""
1591
+ # Use get_all_methods to include inherited methods
1592
+ all_methods = self._class.get_all_methods() if hasattr(self._class, 'get_all_methods') else self._class.methods
1593
+ if name in all_methods:
1594
+ return all_methods[name]
1547
1595
  raise AttributeError(f"'{self._class.name}' has no method '{name}'")
1548
1596
 
1549
1597
  def has_method(self, name: str) -> bool:
1550
- """Check if method exists"""
1551
- return name in self._class.methods
1598
+ """Check if method exists (including inherited methods)"""
1599
+ all_methods = self._class.get_all_methods() if hasattr(self._class, 'get_all_methods') else self._class.methods
1600
+ return name in all_methods
1552
1601
 
1553
1602
  def __getattr__(self, name: str) -> Any:
1554
1603
  """Allow direct attribute access for members"""
@@ -2,7 +2,7 @@
2
2
  "name": "cssl",
3
3
  "displayName": "CSSL Language",
4
4
  "description": "Professional syntax highlighting, snippets, and language support for CSSL scripts (.cssl, .cssl-pl, .cssl-mod)",
5
- "version": "1.4.0",
5
+ "version": "1.6.0",
6
6
  "publisher": "IncludeCPP",
7
7
  "icon": "images/cssl.png",
8
8
  "engines": {