@@ -3,122 +3,75 @@ package org.opalj
33package fpcf
44package analyses
55
6+ import scala .language .postfixOps
7+
8+ import java .io .File
69import java .net .URL
7- import scala .util .Try
810
911import org .opalj .ai .domain .l1 .DefaultDomainWithCFGAndDefUse
1012import org .opalj .ai .fpcf .properties .AIDomainFactoryKey
1113import org .opalj .br .analyses .BasicReport
1214import org .opalj .br .analyses .DeclaredMethodsKey
1315import org .opalj .br .analyses .Project
14- import org .opalj .br .analyses .ProjectAnalysisApplication
16+ import org .opalj .br .analyses .ProjectsAnalysisApplication
1517import org .opalj .br .fpcf .ContextProviderKey
16- import org .opalj .br .fpcf .FPCFAnalysesManagerKey
17- import org .opalj .br .fpcf .FPCFLazyAnalysisScheduler
18- import org .opalj .br .fpcf .PropertyStoreKey
1918import org .opalj .br .fpcf .analyses .ContextProvider
19+ import org .opalj .br .fpcf .cli .MultiProjectAnalysisConfig
20+ import org .opalj .br .fpcf .cli .StringAnalysisArg
2021import org .opalj .br .fpcf .properties .Context
2122import org .opalj .br .fpcf .properties .SimpleContextsKey
2223import org .opalj .br .fpcf .properties .cg .Callees
2324import org .opalj .br .fpcf .properties .string .StringConstancyProperty
25+ import org .opalj .cli .AnalysisLevelArg
26+ import org .opalj .fpcf .PropertyStoreBasedCommandLineConfig
2427import org .opalj .tac .cg .AllocationSiteBasedPointsToCallGraphKey
2528import org .opalj .tac .fpcf .analyses .cg .reflection .ReflectionRelatedCallsAnalysisScheduler
26- import org .opalj .tac .fpcf .analyses .string .LazyStringAnalysis
27- import org .opalj .tac .fpcf .analyses .string .flowanalysis .LazyMethodStringFlowAnalysis
28- import org .opalj .tac .fpcf .analyses .string .l0 .LazyL0StringFlowAnalysis
29- import org .opalj .tac .fpcf .analyses .string .l1 .LazyL1StringFlowAnalysis
30- import org .opalj .tac .fpcf .analyses .string .l2 .LazyL2StringFlowAnalysis
31- import org .opalj .tac .fpcf .analyses .string .l3 .LazyL3StringFlowAnalysis
32- import org .opalj .tac .fpcf .analyses .string .trivial .LazyTrivialStringAnalysis
3329import org .opalj .tac .fpcf .analyses .systemproperties .TriggeredSystemPropertiesAnalysisScheduler
3430import org .opalj .util .PerformanceEvaluation .time
3531import org .opalj .util .Seconds
3632
3733/**
3834 * @author Maximilian Rüsch
3935 */
40- object StringAnalysisDemo extends ProjectAnalysisApplication {
41-
42- private case class Configuration (
43- private val analysisConfig : Configuration .AnalysisConfig
44- ) {
45-
46- def analyses : Seq [FPCFLazyAnalysisScheduler ] = {
47- analysisConfig match {
48- case Configuration .TrivialAnalysis => Seq (LazyTrivialStringAnalysis )
49- case Configuration .LevelAnalysis (level) =>
50- Seq (
51- LazyStringAnalysis ,
52- LazyMethodStringFlowAnalysis ,
53- Configuration .LevelToSchedulerMapping (level)
54- )
36+ object StringAnalysisDemo extends ProjectsAnalysisApplication {
37+
38+ protected class StringAnalysisDemoConfig (args : Array [String ]) extends MultiProjectAnalysisConfig (args)
39+ with PropertyStoreBasedCommandLineConfig {
40+ val description : String =
41+ """
42+ | Analyses the callees of the Main.entrypoint method of the given project,
43+ | e.g. run with the DEVELOPING_OPAL/demos/src/main/resources/opal-xerces-playground.zip package.
44+ |
45+ | Also contains some live logging of runtime information about the property store.
46+ |""" .stripMargin
47+
48+ private val analysisLevelArg =
49+ new AnalysisLevelArg (StringAnalysisArg .description, StringAnalysisArg .levels: _* ) {
50+ override val defaultValue : Option [String ] = Some (" trivial" )
51+ override val withNone = false
5552 }
56- }
57- }
5853
59- private object Configuration {
60-
61- private [Configuration ] trait AnalysisConfig
62- private [Configuration ] case object TrivialAnalysis extends AnalysisConfig
63- private [Configuration ] case class LevelAnalysis (level : Int ) extends AnalysisConfig
64-
65- final val LevelToSchedulerMapping = Map (
66- 0 -> LazyL0StringFlowAnalysis ,
67- 1 -> LazyL1StringFlowAnalysis ,
68- 2 -> LazyL2StringFlowAnalysis ,
69- 3 -> LazyL3StringFlowAnalysis
54+ args(
55+ analysisLevelArg !
7056 )
57+ init()
7158
72- def apply (parameters : Seq [String ]): Configuration = {
73- val levelParameter = parameters.find(_.startsWith(" -level=" )).getOrElse(" -level=trivial" )
74- val analysisConfig = levelParameter.replace(" -level=" , " " ) match {
75- case " trivial" => TrivialAnalysis
76- case string => LevelAnalysis (string.toInt)
77- }
78-
79- new Configuration (analysisConfig)
59+ val analyses : Seq [FPCFAnalysisScheduler [_]] = {
60+ StringAnalysisArg .getAnalyses(apply(analysisLevelArg)).map(getScheduler(_, eager = false ))
8061 }
8162 }
8263
83- override def description : String =
84- """
85- | Analyses the callees of the Main.entrypoint method of the given project,
86- | e.g. run with the DEVELOPING_OPAL/demos/src/main/resources/opal-xerces-playground.zip package.
87- |
88- | Also contains some live logging of runtime information about the property store.
89- |""" .stripMargin
90-
91- override def analysisSpecificParametersDescription : String =
92- s " [-level=trivial| ${Configuration .LevelToSchedulerMapping .keys.toSeq.sorted.mkString(" |" )}] "
93-
94- override def checkAnalysisSpecificParameters (parameters : Seq [String ]): Iterable [String ] = {
95- parameters.flatMap {
96- case levelParameter if levelParameter.startsWith(" -level=" ) =>
97- levelParameter.replace(" -level=" , " " ) match {
98- case " trivial" =>
99- None
100- case string
101- if Try (string.toInt).isSuccess
102- && Configuration .LevelToSchedulerMapping .keySet.contains(string.toInt) =>
103- None
104- case value =>
105- Some (s " Unknown level parameter value: $value" )
106- }
107-
108- case param => Some (s " unknown parameter: $param" )
109- }
110- }
64+ protected type ConfigType = StringAnalysisDemoConfig
11165
112- override def doAnalyze (
113- project : Project [ URL ],
114- parameters : Seq [ String ],
115- isInterrupted : () => Boolean
116- ) : BasicReport = {
117- implicit val configuration : Configuration = Configuration (parameters)
118- BasicReport (analyze(project))
119- }
66+ protected def createConfig ( args : Array [ String ]) : StringAnalysisDemoConfig = new StringAnalysisDemoConfig (args)
67+
68+ override protected def analyze (
69+ cp : Iterable [ File ],
70+ analysisConfig : StringAnalysisDemoConfig ,
71+ execution : Int
72+ ) : ( Project [ URL ], BasicReport ) = {
73+ val (project, projectTime) = analysisConfig.setupProject()
12074
121- def analyze (project : Project [URL ])(implicit configuration : Configuration ): String = {
12275 val domain = classOf [DefaultDomainWithCFGAndDefUse [_]]
12376 project.updateProjectInformationKeyInitializationData(AIDomainFactoryKey ) {
12477 case None => Set (domain)
@@ -137,7 +90,7 @@ object StringAnalysisDemo extends ProjectAnalysisApplication {
13790 analysesManager
13891 .runAll(
13992 cgKey.allCallGraphAnalyses(project)
140- ++ configuration .analyses
93+ ++ analysisConfig .analyses
14194 ++ Seq (
14295 ReflectionRelatedCallsAnalysisScheduler ,
14396 TriggeredSystemPropertiesAnalysisScheduler
@@ -184,7 +137,7 @@ object StringAnalysisDemo extends ProjectAnalysisApplication {
184137 .mkString(" \n | " , " \n | " , " " )
185138 }
186139
187- s """
140+ (project, BasicReport ( s """
188141 |
189142 | Callees: ${calleesByPC.size} ${getPCMethodsList(calleesByPC)}
190143 |
@@ -199,7 +152,7 @@ object StringAnalysisDemo extends ProjectAnalysisApplication {
199152 | Definition depths:
200153 | ${getDepths(_.getClass.getName.endsWith(" VariableDefinition" )).mkString(" \n | " , " \n | " , " " )}
201154 |
202- | took : $analysisTime seconds
203- | """ .stripMargin
155+ | took : $analysisTime seconds (and $projectTime seconds for project setup)
156+ | """ .stripMargin))
204157 }
205158}
0 commit comments