Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring on DifferentialValidator towards more generic Validator #46

Merged
merged 1 commit into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions src/FAST-Core-Tools/FASTAbstractDifferentialValidator.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"
I help checking the completness of FAST meta-model

## Process

For this:
- I go through all source files in a file hierarchy
- I extract a FAST model for each source file
- I re-export the source code from the FAST model
- I extract a new FAST model from the new code, and
- finally I compare the 2 FAST models (they should be the same)

## Caveat

This is not full-proof
- Some ASTs can be different and the code be ""the same"" for example `a + b + c` usually has different AST from `a + (b + c)`
- properties of nodes are currently not tested, so `a==b` is considered equal to `a!=b` because the #operator is not tested

## Configuration

There is a setting strict/not-strict (not by default) that allows to accept some minor AST differences (see above)
For this, a suitable `acceptableAST:differentFrom:` method should be defined that will receive 2 differeing nodes (one in each AST) and must decide whether the difference is acceptable

There is a `skipPaths` list to allow skiping some paths in the main file directory
"
Class {
#name : #FASTAbstractDifferentialValidator,
#superclass : #FASTAbstractValidator,
#instVars : [
'comparator'
],
#category : #'FAST-Core-Tools-Validator'
}

{ #category : #accessing }
FASTAbstractDifferentialValidator >> comparator [

^comparator ifNil: [ comparator := self comparatorClass new ]
]

{ #category : #accessing }
FASTAbstractDifferentialValidator >> comparatorClass [

^FamixModelComparator
]

{ #category : #running }
FASTAbstractDifferentialValidator >> compare: node1 to: node2 [

self comparator compare: node1 to: node2
]

{ #category : #utilities }
FASTAbstractDifferentialValidator >> getASTFromFileReference: aFileReference [

^self getTopLevelNodes: (super getASTFromFileReference: aFileReference)
]

{ #category : #utilities }
FASTAbstractDifferentialValidator >> getRootNode: aModel [

^aModel detect: [ : e | e allParents isEmpty ]
]

{ #category : #utilities }
FASTAbstractDifferentialValidator >> getTopLevelNodes: model [

self subclassResponsibility
]

{ #category : #utilities }
FASTAbstractDifferentialValidator >> reExportAST: ast [

self subclassResponsibility
]

{ #category : #running }
FASTAbstractDifferentialValidator >> runOnSourceFile: aFileReference [

| astOrig astBis topLevelNodes |
aFileReference fullName traceCr.

topLevelNodes := [
self getASTFromFileReference: aFileReference
]
on: Error
do: [
' ** NOT PARSEABLE **' traceCr.
"Note: If we cannot get the original AST, no use to try to regenerate it"
#()
].

topLevelNodes ifNotEmpty: [

astOrig := self getRootNode: topLevelNodes.
astBis := self getRootNode:
(self getASTFromString: (self reExportAST: astOrig)).

self compare: astOrig to: astBis
]
]
103 changes: 103 additions & 0 deletions src/FAST-Core-Tools/FASTAbstractValidator.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
Class {
#name : #FASTAbstractValidator,
#superclass : #Object,
#instVars : [
'skipPaths',
'encoding'
],
#category : #'FAST-Core-Tools-Validator'
}

{ #category : #accessing }
FASTAbstractValidator >> defaultEncoding [
"other possibilities are 'latin1', 'utf8', ...
see `ZnCharacterEncoder knownEncodingIdentifiers` for all possibilities"
^encoding ifNil: [ 'iso-8859-1' ]
]

{ #category : #accessing }
FASTAbstractValidator >> encoding [

^encoding
]

{ #category : #accessing }
FASTAbstractValidator >> encoding: aString [

encoding := aString
]

{ #category : #utilities }
FASTAbstractValidator >> getASTFromFileReference: aFileReference [

^aFileReference readStreamEncoded: self defaultEncoding do: [ :stream |
self getASTFromString: stream contents ]

]

{ #category : #utilities }
FASTAbstractValidator >> getASTFromString: stream [

self subclassResponsibility
]

{ #category : #initialization }
FASTAbstractValidator >> initialize [

super initialize.

skipPaths := #().
]

{ #category : #testing }
FASTAbstractValidator >> isSourceFile: aFileReference [

self subclassResponsibility
]

{ #category : #'instance creation' }
FASTAbstractValidator >> on: aDirectoryName [

self runOnFileReference: aDirectoryName asFileReference
]

{ #category : #running }
FASTAbstractValidator >> runOnDirectory: aDirectory [

aDirectory isDirectory
ifFalse: [ Exception signal: aDirectory fullName , ' not a directory' ].

aDirectory children do: [ :fileRef | self runOnFileReference: fileRef ]
]

{ #category : #running }
FASTAbstractValidator >> runOnFileReference: aFileReference [

(self skipPaths includes: aFileReference fullName)
ifTrue: [ ^self ].

aFileReference isDirectory
ifTrue: [ ^self runOnDirectory: aFileReference ].

(self isSourceFile: aFileReference)
ifTrue: [ ^self runOnSourceFile: aFileReference ].

]

{ #category : #testing }
FASTAbstractValidator >> runOnSourceFile: aFileReference [

self subclassResponsibility
]

{ #category : #accessing }
FASTAbstractValidator >> skipPaths [

^ skipPaths
]

{ #category : #accessing }
FASTAbstractValidator >> skipPaths: anObject [

skipPaths := anObject
]
Loading