@@ -6,6 +6,7 @@ package analyses
66import java .net .URL
77import java .util .concurrent .ScheduledThreadPoolExecutor
88import java .util .concurrent .TimeUnit
9+ import scala .util .Try
910
1011import org .opalj .ai .domain .l1 .DefaultDomainWithCFGAndDefUse
1112import org .opalj .ai .fpcf .properties .AIDomainFactoryKey
@@ -15,6 +16,7 @@ import org.opalj.br.analyses.Project
1516import org .opalj .br .analyses .ProjectAnalysisApplication
1617import org .opalj .br .fpcf .ContextProviderKey
1718import org .opalj .br .fpcf .FPCFAnalysesManagerKey
19+ import org .opalj .br .fpcf .FPCFLazyAnalysisScheduler
1820import org .opalj .br .fpcf .PropertyStoreKey
1921import org .opalj .br .fpcf .analyses .ContextProvider
2022import org .opalj .br .fpcf .properties .Context
@@ -26,7 +28,11 @@ import org.opalj.tac.cg.AllocationSiteBasedPointsToCallGraphKey
2628import org .opalj .tac .fpcf .analyses .cg .reflection .ReflectionRelatedCallsAnalysisScheduler
2729import org .opalj .tac .fpcf .analyses .string .LazyMethodStringFlowAnalysis
2830import org .opalj .tac .fpcf .analyses .string .LazyStringAnalysis
31+ import org .opalj .tac .fpcf .analyses .string .l0 .LazyL0StringFlowAnalysis
32+ import org .opalj .tac .fpcf .analyses .string .l1 .LazyL1StringFlowAnalysis
2933import org .opalj .tac .fpcf .analyses .string .l2 .LazyL2StringFlowAnalysis
34+ import org .opalj .tac .fpcf .analyses .string .l3 .LazyL3StringFlowAnalysis
35+ import org .opalj .tac .fpcf .analyses .string .trivial .LazyTrivialStringAnalysis
3036import org .opalj .tac .fpcf .analyses .systemproperties .TriggeredSystemPropertiesAnalysisScheduler
3137import org .opalj .util .PerformanceEvaluation .time
3238import org .opalj .util .Seconds
@@ -36,6 +42,47 @@ import org.opalj.util.Seconds
3642 */
3743object StringAnalysisDemo extends ProjectAnalysisApplication {
3844
45+ private case class Configuration (
46+ private val analysisConfig : Configuration .AnalysisConfig
47+ ) {
48+
49+ def analyses : Seq [FPCFLazyAnalysisScheduler ] = {
50+ analysisConfig match {
51+ case Configuration .TrivialAnalysis => Seq (LazyTrivialStringAnalysis )
52+ case Configuration .LevelAnalysis (level) =>
53+ Seq (
54+ LazyStringAnalysis ,
55+ LazyMethodStringFlowAnalysis ,
56+ Configuration .LevelToSchedulerMapping (level)
57+ )
58+ }
59+ }
60+ }
61+
62+ private object Configuration {
63+
64+ private [Configuration ] trait AnalysisConfig
65+ private [Configuration ] case object TrivialAnalysis extends AnalysisConfig
66+ private [Configuration ] case class LevelAnalysis (level : Int ) extends AnalysisConfig
67+
68+ final val LevelToSchedulerMapping = Map (
69+ 0 -> LazyL0StringFlowAnalysis ,
70+ 1 -> LazyL1StringFlowAnalysis ,
71+ 2 -> LazyL2StringFlowAnalysis ,
72+ 3 -> LazyL3StringFlowAnalysis
73+ )
74+
75+ def apply (parameters : Seq [String ]): Configuration = {
76+ val levelParameter = parameters.find(_.startsWith(" -level=" )).getOrElse(" -level=trivial" )
77+ val analysisConfig = levelParameter.replace(" -level=" , " " ) match {
78+ case " trivial" => TrivialAnalysis
79+ case string => LevelAnalysis (string.toInt)
80+ }
81+
82+ new Configuration (analysisConfig)
83+ }
84+ }
85+
3986 override def description : String =
4087 """
4188 | Analyses the callees of the Main.entrypoint method of the given project,
@@ -44,13 +91,37 @@ object StringAnalysisDemo extends ProjectAnalysisApplication {
4491 | Also contains some live logging of runtime information about the property store.
4592 |""" .stripMargin
4693
94+ override def analysisSpecificParametersDescription : String =
95+ s " [-level=trivial| ${Configuration .LevelToSchedulerMapping .keys.toSeq.sorted.mkString(" |" )}] "
96+
97+ override def checkAnalysisSpecificParameters (parameters : Seq [String ]): Iterable [String ] = {
98+ parameters.flatMap {
99+ case levelParameter if levelParameter.startsWith(" -level=" ) =>
100+ levelParameter.replace(" -level=" , " " ) match {
101+ case " trivial" =>
102+ None
103+ case string
104+ if Try (string.toInt).isSuccess
105+ && Configuration .LevelToSchedulerMapping .keySet.contains(string.toInt) =>
106+ None
107+ case value =>
108+ Some (s " Unknown level parameter value: $value" )
109+ }
110+
111+ case param => Some (s " unknown parameter: $param" )
112+ }
113+ }
114+
47115 override def doAnalyze (
48116 project : Project [URL ],
49117 parameters : Seq [String ],
50118 isInterrupted : () => Boolean
51- ): BasicReport = BasicReport (analyze(project))
119+ ): BasicReport = {
120+ implicit val configuration : Configuration = Configuration (parameters)
121+ BasicReport (analyze(project))
122+ }
52123
53- def analyze (project : Project [URL ]): String = {
124+ def analyze (project : Project [URL ])( implicit configuration : Configuration ) : String = {
54125 val domain = classOf [DefaultDomainWithCFGAndDefUse [_]]
55126 project.updateProjectInformationKeyInitializationData(AIDomainFactoryKey ) {
56127 case None => Set (domain)
@@ -88,11 +159,7 @@ object StringAnalysisDemo extends ProjectAnalysisApplication {
88159 analysesManager
89160 .runAll(
90161 cgKey.allCallGraphAnalyses(project)
91- ++ Seq (
92- LazyStringAnalysis ,
93- LazyMethodStringFlowAnalysis ,
94- LazyL2StringFlowAnalysis
95- )
162+ ++ configuration.analyses
96163 ++ Seq (
97164 ReflectionRelatedCallsAnalysisScheduler ,
98165 TriggeredSystemPropertiesAnalysisScheduler
0 commit comments