-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathFamixJavaPackage.class.st
More file actions
310 lines (252 loc) · 10.8 KB
/
FamixJavaPackage.class.st
File metadata and controls
310 lines (252 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
"
## Relations
======================
### Parents
| Relation | Origin | Opposite | Type | Comment |
|---|
| `parentPackage` | `FamixTPackageable` | `childEntities` | `FamixTPackage` | Package containing the entity in the code structure (if applicable)|
### Children
| Relation | Origin | Opposite | Type | Comment |
|---|
| `childEntities` | `FamixTPackage` | `parentPackage` | `FamixTPackageable` | |
| `comments` | `FamixTWithComments` | `commentedEntity` | `FamixTComment` | List of comments for the entity|
### Incoming dependencies
| Relation | Origin | Opposite | Type | Comment |
|---|
| `incomingImports` | `FamixTImportable` | `importedEntity` | `FamixTImport` | List of imports of this entity|
### Other
| Relation | Origin | Opposite | Type | Comment |
|---|
| `sourceAnchor` | `FamixTSourceEntity` | `element` | `FamixTSourceAnchor` | SourceAnchor entity linking to the original source code for this entity|
## Properties
======================
| Name | Type | Default value | Comment |
|---|
| `isStub` | `Boolean` | false | Flag true if the entity attributes are incomplete, either because the entity is missing or not imported.|
| `name` | `String` | nil | Basic name of the entity, not full reference.|
"
Class {
#name : 'FamixJavaPackage',
#superclass : 'FamixJavaContainerEntity',
#traits : 'FamixTImportable + FamixTPackage + FamixTPackageable + FamixTWithComments',
#classTraits : 'FamixTImportable classTrait + FamixTPackage classTrait + FamixTPackageable classTrait + FamixTWithComments classTrait',
#category : 'Famix-Java-Entities-Entities',
#package : 'Famix-Java-Entities',
#tag : 'Entities'
}
{ #category : 'meta' }
FamixJavaPackage class >> annotation [
<FMClass: #Package super: #FamixJavaContainerEntity>
<package: #'Famix-Java-Entities'>
<generated>
^ self
]
{ #category : 'Famix-Implementation' }
FamixJavaPackage >> abstractClasses [
^ self classes select: [:c | c isAbstract]
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> abstractness [
"Abstractness is the ratio between the number of abstract classes and the total number of classes in a package, in the range [0, 1]. 0 means the package is fully concrete, 1 it is fully abstract."
<FMProperty: #abstractness type: #Number>
<derived>
<FMComment: 'Abstractness of a package'>
| nsClasses |
nsClasses := self allClasses.
nsClasses size == 0 ifTrue: [ ^ nil ].
^ (nsClasses select: [ :c | c isAbstract ]) size / nsClasses size
]
{ #category : 'visitor' }
FamixJavaPackage >> accept: aVisitor [
<generated>
^ aVisitor visitFamixJavaPackage: self
]
{ #category : 'adding' }
FamixJavaPackage >> addChildNamedEntity: aNamedEntity [
childEntities add: aNamedEntity
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> afferentCoupling [
"Afferent coupling for a package is the number of classes that depend upon this package"
<FMProperty: #afferentCoupling type: #Number>
<derived>
<FMComment: 'Afferent Coupling of a package'>
^ ((self queryAllIncoming atScope: FamixTType) outOfParentUsing: FamixTPackage) size
]
{ #category : 'Famix-Extensions' }
FamixJavaPackage >> allClasses [
self flag: #check. "Maybe we should just have #classes later..."
^ self classes
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> bunchCohesion [
"Computing cohesion (Bunch formula)"
<FMProperty: #bunchCohesion type: #Number>
<derived>
<FMComment: 'Bunch Cohesion of a package. It is also considered anonymous and inner classes (in Java).'>
| myClasses intraConnectivities |
myClasses := self classes.
myClasses := myClasses union: (myClasses flatCollect: [ :c | c allRecursiveTypes ]).
myClasses size == 0 ifTrue: [ ^ nil ].
intraConnectivities := (myClasses collect: [ :c | (c queryAllOutgoing atScope: FamixTType) withinParentUsing: FamixTPackage ]) inject: 0 into: [ :subTotal :each | subTotal + each size ].
^ intraConnectivities / myClasses size squared asFloat
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> bunchCouplingWith: aPackage [
"Computing coupling (Bunch formula) between receiver and aPackage"
| myClasses otherClasses interConnectivities |
myClasses := self classes.
myClasses := myClasses asSet union: (myClasses flatCollect: [ :c | c allRecursiveTypes ]).
otherClasses := aPackage classes.
otherClasses := otherClasses asSet union: (otherClasses flatCollect: [ :c | c allRecursiveTypes ]).
(myClasses size == 0 or: [ otherClasses size == 0 ]) ifTrue: [ ^ nil ].
"All outgoing dependencies"
interConnectivities := (myClasses collect: [ :c | (c queryAllOutgoing atScope: FamixTType) within: aPackage ]) inject: 0 into: [ :subTotal :each | subTotal + each size ].
"Plus all incoming dependencies"
interConnectivities := interConnectivities
+ ((myClasses collect: [ :c | (c queryAllIncoming atScope: FamixTType) within: aPackage ]) inject: 0 into: [ :subTotal :each | subTotal + each size ]).
^ interConnectivities / (2 * myClasses size * otherClasses size) asFloat
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> bunchCouplingWithAll [
"Computing coupling (Bunch formula) between receiver and all packages"
| myClasses interConnectivities allClasses |
myClasses := self classes.
myClasses := myClasses union: (myClasses flatCollect: [ :c | c allRecursiveTypes ]).
allClasses := self mooseModel allModelClasses.
myClasses ifEmpty: [ ^ nil ].
"All outgoing dependencies"
interConnectivities := (myClasses collect: [ :c | (c queryAllOutgoing atScope: FamixTType) outOfParentUsing: FamixTPackage ]) inject: 0 into: [ :subTotal :each | subTotal + each size ].
"Plus all incoming dependencies"
interConnectivities := interConnectivities
+ ((myClasses collect: [ :c | (c queryAllIncoming atScope: FamixTType) outOfParentUsing: FamixTPackage ]) inject: 0 into: [ :subTotal :each | subTotal + each size ]).
^ interConnectivities / (2 * myClasses size * (allClasses size - myClasses size)) asFloat
]
{ #category : 'Famix-Extensions' }
FamixJavaPackage >> childrenOfMyKind [
^ self childEntities allWithSubTypesOf: self class
]
{ #category : 'Famix-Extensions-accessing' }
FamixJavaPackage >> containedEntities [
^ super containedEntities union: self childEntities
]
{ #category : 'Famix-Extensions-accessing' }
FamixJavaPackage >> containedEntities: collection [
self definedClasses: collection.
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> distance [
"D = A + I - 1. A package should be balanced between abstractness and instability, i.e., somewhere between abstract and stable or concrete and unstable. This rule defines the main sequence by the equation A + I - 1 = 0. D is the distance to the main sequence."
<FMProperty: #distance type: #Number>
<derived>
<FMComment: 'Distance of a package'>
| abstractness instability |
abstractness := self abstractness.
instability := self instability.
(abstractness isNil or: [instability isNil]) ifTrue: [^ nil].
^ abstractness + instability - 1
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> efferentCoupling [
"Efferent coupling for a package is the number of classes it depends upon"
<FMProperty: #efferentCoupling type: #Number>
<derived>
<FMComment: 'Efferent Coupling of a package'>
^ ((self queryAllOutgoing outOfParentUsing: FamixTPackage) atScope: FamixTType) size
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> instability [
"I = Ce(P)/(Ce(P)+Ca(P)), in the range [0, 1]. 0 means package is maximally stable (i.e., no dependency to other packages and can not change without big consequences), 1 means it is unstable."
<FMProperty: #instability type: #Number>
<derived>
<FMComment: 'Instability of a package'>
| efferentCoupling afferentCoupling |
efferentCoupling := self efferentCoupling.
afferentCoupling := self afferentCoupling.
(efferentCoupling + afferentCoupling) == 0 ifTrue: [^ nil].
^ efferentCoupling / (efferentCoupling + afferentCoupling)
]
{ #category : 'testing' }
FamixJavaPackage >> isTopLevelPackage [
^ self topLevelPackage == self.
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> martinCohesion [
"Computing cohesion as described by Robert C. Martin"
<FMProperty: #martinCohesion type: #Number>
<derived>
<FMComment: 'Cohesion as defined by Robert C. Martin.'>
| intraConnectivities myClasses |
myClasses := self classes.
myClasses := myClasses union: (myClasses flatCollect: [ :c | c allRecursiveTypes ]).
myClasses size == 0 ifTrue: [ ^ nil ].
intraConnectivities := (myClasses collect: [ :c | (c queryAllOutgoing atScope: FamixTType) withoutSelfLoops withinParentUsing: FamixTPackage ]) inject: 0 into: [ :subTotal :each | subTotal + each size ].
^ ((intraConnectivities + 1) / myClasses size) asFloat
]
{ #category : 'accessing' }
FamixJavaPackage >> methods [
^ self cacheAt: #methods ifAbsentPut: [ self classes flatCollect: #methods ]
]
{ #category : 'printing' }
FamixJavaPackage >> mooseNameOn: stream [
| parent |
parent := self belongsTo.
parent ifNotNil:
[ parent mooseNameOn: stream.
stream
nextPut: $. ].
self name ifNotNil: [stream nextPutAll: self name]
]
{ #category : 'accessing' }
FamixJavaPackage >> numberOfClientPackages [
<FMProperty: #numberOfClientPackages type: #Number>
<FMComment: 'The number of packages which depend on this package'>
<derived>
^ self lookUpPropertyNamed: #numberOfClientPackages computedAs: [ self allClientsAtMyScope size ]
]
{ #category : 'accessing' }
FamixJavaPackage >> numberOfClientPackages: aNumber [
self cacheAt: #numberOfClientPackages put: aNumber
]
{ #category : 'accessing' }
FamixJavaPackage >> numberOfMethods [
<FMProperty: #numberOfMethods type: #Number>
<FMComment: 'The number of methods in a package'>
<derived>
^ self
lookUpPropertyNamed: #numberOfMethods
computedAs: [ self types inject: 0 into: [ :sum :each | sum + each numberOfMethods ] ]
]
{ #category : 'accessing' }
FamixJavaPackage >> numberOfMethods: aNumber [
self cacheAt: #numberOfMethods put: aNumber
]
{ #category : 'printing' }
FamixJavaPackage >> printOn: aStream [
| parent |
parent := self parentPackage.
parent ifNotNil:
[ parent printOn: aStream.
aStream
nextPut: $. ].
self name ifNotNil: [ aStream nextPutAll: self name ].
aStream nextPutAll: ' (Package)'
]
{ #category : 'Famix-Extensions-metrics' }
FamixJavaPackage >> relativeImportanceForSystem [
<FMProperty: #relativeImportanceForSystem type: #Number>
<derived>
<FMComment: 'The number of client packages normalized by the total number of packages'>
^ self lookUpPropertyNamed: #relativeImportanceForSystem
computedAs: [
(self mooseModel allModelPackages size > 1)
ifTrue:[
self numberOfClientPackages / (self mooseModel allModelPackages size - 1)
]
ifFalse: [0]
]
]
{ #category : 'testing' }
FamixJavaPackage >> topLevelPackage [
^ (self parentPackage isNotNil and: [ self parentPackage childEntities anySatisfy: #isType ] ) ifTrue: [ self parentPackage topLevelPackage ] ifFalse: [ self ]
]