1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.themis.xanalysis.solver.proj;
18
19 import io.github.tonywasher.joceanus.themis.xanalysis.parser.base.ThemisXAnalysisInstance.ThemisXAnalysisClassInstance;
20 import io.github.tonywasher.joceanus.themis.xanalysis.parser.proj.ThemisXAnalysisFile;
21 import io.github.tonywasher.joceanus.themis.xanalysis.solver.proj.ThemisXAnalysisSolverDef.ThemisXAnalysisSolverFileDef;
22 import io.github.tonywasher.joceanus.themis.xanalysis.solver.proj.ThemisXAnalysisSolverDef.ThemisXAnalysisSolverPackageDef;
23
24 import java.util.ArrayList;
25 import java.util.List;
26
27
28
29
30 public class ThemisXAnalysisSolverFile
31 implements ThemisXAnalysisSolverFileDef {
32
33
34
35 private final ThemisXAnalysisSolverPackageDef thePackage;
36
37
38
39
40 private final ThemisXAnalysisFile theFile;
41
42
43
44
45 private final ThemisXAnalysisSolverClass theTopLevel;
46
47
48
49
50 private final List<ThemisXAnalysisSolverClass> theClasses;
51
52
53
54
55 private final List<ThemisXAnalysisSolverClass> theReferenced;
56
57
58
59
60 private boolean isCircular;
61
62
63
64
65
66
67
68 ThemisXAnalysisSolverFile(final ThemisXAnalysisSolverPackageDef pPackage,
69 final ThemisXAnalysisFile pFile) {
70
71 thePackage = pPackage;
72 theFile = pFile;
73
74
75 theClasses = new ArrayList<>();
76 for (ThemisXAnalysisClassInstance myClass : theFile.getClasses()) {
77 final ThemisXAnalysisSolverClass mySolverClass = new ThemisXAnalysisSolverClass(this, myClass);
78 theClasses.add(mySolverClass);
79 }
80
81
82 theTopLevel = theClasses.stream().filter(ThemisXAnalysisSolverClass::isTopLevel).findFirst().orElse(null);
83
84
85 theReferenced = new ArrayList<>();
86 }
87
88 @Override
89 public ThemisXAnalysisSolverPackageDef getOwningPackage() {
90 return thePackage;
91 }
92
93 @Override
94 public ThemisXAnalysisFile getUnderlyingFile() {
95 return theFile;
96 }
97
98
99
100
101
102
103 public ThemisXAnalysisSolverClass getTopLevel() {
104 return theTopLevel;
105 }
106
107
108
109
110
111
112 public List<ThemisXAnalysisSolverClass> getClasses() {
113 return theClasses;
114 }
115
116
117
118
119
120
121 public boolean isCircular() {
122 return isCircular;
123 }
124
125 @Override
126 public String toString() {
127 return theFile.toString();
128 }
129
130
131
132
133
134
135
136 public List<ThemisXAnalysisSolverClass> getReferencesTo(final String pPackage) {
137
138 final List<ThemisXAnalysisSolverClass> myReferences = new ArrayList<>();
139 for (ThemisXAnalysisSolverClass myReference : theReferenced) {
140 if (pPackage.equals(myReference.getPackageName())) {
141 myReferences.add(myReference);
142 }
143 }
144 return myReferences;
145 }
146
147
148
149
150
151
152 private List<ThemisXAnalysisSolverClass> getLocalReferences() {
153 return getReferencesTo(thePackage.toString());
154 }
155
156
157
158
159
160
161 public void setReferenced(final List<ThemisXAnalysisSolverClass> pReferenced) {
162
163 theReferenced.addAll(pReferenced.stream().filter(s -> !s.equals(getTopLevel())).toList());
164 }
165
166
167
168
169 public void processLocalReferences() {
170
171 final List<ThemisXAnalysisSolverClass> myFullyReferenced = new ArrayList<>();
172
173
174 for (ThemisXAnalysisSolverClass myClass : getLocalReferences()) {
175
176 processLocalReferences(myFullyReferenced, myClass);
177 }
178
179
180 isCircular = myFullyReferenced.contains(theTopLevel);
181 }
182
183
184
185
186
187
188
189 private void processLocalReferences(final List<ThemisXAnalysisSolverClass> pReferences,
190 final ThemisXAnalysisSolverClass pClass) {
191
192 if (!pReferences.contains(pClass)) {
193
194 pReferences.add(pClass);
195
196
197 if (!pClass.equals(theTopLevel)) {
198
199 for (ThemisXAnalysisSolverClass myClass : ((ThemisXAnalysisSolverFile) pClass.getOwningFile()).getLocalReferences()) {
200
201 processLocalReferences(pReferences, myClass);
202 }
203 }
204 }
205 }
206 }