From 54bcd64792442d79419e9f424674d69fd6fba0a4 Mon Sep 17 00:00:00 2001 From: yann Date: Thu, 16 May 2024 23:30:21 -0400 Subject: [PATCH] Added metaclasses --- src/MoosePy/MSEPythonImporterTest.class.st | 18 +++-- .../MSEPythonToFamixImporterVisitor.class.st | 71 +++++++++++++------ 2 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/MoosePy/MSEPythonImporterTest.class.st b/src/MoosePy/MSEPythonImporterTest.class.st index 3d934a7..457ac9f 100644 --- a/src/MoosePy/MSEPythonImporterTest.class.st +++ b/src/MoosePy/MSEPythonImporterTest.class.st @@ -138,7 +138,7 @@ def greet(name): MSEPythonImporterTest >> testClassIsInModel [ importer accept: pyDoc. - self assert: importer model numberOfClasses equals: 3. + self assert: importer model numberOfClasses equals: 4. self assert: importer model name equals: 'testPythonModelName' ] @@ -146,7 +146,7 @@ MSEPythonImporterTest >> testClassIsInModel [ MSEPythonImporterTest >> testClasses [ importer accept: pyDoc. - self assert: importer classes size equals: 3. + self assert: importer classes size equals: 4. self assert: (importer classNamed: 'Ball') isNotNil. self assert: (importer classNamed: 'Player') isNotNil ] @@ -155,11 +155,11 @@ MSEPythonImporterTest >> testClasses [ MSEPythonImporterTest >> testClassesImportedTwiceAreOnlyImportedOnce [ importer accept: pyDoc. - self assert: importer classes size equals: 3. + self assert: importer classes size equals: 4. importer accept: pyDoc. - self assert: importer classes size equals: 3 + self assert: importer classes size equals: 4 ] { #category : #'tests - extensions' } @@ -849,7 +849,7 @@ class A(S): { #category : #'tests - metaclasses' } MSEPythonImporterTest >> testSSingleClassingleMetaclass [ - | classA classMeta | + | classA classMeta classAMeta | importer accept: (self parseCode: ' class Meta(type): pass @@ -860,13 +860,19 @@ class A(metaclass=Meta): self assert: (importer model allWithType: FamixPythonClass) size - equals: 3. + equals: 4. classA := importer classNamed: 'A'. self assert: classA isNotNil. + self assert: (classA superInheritances first target name) equals: 'object'. + classMeta := importer classNamed: 'Meta'. self assert: classMeta isNotNil. + self assert: (classMeta superInheritances first target name) equals: 'type'. + classAMeta := classA metaclass. + self assert: classAMeta isNotNil. + self assert: classAMeta name equals: 'Meta' ] { #category : #tests } diff --git a/src/MoosePy/MSEPythonToFamixImporterVisitor.class.st b/src/MoosePy/MSEPythonToFamixImporterVisitor.class.st index 6a970ae..a91b1ea 100644 --- a/src/MoosePy/MSEPythonToFamixImporterVisitor.class.st +++ b/src/MoosePy/MSEPythonToFamixImporterVisitor.class.st @@ -98,31 +98,56 @@ MSEPythonToFamixImporterVisitor >> createAnnotationTypeNamed: aString [ ] { #category : #'private-entity-creation' } -MSEPythonToFamixImporterVisitor >> createClass: arg1 [ - - | tmp1 tmp2 tmp3 tmp5 | - tmp2 := arg1 cname value. - tmp1 := model newClass. - tmp1 name: arg1 cname value. - arg1 superClasses do: [ :arg2 | - | tmp6 | - tmp6 := model newInheritance. - tmp6 - superclass: (self classNamed: arg2 name); - subclass: tmp1 ]. - tmp3 := arg1 superClasses reject: [ :arg3 | - arg3 class = PyMetaclassNode ]. - tmp3 ifEmpty: [ - | tmp7 | - tmp5 := model newInheritance. - tmp7 := model newClass. - tmp7 +MSEPythonToFamixImporterVisitor >> createClass: smaCCClass [ + + | famixClass superClasses metaClasses | + famixClass := model newClass. + famixClass name: smaCCClass cname value. + + "Reject all metaclass declarations, keep only superclasses (if any)" + "TODO Handle PyTrailersNode" + superClasses := smaCCClass superClasses reject: [ :s | + s class = PyMetaclassNode ]. + superClasses do: [ :s | + | superName superObject inheritance | + superName := s name. + superObject := self classNamed: superName. + superObject ifNil: [ + superObject := model newClass + name: superName; + stub: true ]. + inheritance := model newInheritance. + inheritance + superclass: superObject; + subclass: famixClass ]. + + "Case for object, only if needed!" + superClasses ifEmpty: [ + | inheritance object | + inheritance := model newInheritance. + object := model newClass. + object name: 'object'; isStub: true. - tmp5 - superclass: tmp7 yourself; - subclass: tmp1 ]. - ^ self setSourceAnchor: tmp1 from: arg1 + inheritance + superclass: object yourself; + subclass: famixClass ]. + + "Reject all superclass declarations, keep only metaclasses (if any, there should be at most one)." + metaClasses := smaCCClass superClasses reject: [ :s | + s class = PySymbolNode or: [ + s class = PyTrailersNode ] ]. + metaClasses do: [ :m | + | metaClassName metaClassObject | + metaClassName := m superclass name. + metaClassObject := self classNamed: metaClassName. + metaClassObject ifNil: [ + metaClassObject := model newClass + name: metaClassName; + stub: true ]. + famixClass metaclass: metaClassObject ]. + + ^ self setSourceAnchor: famixClass from: smaCCClass ] { #category : #'private-entity-creation' }