Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/string analysis #2

Open
wants to merge 318 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
318 commits
Select commit Hold shift + click to select a range
ad37be0
Made the 'pathToStringTree' function less defensive.
Dec 5, 2018
49e2a10
Reducing a StringTree now allows to pre-process the tree.
Dec 5, 2018
46c93d6
Defined and toString method of StringConstancyProperty and made sure …
Dec 5, 2018
355dc34
Collapsed a couple of test methods.
Dec 6, 2018
3952140
Added a test method with 'breaks' and 'continues'.
Dec 6, 2018
2a7839d
Added an example where in the condition of an 'if', a string is appen…
Dec 6, 2018
4dca481
Made the 'makeLeanPath' less defensive.
Dec 7, 2018
062da72
Extended the LocalStringDefinitionAnalysis to support the analysis of…
Dec 8, 2018
b802256
Added a comment.
Dec 9, 2018
e4b7cb0
Removed unnecessary code and formatted the file.
Dec 10, 2018
cf4e529
Started implementing a tool that analyzes a project (like the JDK) f…
Dec 10, 2018
7cf69f3
Extended the class documentation.
Dec 10, 2018
9cab281
Improved the analysis runner (it captures more relevant calls (now it…
Dec 14, 2018
40648b3
Directly query the property store after a new analysis was started.
Dec 14, 2018
d642f75
Refactored the pattern matching.
Dec 14, 2018
e75f8fa
The analysis did not always work correctly (see changed test case). I…
Dec 14, 2018
707fa4a
Added primitive support for field reads: Whenever a field (that is no…
Dec 14, 2018
eb02e54
Changed the analysis to only take one DUVar in the entity pair => Tes…
Dec 18, 2018
0a36c3a
Updated the findDependentVars routine to avoid an endless loop in cas…
Dec 19, 2018
981474e
Added support for the "crissCrossExample" test case that was activate…
Dec 23, 2018
1b783b6
Added a test case which uses a "throwable". This required minor chang…
Dec 28, 2018
46140ea
Needed to minorly change how the StringAnalysisReflectiveCalls uses t…
Dec 28, 2018
006ea0d
Added an analysis which collects which methods of a class are called …
Jan 7, 2020
6a03306
Added support for the evaluation of method parameters (pure strings a…
Jan 1, 2019
83680a5
1) isRelevantMethod was not 100 % correct; 2) Had to change how to ad…
Jan 1, 2019
1e4cfa9
Refined the reduceMultiple method.
Jan 1, 2019
fbc90c1
Extended the analysis in the way that it can now be configured using …
Jan 2, 2019
d2f4c30
More refinements were necessary to handle method parameters properly.
Jan 5, 2019
767ff82
Refined how (natural) loops are detected.
Jan 6, 2019
a6b0af1
Slightly refinement on the algorithm.
Jan 7, 2019
8cfd472
Minor refinement on the check whether an "if" has a corresponding "el…
Jan 7, 2019
d50b158
"seenNodes" contained one element too much.
Jan 7, 2019
49ef8b4
Minor change on the loop finding procedure.
Jan 7, 2019
c8a954b
"seenNodes" needs to contain the branching site (removing it was not …
Jan 7, 2019
f7484f4
Path finding algorithms are now required to find all paths from the s…
Jan 7, 2019
eb91901
removeOuterBranching works now recursively.
Jan 7, 2019
369c228
Refined the makeLeanPathAcc function.
Jan 7, 2019
bd1f381
Methods, which return a string but do not belong to a group of interp…
Jan 7, 2019
2355009
Needed to add a condition in order to make sure that the correct orde…
Jan 8, 2019
724fdfc
Added an explanatory comment.
Jan 9, 2019
10756d3
makeLeanPath 1) did not find all usages in case an object has > 1 def…
Jan 9, 2019
1cd2677
Added support for interpreting integer values (only "IntConst" at the…
Jan 9, 2019
aca20a6
Added support for characters.
Jan 9, 2019
ad89eaf
No need to compute the three address code twice.
Jan 9, 2019
60c8502
Changed the DefaultPathFinder to early stop when the required paths h…
Jan 10, 2019
6e23936
Added the current state of the runner that was used to get numbers of…
Jan 14, 2019
a984721
Added primitive support for static field read operations.
Jan 14, 2019
c493128
Generalized the Array(Load)Interpreter to also support ArrayStores.
Jan 14, 2019
d89970a
Refined the doesPathExistTo method.
Jan 15, 2019
645a88e
Extended the path finding procedure to recognize when it is started w…
Jan 15, 2019
dfc3e78
1) Added relevant methods for javax.crypto
Jan 15, 2019
3df533f
Removed a condition (some loop headers were not correctly identified).
Jan 17, 2019
6b80436
Started with the new algorithm.
Jan 17, 2019
8752c4e
Finished re-writing the path finding procedure.
Jan 21, 2019
0c68498
Implemented a path finding procedure which takes into consideration o…
Jan 22, 2019
b5dbbf2
Had to slightly refine the interpretAppendCall method (for the reason…
Jan 23, 2019
e87c14f
Various minor fixes on the path finding procedures (now the whole JDK…
Jan 23, 2019
66ca5ee
Slightly updated the runner (no new or modifier logic, however).
Jan 23, 2019
5281968
Optimized the imports.
Jan 23, 2019
d9291f5
Changes required by the latest 'develop' branch.
Jan 25, 2019
b8570be
Made StringConstancyProperty extend Property.
Jan 25, 2019
d3a0e16
Further changes were required on the StringAnalysisReflectiveCalls fi…
Jan 25, 2019
50ee153
Removed unnecessary comments and properly formatted the file.
Jan 25, 2019
b7fe3ed
Renamed classes, files, and packages (to match the same naming conven…
Jan 26, 2019
a74f252
Simplified the code.
Jan 26, 2019
8a8ee87
Generalized the StringAnalysisTest.
Jan 26, 2019
fc68364
Added a InterproceduralStringAnalysis (currently not interprocedural)…
Jan 26, 2019
acdee4b
Renamed the LocalStringAnalysisMatcher file.
Jan 26, 2019
1a1ae06
Extended the test suite by analyses that are required to use the call…
Jan 28, 2019
d5edeec
1) Split the InterpretationHandler into a class hierarchy with two su…
Jan 28, 2019
946d377
Fixed a copy & paste error in the "apply" method.
Jan 28, 2019
b2b8758
Extended the constructor to take further information required for int…
Jan 29, 2019
d060592
Changed the interface of the InterpretationHandler and AbstractString…
Jan 29, 2019
77df34c
Added the interprocedural counterpart.
Jan 29, 2019
d6005cc
Slightly changed the interface of AbstractStringInterpreter (which, a…
Jan 31, 2019
6faabc1
Corrected the "extractFromPPCR" method.
Jan 31, 2019
eb930e8
Continued making the analysis interprocedural.
Jan 31, 2019
1fb06fa
Fixed a little but in the local string analysis which lead to the fac…
Jan 31, 2019
f11b799
Renamed "LocalStringAnalysis" to "IntraproceduralStringAnalysis".
Jan 31, 2019
814ef3a
Had to add the "derivedProperty".
Jan 31, 2019
36b1b17
Renamed the upper and lower bound of the StringConstancyProperty to "…
Jan 31, 2019
e97a884
Started added support for parameters (context-sensitive).
Feb 1, 2019
6166760
Slightly changed two test cases (1. to use more chars and 2. to use a…
Feb 1, 2019
b359309
Changed "[AnIntegerValue]" to its RegEx equivalent.
Feb 2, 2019
6ff7355
Changed "[AFloatValue]" to its corresponding RegEx and refined / exte…
Feb 2, 2019
7032a79
Changed one interprocedural test case in a way to use a method from a…
Feb 2, 2019
b59f41c
Wrapped the regular expressions in "^" and "$" (to indicate that real…
Feb 2, 2019
346eb3e
Added test cases where methods are called that are out of scope and t…
Feb 2, 2019
d137145
Formatted the file + fixed a typo.
Feb 2, 2019
0ace577
Extended a function call.
Feb 2, 2019
aaf1091
Removed ToDos (I guess they cannot be done as I thought).
Feb 3, 2019
b07cf7f
Extended the interprocedural analysis to better handle float / double…
Feb 3, 2019
c515d4f
Added a comment describing the high-level approach of this analysis.
Feb 3, 2019
c53593a
Added a comment describing the high-level approach of this analysis.
Feb 3, 2019
5f6d039
Extended the interprocedural analysis to finalize results of expressi…
Feb 3, 2019
37e8bb4
Improved the structure of the interpretation part by creating corresp…
Feb 4, 2019
2fef579
Refactored code to avoid code duplication.
Feb 4, 2019
cc47d2d
Created a common interface for the finalizers.
Feb 4, 2019
b793bc7
Moved the "finalizer" package into the "interprocedural" package (as …
Feb 4, 2019
59478e9
Interprocedural "append" operations are now supported.
Feb 4, 2019
5249460
Removed a comment (TODO).
Feb 5, 2019
df988a5
Refined the "getDeclaredMethod" to include the declaring class in the…
Feb 5, 2019
99664c7
Added support for virtual function calls where multiple implementatio…
Feb 7, 2019
459eddd
As one parameter of StringConstancyInformation#reduceMultiple was cha…
Feb 7, 2019
4da38eb
1) Changed the InterproceduralStringAnalysis to work context-insensitive
Feb 12, 2019
7646f06
1) Fixed the usage of EPS handling
Feb 15, 2019
a98fdac
Added the computation state of the InterproceduralStringAnalysis into…
Feb 15, 2019
b6fca96
Removed unnecessary arguments ("data: P").
Feb 15, 2019
76b9d22
Changed the "dependees" field in InterproceduralComputationState to a…
Feb 15, 2019
3be8dbf
Extended the analysis in the way that it evaluates parameters of the …
Feb 19, 2019
17cfa1e
Removed unnecessary arguments / parameters.
Feb 19, 2019
f2a59d4
Fixed a little bug in the procedure that computes lean paths.
Feb 19, 2019
e1204dc
Fixed a little bug in the procedure that builds paths for "switch" co…
Feb 19, 2019
4b0cd77
Removed a TODO comment.
Feb 19, 2019
1979acf
Allow the repetitive evaluation of constant expressions.
Feb 19, 2019
438e1f6
Slightly changed the "isStringBuilderBufferToStringCall" function (it…
Feb 19, 2019
a8fe588
Extended the ArrayPreparationInterpreter to capture a result in case …
Feb 19, 2019
01c3529
Slightly changed the parameter registration and fixed a bug in the re…
Feb 20, 2019
2214045
Added primitive support for GetStatic expressions (needs to be enhanc…
Feb 22, 2019
1c50c9c
Correctly handle the case if no TAC is available.
Feb 22, 2019
9d18839
Minor changes.
Feb 23, 2019
4706bab
Added handling for the implicit "this" parameter.
Feb 26, 2019
c2cc00b
Added support for an "append" argument which > 1 definition site.
Feb 26, 2019
8f6b610
Added support for functions as arguments to (other) functions.
Feb 26, 2019
d345766
Provide a default value if a path could only be reduced to the neutra…
Feb 26, 2019
28d383e
The "append" finalizer did not correctly finalize when multiple defin…
Feb 26, 2019
f71f9fa
Finalizers might have dependencies among each other as well. These ar…
Feb 27, 2019
4b6ab1c
Refined the procedure for finding the correct method for which to get…
Feb 27, 2019
cc020df
Converted some comments to doc strings.
Feb 27, 2019
46beee4
Added support for the interpretation of functions which have other fu…
Feb 27, 2019
56c174b
Fixed a little bug.
Feb 28, 2019
e894819
Having the TAC and the CFG stored together is redundant => CFG was re…
Feb 28, 2019
9535106
Added further comments / explanations regarding the feature implement…
Feb 28, 2019
8160f2b
Turned InterpretationHandler#processedDefSites into a map to have co…
Feb 28, 2019
07b28fa
Improved the analysis in the way that it does not collect callers inf…
Feb 28, 2019
1c9de07
Exception information are regarded as dynamic, i.e., lower bound.
Feb 28, 2019
3685c83
Callers information are only collected if at least one of the paramet…
Mar 1, 2019
39e0005
Improved handling of declared methods.
Mar 1, 2019
a479bcd
Simplified the condition whether to retrieve callers information or not.
Mar 1, 2019
9a6acc8
The path transformer may need to update the fpe2sci map.
Mar 2, 2019
3b251a6
Refined the handling of functions.
Mar 3, 2019
ce1529b
Refined the procedure to determine whether callers information are re…
Mar 3, 2019
8d27769
In some cases it was unnecessary to collect callers information as th…
Mar 4, 2019
b204438
Added handling for the default case.
Mar 4, 2019
5c2a104
Refined the finalization handling.
Mar 4, 2019
dc6e358
Added a test case which, currently, does not work, as there is a cycl…
Mar 4, 2019
b3a5a8d
Refined the handling of NonVirtualFunctionCalls and modified some co…
Mar 4, 2019
0ca4223
Refined a condition.
Mar 5, 2019
a52f5da
Changed a parameter the "findPaths" function is called with.
Mar 5, 2019
a438895
Modified a condition.
Mar 5, 2019
8bc4390
Had to refine when a result is added to the fpe2sci map (adding the n…
Mar 5, 2019
ebedcbb
Added a test case which did not work previously but does so now becau…
Mar 5, 2019
8831a1e
Slightly refined the array finalizer in the way to finalize required …
Mar 5, 2019
f997787
Changed the handling when no TAC is available.
Mar 5, 2019
ac868a0
Prevented the procedure from trying to elements that do not exist.
Mar 5, 2019
ad5ac79
Needed to add a case in order for the match to be exhaustive.
Mar 5, 2019
8ef8efd
Not only VirtualFunctionCalls might be involved in finding definition…
Mar 5, 2019
adf6559
The mapping from variable / entity to index might be a 1-to-n relatio…
Mar 5, 2019
3f7b48f
Changed the analysis to retrieve the TAC from the property store.
Mar 5, 2019
f967965
Started adding support for fields.
Mar 6, 2019
50de368
Refined the handling of fields.
Mar 6, 2019
365a701
Added some important details to a test case.
Mar 6, 2019
01e4532
Added a test case where a field is read that is not written at all.
Mar 6, 2019
7ceabbb
Fixed a bug in the natural loop finding procedure. Sometimes, not ent…
Mar 6, 2019
8136bf4
The "fix" done with commit #729bee2 was not entirely correct (but now!).
Mar 6, 2019
bb9af97
Formatted the file.
Mar 6, 2019
090a311
Refined the getStartAndEndIndexOfCondWithAlternative procedure.
Mar 6, 2019
cdd76a4
Added a condition to detect conditionals without alternative.
Mar 6, 2019
2917ae6
Refined the handling of switch.
Mar 7, 2019
20d8f29
Refined the handling of int/char values.
Mar 7, 2019
9816b6e
Refined the handling of switch.
Mar 7, 2019
42e9aeb
Retrieve the TAC via the TAC provider again (StringAnalysisTest will …
Mar 7, 2019
8745dea
Had to change how the property store is setup in InterproceduralStrin…
Mar 8, 2019
c8a22c0
Slightly simplified the ArrayPreparationInterpreter.
Mar 8, 2019
c508229
Formatted the file.
Mar 8, 2019
069ab76
Refined the handling of the TAC.
Mar 8, 2019
25b7065
Restructured the file helper methods.
Mar 8, 2019
cefaa3a
Simplified a routine.
Mar 8, 2019
e93483b
Put an EPS to the dependees list only if a non-final result could be …
Mar 8, 2019
f7724d0
Do not add TAC entities twice to the property store.
Mar 8, 2019
4ca88ea
Avoided code duplication.
Mar 8, 2019
aacc946
Avoided some code duplication + cyclic dependencies are now resolved.
Mar 8, 2019
de03a45
Updated a comment.
Mar 8, 2019
cb8689f
Refined the handling of field read operations.
Mar 8, 2019
3a1fe05
Added a test case where a field of an unsupported type is read.
Mar 8, 2019
b72884a
Refined the handling of fields in the sense that no initialization (e…
Mar 8, 2019
d8bceff
Extended the support for primitive number types.
Mar 8, 2019
6fa72fd
Added a test case where a field is initialized using a constructor pa…
Mar 8, 2019
2d1a202
Slightly refined the procedure to detect conditionals with or without…
Mar 9, 2019
c3ac88a
Some (minor) improvements / bug fixes on the path finding procedure.
Mar 9, 2019
fa30475
Some (minor) improvements / bug fixes on the path finding procedure.
Mar 9, 2019
68d5309
Made the path finding procedure more robust.
Mar 10, 2019
bf7e6b1
Refined the handling of the TACMade the path finding procedure more r…
Mar 10, 2019
f9eddb6
Fixed a TODO regarding housekeeping.
Mar 10, 2019
0e0e81d
Do not compare by reference.
Mar 10, 2019
5f20b82
Added support for correctly handling intermediate results.
Mar 10, 2019
72ac05b
Avoided code duplication and cleaned the code.
Mar 10, 2019
0a37642
Added support for non-virtual functions which return more than one va…
Mar 11, 2019
f9d1ffc
Added support for static functions which return more than one value.
Mar 11, 2019
b98ed9e
Added test cases where functions have no return values.
Mar 11, 2019
b2129f8
Virtual function with several return values are now supported as well.
Mar 11, 2019
bce4bfb
Merged two test cases into one.
Mar 11, 2019
36ecc66
Added support for calls to String#valueOf.
Mar 11, 2019
1e8ee3f
Avoided code duplication.
Mar 11, 2019
effd2cb
Changed the interface of AbstractStringInterpreter#interpret to retur…
Mar 11, 2019
c323747
Implemented the hashCode and equals method (without it the Property S…
Mar 11, 2019
9126130
Extended the handling of arrays in the way that an interpretation may…
Mar 11, 2019
085d70d
Made the path transforming procedure more robust.
Mar 11, 2019
9c89f96
A "Cond" or "Or" tree may not necessarily have append elements.
Mar 11, 2019
613c49e
Slightly improved the procedure to determine whether a conditional ha…
Mar 11, 2019
235c610
On every generation of an interim, compute a new upper bound.
Mar 11, 2019
c3f1318
Narrowed the return type of InterproceduralInterpretationHandler#proc…
Mar 11, 2019
33a9c3c
Removed the "continuation" parameter from the InterproceduralInterpre…
Mar 12, 2019
97ea127
Had to refine the state of the interim state ("copy" does not copy al…
Mar 12, 2019
869fe8d
Refined the handling of try-catch-finally.
Mar 12, 2019
ad1b5c0
Refined the procedure to find the definition sites of a StringBuilder.
Mar 12, 2019
3d04763
Avoid an endless loop by tracking seen elements.
Mar 12, 2019
7d1ae00
Avoid endless recursion by checking to not start the procedure with i…
Mar 12, 2019
e0a35e1
Refined the handling of callers by introducing a threshold.
Mar 12, 2019
8624227
Improved the handling of try-catch blocks.
Mar 12, 2019
871eb4a
Removed an unnecessary line.
Mar 12, 2019
54ef3f9
Improved the handling of interim results.
Mar 12, 2019
c5bd57e
Had to refine how to update the part of the state that captures inter…
Mar 13, 2019
735d5fb
Added a question / todo.
Mar 13, 2019
2437647
Made the procedure more robust.
Mar 13, 2019
87908a9
Committed the state of this analysis which is actually used to analyz…
Mar 13, 2019
a68c649
Added support for static field read operations.
Mar 13, 2019
cb0b6b7
Changed the symbol, which is used to indicate that a (sub) string can…
Mar 14, 2019
670e38e
Fixed a typo.
Mar 14, 2019
5eacbf2
The path finding procedure could run in an endless loop which is now …
Mar 15, 2019
9b82d5a
Made this finalizer more robust.
Mar 15, 2019
0973b3f
Made the path finding procedure more robust by avoiding -1 values if …
Mar 15, 2019
e6735b5
Made the reduce accumulator more robust.
Mar 15, 2019
07fd194
Made the path finding procedure more robust by avoiding that the end …
Mar 15, 2019
d02f209
Extended the analysis to make the number of field write accesses conf…
Mar 17, 2019
8d6030b
Added a comment / TODO.
Mar 18, 2019
0810be3
Added a comment / TODO.
Mar 18, 2019
43a35f2
When the field interpreter was extended to support the threshold, a l…
Mar 21, 2019
92e0c52
Under some circumstances, the empty string was turned into the lower …
Mar 21, 2019
82b1444
Added support for NewArray expressions.
Mar 21, 2019
753a092
Approximate the results of a function, which does not return a String…
Mar 25, 2019
35f94c9
Merge remote-tracking branch 'upstream/develop' into feature/string-a…
Mar 25, 2019
81e11c9
Changed the way the (interprocedural) string analysis tests are execu…
Apr 2, 2019
4587e60
Merge remote-tracking branch 'upstream/develop' into feature/string-a…
Apr 2, 2019
d4a7195
re-applied review comments from PR #1
Jan 7, 2020
f00721b
sync with develop
Jan 7, 2020
f9ae631
resolved merge conflicts
Jan 7, 2020
723c5a4
Merge branch 'develop' into feature/StringAnalysis
Jan 31, 2020
8b47c05
Merge branch 'develop' into feature/StringAnalysis
Feb 3, 2020
51338da
minor refactoring in tests
Feb 3, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,22 @@ package org.opalj.support.info
import scala.annotation.switch

import java.net.URL
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicInteger

import scala.collection.mutable
import scala.collection.mutable.ListBuffer

import org.opalj.log.GlobalLogContext
import org.opalj.value.ValueInformation
import org.opalj.log.OPALLogger
import org.opalj.br.analyses.BasicReport
import org.opalj.br.analyses.Project
import org.opalj.br.analyses.ProjectAnalysisApplication
import org.opalj.br.analyses.ReportableAnalysisResult
import org.opalj.tac.Assignment
import org.opalj.tac.Call
import org.opalj.tac.DUVar
import org.opalj.tac.ExprStmt
import org.opalj.tac.LazyDetachedTACAIKey
import org.opalj.tac.NonVirtualMethodCall
import org.opalj.tac.StaticMethodCall
import org.opalj.tac.VirtualMethodCall
import org.opalj.tac.VirtualFunctionCall
import org.opalj.tac.fpcf.analyses.cg.V
import org.opalj.tac.EagerDetachedTACAIKey

/**
* Analyzes a project for how a particular class is used within that project. Collects information
Expand All @@ -34,28 +31,41 @@ import org.opalj.tac.VirtualMethodCall
* [[ClassUsageAnalysis.analysisSpecificParametersDescription]].
*
* @author Patrick Mell
* @author Dominik Helm
*/
object ClassUsageAnalysis extends ProjectAnalysisApplication {

private type V = DUVar[ValueInformation]

implicit val logContext: GlobalLogContext.type = GlobalLogContext

override def title: String = "Class Usage Analysis"

override def description: String = {
"Analyzes a project for how a particular class is used within it, i.e., which methods "+
"of instances of that class are called"
"Analysis a project for how a particular class is used, i.e., which methods are called "+
"on it"
}

/**
* The fully-qualified name of the class that is to be analyzed in a Java format, i.e., dots as
* package / class separators.
*/
private var className = "java.lang.StringBuilder"

/**
* The analysis can run in two modes: Fine-grained or coarse-grained. Fine-grained means that
* two method are considered as the same only if their method descriptor is the same, i.e., this
* mode enables a differentiation between overloaded methods.
* The coarse-grained method, however, regards two method calls as the same if the class of the
* base object as well as the method name are equal, i.e., overloaded methods are not
* distinguished.
*/
private var isFineGrainedAnalysis = false

/**
* Takes a [[Call]] and assembles the method descriptor for this call. The granularity is
* determined by [[isFineGrainedAnalysis]]: For a fine-grained analysis, the returned string has
* the format "[fully-qualified classname]#[method name]: [stringified method descriptor]" and
* for a coarse-grained analysis: [fully-qualified classname]#[method name].
*/
private def assembleMethodDescriptor(call: Call[V], isFineGrainedAnalysis: Boolean): String = {
private def assembleMethodDescriptor(call: Call[V]): String = {
val fqMethodName = s"${call.declaringClass.toJava}#${call.name}"
if (isFineGrainedAnalysis) {
val methodDescriptor = call.descriptor.toString
Expand All @@ -66,44 +76,28 @@ object ClassUsageAnalysis extends ProjectAnalysisApplication {
}

/**
* Takes any [[Call]], checks whether the base object is of type [[className]] and if so,
* updates the passed map by adding the count of the corresponding method. The granularity for
* counting is determined by [[isFineGrainedAnalysis]].
* Takes any function [[Call]], checks whether the base object is of type [[className]] and if
* so, updates the passed map by adding the count of the corresponding method. The granularity
* for counting is determined by [[isFineGrainedAnalysis]].
*/
private def processCall(
call: Call[V],
map: ConcurrentHashMap[String, AtomicInteger],
className: String,
isFineGrainedAnalysis: Boolean
): Unit = {
private def processFunctionCall(call: Call[V], map: mutable.Map[String, Int]): Unit = {
val declaringClassName = call.declaringClass.toJava
if (declaringClassName == className) {
val methodDescriptor = assembleMethodDescriptor(call, isFineGrainedAnalysis)
if (map.putIfAbsent(methodDescriptor, new AtomicInteger(1)) != null) {
map.get(methodDescriptor).addAndGet(1)
val methodDescriptor = assembleMethodDescriptor(call)
if (map.contains(methodDescriptor)) {
map(methodDescriptor) += 1
} else {
map(methodDescriptor) = 1
}
}
}

override def analysisSpecificParametersDescription: String = {
"-class=<fully-qualified class name> \n"+
"[-class=<fully-qualified class name> (Default: java.lang.StringBuilder)]\n"+
"[-granularity=<fine|coarse> (Default: coarse)]"
}

/**
* The fully-qualified name of the class that is to be analyzed in a Java format, i.e., dots as
* package / class separators.
*/
private final val parameterNameForClass = "-class="

/**
* The analysis can run in two modes: Fine-grained or coarse-grained. Fine-grained means that
* two methods are considered equal iff their method descriptor is the same, i.e., this mode
* enables a differentiation between overloaded methods.
* The coarse-grained method, however, regards two method calls as the same if the class of the
* base object as well as the method name are equal, i.e., overloaded methods are not
* distinguished.
*/
private final val parameterNameForGranularity = "-granularity="

override def checkAnalysisSpecificParameters(parameters: Seq[String]): Traversable[String] = {
Expand All @@ -118,60 +112,58 @@ object ClassUsageAnalysis extends ProjectAnalysisApplication {
* Takes the parameters passed as program arguments, i.e., in the format
* "-[param name]=[value]", extracts the values and sets the corresponding object variables.
*/
private def getAnalysisParameters(parameters: Seq[String]): (String, Boolean) = {
private def setAnalysisParameters(parameters: Seq[String]): Unit = {
val classParam = parameters.find(_.startsWith(parameterNameForClass))
val className = if (classParam.isDefined) {
classParam.get.substring(classParam.get.indexOf("=") + 1)
} else {
throw new IllegalArgumentException("missing argument: -class")
if (classParam.isDefined) {
className = classParam.get.substring(classParam.get.indexOf("=") + 1)
}

val granularityParam = parameters.find(_.startsWith(parameterNameForGranularity))
val isFineGrainedAnalysis =
if (granularityParam.isDefined) {
granularityParam.get.substring(granularityParam.get.indexOf("=") + 1) match {
case "fine" ⇒ true
case "coarse" ⇒ false
case _ ⇒
val msg = "incorrect argument: -granularity must be one of fine|coarse"
throw new IllegalArgumentException(msg)
}
if (granularityParam.isDefined) {
val granularity = granularityParam.get.substring(granularityParam.get.indexOf("=") + 1)
if (granularity == "fine") {
isFineGrainedAnalysis = true
} else if (granularity == "coarse") {
isFineGrainedAnalysis = false
} else {
false // default is coarse grained
val errMsg = s"failed parsing the granularity; it must be either 'fine' or "+
s"'coarse' but got '$granularity'"
OPALLogger.error("fatal", errMsg)
sys.exit(2)
}

(className, isFineGrainedAnalysis)
}
}

override def doAnalyze(
project: Project[URL], parameters: Seq[String], isInterrupted: () ⇒ Boolean
): ReportableAnalysisResult = {
val (className, isFineGrainedAnalysis) = getAnalysisParameters(parameters)
val resultMap: ConcurrentHashMap[String, AtomicInteger] = new ConcurrentHashMap()
val tacProvider = project.get(LazyDetachedTACAIKey)
setAnalysisParameters(parameters)
val resultMap = mutable.Map[String, Int]()
val tacProvider = project.get(EagerDetachedTACAIKey)

project.parForeachMethodWithBody() { methodInfo
tacProvider(methodInfo.method).stmts.foreach { stmt ⇒
project.allMethodsWithBody.foreach { m
tacProvider(m).stmts.foreach { stmt ⇒
(stmt.astID: @switch) match {
case Assignment.ASTID | ExprStmt.ASTID ⇒
stmt.asAssignmentLike.expr match {
case c: Call[V] @unchecked ⇒
processCall(c, resultMap, className, isFineGrainedAnalysis)
case _ ⇒
}
case NonVirtualMethodCall.ASTID | VirtualMethodCall.ASTID |
StaticMethodCall.ASTID ⇒
processCall(stmt.asMethodCall, resultMap, className, isFineGrainedAnalysis)
case Assignment.ASTID ⇒ stmt match {
case Assignment(_, _, c: VirtualFunctionCall[V]) ⇒
processFunctionCall(c, resultMap)
case _ ⇒
}
case ExprStmt.ASTID ⇒ stmt match {
case ExprStmt(_, c: VirtualFunctionCall[V]) ⇒
processFunctionCall(c, resultMap)
case _ ⇒
}
case _ ⇒
}
}
}

val report = ListBuffer[String]("Result:")
// Transform to a list, sort in ascending order of occurrences, and format the information
resultMap.entrySet().stream().sorted { (value1, value2) ⇒
value1.getValue.get().compareTo(value2.getValue.get())
}.forEach(next ⇒ report.append(s"${next.getKey}: ${next.getValue}"))
val report = ListBuffer[String]("Results")
// Transform to a list, sort in ascending order of occurrences and format the information
report.appendAll(resultMap.toList.sortWith(_._2 < _._2).map {
case (descriptor: String, count: Int) ⇒ s"$descriptor: $count"
})
BasicReport(report)
}

Expand Down
Loading