Skip to content

Commit

Permalink
Add function definition and parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
aurelikama committed Aug 17, 2023
1 parent 988d795 commit 0a137da
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 32 deletions.
79 changes: 69 additions & 10 deletions src/MoosePy/MSEPythonImporterTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@ Class {
'pyDoc',
'importer',
'fileSystem',
'file'
'file',
'pyDoc2',
'file2'
],
#category : #MoosePy
}

{ #category : #accessing }
MSEPythonImporterTest >> codeBig1 [

^ PythonParser parseFileWithErrors: (fileSystem / (self moduleName2 , '.py'))
]

{ #category : #accessing }
MSEPythonImporterTest >> importer [

Expand All @@ -21,21 +29,35 @@ MSEPythonImporterTest >> moduleName [
^ 'sprite_collect_blocks'


]

{ #category : #running }
MSEPythonImporterTest >> moduleName2 [
^ 'sprite_collect_blocks_2'


]

{ #category : #running }
MSEPythonImporterTest >> setUp [

fileSystem := FileSystem memory.

"load sourceBug2"
file := fileSystem workingDirectory / (self moduleName, '.py').
file writeStreamDo: [ :stream | stream nextPutAll: PythonParserTests new sourceBig2 ].
pyDoc := self sourceBig2.
importer := self importer.


file writeStreamDo: [ :stream | stream nextPutAll: PythonParserTests new sourceBig2 ].
pyDoc := self sourceBig2.

"load codeBig1"
file2 := fileSystem workingDirectory / (self moduleName2, '.py').
file2 writeStreamDo: [ :stream | stream nextPutAll: PythonParserTests new codeBig1 ].
pyDoc2 := self codeBig1.

importer := self importer.
"file writeStreamDo: [ :stream | stream nextPutAll: PythonParserTests new sourceBig2 ].
pyDoc := self sourceBig2.
importer := self importer."


]
Expand Down Expand Up @@ -74,7 +96,8 @@ MSEPythonImporterTest >> testClassesImportedTwiceAreOnlyImportedOnce [

{ #category : #'tests - files' }
MSEPythonImporterTest >> testFileIsOk [
self assert: (fileSystem / (self moduleName, '.py')) contents size equals: 7586
self assert: (fileSystem / (self moduleName, '.py')) contents size equals: 7586.
self assert: (fileSystem / (self moduleName2, '.py')) contents size equals: 3259

]

Expand Down Expand Up @@ -103,6 +126,29 @@ MSEPythonImporterTest >> testImportFamixClass [
self assert: secondClass name equals: 'Wall'.
]

{ #category : #'tests - classes' }
MSEPythonImporterTest >> testImportFamixFunction [

| func |
importer accept: pyDoc2.
func := importer functionNamed: 'sprite_collect_blocks_2.tryToPlaceWord'.
self assert: func class equals: FamixPythonFunction.
self assert: func name equals: 'tryToPlaceWord'.
self assert: func signature equals: 'grid, word'

]

{ #category : #'tests - classes' }
MSEPythonImporterTest >> testImportFamixFunctionKnowsItsModule [

| func module |
importer accept: pyDoc2.
func := importer functionNamed: 'sprite_collect_blocks_2.tryToPlaceWord'.
module := importer moduleNamed: 'sprite_collect_blocks_2'.
self assert: func functionOwner equals: module.
self assert: func functionOwner class equals: FamixPythonModule
]

{ #category : #'tests - classes' }
MSEPythonImporterTest >> testImportFamixMethod [

Expand Down Expand Up @@ -134,15 +180,20 @@ MSEPythonImporterTest >> testImportFamixParameter [
param := importer parameterNamed: 'Player.__init__.joystick_no'.
self assert: param class equals: FamixPythonParameter.
self assert: param name equals: 'joystick_no'.
" self assert: param parentBehaviouralEntity class equals: FamixPythonClass "

importer accept: pyDoc2.
param := importer parameterNamed: 'sprite_collect_blocks_2.tryToPlaceWord.word'.
self assert: param class equals: FamixPythonParameter.
self assert: param name equals: 'word'.
]

{ #category : #tests }
MSEPythonImporterTest >> testImportFunctions [

importer accept: pyDoc.
self assert: importer methods size equals: 5.
self assert: importer methods keys equals: #('Wall.__init__' 'Ball.update' 'Player.update' 'Player.__init__' 'Ball.__init__')
importer accept: pyDoc2.
self assert: importer functions size equals: 4.
self assert: importer functions keys equals: #('sprite_collect_blocks_2.tryToPlaceWord' 'sprite_collect_blocks_2.placeWord'
'sprite_collect_blocks_2.printGrid' 'sprite_collect_blocks_2.createGrid')
]

{ #category : #'tests - module' }
Expand Down Expand Up @@ -176,6 +227,14 @@ MSEPythonImporterTest >> testImportKnowsItsModule [

]

{ #category : #tests }
MSEPythonImporterTest >> testImportMethods [

importer accept: pyDoc.
self assert: importer methods size equals: 5.
self assert: importer methods keys equals: #('Wall.__init__' 'Ball.update' 'Player.update' 'Player.__init__' 'Ball.__init__')
]

{ #category : #'tests - module' }
MSEPythonImporterTest >> testImportModule [

Expand Down
121 changes: 99 additions & 22 deletions src/MoosePy/MSEPythonToFamixImporterVisitor.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ Class {
#category : #MoosePy
}

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> basicCreateFunction: aSelector withSignature: aSignature [
| function |
function := model newFunction.
function name: aSelector.
function isStub: true.
function signature: aSignature.
^ function

]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> basicCreateMethod: aSelector withSignature: aSignature [
| method |
Expand Down Expand Up @@ -47,9 +58,25 @@ MSEPythonToFamixImporterVisitor >> createClass: aClass [
]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> createFunction: aMethodNode [
MSEPythonToFamixImporterVisitor >> createFunction: aFunctionNode [

| function signature thisModule thisModuleName |
signature := aFunctionNode parameters ifNotNil: [
aFunctionNode parameters signatureString ].
function := self
basicCreateFunction: aFunctionNode fname value
withSignature: signature.

self halt.
self
ensureParameters: aFunctionNode parameters
inFunctionName: aFunctionNode.


functions at: (self functionPath: aFunctionNode) put: function.

thisModuleName := (self moduleNameFromFonction: aFunctionNode) asSymbol.
thisModule := (self ensureModule: thisModuleName).
function functionOwner: thisModule
]

{ #category : #visiting }
Expand All @@ -71,7 +98,7 @@ MSEPythonToFamixImporterVisitor >> createImport: anImport [
{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> createMethod: aMethodNode [

| method thisClass methodPath |
| method thisClass |
method := self
basicCreateMethod: aMethodNode fname value
withSignature: aMethodNode parameters signatureString.
Expand All @@ -82,7 +109,7 @@ MSEPythonToFamixImporterVisitor >> createMethod: aMethodNode [

"unclear that we want to have a key based on the name."
methods
at: aMethodNode parent cname value , '.' , aMethodNode fname value
at: (self methodPath: aMethodNode)
put: method.
thisClass := aMethodNode parent.
method parentType: (self ensureClass: thisClass)
Expand All @@ -98,6 +125,20 @@ MSEPythonToFamixImporterVisitor >> createModule: aModuleNode [

]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> createParameter: aParameter withFunctionName: aMethodNode [

| parameterName parameter |
parameterName := aParameter nameToken value.
parameter := (FamixPythonParameter new name: parameterName).

parameters
at: (self functionPath: aMethodNode) , '.' , parameterName
put: parameter.

"parameter parentBehaviouralEntity: (self ensureMethod: aMethodNode)"
]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> createParameter: aParameter withMethodName: aMethodNode [

Expand All @@ -120,18 +161,20 @@ MSEPythonToFamixImporterVisitor >> ensureClass: aClassNode [

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> ensureFunction: aFunctionNode [

^ functions
at: aFunctionNode parent cname value, '.' , aFunctionNode fname value
ifAbsent: [ self createFunction: aFunctionNode ]

| filename |
filename := self functionPath: aFunctionNode.
^ functions
at: filename , '.' , aFunctionNode fname value
ifAbsent: [ self createFunction: aFunctionNode ]
]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> ensureMethod: aFunctionNode [
MSEPythonToFamixImporterVisitor >> ensureMethod: aMethodNode [

^ methods
at: aFunctionNode parent cname value, '.' , aFunctionNode fname value
ifAbsent: [ self createMethod: aFunctionNode ]
at: (self methodPath: aMethodNode)
ifAbsent: [ self createMethod: aMethodNode ]
]

{ #category : #'private-entity-creation' }
Expand All @@ -142,15 +185,40 @@ MSEPythonToFamixImporterVisitor >> ensureModule: aModuleNode [
ifAbsent: [ self createModule: aModuleNode ]
]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> ensureParameters: theParameters inFunctionName: aFunctionNode [

^ theParameters ifNotNil: [
theParameters args collect: [ :parameter |
parameters
at:
(self functionPath: aFunctionNode) , '.'
, parameter nameToken value
ifAbsent: [
self createParameter: parameter withFunctionName: aFunctionNode ] ] ]
]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> ensureParameters: theParameters inMethodName: aMethodNode [


^ theParameters args collect: [ :parameter |
parameters
at: (self methodPath: aMethodNode) , '.' , parameter nameToken value
ifAbsent: [
self createParameter: parameter withMethodName: aMethodNode ] ]
^ theParameters ifNotNil: [
theParameters args collect: [ :parameter |
parameters
at:
(self methodPath: aMethodNode) , '.' , parameter nameToken value
ifAbsent: [
self createParameter: parameter withMethodName: aMethodNode ] ] ]
]

{ #category : #'accessing - methods' }
MSEPythonToFamixImporterVisitor >> functionNamed: aString [
^ functions at: aString ifAbsent: [ nil ]
]

{ #category : #'accessing - methods' }
MSEPythonToFamixImporterVisitor >> functionPath: aFunctionNode [
^ (self moduleNameFromFonction: aFunctionNode ) , '.'
, aFunctionNode fname value.
]

{ #category : #'accessing - methods' }
Expand Down Expand Up @@ -198,14 +266,23 @@ MSEPythonToFamixImporterVisitor >> model [
^ model
]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> moduleNameFromFonction: aFunctionNode [

^((aFunctionNode parent attributes array first value
fullName) removePrefix: '/') removeSuffix: '.py'.
]

{ #category : #'private-entity-creation' }
MSEPythonToFamixImporterVisitor >> moduleNameStringOf: aModuleNode [
"should push that to the PyInputFileNode"

^ aModuleNode filename
ifNil: [ 'Main Module']
ifNotNil: [:s | s basenameWithoutExtension ]


^(aModuleNode isString
ifTrue: [ aModuleNode ]
ifFalse: [
aModuleNode filename
ifNil: [ 'Main Module' ]
ifNotNil: [ :s | s basenameWithoutExtension ] ] )value
]

{ #category : #accessing }
Expand Down

0 comments on commit 0a137da

Please sign in to comment.