Skip to content

Commit baae107

Browse files
committed
Merge branch 'feature-enums' into 'develop'
Support for enums and static variables See merge request program-slicing/SDG!62
2 parents b27bc83 + 629420d commit baae107

File tree

218 files changed

+29736
-387
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

218 files changed

+29736
-387
lines changed

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Warning: all method calls must resolve to a method declaration. If your Java pro
1313

1414
JavaSDGSlicer manages its dependencies through maven, so you need to have the JDK (≥11) and Maven installed, then run
1515
```
16-
mvn package
16+
mvn package -Dmaven.test.skip
1717
```
1818

1919
A fat jar containing all the project's dependencies can be then located at `./sdg-cli/target/sdg-cli-{version}-jar-with-dependencies.jar`.
@@ -57,7 +57,7 @@ java -jar sdg-cli.jar --help
5757
Our slicer requires the input Java program to be compilable, so all libraries must be provided using the `-i` flag. For the cases where the source code is not available, you may include the required libraries in the Java classpath by using the following call:
5858

5959
```
60-
java -cp sdg-cli.jar:your-libraries.jar es.upv.slicing.cli.Slicer -c Example.java#11:sum
60+
java -cp your-libraries.jar -jar sdg-cli.jar -c Example.java#11:sum
6161
```
6262

6363
This approach produces lower quality slices, as the contents of the library calls are unknown.
@@ -77,6 +77,4 @@ If the graph is of interest, it can be outputted in `dot` or PDF format via `SDG
7777

7878
## Missing Java features
7979

80-
* Object-oriented features: abstract classes, interfaces, class, method and field inheritance, anonymous classes, lambdas.
8180
* Parallel features: threads, shared memory, synchronized methods, etc.
82-
* Exception handling: `finally`, try with resources.

javaparser-symbol-solver-core/pom.xml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<parent>
4+
<artifactId>sdg</artifactId>
5+
<groupId>es.upv.mist.slicing</groupId>
6+
<version>1.3.0</version>
7+
</parent>
8+
<modelVersion>4.0.0</modelVersion>
9+
10+
<artifactId>javaparser-symbol-solver-core</artifactId>
11+
<groupId>com.github.javaparser</groupId>
12+
<version>3.23.2</version>
13+
<packaging>jar</packaging>
14+
<description>A Symbol Solver for Java, built on top of JavaParser (core)</description>
15+
16+
<licenses>
17+
<license>
18+
<name>GNU Lesser General Public License</name>
19+
<url>http://www.gnu.org/licenses/lgpl-3.0.html</url>
20+
<distribution>repo</distribution>
21+
</license>
22+
<license>
23+
<name>Apache License, Version 2.0</name>
24+
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
25+
<distribution>repo</distribution>
26+
<comments>A business-friendly OSS license</comments>
27+
</license>
28+
</licenses>
29+
30+
<properties>
31+
<java.version>1.8</java.version>
32+
<build.timestamp>${maven.build.timestamp}</build.timestamp>
33+
</properties>
34+
35+
<dependencies>
36+
<dependency>
37+
<groupId>com.github.javaparser</groupId>
38+
<artifactId>javaparser-core</artifactId>
39+
<version>3.23.1</version>
40+
</dependency>
41+
<dependency>
42+
<groupId>org.javassist</groupId>
43+
<artifactId>javassist</artifactId>
44+
<version>3.28.0-GA</version>
45+
</dependency>
46+
<dependency>
47+
<groupId>com.google.guava</groupId>
48+
<artifactId>guava</artifactId>
49+
<version>31.0.1-jre</version>
50+
</dependency>
51+
</dependencies>
52+
53+
<build>
54+
<plugins>
55+
<!-- Set JPMS module name -->
56+
<plugin>
57+
<groupId>org.apache.maven.plugins</groupId>
58+
<artifactId>maven-jar-plugin</artifactId>
59+
<configuration>
60+
<archive>
61+
<manifestEntries>
62+
<Automatic-Module-Name>com.github.javaparser.symbolsolver.core</Automatic-Module-Name>
63+
</manifestEntries>
64+
</archive>
65+
</configuration>
66+
</plugin>
67+
</plugins>
68+
</build>
69+
</project>
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
/*
2+
* Copyright (C) 2015-2016 Federico Tomassetti
3+
* Copyright (C) 2017-2020 The JavaParser Team.
4+
*
5+
* This file is part of JavaParser.
6+
*
7+
* JavaParser can be used either under the terms of
8+
* a) the GNU Lesser General Public License as published by
9+
* the Free Software Foundation, either version 3 of the License, or
10+
* (at your option) any later version.
11+
* b) the terms of the Apache License
12+
*
13+
* You should have received a copy of both licenses in LICENCE.LGPL and
14+
* LICENCE.APACHE. Please refer to those files for details.
15+
*
16+
* JavaParser is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Lesser General Public License for more details.
20+
*/
21+
22+
package com.github.javaparser.symbolsolver;
23+
24+
import com.github.javaparser.ast.CompilationUnit;
25+
import com.github.javaparser.ast.Node;
26+
import com.github.javaparser.ast.body.*;
27+
import com.github.javaparser.ast.expr.*;
28+
import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
29+
import com.github.javaparser.ast.type.Type;
30+
import com.github.javaparser.resolution.SymbolResolver;
31+
import com.github.javaparser.resolution.UnsolvedSymbolException;
32+
import com.github.javaparser.resolution.declarations.*;
33+
import com.github.javaparser.resolution.types.ResolvedPrimitiveType;
34+
import com.github.javaparser.resolution.types.ResolvedType;
35+
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
36+
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
37+
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.*;
38+
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
39+
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
40+
41+
/**
42+
* This implementation of the SymbolResolver wraps the functionality of the library to make them easily usable
43+
* from JavaParser nodes.
44+
* <p>
45+
* An instance of this class should be created once and then injected in all the CompilationUnit for which we
46+
* want to enable symbol resolution. To do so the method inject can be used, or you can use
47+
* {@link com.github.javaparser.ParserConfiguration#setSymbolResolver(SymbolResolver)} and the parser will do the
48+
* injection for you.
49+
*
50+
* @author Federico Tomassetti
51+
*/
52+
public class JavaSymbolSolver implements SymbolResolver {
53+
54+
private static class ArrayLengthValueDeclaration implements ResolvedValueDeclaration {
55+
56+
private static final ArrayLengthValueDeclaration INSTANCE = new ArrayLengthValueDeclaration();
57+
58+
private ArrayLengthValueDeclaration() {
59+
60+
}
61+
62+
@Override
63+
public String getName() {
64+
return "length";
65+
}
66+
67+
@Override
68+
public ResolvedType getType() {
69+
return ResolvedPrimitiveType.INT;
70+
}
71+
}
72+
73+
private TypeSolver typeSolver;
74+
75+
public JavaSymbolSolver(TypeSolver typeSolver) {
76+
this.typeSolver = typeSolver;
77+
}
78+
79+
/**
80+
* Register this SymbolResolver into a CompilationUnit, so that symbol resolution becomes available to
81+
* all nodes part of the CompilationUnit.
82+
*/
83+
public void inject(CompilationUnit destination) {
84+
destination.setData(Node.SYMBOL_RESOLVER_KEY, this);
85+
}
86+
87+
@Override
88+
public <T> T resolveDeclaration(Node node, Class<T> resultClass) {
89+
if (node instanceof MethodDeclaration) {
90+
return resultClass.cast(new JavaParserMethodDeclaration((MethodDeclaration) node, typeSolver));
91+
}
92+
if (node instanceof ClassOrInterfaceDeclaration) {
93+
ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver);
94+
if (resultClass.isInstance(resolved)) {
95+
return resultClass.cast(resolved);
96+
}
97+
}
98+
if (node instanceof EnumDeclaration) {
99+
ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver);
100+
if (resultClass.isInstance(resolved)) {
101+
return resultClass.cast(resolved);
102+
}
103+
}
104+
if (node instanceof EnumConstantDeclaration) {
105+
ResolvedEnumDeclaration enumDeclaration = node.findAncestor(EnumDeclaration.class).get().resolve().asEnum();
106+
ResolvedEnumConstantDeclaration resolved = enumDeclaration.getEnumConstants().stream().filter(c -> ((JavaParserEnumConstantDeclaration) c).getWrappedNode() == node).findFirst().get();
107+
if (resultClass.isInstance(resolved)) {
108+
return resultClass.cast(resolved);
109+
}
110+
}
111+
if (node instanceof ConstructorDeclaration) {
112+
ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) node;
113+
TypeDeclaration<?> typeDeclaration = (TypeDeclaration<?>) node.getParentNode().get();
114+
ResolvedReferenceTypeDeclaration resolvedTypeDeclaration = resolveDeclaration(typeDeclaration, ResolvedReferenceTypeDeclaration.class);
115+
ResolvedConstructorDeclaration resolved = resolvedTypeDeclaration.getConstructors().stream()
116+
.filter(c -> c instanceof JavaParserConstructorDeclaration)
117+
.filter(c -> ((JavaParserConstructorDeclaration<?>) c).getWrappedNode() == constructorDeclaration)
118+
.findFirst()
119+
.orElseThrow(() -> new RuntimeException("This constructor cannot be found in its parent. This seems wrong"));
120+
if (resultClass.isInstance(resolved)) {
121+
return resultClass.cast(resolved);
122+
}
123+
}
124+
if (node instanceof AnnotationDeclaration) {
125+
ResolvedReferenceTypeDeclaration resolved = JavaParserFactory.toTypeDeclaration(node, typeSolver);
126+
if (resultClass.isInstance(resolved)) {
127+
return resultClass.cast(resolved);
128+
}
129+
}
130+
if (node instanceof AnnotationMemberDeclaration) {
131+
ResolvedAnnotationDeclaration annotationDeclaration = node.findAncestor(AnnotationDeclaration.class).get().resolve();
132+
ResolvedAnnotationMemberDeclaration resolved = annotationDeclaration.getAnnotationMembers().stream().filter(c -> ((JavaParserAnnotationMemberDeclaration) c).getWrappedNode() == node).findFirst().get();
133+
if (resultClass.isInstance(resolved)) {
134+
return resultClass.cast(resolved);
135+
}
136+
}
137+
if (node instanceof FieldDeclaration) {
138+
FieldDeclaration fieldDeclaration = (FieldDeclaration) node;
139+
if (fieldDeclaration.getVariables().size() != 1) {
140+
throw new RuntimeException("Cannot resolve a Field Declaration including multiple variable declarators. Resolve the single variable declarators");
141+
}
142+
ResolvedFieldDeclaration resolved = new JavaParserFieldDeclaration(fieldDeclaration.getVariable(0), typeSolver);
143+
if (resultClass.isInstance(resolved)) {
144+
return resultClass.cast(resolved);
145+
}
146+
}
147+
if (node instanceof VariableDeclarator) {
148+
ResolvedValueDeclaration resolved;
149+
if (node.getParentNode().isPresent() && node.getParentNode().get() instanceof FieldDeclaration) {
150+
resolved = new JavaParserFieldDeclaration((VariableDeclarator) node, typeSolver);
151+
} else if (node.getParentNode().isPresent() && node.getParentNode().get() instanceof VariableDeclarationExpr) {
152+
resolved = new JavaParserVariableDeclaration((VariableDeclarator) node, typeSolver);
153+
} else {
154+
throw new UnsupportedOperationException("Parent of VariableDeclarator is: " + node.getParentNode());
155+
}
156+
if (resultClass.isInstance(resolved)) {
157+
return resultClass.cast(resolved);
158+
}
159+
}
160+
if (node instanceof MethodCallExpr) {
161+
SymbolReference<ResolvedMethodDeclaration> result = JavaParserFacade.get(typeSolver).solve((MethodCallExpr) node);
162+
if (result.isSolved()) {
163+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
164+
return resultClass.cast(result.getCorrespondingDeclaration());
165+
}
166+
} else {
167+
throw new UnsolvedSymbolException("We are unable to find the method declaration corresponding to " + node);
168+
}
169+
}
170+
if (node instanceof ObjectCreationExpr) {
171+
SymbolReference<ResolvedConstructorDeclaration> result = JavaParserFacade.get(typeSolver).solve((ObjectCreationExpr) node);
172+
if (result.isSolved()) {
173+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
174+
return resultClass.cast(result.getCorrespondingDeclaration());
175+
}
176+
} else {
177+
throw new UnsolvedSymbolException("We are unable to find the constructor declaration corresponding to " + node);
178+
}
179+
}
180+
if (node instanceof NameExpr) {
181+
SymbolReference<? extends ResolvedValueDeclaration> result = JavaParserFacade.get(typeSolver).solve((NameExpr) node);
182+
if (result.isSolved()) {
183+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
184+
return resultClass.cast(result.getCorrespondingDeclaration());
185+
}
186+
} else {
187+
throw new UnsolvedSymbolException("We are unable to find the value declaration corresponding to " + node);
188+
}
189+
}
190+
if (node instanceof MethodReferenceExpr) {
191+
SymbolReference<ResolvedMethodDeclaration> result = JavaParserFacade.get(typeSolver).solve((MethodReferenceExpr) node);
192+
if (result.isSolved()) {
193+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
194+
return resultClass.cast(result.getCorrespondingDeclaration());
195+
}
196+
} else {
197+
throw new UnsolvedSymbolException("We are unable to find the method declaration corresponding to " + node);
198+
}
199+
}
200+
if (node instanceof FieldAccessExpr) {
201+
SymbolReference<? extends ResolvedValueDeclaration> result = JavaParserFacade.get(typeSolver).solve((FieldAccessExpr) node);
202+
if (result.isSolved()) {
203+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
204+
return resultClass.cast(result.getCorrespondingDeclaration());
205+
}
206+
} else {
207+
if (((FieldAccessExpr) node).getName().getId().equals("length")) {
208+
ResolvedType scopeType = ((FieldAccessExpr) node).getScope().calculateResolvedType();
209+
if (scopeType.isArray()) {
210+
if (resultClass.isInstance(ArrayLengthValueDeclaration.INSTANCE)) {
211+
return resultClass.cast(ArrayLengthValueDeclaration.INSTANCE);
212+
}
213+
}
214+
}
215+
throw new UnsolvedSymbolException("We are unable to find the value declaration corresponding to " + node);
216+
}
217+
}
218+
if (node instanceof ThisExpr) {
219+
SymbolReference<ResolvedTypeDeclaration> result = JavaParserFacade.get(typeSolver).solve((ThisExpr) node);
220+
if (result.isSolved()) {
221+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
222+
return resultClass.cast(result.getCorrespondingDeclaration());
223+
}
224+
} else {
225+
throw new UnsolvedSymbolException("We are unable to find the type declaration corresponding to " + node);
226+
}
227+
}
228+
if (node instanceof ExplicitConstructorInvocationStmt) {
229+
SymbolReference<ResolvedConstructorDeclaration> result = JavaParserFacade.get(typeSolver).solve((ExplicitConstructorInvocationStmt) node);
230+
if (result.isSolved()) {
231+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
232+
return resultClass.cast(result.getCorrespondingDeclaration());
233+
}
234+
} else {
235+
throw new UnsolvedSymbolException("We are unable to find the constructor declaration corresponding to " + node);
236+
}
237+
}
238+
if (node instanceof Parameter) {
239+
if (ResolvedParameterDeclaration.class.equals(resultClass)) {
240+
Parameter parameter = (Parameter) node;
241+
CallableDeclaration callableDeclaration = node.findAncestor(CallableDeclaration.class).get();
242+
ResolvedMethodLikeDeclaration resolvedMethodLikeDeclaration;
243+
if (callableDeclaration.isConstructorDeclaration()) {
244+
resolvedMethodLikeDeclaration = callableDeclaration.asConstructorDeclaration().resolve();
245+
} else {
246+
resolvedMethodLikeDeclaration = callableDeclaration.asMethodDeclaration().resolve();
247+
}
248+
for (int i = 0; i < resolvedMethodLikeDeclaration.getNumberOfParams(); i++) {
249+
if (resolvedMethodLikeDeclaration.getParam(i).getName().equals(parameter.getNameAsString())) {
250+
return resultClass.cast(resolvedMethodLikeDeclaration.getParam(i));
251+
}
252+
}
253+
}
254+
}
255+
if (node instanceof AnnotationExpr) {
256+
SymbolReference<ResolvedAnnotationDeclaration> result = JavaParserFacade.get(typeSolver).solve((AnnotationExpr) node);
257+
if (result.isSolved()) {
258+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
259+
return resultClass.cast(result.getCorrespondingDeclaration());
260+
}
261+
} else {
262+
throw new UnsolvedSymbolException("We are unable to find the annotation declaration corresponding to " + node);
263+
}
264+
}
265+
if (node instanceof PatternExpr) {
266+
SymbolReference<? extends ResolvedValueDeclaration> result = JavaParserFacade.get(typeSolver).solve((PatternExpr) node);
267+
if (result.isSolved()) {
268+
if (resultClass.isInstance(result.getCorrespondingDeclaration())) {
269+
return resultClass.cast(result.getCorrespondingDeclaration());
270+
}
271+
} else {
272+
throw new UnsolvedSymbolException("We are unable to find the method declaration corresponding to " + node);
273+
}
274+
}
275+
throw new UnsupportedOperationException("Unable to find the declaration of type " + resultClass.getSimpleName()
276+
+ " from " + node.getClass().getSimpleName());
277+
}
278+
279+
@Override
280+
public <T> T toResolvedType(Type javaparserType, Class<T> resultClass) {
281+
ResolvedType resolvedType = JavaParserFacade.get(typeSolver).convertToUsage(javaparserType, javaparserType);
282+
if (resultClass.isInstance(resolvedType)) {
283+
return resultClass.cast(resolvedType);
284+
}
285+
throw new UnsupportedOperationException("Unable to get the resolved type of class "
286+
+ resultClass.getSimpleName() + " from " + javaparserType);
287+
}
288+
289+
@Override
290+
public ResolvedType calculateType(Expression expression) {
291+
return JavaParserFacade.get(typeSolver).getType(expression);
292+
}
293+
}

0 commit comments

Comments
 (0)