Skip to content
Open
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
19 changes: 19 additions & 0 deletions docs/mooseide-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,22 @@ fork-first v3 development work, not a published v3 release.

GitHub CI loads these optional tests in the ready-made Moose image. The plain
Pharo job continues to test Core without GUI dependencies.

## Dead-code candidates

Use `FmxSQLDeadCodeRule openOn: routines` to open the standard Dead Code browser
with the SQL refuting rule selected, or select that rule explicitly in an existing
browser before computing. SQL routines are externally callable, so this SQL preset
protects all of them until a closed-world candidate set is explicitly supplied.
The generic OO preset alone is not a SQL dead-code analysis.
Trigger/constraint bindings and missing or incomplete analysis remain protected.
For an explicitly bounded analysis, configure its selected `FmxSQLDeadCodeRule`:

```smalltalk
rule closedWorldCandidates: knownClosedWorldRoutines.
rule externalEntryPoints: knownExternalRoots.
```

The remaining results are candidates, not proof that routines can be dropped.
This integration does not execute database DDL or remove definitions. Existing
non-SQL dead-code rules retain their behavior.
54 changes: 54 additions & 0 deletions src/FamixNGSQL-MooseIDE-Tests/FmxSQLDeadCodeTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Class {
#name : #FmxSQLDeadCodeTest,
#superclass : #TestCase,
#category : #'FamixNGSQL-MooseIDE-Tests'
}
{ #category : #tests }
FmxSQLDeadCodeTest >> testDefaultProtectsExternalAndUncertainRoutines [
| routine rule |
routine := FmxSQLStoredProcedure new.
rule := FmxSQLDeadCodeRule new.
self deny: rule selectedByDefault.
self assert: (rule notDead: routine).
rule closedWorldCandidates: { routine }.
self assert: (rule notDead: routine).
routine cacheAt: #analysisStatus put: #visited.
self deny: (rule notDead: routine).
rule externalEntryPoints: { routine }.
self assert: (rule notDead: routine).
self deny: (rule notDead: FamixStMethod new)
]
{ #category : #tests }
FmxSQLDeadCodeTest >> testTriggerBindingProtectsClosedWorldCandidate [
| routine rule |
routine := FmxSQLTriggerStoredProcedure new.
routine cacheAt: #analysisStatus put: #visited.
FmxSQLTrigger new storedProcedure: routine.
rule := FmxSQLDeadCodeRule new closedWorldCandidates: { routine }; yourself.
self assert: (rule notDead: routine)
]
{ #category : #tests }
FmxSQLDeadCodeTest >> testConstraintBindingProtectsClosedWorldCandidate [
| routine rule |
routine := FmxSQLStoredProcedure new.
routine cacheAt: #analysisStatus put: #visited.
FmxSQLCheckConstraint new addStoredProceduresCalled: routine.
rule := FmxSQLDeadCodeRule new closedWorldCandidates: { routine }; yourself.
self assert: (rule notDead: routine)
]
{ #category : #tests }
FmxSQLDeadCodeTest >> testStandardBrowserUsesConservativeDefault [
| model routine browser rule |
model := FmxSQLModel new.
routine := FmxSQLStoredProcedure new name: 'candidate'; mooseModel: model; yourself.
routine cacheAt: #analysisStatus put: #visited.
browser := FmxSQLDeadCodeRule openOn: { routine }.
[
browser specModel runComputation.
self assertEmpty: browser specModel deadEntities.
rule := browser specModel chosenRules detect: [ :each | each isKindOf: FmxSQLDeadCodeRule ].
rule closedWorldCandidates: { routine }.
browser specModel runComputation.
self assert: (browser specModel deadEntities includes: routine) ]
ensure: [ browser window ifNotNil: #close ]
]
44 changes: 44 additions & 0 deletions src/FamixNGSQL-MooseIDE/FmxSQLDeadCodeRule.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"SQL routines are externally callable. The default protects them all.
Opt into a closed-world candidate set only when its external callers are known.
Trigger/constraint entry points and incomplete analysis remain protected."
Class {
#name : #FmxSQLDeadCodeRule,
#superclass : #MiDeadAbstractRule,
#instVars : [ 'closedWorldCandidates', 'externalEntryPoints' ],
#category : #'FamixNGSQL-MooseIDE'
}
{ #category : #initialization }
FmxSQLDeadCodeRule >> initialize [
super initialize.
closedWorldCandidates := IdentitySet new.
externalEntryPoints := IdentitySet new
]
{ #category : #accessing }
FmxSQLDeadCodeRule >> closedWorldCandidates: entities [ closedWorldCandidates := entities asIdentitySet ]
{ #category : #accessing }
FmxSQLDeadCodeRule >> externalEntryPoints: entities [ externalEntryPoints := entities asIdentitySet ]
{ #category : #accessing }
FmxSQLDeadCodeRule >> name [ ^ super name, 'PostgreSQL entry points and incomplete evidence' ]
{ #category : #testing }
FmxSQLDeadCodeRule >> selectedByDefault [ ^ false ]
{ #category : #testing }
FmxSQLDeadCodeRule >> notDead: entity [
(entity isKindOf: FmxSQLStoredProcedure) ifFalse: [ ^ false ].
(closedWorldCandidates includes: entity) ifFalse: [ ^ true ].
(externalEntryPoints includes: entity) ifTrue: [ ^ true ].
((entity respondsTo: #triggers) and: [ entity triggers isNotEmpty ]) ifTrue: [ ^ true ].
(entity checkConstraintsCalling isNotEmpty or: [ entity exclusionConstraintsCalling isNotEmpty ]) ifTrue: [ ^ true ].
^ (entity cacheAt: #analysisStatus ifAbsent: [ nil ]) ~= #visited
]

{ #category : #opening }
FmxSQLDeadCodeRule class >> openOn: entities [
| browser |
(entities isEmpty or: [ (entities allSatisfy: [ :entity | entity isKindOf: FmxSQLStoredProcedure ]) not ])
ifTrue: [ self error: 'SQL dead-code analysis expects a nonempty routine collection' ].
browser := MiDeadBrowser new.
browser open.
browser specModel chooseRules: { self new }.
browser followEntity: entities asMooseGroup.
^ browser
]