Compare commits

...

48 Commits

Author SHA1 Message Date
gangz 933150b026 Merge branch 'master' of github.com:multilang-depends/depends 2023-05-10 13:05:35 +08:00
gangz 76f91ed49d fix test error of PythonImportTest 2023-05-10 13:04:20 +08:00
Zhang Gang 5e19539d28
Merge pull request #47 from jlefever/fix-to-file-null
fix NullPointerException in DependencyGenerator
2023-04-13 07:30:49 +08:00
Jason Lefever 19a2040dc4 fix NullPointerException in DependencyGenerator 2023-04-12 16:02:23 -04:00
Zhang Gang 3339f8b532
Update README.md 2023-03-31 15:07:17 +08:00
Zhang Gang 75f2d213a3
Merge pull request #45 from jlefever/lineno-bug
Fix incorrect line numbers on some parameter dependencies
2023-02-14 16:01:38 +08:00
Jason Lefever c3874e4b70 fix incorrect line numbers on some parameter dependencies 2023-02-12 17:48:51 -05:00
Gang ZHANG 2c272809ae fix python import issue 2022-11-04 07:32:15 +08:00
Gang ZHANG 6bd17bb8ea fix: python names with dot should be processed correctly 2022-11-03 08:58:24 +08:00
Gang ZHANG 66db5d509e fix: python function parameter could be star 2022-11-03 08:20:29 +08:00
Gang ZHANG 9e012e4d0c fix implementation of python alias 2022-11-02 09:25:02 +08:00
Gang ZHANG 982b1e2859 add feature of python: assignment treat as alias for class name 2022-10-31 09:25:31 +08:00
Gang ZHANG 910f31e4f2 adjust python import strategy(file as module, instead of directly use package name) 2022-10-30 14:45:39 +08:00
Gang ZHANG c09675c980 fix null pointer exception in ruby visitor 2022-10-23 14:14:47 +08:00
Gang ZHANG 68a5dccf66 refine gitignore 2022-10-23 12:06:28 +08:00
Gang ZHANG a7f33f2d1f add command parameter of self-dependencies output 2022-09-29 23:03:14 +08:00
Gang ZHANG 96b416adcc add jaxb-api to fix issue of package javax.xml.bind.annotation does not exist issue 2022-09-29 07:49:31 +08:00
Gang ZHANG 739aabc582 output object type of detail data 2022-09-28 23:57:56 +08:00
Gang ZHANG 27f1206a1a support to scan once with multi-level granularities outputs 2022-09-28 23:43:55 +08:00
Gang ZHANG 877c1ac1d3 fix broken tests 2022-09-21 08:27:19 +08:00
Gang ZHANG 80cc02fe91 update link relation name from impl link to link, because we already add possibile dependency output 2022-09-21 08:18:42 +08:00
Gang ZHANG 40399d6885 add comments to Expression class 2022-09-21 08:15:52 +08:00
Gang ZHANG dc6e7fdf8b add test of possible relation 2022-09-21 07:58:41 +08:00
Gang ZHANG 55854a2a5c add possible dependencies of multiple declared functions/vars 2022-09-21 00:40:41 +08:00
Gang ZHANG 9f09879d12 upgrade to 0.9.7 2022-09-19 23:57:03 +08:00
Gang ZHANG f114c9c371 add bulit-in type into repo 2022-09-19 23:54:38 +08:00
Gang ZHANG 2b1ba79bca add util jar 2022-09-19 23:24:36 +08:00
Gang ZHANG d003ee4afa fix: duck typing multiple entities may introduce redundant relations 2022-09-18 16:35:35 +08:00
Gang ZHANG dbabb7e459 fix: lost put parameter var into repo in python listener 2022-09-18 15:58:53 +08:00
Gang ZHANG 0be07f93f6 add test for duplicate expression counter 2022-09-16 00:30:36 +08:00
Gang ZHANG 37e4783691 refactory of DependencyGenerator, and add duck type output 2022-09-15 23:49:45 +08:00
Gang ZHANG 57f729a36c refactory: remove useless relationCount 2022-09-15 07:34:10 +08:00
Gang ZHANG 42dbac90d8 refine the output format - strip all data (include file name,object name) 2022-09-14 21:58:44 +08:00
Gang ZHANG 8e144f23fa refactory: simplified main function 2022-09-14 21:27:14 +08:00
Gang ZHANG 7dfb555a41 fix: ruby line counter should start from 1 instead of 0 2022-09-14 08:45:48 +08:00
Gang ZHANG 75f07ae8c1 refine output of detail format and error message of ruby 2022-09-12 06:21:16 +08:00
Gang ZHANG c1c275b968 fix: ruby global var could introduce NPE 2022-09-11 23:24:42 +08:00
Gang ZHANG 4286870bf9 refactory: refine responsbility of file parser/lang processor 2022-09-11 21:43:01 +08:00
Gang ZHANG b4f94214f3 refactory: make parse paramter belongs to ***Parser.parse() instead of ***Parser() 2022-09-11 16:17:59 +08:00
Gang ZHANG aaa26dab1a refactory: included file locator 2022-09-11 15:32:54 +08:00
Gang ZHANG 64658ef45e refactory: included file locator 2022-09-11 15:29:32 +08:00
Gang ZHANG b6feb81872 refactory: simplified build-in types related work 2022-09-11 15:19:06 +08:00
Gang ZHANG 1016ff9298 remove executor of ruby parser 2022-09-10 21:47:19 +08:00
gangz 2f0724800b fix: error prompt 2022-06-07 21:49:05 +08:00
Zhang Gang 1b716a0142
Merge pull request #33 from thebjorn/master
Fix broken .bat file.
2022-06-04 22:10:06 +08:00
gangz 8e4797add8 update developer guide 2022-06-04 22:07:39 +08:00
Bjorn Pettersen de96fe0e73 bah. %~dp0 includes the trailing backslash. 2021-04-04 14:31:38 +02:00
Bjorn Pettersen 80d79ed5e2 Turn off echo of command being executed, remove exec (doesn't exist in .bat land), and look for .jar file in the same directory as the .bat file. 2021-04-04 14:23:24 +02:00
158 changed files with 1471 additions and 1258 deletions

6
.gitignore vendored
View File

@ -3,14 +3,8 @@
*.class
*.log
.idea/
out/
data/
*.DS_Store
/target/
.classpath
.project
.settings/
META-INF/
result/
java_design_pattern_test/
lang

View File

@ -50,7 +50,7 @@ The CLI tool usage could be listed by ```depends --help```, like following:
-h, --help Display this help and exit
-s, --strip-leading-path Strip the leading path.
-m, --map Output DV8 dependency map file.
-m, --n-map-files Output DV8 dependency map file.
-p, --namepattern=<namePathPattern>
The name path separators.[default(/),dot(.)

View File

@ -1,2 +1,2 @@
exec java -jar depends.jar %*
@echo off
java -jar %~dp0depends.jar %*

View File

@ -1 +0,0 @@
mvn clean package

View File

@ -1,6 +1,18 @@
**Depends设计说明**
**v20190215 **
#下载和编译
## java版本
Depends使用Java8编写。如果您安装的是Java的其他版本请首先安装Java8 JDK。并且把Java版本切换到Java8.
## 依赖
Depends使用了若干依赖。除了Pom文件中指定的依赖还需要显式安装一些依赖。
首先你需要下载https://github.com/multilang-depends/utils并使用mvn install安装。
此外,还需要运行源码下面的./install_lib.sh或.\install_lib.bat安装一些依赖。
## 编译
现在你应该可以顺利的运行mvn package来获得编译的Jar包了。在此基础上就可以对代码进行修改。
语言扩展说明
============

View File

@ -94,7 +94,7 @@ For example, the implementation of FileParser is as follows:
The steps are:
Create a Lexer, create a Parse, create a Listener, and start traversing each of the syntax elements of interest.
### Impelemnt the listener/visitor:
### Implement the listener/visitor:
First, create a context for the file:
@ -113,7 +113,7 @@ Then, for each code element, tell the context some information required. for exa
super.enterFuncdef(ctx);
}
We already succefully make the depends knows that a function entity is created.
We already successfully make the depends on knows that a function entity is created.
### Language-specific Import Locator
@ -221,7 +221,7 @@ ContainerEntity. AliasEntity is essentially an alias, so it points directly to E
ContainerEntity is the public parent class for most types, and its immediate subclasses include MultiDeclareEntity.
FileEntity, AnonymousBlock, FunctionEntity, TypeEntity and VarEntity.
PackageEntity is a subclass of TypeEnity. This concept is incorrect. In the subsequent stage, the design reason should be further investigated and reconstructed.
PackageEntity is a subclass of TypeEntity. This concept is incorrect. In the subsequent stage, the design reason should be further investigated and reconstructed.
### How does EntityRepo maintain data?

Binary file not shown.

View File

@ -16,3 +16,5 @@ mvn install:install-file -DgroupId=eclipse-photon -DartifactId=org.eclipse.core.
mvn install:install-file -DgroupId=eclipse-photon -DartifactId=org.eclipse.core.resources -Dversion=3.13.500.v20190819-0800 -Dpackaging=jar -Dfile=./jars/org.eclipse.core.resources_3.13.500.v20190819-0800.jar -DgeneratePom=true
mvn install:install-file -DgroupId=cn.emergentdesign.se -DartifactId=utils -Dversion=0.0.1 -Dpackaging=jar -Dfile=./jars/cn.emergentdesign.se.utils_0.1.1.jar -DgeneratePom=true

View File

@ -16,3 +16,4 @@ mvn install:install-file -DgroupId=eclipse-photon -DartifactId=org.eclipse.core.
mvn install:install-file -DgroupId=eclipse-photon -DartifactId=org.eclipse.core.resources -Dversion=3.13.500.v20190819-0800 -Dpackaging=jar -Dfile=./jars/org.eclipse.core.resources_3.13.500.v20190819-0800.jar -DgeneratePom=true
mvn install:install-file -DgroupId=cn.emergentdesign.se -DartifactId=utils -Dversion=0.0.1 -Dpackaging=jar -Dfile=./jars/cn.emergentdesign.se.utils_0.1.1.jar -DgeneratePom=true

15
pom.xml
View File

@ -7,7 +7,7 @@
<groupId>cn.emergentdesign.se</groupId>
<artifactId>depends</artifactId>
<!-- <version>1.0-SNAPSHOT</version> -->
<version>0.9.6</version>
<version>0.9.7</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<antlr4.visitor>true</antlr4.visitor>
@ -188,10 +188,15 @@
<version>0.5.5-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.5.1</version>
</dependency>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</project>

View File

@ -24,15 +24,15 @@ SOFTWARE.
package depends;
import java.util.ArrayList;
import java.util.List;
import depends.deptypes.DependencyType;
import depends.extractor.LangProcessorRegistration;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import java.util.ArrayList;
import java.util.List;
@Command(name = "depends")
public class DependsCommand {
public static class SupportedLangs extends ArrayList<String> {
@ -62,8 +62,8 @@ public class DependsCommand {
@Option(names = {"--strip-paths"}, split=",", description = "The path(s) to be stripped. if -s enabled, the path(s) start after <src>. "
+ "Otherwise, the path(s) should be valid.")
private String[] strippedPaths = new String[]{};
@Option(names = {"-g", "--granularity"}, description = "Granularity of dependency.[file(default),method,structure,L#(the level of folder. e.g. L1=1st level folder)]")
private String granularity="file";
@Option(names = {"-g", "--granularity"}, split=",", description = "Granularity of dependency.[file(default),method,structure]")
private String[] granularity=new String[]{"file"};
@Option(names = {"-p", "--namepattern"}, description = "The name path pattern.[dot(.), unix(/) or windows(\\)")
private String namePathPattern="";
@Option(names = {"-i","--includes"},split=",", description = "The files of searching path")
@ -79,7 +79,9 @@ public class DependsCommand {
@Option(names = {"--external-deps"}, description = "Output external dependencies")
private boolean outputExternalDependencies = false;
@Option(names = {"--duck-typing-deduce"}, description = "Deduce implicit variable types")
private boolean duckTypingDeduce = true;
private boolean duckTypingDeduce = true;
@Option(names = {"--output-self-deps"}, description = "Output self dependencies")
private boolean outputSelfDependencies = false;
@Option(names = {"-h","--help"}, usageHelp = true, description = "display this help and exit")
boolean help;
public DependsCommand() {
@ -120,7 +122,7 @@ public class DependsCommand {
public boolean isHelp() {
return help;
}
public String getGranularity() {
public String[] getGranularity() {
return granularity;
}
public String getNamePathPattern() {
@ -154,7 +156,9 @@ public class DependsCommand {
public boolean isOutputExternalDependencies() {
return outputExternalDependencies;
}
public boolean isOutputSelfDependencies() {
return outputSelfDependencies;
}
public boolean isDuckTypingDeduce() {
return this.duckTypingDeduce;
}

View File

@ -36,7 +36,6 @@ import depends.generator.FileDependencyGenerator;
import depends.generator.FunctionDependencyGenerator;
import depends.generator.StructureDependencyGenerator;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.transform.MatrixLevelReducer;
import depends.relations.BindingResolver;
import depends.relations.IBindingResolver;
import depends.relations.RelationCounter;
@ -52,21 +51,26 @@ import picocli.CommandLine;
import picocli.CommandLine.PicocliException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* The entry pooint of depends
*/
public class Main {
public static void main(String[] args) {
try {
LangRegister langRegister = new LangRegister();
langRegister.register();
DependsCommand app = CommandLine.populateCommand(new DependsCommand(), args);
if (app.help) {
DependsCommand appArgs = CommandLine.populateCommand(new DependsCommand(), args);
if (appArgs.help) {
CommandLine.usage(new DependsCommand(), System.out);
System.exit(0);
}
executeCommand(app);
verifyParameters(appArgs);
executeCommand(appArgs);
} catch (Exception e) {
if (e instanceof PicocliException) {
CommandLine.usage(new DependsCommand(), System.out);
@ -80,24 +84,29 @@ public class Main {
}
}
private static void verifyParameters(DependsCommand args) throws ParameterException {
String[] granularities = args.getGranularity();
List<String> validGranularities = Arrays.asList(new String[]{"file", "method", "structure"});
for (String g:granularities){
if (!validGranularities.contains(g)){
throw new ParameterException("granularity is invalid:"+g);
}
}
}
@SuppressWarnings("unchecked")
private static void executeCommand(DependsCommand app) throws ParameterException {
String lang = app.getLang();
String inputDir = app.getSrc();
String[] includeDir = app.getIncludes();
String outputName = app.getOutputName();
String outputDir = app.getOutputDir();
String[] outputFormat = app.getFormat();
private static void executeCommand(DependsCommand args) throws ParameterException {
String lang = args.getLang();
String inputDir = args.getSrc();
String[] includeDir = args.getIncludes();
String outputName = args.getOutputName();
String outputDir = args.getOutputDir();
String[] outputFormat = args.getFormat();
inputDir = FileUtil.uniqFilePath(inputDir);
boolean supportImplLink = false;
if (app.getLang().equals("cpp") || app.getLang().equals("python")) supportImplLink = true;
if (app.isAutoInclude()) {
FolderCollector includePathCollector = new FolderCollector();
List<String> additionalIncludePaths = includePathCollector.getFolders(inputDir);
additionalIncludePaths.addAll(Arrays.asList(includeDir));
includeDir = additionalIncludePaths.toArray(new String[] {});
if (args.isAutoInclude()) {
includeDir = appendAllFoldersToIncludePath(inputDir, includeDir);
}
AbstractLangProcessor langProcessor = LangProcessorRegistration.getRegistry().getProcessorOf(lang);
@ -105,29 +114,28 @@ public class Main {
System.err.println("Not support this language: " + lang);
return;
}
IBindingResolver bindingResolver = new BindingResolver(langProcessor.getEntityRepo(), langProcessor.getImportLookupStrategy(), langProcessor.getBuiltInType()
, app.isOutputExternalDependencies(), app.isDuckTypingDeduce());
IBindingResolver bindingResolver = new BindingResolver(langProcessor, args.isOutputExternalDependencies(), args.isDuckTypingDeduce());
long startTime = System.currentTimeMillis();
//step1: build data
EntityRepo entityRepo = langProcessor.buildDependencies(inputDir, includeDir, bindingResolver);
new RelationCounter(entityRepo,supportImplLink,langProcessor, bindingResolver).computeRelations();
new RelationCounter(entityRepo,langProcessor, bindingResolver).computeRelations();
System.out.println("Dependency done....");
//step2: generate dependencies matrix
DependencyGenerator dependencyGenerator = getDependencyGenerator(app, inputDir);
DependencyMatrix matrix = dependencyGenerator.identifyDependencies(entityRepo,app.getTypeFilter());
//step3: output
if (app.getGranularity().startsWith("L")) {
matrix = new MatrixLevelReducer(matrix,app.getGranularity().substring(1)).shrinkToLevel();
List<DependencyGenerator> dependencyGenerators = getDependencyGenerators(args, inputDir);
for (DependencyGenerator dependencyGenerator:dependencyGenerators) {
DependencyMatrix matrix = dependencyGenerator.identifyDependencies(entityRepo, args.getTypeFilter());
DependencyDumper output = new DependencyDumper(matrix);
output.outputResult(outputName+"-"+dependencyGenerator.getType(), outputDir, outputFormat);
}
DependencyDumper output = new DependencyDumper(matrix);
output.outputResult(outputName,outputDir,outputFormat);
if (app.isOutputExternalDependencies()) {
if (args.isOutputExternalDependencies()) {
Set<UnsolvedBindings> unsolved = langProcessor.getExternalDependencies();
UnsolvedSymbolDumper unsolvedSymbolDumper = new UnsolvedSymbolDumper(unsolved,app.getOutputName(),app.getOutputDir(),
new LeadingNameStripper(app.isStripLeadingPath(),inputDir,app.getStrippedPaths()));
UnsolvedSymbolDumper unsolvedSymbolDumper = new UnsolvedSymbolDumper(unsolved,args.getOutputName(),args.getOutputDir(),
new LeadingNameStripper(args.isStripLeadingPath(),inputDir,args.getStrippedPaths()));
unsolvedSymbolDumper.output();
}
long endTime = System.currentTimeMillis();
@ -135,14 +143,21 @@ public class Main {
CacheManager.create().shutdown();
System.out.println("Consumed time: " + (float) ((endTime - startTime) / 1000.00) + " s, or "
+ (float) ((endTime - startTime) / 60000.00) + " min.");
if ( app.isDv8map()) {
if ( args.isDv8map()) {
DV8MappingFileBuilder dv8MapfileBuilder = new DV8MappingFileBuilder(langProcessor.supportedRelations());
dv8MapfileBuilder.create(outputDir+ File.separator+"depends-dv8map.mapping");
}
}
private static DependencyGenerator getDependencyGenerator(DependsCommand app, String inputDir) throws ParameterException {
private static String[] appendAllFoldersToIncludePath(String inputDir, String[] includeDir) {
FolderCollector includePathCollector = new FolderCollector();
List<String> additionalIncludePaths = includePathCollector.getFolders(inputDir);
additionalIncludePaths.addAll(Arrays.asList(includeDir));
includeDir = additionalIncludePaths.toArray(new String[] {});
return includeDir;
}
private static List<DependencyGenerator> getDependencyGenerators(DependsCommand app, String inputDir) throws ParameterException {
FilenameWritter filenameWritter = new EmptyFilenameWritter();
if (!StringUtils.isEmpty(app.getNamePathPattern())) {
if (app.getNamePathPattern().equals("dot")||
@ -159,34 +174,30 @@ public class Main {
}
}
/* by default use file dependency generator */
DependencyGenerator dependencyGenerator = new FileDependencyGenerator();
if (!StringUtils.isEmpty(app.getGranularity())) {
List<DependencyGenerator> dependencyGenerators = new ArrayList<>();
for (int i=0;i<app.getGranularity().length;i++) {
/* by default use file dependency generator */
DependencyGenerator dependencyGenerator = null;
/* method parameter means use method generator */
if (app.getGranularity().equals("method"))
if (app.getGranularity()[i].equals("method"))
dependencyGenerator = new FunctionDependencyGenerator();
else if (app.getGranularity().equals("structure"))
else if (app.getGranularity()[i].equals("file"))
dependencyGenerator = new FileDependencyGenerator();
else if (app.getGranularity()[i].equals("structure"))
dependencyGenerator = new StructureDependencyGenerator();
else if (app.getGranularity().equals("file"))
/*no action*/;
else if (app.getGranularity().startsWith("L"))
/*no action*/;
else
throw new ParameterException("Unknown granularity parameter:" + app.getGranularity());
}
if (app.isStripLeadingPath() ||
app.getStrippedPaths().length>0) {
dependencyGenerator.setLeadingStripper(new LeadingNameStripper(app.isStripLeadingPath(), inputDir, app.getStrippedPaths()));
dependencyGenerators.add(dependencyGenerator);
if (app.isStripLeadingPath() ||
app.getStrippedPaths().length > 0) {
dependencyGenerator.setLeadingStripper(new LeadingNameStripper(app.isStripLeadingPath(), inputDir, app.getStrippedPaths()));
}
if (app.isDetail()) {
dependencyGenerator.setGenerateDetail(true);
}
dependencyGenerator.setOutputSelfDependencies(app.isOutputSelfDependencies());
dependencyGenerator.setFilenameRewritter(filenameWritter);
}
if (app.isDetail()) {
dependencyGenerator.setGenerateDetail(true);
}
dependencyGenerator.setFilenameRewritter(filenameWritter);
return dependencyGenerator;
return dependencyGenerators;
}
}

View File

@ -40,13 +40,14 @@ public class DependencyType {
public static final String CREATE = "Create";
public static final String CAST = "Cast";
public static final String THROW = "Throw";
public static final String IMPLLINK = "ImplLink";
public static final String LINK = "Link";
public static final String ANNOTATION = "Annotation";
public static final String MIXIN = "MixIn";
public static final String PomParent = "Parent";
public static final String PomPlugin = "Plugin";
public static final String PomDependency = "Dependency";
public static final String POSSIBLE_DEP = "(possible)";
public static ArrayList<String> allDependencies() {
ArrayList<String> depedencyTypes = new ArrayList<String>();
@ -65,7 +66,7 @@ public class DependencyType {
depedencyTypes.add(THROW);
depedencyTypes.add(ANNOTATION);
depedencyTypes.add(MIXIN);
depedencyTypes.add(IMPLLINK);
depedencyTypes.add(LINK);
depedencyTypes.add(PomParent);
depedencyTypes.add(PomPlugin);
depedencyTypes.add(PomDependency);

View File

@ -145,7 +145,7 @@ public abstract class Entity {
deduceQualifiedName();
}
public final String getQualifiedName() {
public String getQualifiedName() {
return qualifiedName;
}

View File

@ -113,15 +113,25 @@ public class Expression implements Serializable{
}
//referer referredEntity -- TODO:maybe not require
if (this.referredEntityId!=null && this.referredEntity==null)
if (this.referredEntityId!=null && this.referredEntity==null) {
this.referredEntity = repo.getEntity(this.referredEntityId);
if (this.referredEntity ==null){
System.err.println("unexpected: referred Entity is null" + this.referredEntityId + this.text+this.id);
}
}
}
/**
* Set type of the expression
* @param type
* @param referredEntity
* @param bindingResolver
* if it is already has type, it will skip
* if it is already referered entity, it will skip
* if the type changed, parent expression will be re-caculated
* For dynamic type language, return type or parameters, variables may depends on the expression type,
* so once we get the type of expression, we will assign type to them.
*
* @param type the type of the expression
* @param referredEntity the entity of the expression point to, which is used to calculate dependency relation
* @param bindingResolver a parameter which will be passed to deduced parent type
*/
public void setType(TypeEntity type, Entity referredEntity, IBindingResolver bindingResolver) {
if (this.getReferredEntity()==null && referredEntity!=null) {
@ -131,6 +141,7 @@ public class Expression implements Serializable{
boolean changedType = false;
if (this.type==null && type!=null) {
this.type = type;
changedType = true;
for (VarEntity var:deducedTypeVars) {
if (var!=null) {
var.setType(this.type);
@ -141,7 +152,6 @@ public class Expression implements Serializable{
func.addReturnType(this.type);
}
}
changedType = true;
}
if (this.referredEntity==null)
this.setReferredEntity(this.type);
@ -153,6 +163,7 @@ public class Expression implements Serializable{
/**
* deduce type of parent based on child's type
*
* @param bindingResolver
*/
private void deduceTheParentType(IBindingResolver bindingResolver) {
@ -178,24 +189,7 @@ public class Expression implements Serializable{
else if (parent.isDot) {
if (parent.isCall()) {
List<Entity> funcs = this.getType().lookupFunctionInVisibleScope(parent.identifier);
if (funcs!=null) {
//funcs = funcs.stream().filter(item->!(item instanceof MultiDeclareEntities)).collect(Collectors.toList());
if (funcs.size()>0) {
Entity func = funcs.get(0);
if (funcs.size()>1) {
MultiDeclareEntities m = new MultiDeclareEntities(func, bindingResolver.getRepo().generateId());
bindingResolver.getRepo().add(m);
for (int i=1;i<funcs.size();i++) {
m.add(funcs.get(i));
}
parent.setType(func.getType(), m, bindingResolver);
parent.setReferredEntity(m);
}else {
parent.setType(func.getType(), func, bindingResolver);
parent.setReferredEntity(func);
}
}
}
parent.setReferredFunctions(bindingResolver, funcs);
}else {
Entity var = this.getType().lookupVarInVisibleScope(parent.identifier);
if (var!=null) {
@ -203,22 +197,7 @@ public class Expression implements Serializable{
parent.setReferredEntity(var);
}else {
List<Entity> funcs = this.getType().lookupFunctionInVisibleScope(parent.identifier);
if (funcs!=null) {
Entity func = funcs.get(0);
if (funcs.size()>1) {
MultiDeclareEntities m = new MultiDeclareEntities(func, bindingResolver.getRepo().generateId());
bindingResolver.getRepo().add(m);
for (int i=1;i<funcs.size();i++) {
m.add(funcs.get(i));
}
parent.setType(func.getType(), m, bindingResolver);
parent.setReferredEntity(m);
}else {
parent.setType(func.getType(), func, bindingResolver);
parent.setReferredEntity(func);
}
}
parent.setReferredFunctions(bindingResolver,funcs);
}
}
if (parent.getType()==null) {
@ -233,6 +212,33 @@ public class Expression implements Serializable{
parent.setReferredEntity(parent.type);
}
/**
* set expr's referred entity to functions
* why do not use 'setReferredEntity' directly?
* in case of multiple functions, we should first construct a multi-declare entities object,
* than set the type to multi-declare entity, for future resolver,
* for example in duck typing case:
* conn.send().foo, if conn is mutiple type (A, B), send should be search in both A and B
* @param bindingResolver
* @param funcs
*/
private void setReferredFunctions(IBindingResolver bindingResolver, List<Entity> funcs) {
if (funcs ==null ||funcs.size()==0) return;
Entity func = funcs.get(0);
if (funcs.size()==1){
setType(func.getType(), func, bindingResolver);
setReferredEntity(func);
return;
}
MultiDeclareEntities m = new MultiDeclareEntities(func, bindingResolver.getRepo().generateId());
bindingResolver.getRepo().add(m);
for (int i = 1; i< funcs.size(); i++) {
m.add(funcs.get(i));
}
setType(func.getType(), m, bindingResolver);
setReferredEntity(m);
}
private void setReferredEntity(Entity referredEntity) {
this.referredEntity = referredEntity;
if (this.referredEntity!=null) {
@ -240,11 +246,19 @@ public class Expression implements Serializable{
}
}
/**
* remember the vars depends on the expression type
* @param var
*/
public void addDeducedTypeVar(VarEntity var) {
this.deducedTypeVars.add(var);
this.deducedTypeVarsId.add(var.getId());
}
/**
* remember the functions depends on the expression type
* @param var
*/
public void addDeducedTypeFunction(FunctionEntity function) {
this.deducedTypeFunctions.add(function);
this.deducedTypeFunctionsId.add(function.id);

View File

@ -37,16 +37,20 @@ public class FileEntity extends TypeEntity {
private Collection<Entity> importedTypes = new ArrayList<>();
private List<TypeEntity> declaredTypes = new ArrayList<>();
private ImportedFileCollector importedFileCollector = null;
private boolean fileAsModule = false;
private String moduleName = "";
public FileEntity() {}
public FileEntity(String fullName, int fileId, boolean isInProjectScope) {
public FileEntity(boolean fileAsModule,String fullName, int fileId, boolean isInProjectScope) {
super(GenericName.build(fullName), null, fileId);
setQualifiedName(fullName);
this.isInProjectScope = isInProjectScope;
this.fileAsModule = fileAsModule;
}
public FileEntity(String fullName, int fileId) {
this(fullName, fileId, true);
public FileEntity(boolean fileAsModule,String fullName, int fileId) {
this(fileAsModule,fullName, fileId, true);
}
public void addImport(Import imported) {
@ -74,20 +78,26 @@ public class FileEntity extends TypeEntity {
}
return null;
}
@Override
public String getQualifiedName(boolean overrideFileWithPackage) {
if (!overrideFileWithPackage) {
return super.getQualifiedName();
}
if (this.getParent() == null) {
if (this.getParent() == null ||
!(this.getParent() instanceof PackageEntity)) {
if (fileAsModule){
return super.getQualifiedName();
}
return "";
}
if (this.getParent() instanceof PackageEntity)
//parent is PackageEntity
if (!fileAsModule) {
return this.getParent().getQualifiedName();
else
return super.getQualifiedName();
}else {
if (moduleName==null || moduleName.equals("")){
return this.getParent().getQualifiedName();
}
return this.getParent().getQualifiedName() + "." +moduleName;
}
}
@Override
@ -166,4 +176,7 @@ public class FileEntity extends TypeEntity {
}
}
public void setModuleName(String moduleName) {
this.moduleName = moduleName;
}
}

View File

@ -24,13 +24,13 @@ SOFTWARE.
package depends.entity;
import depends.relations.IBindingResolver;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import depends.relations.IBindingResolver;
/**
* MultiDeclareEntity is a special container, which is used as a wrapper
* of multi-declaration. for example,
@ -57,8 +57,11 @@ public class MultiDeclareEntities extends ContainerEntity {
entity.setMutliDeclare(this);
if (entity instanceof TypeEntity)
this.containsTypeEntity = true;
entities.add(entity);
if (entity instanceof MultiDeclareEntities){
((MultiDeclareEntities)entity).entities.forEach(e->add(e));
}else {
entities.add(entity);
}
}
public List<Entity> getEntities() {

View File

@ -33,12 +33,17 @@ import java.util.Set;
public abstract class BuiltInType {
public void createBuiltInTypes() {
for(String prefix:getBuiltInPrefixStr()) {
public BuiltInType(){
createBuiltInTypes();
}
/**
* Init the build in types data
*/
private void createBuiltInTypes() {
for(String prefix: getBuiltInTypePrefix()) {
builtInPrefix.add(prefix);
}
for (String type:getBuiltInTypeStr()) {
for (String type: getBuiltInTypeName()) {
builtInType.add(type);
}
for (String method:getBuiltInMethods()) {
@ -46,31 +51,58 @@ public abstract class BuiltInType {
}
}
public abstract String[] getBuiltInMethods();
public abstract String[] getBuiltInTypeStr();
public abstract String[] getBuiltInPrefixStr() ;
protected String[] getBuiltInMethods(){return new String[]{};}
protected String[] getBuiltInTypeName(){return new String[]{};}
protected String[] getBuiltInTypePrefix() {return new String[]{};}
private Set<String> builtInType = new HashSet<>();
private Set<String> builtInPrefix = new HashSet<>();
private Set<String> builtInMethod = new HashSet<>();
public boolean isBuiltInType(String type) {
if (TypeEntity.buildInType.getRawName().uniqName().equals(type)) return true;
return builtInType.contains(type);
/**
* To determine whether a type name is built-in
* @param typeName
* @return
*/
public boolean isBuiltInType(String typeName) {
return TypeEntity.buildInType.getRawName().uniqName().equals(typeName) ||
builtInType.contains(typeName)||
isBuiltInTypePrefix(typeName);
}
public boolean isBuiltInTypePrefix(String type) {
/**
* To determine a typeName is a built-in type based on prefix.
* For example, in Java language, name start with java.*, javax.*, com.sun.*
* is build-in types
* @param typeName
* @return
*/
private boolean isBuiltInTypePrefix(String typeName) {
for (String prefix:builtInPrefix) {
if (type.startsWith(prefix)) return true;
if (typeName.startsWith(prefix)) return true;
}
return false;
}
/**
* In some language, there are common methods, like in ruby,
* object_id is a method for all type
* @param name
* @return
*/
public boolean isBuildInMethod(String name) {
return builtInMethod.contains(name);
}
/**
* Used by duck typing deduce feature:
* - if all calls of a type are build in method,
* then no duck typing is deduced
* Refer to Python built-in type for example
*
* @param functionCalls
* @return
*/
public boolean isBuildInTypeMethods(List<FunctionCall> functionCalls) {
return false;
}

View File

@ -50,7 +50,9 @@ public interface EntityRepo extends IdGenerator {
Iterator<Entity> sortedFileIterator();
void addFile(FileEntity currentFileEntity);
void clear();
FileEntity getFileEntity(String fileFullPath);
void completeFile(String fileFullPath);
}

View File

@ -1,9 +1,7 @@
package depends.entity.repo;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.GenericName;
import depends.entity.MultiDeclareEntities;
import depends.entity.*;
import multilang.depends.util.file.FileUtil;
import java.util.*;
import java.util.Map.Entry;
@ -38,6 +36,7 @@ public class InMemoryEntityRepo extends SimpleIdGenerator implements EntityRepo
allEntieisByName = new TreeMap<>();
allEntitiesById = new TreeMap<>();
allFileEntitiesByOrder = new LinkedList<>();
add(TypeEntity.buildInType);
}
@Override
@ -98,15 +97,37 @@ public class InMemoryEntityRepo extends SimpleIdGenerator implements EntityRepo
return allFileEntitiesByOrder.iterator();
}
@Override
public void addFile(FileEntity fileEntity) {
allFileEntitiesByOrder.add(fileEntity);
}
@Override
public void clear() {
allEntieisByName.clear();
allEntitiesById.clear();
allFileEntitiesByOrder.clear();
}
@Override
public FileEntity getFileEntity(String fileFullPath) {
fileFullPath = FileUtil.uniqFilePath(fileFullPath);
Entity entity = this.getEntity(fileFullPath);
if (entity ==null) return null;
if (entity instanceof FileEntity) return (FileEntity) entity;
if (entity instanceof MultiDeclareEntities){
MultiDeclareEntities multiDeclare = (MultiDeclareEntities) entity;
for (Entity theEntity: multiDeclare.getEntities()){
if (theEntity instanceof FileEntity){
return (FileEntity) theEntity;
}
}
}
return null;
}
@Override
public void completeFile(String fileFullPath) {
FileEntity fileEntity = getFileEntity(fileFullPath);
// in case of parse error(throw exception), the file entity may not exists
if (fileEntity!=null) {
fileEntity.cacheAllExpressions();
allFileEntitiesByOrder.add(fileEntity);
}
}
}

View File

@ -1,42 +0,0 @@
/*
MIT License
Copyright (c) 2018-2019 Gang ZHANG
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
package depends.entity.repo;
public class NullBuiltInType extends BuiltInType {
@Override
public String[] getBuiltInTypeStr() {
return new String[] {};
}
@Override
public String[] getBuiltInPrefixStr() {
return new String[] {};
}
@Override
public String[] getBuiltInMethods() {
return new String[]{};
}
}

View File

@ -81,7 +81,7 @@ abstract public class AbstractLangProcessor {
* @param fileFullPath
* @return
*/
public abstract FileParser createFileParser(String fileFullPath);
public abstract FileParser createFileParser();
public IBindingResolver bindingResolver;
protected EntityRepo entityRepo;
@ -138,8 +138,6 @@ abstract public class AbstractLangProcessor {
}
/**
*
* @param callAsImpl
* @return unsolved bindings
*/
public void resolveBindings() {
@ -160,32 +158,30 @@ abstract public class AbstractLangProcessor {
@Override
public void visit(File file) {
String fileFullPath = file.getAbsolutePath();
fileFullPath = FileUtil.uniqFilePath(fileFullPath);
if (!fileFullPath.startsWith(inputSrcPath)) {
return;
}
if (isPhase2Files(fileFullPath)) {
} else {
parseFile(fileFullPath);
}
parseFile(fileFullPath, phase2Files);
}
});
fileTransversal.extensionFilter(this.fileSuffixes());
fileTransversal.travers(this.inputSrcPath);
for (String f : phase2Files) {
parseFile(f);
parseFile(f, phase2Files);
}
System.out.println("all files procceed successfully...");
}
protected void parseFile(String fileFullPath) {
FileParser fileParser = createFileParser(fileFullPath);
protected void parseFile(String fileFullPath, Set<String> phase2Files) {
FileParser fileParser = createFileParser();
try {
System.out.println("parsing " + fileFullPath + "...");
fileParser.parse();
if (fileParser.isPhase2Files(fileFullPath)){
phase2Files.add(fileFullPath);
}else {
fileParser.parse(fileFullPath);
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
@ -194,10 +190,6 @@ abstract public class AbstractLangProcessor {
}
}
protected boolean isPhase2Files(String fileFullPath) {
return false;
}
public List<String> includePaths() {
if (this.includePaths ==null) {
this.includePaths = buildIncludePath();
@ -239,7 +231,18 @@ abstract public class AbstractLangProcessor {
return relation;
}
/**
* Whether to resolve expression immediately during parse
* @return
*/
public boolean isEagerExpressionResolve(){
return false;
}
/**
* Call as Impl:
* implicit call (for example polymorphic in cpp)
* @return
*/
public boolean supportCallAsImpl(){return false;};
}

View File

@ -24,9 +24,44 @@ SOFTWARE.
package depends.extractor;
import depends.entity.FileEntity;
import depends.entity.repo.EntityRepo;
import multilang.depends.util.file.FileUtil;
import java.io.IOException;
public interface FileParser {
void parse() throws IOException;
public abstract class FileParser {
protected EntityRepo entityRepo;
/**
* parse files
* @param filePath
* @throws IOException
*/
public final void parse(String filePath) throws IOException{
filePath = FileUtil.uniqFilePath(filePath);
/* If file already exist, skip it */
FileEntity fileEntity = entityRepo.getFileEntity(filePath);
if (fileEntity!=null) {
System.out.println("already parsed " + filePath + "...skip");
if (!fileEntity.isInProjectScope())
fileEntity.setInProjectScope(true);
}else {
System.out.println("parsing " + filePath + "...");
parseFile(filePath);
entityRepo.completeFile(filePath);
}
}
/**
* The actual file parser - it should put parsed entities into entityRepo;
* @param filePath - it is alread unique file path name
* @throws IOException
*/
protected abstract void parseFile(String filePath) throws IOException;
protected boolean isPhase2Files(String filePath){
return false;
}
}

View File

@ -50,17 +50,13 @@ public abstract class HandlerContext {
this.bindingResolver = bindingResolver;
}
public FileEntity startFile(String fileName) {
currentFileEntity = new FileEntity(fileName, idGenerator.generateId(),true);
public FileEntity startFile(boolean fileAsModule, String fileName) {
currentFileEntity = new FileEntity(fileAsModule, fileName, idGenerator.generateId(),true);
pushToStack(currentFileEntity);
addToRepo(currentFileEntity);
return currentFileEntity;
}
public void done() {
entityRepo.addFile(this.currentFile());
}
public TypeEntity foundNewType(GenericName name, Integer startLine) {
TypeEntity currentTypeEntity = new TypeEntity(name, this.latestValidContainer(),
idGenerator.generateId());
@ -290,6 +286,7 @@ public abstract class HandlerContext {
if (currentFunction()==null) return null;
VarEntity varEntity = new VarEntity(GenericName.build(paramName),null,currentFunction(),idGenerator.generateId());
currentFunction().addParameter(varEntity);
addToRepo(varEntity);
return varEntity;
}
@ -314,8 +311,13 @@ public abstract class HandlerContext {
private VarEntity getVarInLocalFile(ContainerEntity container, GenericName varName) {
Entity entity = bindingResolver.resolveName(container, varName, false);
if (entity ==null ) return null;
if (!entity.getAncestorOfType(FileEntity.class).equals(currentFileEntity)) return null;
if (entity instanceof VarEntity) return (VarEntity)entity;
Entity fileEntity = entity.getAncestorOfType(FileEntity.class);
if (fileEntity ==null ){
//may not exist in fileEntity, for example global vars
}else{
if (!fileEntity.equals(currentFileEntity)) return null;
if (entity instanceof VarEntity) return (VarEntity)entity;
}
return null;
}

View File

@ -22,18 +22,31 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
package depends.extractor.ruby;
package depends.extractor;
import multilang.depends.util.file.FileUtil;
import java.io.File;
import java.util.List;
import multilang.depends.util.file.FileUtil;
public class IncludedFileLocator {
/**
* Search file in all included path
*/
public final class IncludedFileLocator {
private List<String> includesPath;
public IncludedFileLocator(List<String> includedPath) {
this.includesPath = includedPath;
}
/**
* Search file in all included path
* * search the filename directly
* * search the filename based in given start path (usually current working directory
* * search the filename in all included paths
* @param dirPath
* @param importedFilename
* @return
*/
public String uniqFileName(String dirPath, String importedFilename) {
if (FileUtil.existFile(importedFilename)) return FileUtil.uniqFilePath(importedFilename);
if (dirPath!=null) {

View File

@ -26,6 +26,6 @@ package depends.extractor;
public interface ParserCreator {
FileParser createFileParser(String src);
FileParser createFileParser();
}

View File

@ -28,12 +28,8 @@ import depends.entity.repo.BuiltInType;
public class CppBuiltInType extends BuiltInType {
public CppBuiltInType() {
super.createBuiltInTypes();
}
@Override
public String[] getBuiltInTypeStr() {
protected String[] getBuiltInTypeName() {
return new String[] { "alignas", "alignof", "asm", "auto", "bool", "break", "case", "catch", "char",
"char16_t", "char32_t", "class", "const", "constexpr", "const_cast", "continue", "decltype",
"default", "delete", "do", "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern",
@ -64,12 +60,7 @@ public class CppBuiltInType extends BuiltInType {
}
@Override
public String[] getBuiltInPrefixStr() {
protected String[] getBuiltInTypePrefix() {
return new String[] {"__"};
}
@Override
public String[] getBuiltInMethods() {
return new String[]{};
}
}

View File

@ -26,13 +26,8 @@ package depends.extractor.cpp;
import depends.entity.repo.EntityRepo;
public abstract class CppFileParser implements depends.extractor.FileParser {
protected String fileFullPath;
protected EntityRepo entityRepo;
public CppFileParser(String fileFullPath, EntityRepo entityRepo) {
this.fileFullPath = fileFullPath;
public abstract class CppFileParser extends depends.extractor.FileParser {
public CppFileParser(EntityRepo entityRepo) {
this.entityRepo = entityRepo;
}
}

View File

@ -64,9 +64,8 @@ public class CppHandlerContext extends HandlerContext {
}
@Override
public FileEntity startFile(String fileName) {
currentFileEntity = new FileEntity(fileName, idGenerator.generateId(),true);
currentFileEntity = new FileEntity(false, fileName, idGenerator.generateId(),true);
pushToStack(currentFileEntity);
entityRepo.add(currentFileEntity);
return currentFileEntity;

View File

@ -58,7 +58,7 @@ public class CppProcessor extends AbstractLangProcessor {
}
@Override
public FileParser createFileParser(String fileFullPath) {
public FileParser createFileParser() {
if (macroRepo == null) {
macroRepo = new MacroEhcacheRepo(entityRepo);
macroRepo.buildDefaultMap(super.includePaths());
@ -66,7 +66,7 @@ public class CppProcessor extends AbstractLangProcessor {
if (preprocessorHandler==null) {
preprocessorHandler = new PreprocessorHandler(super.inputSrcPath,super.includePaths());
}
return new CdtCppFileParser(fileFullPath, entityRepo, preprocessorHandler, bindingResolver, macroRepo);
return new CdtCppFileParser(entityRepo, preprocessorHandler, bindingResolver, macroRepo);
}
@Override
@ -94,16 +94,12 @@ public class CppProcessor extends AbstractLangProcessor {
depedencyTypes.add(USE);
depedencyTypes.add(CAST);
depedencyTypes.add(THROW);
depedencyTypes.add(IMPLLINK);
depedencyTypes.add(LINK);
return depedencyTypes;
}
@Override
protected boolean isPhase2Files(String fileFullPath) {
if (fileFullPath.endsWith(".h") || fileFullPath.endsWith(".hh") || fileFullPath.endsWith(".hpp")
|| fileFullPath.endsWith(".hxx"))
return true;
return false;
public boolean supportCallAsImpl() {
return true;
}
}

View File

@ -24,13 +24,10 @@ SOFTWARE.
package depends.extractor.cpp.cdt;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.cpp.CppFileParser;
import depends.extractor.cpp.MacroRepo;
import depends.relations.IBindingResolver;
import multilang.depends.util.file.FileUtil;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import java.io.IOException;
@ -38,22 +35,20 @@ import java.util.HashMap;
import java.util.Map;
public class CdtCppFileParser extends CppFileParser {
private PreprocessorHandler preprocessorHandler ;
private IBindingResolver bindingResolver;
private MacroRepo macroRepo;
public CdtCppFileParser(String fileFullPath, EntityRepo entityRepo, PreprocessorHandler preprocessorHandler, IBindingResolver bindingResolver, MacroRepo macroRepo) {
super(fileFullPath, entityRepo);
public CdtCppFileParser(EntityRepo entityRepo, PreprocessorHandler preprocessorHandler, IBindingResolver bindingResolver, MacroRepo macroRepo) {
super(entityRepo);
this.preprocessorHandler = preprocessorHandler;
this.fileFullPath = FileUtil.uniqFilePath(fileFullPath);
this.bindingResolver = bindingResolver;
this.macroRepo= macroRepo;
}
@Override
public void parse() throws IOException {
protected void parseFile(String fileFullPath) throws IOException {
Map<String, String> macroMap = new HashMap<>(macroRepo.getDefaultMap());
parse(true,macroMap);
parse(fileFullPath,macroMap);
}
/**
@ -61,24 +56,13 @@ public class CdtCppFileParser extends CppFileParser {
* @param isInScope whether the parse is invoked by project file or an 'indirect' included file
* @return
*/
public void parse(boolean isInScope,Map<String, String> macroMap) {
/** If file already exist, skip it */
Entity fileEntity = entityRepo.getEntity(fileFullPath);
if (fileEntity!=null && fileEntity instanceof FileEntity) {
FileEntity t = ((FileEntity)fileEntity);
if (!t.isInProjectScope() && isInScope)
t.setInProjectScope(true);
return;
}
if (fileFullPath.contains("regex.h")){
System.out.println("stop");
}
public void parse(String fileFullPath,Map<String, String> macroMap) throws IOException {
CppVisitor bridge = new CppVisitor(fileFullPath, entityRepo, preprocessorHandler, bindingResolver);
IASTTranslationUnit tu = (new CDTParser(preprocessorHandler.getIncludePaths())).parse(fileFullPath,macroMap);
boolean containsIncludes = false;
for (String incl:preprocessorHandler.getDirectIncludedFiles(tu.getAllPreprocessorStatements(),fileFullPath)) {
CdtCppFileParser importedParser = new CdtCppFileParser(incl, entityRepo, preprocessorHandler, bindingResolver,macroRepo);
importedParser.parse(false,macroMap);
CdtCppFileParser importedParser = new CdtCppFileParser(entityRepo, preprocessorHandler, bindingResolver,macroRepo);
importedParser.parse(incl);
Map<String, String> macros = macroRepo.get(incl);
if (macros!=null)
macroMap.putAll(macros);
@ -87,12 +71,16 @@ public class CdtCppFileParser extends CppFileParser {
if (containsIncludes) {
tu = (new CDTParser(preprocessorHandler.getIncludePaths())).parse(fileFullPath,macroMap);
}
macroRepo.putMacros(this.fileFullPath,macroMap,tu.getMacroDefinitions());
macroRepo.putMacros(fileFullPath,macroMap,tu.getMacroDefinitions());
tu.accept(bridge);
fileEntity = entityRepo.getEntity(fileFullPath);
((FileEntity)fileEntity).cacheAllExpressions();
bridge.done();
return;
}
@Override
protected boolean isPhase2Files(String fileFullPath) {
if (fileFullPath.endsWith(".h") || fileFullPath.endsWith(".hh") || fileFullPath.endsWith(".hpp")
|| fileFullPath.endsWith(".hxx"))
return true;
return false;
}
}

View File

@ -335,8 +335,4 @@ public class CppVisitor extends ASTVisitor {
}
return super.visit(parameterDeclaration);
}
public void done() {
context.done();
}
}

View File

@ -27,19 +27,4 @@ package depends.extractor.empty;
import depends.entity.repo.BuiltInType;
public class EmptyBuiltInType extends BuiltInType {
@Override
public String[] getBuiltInMethods() {
return new String[] {};
}
@Override
public String[] getBuiltInTypeStr() {
return new String[] {};
}
@Override
public String[] getBuiltInPrefixStr() {
return new String[] {};
}
}

View File

@ -28,12 +28,8 @@ import depends.entity.repo.BuiltInType;
public class GoBuiltInType extends BuiltInType {
public GoBuiltInType() {
super.createBuiltInTypes();
}
@Override
public String[] getBuiltInTypeStr() {
protected String[] getBuiltInTypeName() {
return new String[]{
"<Built-in>",
"break", "default", "func", "interface",
@ -49,16 +45,4 @@ public class GoBuiltInType extends BuiltInType {
"_"
};
}
@Override
public String[] getBuiltInPrefixStr() {
return new String[]{
};
}
@Override
public String[] getBuiltInMethods() {
return new String[]{};
}
}

View File

@ -40,19 +40,16 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.IOException;
public class GoFileParser implements depends.extractor.FileParser{
private String fileFullPath;
private EntityRepo entityRepo;
public class GoFileParser extends depends.extractor.FileParser{
private IBindingResolver bindingResolver;
public GoFileParser(String fileFullPath, EntityRepo entityRepo, IBindingResolver bindingResolver) {
this.fileFullPath = fileFullPath;
public GoFileParser(EntityRepo entityRepo, IBindingResolver bindingResolver) {
this.entityRepo = entityRepo;
this.bindingResolver = bindingResolver;
}
@Override
public void parse() throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
protected void parseFile(String fileFullPath) throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
Lexer lexer = new GoLexer(input);
lexer.setInterpreter(new LexerATNSimulator(lexer, lexer.getATN(), lexer.getInterpreter().decisionToDFA, new PredictionContextCache()));
CommonTokenStream tokens = new CommonTokenStream(lexer);

View File

@ -25,6 +25,7 @@ SOFTWARE.
package depends.extractor.golang;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.PackageEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.HandlerContext;
@ -46,4 +47,7 @@ public class GoHandlerContext extends HandlerContext {
return pkgEntity;
}
public FileEntity startFile(String fileName) {
return super.startFile(false, fileName);
}
}

View File

@ -52,8 +52,8 @@ public class GoProcessor extends AbstractLangProcessor {
}
@Override
public FileParser createFileParser(String fileFullPath) {
return new GoFileParser(fileFullPath, entityRepo, bindingResolver);
public FileParser createFileParser() {
return new GoFileParser( entityRepo, bindingResolver);
}
@Override
@ -81,7 +81,7 @@ public class GoProcessor extends AbstractLangProcessor {
depedencyTypes.add(USE);
depedencyTypes.add(CAST);
depedencyTypes.add(THROW);
depedencyTypes.add(IMPLLINK);
depedencyTypes.add(LINK);
return depedencyTypes;
}

View File

@ -28,11 +28,8 @@ import depends.entity.repo.BuiltInType;
public class JavaBuiltInType extends BuiltInType{
public JavaBuiltInType() {
super.createBuiltInTypes();
}
@Override
public String[] getBuiltInTypeStr() {
protected String[] getBuiltInTypeName() {
return new String[]{
"void","int","double","char","byte","boolean","long","short","float",
"BigDecimal","Integer","Double","Char","Byte","Boolean","Long","Short","Float",
@ -79,14 +76,9 @@ public class JavaBuiltInType extends BuiltInType{
};
}
@Override
public String[] getBuiltInPrefixStr() {
protected String[] getBuiltInTypePrefix() {
return new String[]{
"java.","javax.","com.sun."
};
}
@Override
public String[] getBuiltInMethods() {
return new String[]{};
}
}

View File

@ -24,9 +24,8 @@ SOFTWARE.
package depends.extractor.java;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.FileParser;
import depends.relations.IBindingResolver;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
@ -40,19 +39,16 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.IOException;
public class JavaFileParser implements depends.extractor.FileParser{
private String fileFullPath;
private EntityRepo entityRepo;
public class JavaFileParser extends FileParser {
private IBindingResolver bindingResolver;
public JavaFileParser(String fileFullPath,EntityRepo entityRepo, IBindingResolver bindingResolver) {
this.fileFullPath = fileFullPath;
public JavaFileParser(EntityRepo entityRepo, IBindingResolver bindingResolver) {
this.entityRepo = entityRepo;
this.bindingResolver = bindingResolver;
}
@Override
public void parse() throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
protected void parseFile(String fileFullPath) throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
Lexer lexer = new JavaLexer(input);
lexer.setInterpreter(new LexerATNSimulator(lexer, lexer.getATN(), lexer.getInterpreter().decisionToDFA, new PredictionContextCache()));
CommonTokenStream tokens = new CommonTokenStream(lexer);
@ -63,11 +59,8 @@ public class JavaFileParser implements depends.extractor.FileParser{
ParseTreeWalker walker = new ParseTreeWalker();
try {
walker.walk(bridge, parser.compilationUnit());
Entity fileEntity = entityRepo.getEntity(fileFullPath);
((FileEntity)fileEntity).cacheAllExpressions();
interpreter.clearDFA();
bridge.done();
}catch (Exception e) {
System.err.println("error encountered during parse..." );
e.printStackTrace();

View File

@ -25,6 +25,7 @@ SOFTWARE.
package depends.extractor.java;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.PackageEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.HandlerContext;
@ -46,6 +47,8 @@ public class JavaHandlerContext extends HandlerContext {
return pkgEntity;
}
public FileEntity startFile(String fileName) {
return super.startFile(false, fileName);
}
}

View File

@ -334,9 +334,4 @@ public class JavaListener extends JavaParserBaseListener {
context.currentType().addTypeParameter(GenericName.build(typeParam.IDENTIFIER().getText()));
}
}
public void done() {
context.done();
}
}

View File

@ -51,8 +51,8 @@ public class JavaProcessor extends AbstractLangProcessor {
}
@Override
public FileParser createFileParser(String fileFullPath) {
return new JavaFileParser(fileFullPath,entityRepo, bindingResolver);
public FileParser createFileParser() {
return new JavaFileParser(entityRepo, bindingResolver);
}
@Override

View File

@ -11,24 +11,20 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.IOException;
public class KotlinFileParser implements FileParser {
public class KotlinFileParser extends FileParser {
@Override
public void parse() throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
Lexer lexer = new KotlinLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
KotlinParser parser = new KotlinParser(tokens);
KotlinListener bridge = new KotlinListener(fileFullPath, entityRepo, bindingResolver);
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(bridge, parser.kotlinFile());
protected void parseFile(String fileFullPath) throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
Lexer lexer = new KotlinLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
KotlinParser parser = new KotlinParser(tokens);
KotlinListener bridge = new KotlinListener(fileFullPath, entityRepo, bindingResolver);
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(bridge, parser.kotlinFile());
}
private String fileFullPath;
private EntityRepo entityRepo;
private IBindingResolver bindingResolver;
public KotlinFileParser(String fileFullPath,EntityRepo entityRepo, IBindingResolver bindingResolver) {
this.fileFullPath = fileFullPath;
public KotlinFileParser(EntityRepo entityRepo, IBindingResolver bindingResolver) {
this.entityRepo = entityRepo;
this.bindingResolver = bindingResolver;
}

View File

@ -10,4 +10,5 @@ public class KotlinHandlerContext extends JavaHandlerContext {
super(entityRepo, bindingResolver);
}
}

View File

@ -39,8 +39,8 @@ public class KotlinProcessor extends AbstractLangProcessor {
}
@Override
public FileParser createFileParser(String fileFullPath) {
return new KotlinFileParser(fileFullPath,entityRepo, bindingResolver);
public FileParser createFileParser() {
return new KotlinFileParser(entityRepo, bindingResolver);
}
@Override

View File

@ -24,14 +24,11 @@ SOFTWARE.
package depends.extractor.pom;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.FileParser;
import depends.extractor.xml.XMLLexer;
import depends.extractor.xml.XMLParser;
import depends.relations.IBindingResolver;
import multilang.depends.util.file.FileUtil;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
@ -41,16 +38,12 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.IOException;
import java.util.List;
public class PomFileParser implements FileParser {
private String fileFullPath;
private EntityRepo entityRepo;
public class PomFileParser extends FileParser {
private PomProcessor parseCreator;
private List<String> includePaths;
private IBindingResolver bindingResolver;
public PomFileParser(String fileFullPath, EntityRepo entityRepo, List<String> includePaths, PomProcessor pomProcessor, IBindingResolver bindingResolver) {
this.fileFullPath = FileUtil.uniqFilePath(fileFullPath);
public PomFileParser(EntityRepo entityRepo, List<String> includePaths, PomProcessor pomProcessor, IBindingResolver bindingResolver) {
this.entityRepo = entityRepo;
this.parseCreator = pomProcessor;
this.includePaths = includePaths;
@ -58,13 +51,8 @@ public class PomFileParser implements FileParser {
}
@Override
public void parse() throws IOException {
/* If file already exist, skip it */
Entity fileEntity = entityRepo.getEntity(fileFullPath);
if (fileEntity!=null && fileEntity instanceof FileEntity) {
return;
}
/*parse file*/
protected void parseFile(String fileFullPath) throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
Lexer lexer = new XMLLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
@ -72,9 +60,6 @@ public class PomFileParser implements FileParser {
PomListener bridge = new PomListener(fileFullPath, entityRepo, includePaths,parseCreator, bindingResolver);
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(bridge, parser.document());
fileEntity = entityRepo.getEntity(fileFullPath);
bridge.done();
((FileEntity)fileEntity).cacheAllExpressions();
}
}

View File

@ -24,6 +24,7 @@ SOFTWARE.
package depends.extractor.pom;
import depends.entity.FileEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.HandlerContext;
@ -33,4 +34,7 @@ public class PomHandlerContext extends HandlerContext {
super(entityRepo, null);
}
public FileEntity startFile(String fileName) {
return super.startFile(false, fileName);
}
}

View File

@ -34,6 +34,7 @@ import depends.extractor.xml.XMLParserBaseListener;
import depends.relations.IBindingResolver;
import org.antlr.v4.runtime.ParserRuleContext;
import java.io.IOException;
import java.util.List;
import java.util.Stack;
@ -135,12 +136,11 @@ public class PomListener extends XMLParserBaseListener {
context.currentFile().addImport(pomParent);
String parentFileName = new PomLocator(includePaths, pomParent).getLocation();
if (parentFileName != null) {
FileParser importedParser = parseCreator.createFileParser(parentFileName);
FileParser importedParser = parseCreator.createFileParser();
try {
System.out.println("parsing " + parentFileName);
importedParser.parse();
} catch (Exception e) {
System.err.println("parsing error in " + parentFileName);
importedParser.parse(parentFileName);
} catch (IOException e) {
System.err.println("error occurred during parse "+ parentFileName);
}
}
pomCoords.pop();
@ -162,9 +162,4 @@ public class PomListener extends XMLParserBaseListener {
String name = p.Name().get(0).getText();
return name;
}
public void done() {
context.done();
}
}

View File

@ -60,8 +60,8 @@ public class PomProcessor extends AbstractLangProcessor {
}
@Override
public FileParser createFileParser(String fileFullPath) {
return new PomFileParser(fileFullPath,entityRepo,includePaths(),this, bindingResolver);
public FileParser createFileParser() {
return new PomFileParser(entityRepo,includePaths(),this, bindingResolver);
}
@Override

View File

@ -49,7 +49,12 @@ public abstract class BasePythonProcessor extends AbstractLangProcessor{
depedencyTypes.add(CREATE);
depedencyTypes.add(USE);
depedencyTypes.add(THROW);
depedencyTypes.add(IMPLLINK);
depedencyTypes.add(LINK);
return depedencyTypes;
}
@Override
public boolean supportCallAsImpl() {
return true;
}
}

View File

@ -1,8 +1,5 @@
package depends.extractor.python;
import java.util.ArrayList;
import java.util.List;
import depends.entity.FunctionCall;
import depends.entity.FunctionEntity;
import depends.entity.GenericName;
@ -10,9 +7,13 @@ import depends.entity.TypeEntity;
import depends.entity.repo.BuiltInType;
import depends.relations.FunctionMatcher;
import java.util.ArrayList;
import java.util.List;
public class PythonBuiltInType extends BuiltInType {
public static String[] BUILT_IN_FUNCTIONS = { "abs", "delattr", "hash", "memoryview", "set", "all", "dict", "help",
public static final String PACKAGE_PY_NAME = "__init__.py";
public static String[] BUILT_IN_FUNCTIONS = { "abs", "delattr", "hash", "memoryview", "set", "all", "dict", "help",
"min", "setattr", "any", "dir", "hex", "next", "slice", "exit", "ascii", "divmod", "id", "object", "sorted",
"bin", "enumerate", "input", "oct", "staticmethod", "bool", "eval", "int", "open", "str", "breakpoint",
"exec", "isinstance", "ord", "sum", "bytearray", "filter", "issubclass", "pow", "super", "bytes", "float",
@ -82,25 +83,6 @@ public class PythonBuiltInType extends BuiltInType {
buildInTypes.add(type);
}
@Override
public String[] getBuiltInMethods() {
// TODO Auto-generated method stub
return null;
}
@Override
public String[] getBuiltInTypeStr() {
// TODO Auto-generated method stub
return null;
}
@Override
public String[] getBuiltInPrefixStr() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isBuildInTypeMethods(List<FunctionCall> functionCalls) {
for (TypeEntity type:buildInTypes) {

View File

@ -1,9 +1,6 @@
package depends.extractor.python;
import depends.entity.AliasEntity;
import depends.entity.Entity;
import depends.entity.GenericName;
import depends.entity.PackageEntity;
import depends.entity.*;
import depends.entity.repo.EntityRepo;
import depends.extractor.HandlerContext;
import depends.relations.IBindingResolver;
@ -24,7 +21,7 @@ public class PythonHandlerContext extends HandlerContext {
Entity parent = entity.getParent();
if (parent == null)
return;
if (parent.getRawName().getName().endsWith("__init__.py")) {
if (parent.getRawName().getName().endsWith(PythonBuiltInType.PACKAGE_PY_NAME)) {
Entity packageEntity = parent.getAncestorOfType(PackageEntity.class);
if (packageEntity == null)
return;
@ -50,4 +47,7 @@ public class PythonHandlerContext extends HandlerContext {
return alias;
}
public FileEntity startFile(String fileName) {
return super.startFile(true, fileName);
}
}

View File

@ -5,10 +5,12 @@ import depends.entity.repo.IdGenerator;
import depends.extractor.HandlerContext;
import depends.extractor.python.PythonHandlerContext;
import depends.extractor.python.PythonParser.*;
import depends.extractor.python.PythonParserBaseListener;
import depends.extractor.python.PythonParserBaseVisitor;
import depends.relations.IBindingResolver;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.util.ArrayList;
import java.util.List;
@ -50,6 +52,15 @@ public class ExpressionUsage {
return names;
}
private List<String> getName(List<Testlist_star_exprContext> testlist_star_expr) {
List<String> names = new ArrayList<>();
for (Testlist_star_exprContext expr:testlist_star_expr){
expr.accept(new NameCollector(names));
}
return names;
}
public void foundExpression(ParserRuleContext ctx) {
if (!isStartOfContainerRule(ctx)) {
return ;
@ -79,7 +90,9 @@ public class ExpressionUsage {
expression.setSet(true);
expression.setIdentifier(exprAssign.testlist_star_expr().getText());
if (isValidIdentifier(expression.getIdentifier())) {
makeSureVarExist(expression.getIdentifier(), ctx);
if (!isAlias(exprAssign)){
makeSureVarExist(expression.getIdentifier(), ctx);
}
}
deduceVarTypeInCaseOfAssignment((Expr_stmtContext)ctx,expression);
}
@ -96,6 +109,49 @@ public class ExpressionUsage {
}
private boolean isAlias(Expr_stmtContext exprAssign) {
//if contain arguments, like a = A(), it must be a variable
if (containArguments(exprAssign)){
return false;
}
String theName = exprAssign.testlist_star_expr().getText();
List<String> assignNames = this.getName(exprAssign.assign_part().testlist_star_expr());
if (assignNames.size()==0) return false;
String assignName = namesToDot(assignNames);
Entity type = bindingResolver.resolveName(context.lastContainer(), GenericName.build(assignName),true);
if (type==null)
return false;
if (!(type instanceof TypeEntity))
return false;
context.foundNewAlias(theName,assignName);
return true;
}
private String namesToDot(List<String> assignNames) {
StringBuilder sb = new StringBuilder();
for (String s:assignNames){
if (sb.length()>0){
sb.append(".");
}
sb.append(s);
}
return sb.toString();
}
private boolean containArguments(Expr_stmtContext expr) {
final boolean[] containsArgument = {false};
PythonParserBaseListener visitor = new PythonParserBaseListener() {
@Override
public void enterArguments(ArgumentsContext ctx) {
containsArgument[0] = true;
super.enterArguments(ctx);
}
};
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(visitor,expr);
return containsArgument[0];
}
private void deduceReturnTypeInCaseOfReturn(Return_stmtContext ctx, Expression expression) {
FunctionEntity currentFunction = context.currentFunction();
if (currentFunction == null)
@ -106,9 +162,8 @@ public class ExpressionUsage {
private void makeSureVarExist(GenericName identifier, ParserRuleContext ctx) {
if (null==context.foundEntityWithName(identifier)) {
VarEntity var = context.foundVarDefinition(context.lastContainer(), identifier.getName(),ctx.getStart().getLine());
VarEntity var = context.foundVarDefinition(context.lastContainer(), identifier.getName(), ctx.getStart().getLine());
var.setLine(ctx.getStart().getLine());
}
}
@ -290,9 +345,8 @@ class NameCollector extends PythonParserBaseVisitor<Void>{
this.names = names;
}
@Override
public Void visitAtom(AtomContext ctx) {
if (ctx.name()!=null)
names.add(ctx.name().getText());
return super.visitAtom(ctx);
public Void visitName(NameContext ctx) {
names.add(ctx.getText());
return super.visitName(ctx);
}
}

View File

@ -3,10 +3,11 @@ package depends.extractor.python.union;
import depends.entity.*;
import depends.entity.repo.EntityRepo;
import depends.extractor.python.NameAliasImport;
import depends.extractor.python.PythonBuiltInType;
import depends.extractor.python.PythonHandlerContext;
import depends.extractor.python.PythonParser.*;
import depends.extractor.python.PythonParserBaseListener;
import depends.extractor.ruby.IncludedFileLocator;
import depends.extractor.IncludedFileLocator;
import depends.importtypes.FileImport;
import depends.relations.IBindingResolver;
import multilang.depends.util.file.FileUtil;
@ -19,6 +20,12 @@ import java.util.List;
public class PythonCodeListener extends PythonParserBaseListener{
private final PythonHandlerContext context;
// @Override
// public void exitEveryRule(ParserRuleContext ctx) {
// System.out.println(ctx.getClass().getSimpleName().replace("Context","")+":"+ctx.getText());
// super.exitEveryRule(ctx);
// }
private final ExpressionUsage expressionUsage;
private final EntityRepo entityRepo;
private final IncludedFileLocator includeFileLocator;
@ -33,7 +40,6 @@ public class PythonCodeListener extends PythonParserBaseListener{
this.includeFileLocator = includeFileLocator;
this.bindingResolver = bindingResolver;
this.pythonProcessor = pythonProcessor;
String dir = FileUtil.uniqFilePath(FileUtil.getLocatedDir(fileFullPath));
if (entityRepo.getEntity(dir) == null) {
PackageEntity pacakgeEntity = new PackageEntity(dir, entityRepo.generateId());
@ -43,7 +49,11 @@ public class PythonCodeListener extends PythonParserBaseListener{
PackageEntity packageEntity = (PackageEntity) entityRepo.getEntity(dir);
String moduleName = fileEntity.getRawName().uniqName().substring(packageEntity.getRawName().uniqName().length() + 1);
if (moduleName.endsWith(".py"))
moduleName.substring(0, moduleName.length() - ".py".length());
moduleName = moduleName.substring(0, moduleName.length() - ".py".length());
if (fileEntity.getRawName().uniqName().endsWith(PythonBuiltInType.PACKAGE_PY_NAME)){
moduleName = "";
}
fileEntity.setModuleName(moduleName);
Entity.setParent(fileEntity, packageEntity);
packageEntity.addChild(FileUtil.getShortFileName(fileEntity.getRawName().uniqName()).replace(".py", ""), fileEntity);
}
@ -56,7 +66,7 @@ public class PythonCodeListener extends PythonParserBaseListener{
if (dotted_as_name.name()!=null) {
aliasName = dotted_as_name.name().getText();
}
List<String> fullNames = foundImportedModuleOrPackage(0,moduleName);
List<String> fullNames = sureImportedModulesParsed(0,moduleName,null);
for (String fullName:fullNames) {
if (FileUtil.existFile(fullName) && !(FileUtil.isDirectory(fullName))) {
@ -69,15 +79,15 @@ public class PythonCodeListener extends PythonParserBaseListener{
}
@Override
public void enterFrom_stmt(From_stmtContext ctx) {
String moduleName = null;
String fromName = null;
if (ctx.dotted_name() != null) {
moduleName = ctx.dotted_name().getText();
fromName = ctx.dotted_name().getText();
}
int prefixDotCount = getDotCounter(ctx);
List<String> moduleNames = getModuleNames(ctx.import_as_names());
List<String> fullNames = sureImportedModulesParsed(prefixDotCount, fromName,moduleNames);
List<String> fullNames = foundImportedModuleOrPackage(prefixDotCount, moduleName);
for (String fullName:fullNames) {
if (ctx.import_as_names() == null) {// import *
ContainerEntity moduleEntity = (ContainerEntity) (entityRepo.getEntity(fullName));
if (moduleEntity != null) {
@ -113,8 +123,7 @@ public class PythonCodeListener extends PythonParserBaseListener{
if (FileUtil.existFile(fileName) && !(FileUtil.isDirectory(fileName))) {
context.foundNewImport(new FileImport(fileName));
}
}
if (FileUtil.existFile(fullName) && !(FileUtil.isDirectory(fullName))) {
}else if (FileUtil.existFile(fullName)) {
context.foundNewImport(new FileImport(fullName));
}
Entity itemEntity = bindingResolver.resolveName(entityRepo.getEntity(fullName), GenericName.build(name), true);
@ -127,8 +136,18 @@ public class PythonCodeListener extends PythonParserBaseListener{
}
super.enterFrom_stmt(ctx);
}
private List<String> getModuleNames(Import_as_namesContext import_as_names) {
List<String> names = new ArrayList<>();
if (import_as_names==null)
return names;
for (Import_as_nameContext item : import_as_names.import_as_name()) {
String name = item.name(0).getText();
names.add(name);
}
return names;
}
private int getDotCounter(From_stmtContext ctx) {
int total = 0;
if (ctx.DOT()!=null){
@ -139,54 +158,82 @@ public class PythonCodeListener extends PythonParserBaseListener{
}
return total;
}
private List<String> foundImportedModuleOrPackage(int prefixDotCount, String originalName) {
private List<String> sureImportedModulesParsed(int prefixDotCount, String fromName, List<String> moduleNames) {
ArrayList<String> visitedFiles = new ArrayList<>();
/* compute prefix path */
String dir = FileUtil.getLocatedDir(context.currentFile().getRawName().uniqName());
String preFix = "";
for (int i = 0; i < prefixDotCount - 1; i++) {
preFix = preFix + ".." + File.separator;
}
dir = dir + File.separator + preFix;
String fullName = null;
if (originalName != null) {
String importedName = originalName.replace(".", File.separator);
fullName = includeFileLocator.uniqFileName(dir, importedName);
if (fullName == null) {
fullName = includeFileLocator.uniqFileName(dir, importedName + ".py");
}
} else {
fullName = FileUtil.uniqFilePath(dir);
/* compute importedName */
String importedName = "";
if (fromName!=null) {
importedName = fromName.replace(".", File.separator);
}
if (fullName != null) {
if (FileUtil.isDirectory(fullName)) {
if (!FileUtil.uniqFilePath(fullName).equals(FileUtil.uniqFilePath(dir))) {
File d = new File(fullName);
File[] files = d.listFiles();
for (File file : files) {
if (!file.isDirectory()) {
if (file.getAbsolutePath().endsWith(".py")) {
visitIncludedFile(FileUtil.uniqFilePath(file.getAbsolutePath()));
}
}
}
/* search importedName from all included paths */
String uniqFrom = includeFileLocator.uniqFileName(dir, importedName);
if (uniqFrom==null)
uniqFrom = includeFileLocator.uniqFileName(dir,importedName+".py");
if (uniqFrom==null){ //cannot find the path
return visitedFiles;
}
if (uniqFrom.endsWith(".py")){
return visitIncludedFile(uniqFrom);
}
if (moduleNames!=null && moduleNames.size()>0){
for (String moduleName:moduleNames){
String fileName = uniqFrom + File.separator + moduleName;
if (!FileUtil.existFile(fileName)){
fileName +=".py";
}else if (FileUtil.isDirectory(fileName)){
fileName += File.separator + PythonBuiltInType.PACKAGE_PY_NAME;
}
} else {
visitIncludedFile(fullName);
List<String> files = visitIncludedFile(fileName);
visitedFiles.addAll(files);
}
}else{
return visitIncludedFile(uniqFrom);
}
ArrayList<String> r = new ArrayList<>();
if (fullName==null) return r;
r.add(fullName);
if (FileUtil.existFile(fullName+File.separator + "__init__.py")) {
r.add( fullName+File.separator +"__init__.py");
}
return r;
return visitedFiles;
}
private void visitIncludedFile(String fullName) {
PythonFileParser importedParser = new PythonFileParser(fullName, entityRepo, includeFileLocator, bindingResolver,
private List<String> visitIncludedFile(String fullName) {
List<String> visitedFiles = new ArrayList<>();
if (FileUtil.isDirectory(fullName)){
File d = new File(fullName);
File[] files = d.listFiles();
for (File file : files) {
if (!file.isDirectory()) {
if (file.getAbsolutePath().endsWith(".py")) {
String fileName = FileUtil.uniqFilePath(file.getAbsolutePath());
visitIncludedFile(fileName);
visitedFiles.add(fileName);
}
}
}
if (FileUtil.existFile(fullName+File.separator + PythonBuiltInType.PACKAGE_PY_NAME)) {
visitedFiles.add( fullName+File.separator +PythonBuiltInType.PACKAGE_PY_NAME);
}
}else{
invokeParser(fullName);
visitedFiles.add(fullName);
}
return visitedFiles;
}
private void invokeParser(String fileName){
PythonFileParser importedParser = new PythonFileParser(entityRepo, includeFileLocator, bindingResolver,
pythonProcessor);
try {
importedParser.parse();
importedParser.parse(fileName);
} catch (IOException e) {
e.printStackTrace();
}
@ -240,8 +287,14 @@ public class PythonCodeListener extends PythonParserBaseListener{
List<String> result = new ArrayList<>();
for (Def_parametersContext params:def_parameters) {
for (Def_parameterContext param:params.def_parameter()) {
String p = getName( param.named_parameter().name());
result.add(p);
if (!(param.named_parameter()==null)){
String p = getName( param.named_parameter().name());
result.add(p);
}
else{
// STAR, we ignore it
// refer to definition: def_parameter:named_parameter (ASSIGN test)? | STAR
}
}
}
@ -368,7 +421,4 @@ public class PythonCodeListener extends PythonParserBaseListener{
expressionUsage.stopExpr();
super.exitAssert_stmt(ctx);
}
public void done() {
context.done();
}
}

View File

@ -1,13 +1,12 @@
package depends.extractor.python.union;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.FileParser;
import depends.extractor.IncludedFileLocator;
import depends.extractor.python.PythonLexer;
import depends.extractor.python.PythonParser;
import depends.extractor.ruby.IncludedFileLocator;
import depends.relations.IBindingResolver;
import multilang.depends.util.file.FileUtil;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
@ -16,17 +15,13 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.IOException;
public class PythonFileParser implements FileParser {
private String fileFullPath;
private EntityRepo entityRepo;
public class PythonFileParser extends FileParser {
private IBindingResolver bindingResolver;
private IncludedFileLocator includeFileLocator;
private PythonProcessor processor;
public PythonFileParser(String fileFullPath, EntityRepo entityRepo, IncludedFileLocator includeFileLocator,
public PythonFileParser(EntityRepo entityRepo, IncludedFileLocator includeFileLocator,
IBindingResolver bindingResolver, PythonProcessor pythonProcessor) {
this.fileFullPath = fileFullPath;
this.entityRepo = entityRepo;
this.bindingResolver = bindingResolver;
this.includeFileLocator = includeFileLocator;
@ -34,12 +29,8 @@ public class PythonFileParser implements FileParser {
}
@Override
public void parse() throws IOException {
/** If file already exist, skip it */
Entity fileEntity = entityRepo.getEntity(fileFullPath);
if (fileEntity!=null && fileEntity instanceof FileEntity) {
return;
}
protected void parseFile(String fileFullPath) throws IOException {
fileFullPath = FileUtil.uniqFilePath(fileFullPath);
CharStream input = CharStreams.fromFileName(fileFullPath);
Lexer lexer = new PythonLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
@ -49,9 +40,6 @@ public class PythonFileParser implements FileParser {
PythonCodeListener bridge = new PythonCodeListener(fileFullPath, entityRepo, bindingResolver, includeFileLocator, processor);
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(bridge, parser.file_input());
fileEntity = entityRepo.getEntity(fileFullPath);
((FileEntity)fileEntity).cacheAllExpressions();
bridge.done();
}
}

View File

@ -2,7 +2,7 @@ package depends.extractor.python.union;
import depends.extractor.FileParser;
import depends.extractor.python.BasePythonProcessor;
import depends.extractor.ruby.IncludedFileLocator;
import depends.extractor.IncludedFileLocator;
public class PythonProcessor extends BasePythonProcessor {
@ -18,9 +18,9 @@ public class PythonProcessor extends BasePythonProcessor {
@Override
public FileParser createFileParser(String fileFullPath) {
public FileParser createFileParser() {
IncludedFileLocator includeFileLocator = new IncludedFileLocator(super.includePaths());
return new PythonFileParser(fileFullPath,entityRepo,includeFileLocator, bindingResolver,this);
return new PythonFileParser(entityRepo,includeFileLocator, bindingResolver,this);
}

View File

@ -27,19 +27,6 @@ package depends.extractor.ruby;
import depends.entity.repo.BuiltInType;
public class RubyBuiltInType extends BuiltInType {
public RubyBuiltInType() {
super.createBuiltInTypes();
}
@Override
public String[] getBuiltInTypeStr() {
return new String[] {};
}
@Override
public String[] getBuiltInPrefixStr() {
return new String[] {};
}
@Override
public String[] getBuiltInMethods() {

View File

@ -25,17 +25,18 @@ SOFTWARE.
package depends.extractor.ruby;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.PackageEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.FileParser;
import depends.extractor.HandlerContext;
import depends.extractor.IncludedFileLocator;
import depends.extractor.ParserCreator;
import depends.importtypes.FileImport;
import depends.relations.IBindingResolver;
import multilang.depends.util.file.FileUtil;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
public class RubyHandlerContext extends HandlerContext {
@ -43,7 +44,6 @@ public class RubyHandlerContext extends HandlerContext {
private ParserCreator parserCreator;
public RubyHandlerContext(EntityRepo entityRepo,
IncludedFileLocator includedFileLocator,
ExecutorService executorService,
IBindingResolver bindingResolver, ParserCreator parserCreator) {
super(entityRepo, bindingResolver);
this.includedFileLocator = includedFileLocator;
@ -71,10 +71,9 @@ public class RubyHandlerContext extends HandlerContext {
System.err.println("Warning: cannot found included file " + importedFilename );
continue;
}
FileParser importedParser = parserCreator.createFileParser(inclFileName);
FileParser importedParser = parserCreator.createFileParser();
try {
System.out.println("parsing "+inclFileName);
importedParser.parse();
importedParser.parse(inclFileName);
} catch (Exception e) {
System.err.println("parsing error in "+inclFileName);
}
@ -102,6 +101,7 @@ public class RubyHandlerContext extends HandlerContext {
}
}
public FileEntity startFile(String fileName) {
return super.startFile(false, fileName);
}
}

View File

@ -27,21 +27,19 @@ package depends.extractor.ruby;
import depends.entity.repo.BuiltInType;
import depends.extractor.AbstractLangProcessor;
import depends.extractor.FileParser;
import depends.extractor.IncludedFileLocator;
import depends.extractor.ParserCreator;
import depends.extractor.ruby.jruby.JRubyFileParser;
import depends.relations.ImportLookupStrategy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static depends.deptypes.DependencyType.*;
public class RubyProcessor extends AbstractLangProcessor implements ParserCreator{
private static final String LANG = "ruby";
private static final String[] SUFFIX = new String[] {".rb"};
private ExecutorService executor;
@Override
public String supportedLanguage() {
@ -55,16 +53,8 @@ public class RubyProcessor extends AbstractLangProcessor implements ParserCreato
@Override
public FileParser createFileParser(String fileFullPath) {
executor = Executors.newSingleThreadExecutor();
return new JRubyFileParser(fileFullPath,entityRepo,executor,new IncludedFileLocator(super.includePaths()), bindingResolver,this);
}
@Override
protected void finalize() throws Throwable {
this.executor.shutdown();
super.finalize();
public FileParser createFileParser() {
return new JRubyFileParser(entityRepo,new IncludedFileLocator(super.includePaths()), bindingResolver,this);
}
@Override

View File

@ -24,39 +24,30 @@ SOFTWARE.
package depends.extractor.ruby.jruby;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.repo.EntityRepo;
import depends.extractor.FileParser;
import depends.extractor.IncludedFileLocator;
import depends.extractor.ParserCreator;
import depends.extractor.ruby.IncludedFileLocator;
import depends.relations.IBindingResolver;
import multilang.depends.util.file.FileUtil;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.jrubyparser.CompatVersion;
import org.jrubyparser.Parser;
import org.jrubyparser.ast.Node;
import org.jrubyparser.lexer.SyntaxException;
import org.jrubyparser.parser.ParserConfiguration;
import java.io.IOException;
import java.io.StringReader;
import java.util.concurrent.ExecutorService;
public class JRubyFileParser implements FileParser {
private String fileFullPath;
private EntityRepo entityRepo;
private ExecutorService executor;
public class JRubyFileParser extends FileParser {
private IncludedFileLocator includesFileLocator;
private IBindingResolver bindingResolver;
private ParserCreator parserCreator;
public JRubyFileParser(String fileFullPath, EntityRepo entityRepo,
ExecutorService executorService,
public JRubyFileParser( EntityRepo entityRepo,
IncludedFileLocator includesFileLocator,
IBindingResolver bindingResolver, ParserCreator parserCreator) {
this.fileFullPath = FileUtil.uniqFilePath(fileFullPath);
this.entityRepo = entityRepo;
this.executor = executorService;
this.includesFileLocator = includesFileLocator;
this.bindingResolver = bindingResolver;
this.parserCreator = parserCreator;
@ -64,27 +55,20 @@ public class JRubyFileParser implements FileParser {
@SuppressWarnings("unchecked")
@Override
public void parse() throws IOException {
/** If file already exist, skip it */
Entity fileEntity = entityRepo.getEntity(fileFullPath);
if (fileEntity!=null && fileEntity instanceof FileEntity) {
return;
}
protected void parseFile(String fileFullPath) throws IOException {
CharStream input = CharStreams.fromFileName(fileFullPath);
Parser rubyParser = new Parser();
StringReader in = new StringReader(input.toString());
CompatVersion version = CompatVersion.RUBY2_3;
ParserConfiguration config = new ParserConfiguration(0, version);
try {
Node node = rubyParser.parse("<code>", in, config);
JRubyVisitor parser = new JRubyVisitor(fileFullPath, entityRepo, includesFileLocator,executor, bindingResolver,parserCreator);
Node node = rubyParser.parse(fileFullPath, in, config);
JRubyVisitor parser = new JRubyVisitor(fileFullPath, entityRepo, includesFileLocator, bindingResolver,parserCreator);
node.accept(parser);
fileEntity = entityRepo.getEntity(fileFullPath);
((FileEntity)fileEntity).cacheAllExpressions();
parser.done();
}catch(Exception e) {
System.err.println("parsing error in "+fileFullPath);
}catch(SyntaxException e) {
System.out.println("parsing error in "+e.getPosition() + "(" + e.getMessage() + ")");
}catch (Exception e){
e.printStackTrace();
}
}

View File

@ -27,7 +27,7 @@ package depends.extractor.ruby.jruby;
import depends.entity.*;
import depends.entity.repo.EntityRepo;
import depends.extractor.ParserCreator;
import depends.extractor.ruby.IncludedFileLocator;
import depends.extractor.IncludedFileLocator;
import depends.extractor.ruby.RubyHandlerContext;
import depends.relations.IBindingResolver;
import org.jrubyparser.ast.*;
@ -35,7 +35,6 @@ import org.jrubyparser.util.NoopVisitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
public class JRubyVisitor extends NoopVisitor {
@ -44,8 +43,8 @@ public class JRubyVisitor extends NoopVisitor {
private ExpressionUsage expressionUsage;
public JRubyVisitor(String fileFullPath, EntityRepo entityRepo, IncludedFileLocator includedFileLocator,
ExecutorService executorService, IBindingResolver bindingResolver, ParserCreator parserCreator) {
this.context = new RubyHandlerContext(entityRepo, includedFileLocator, executorService, bindingResolver, parserCreator);
IBindingResolver bindingResolver, ParserCreator parserCreator) {
this.context = new RubyHandlerContext(entityRepo, includedFileLocator, bindingResolver, parserCreator);
expressionUsage = new ExpressionUsage(context, entityRepo, helper, bindingResolver);
context.startFile(fileFullPath);
@ -60,7 +59,7 @@ public class JRubyVisitor extends NoopVisitor {
@Override
public Object visitModuleNode(ModuleNode node) {
String name = helper.getName(node.getCPath());
context.foundNamespace(name,node.getPosition().getStartLine());
context.foundNamespace(name,node.getPosition().getStartLine()+1);
super.visitModuleNode(node);
context.exitLastedEntity();
return null;
@ -68,7 +67,7 @@ public class JRubyVisitor extends NoopVisitor {
@Override
public Object visitClassNode(ClassNode node) {
TypeEntity type = context.foundNewType(helper.getName(node.getCPath()),node.getPosition().getStartLine());
TypeEntity type = context.foundNewType(helper.getName(node.getCPath()),node.getPosition().getStartLine()+1);
Node superNode = node.getSuper();
if (superNode instanceof ConstNode ||
@ -97,7 +96,7 @@ public class JRubyVisitor extends NoopVisitor {
public Object visitFCallNode(FCallNode node) {
String fname = helper.getName(node);
Collection<String> params = getParams(node);
context.processSpecialFuncCall(fname, params, node.getPosition().getStartLine());
context.processSpecialFuncCall(fname, params, node.getPosition().getStartLine()+1);
return super.visitFCallNode(node);
}
@ -122,7 +121,7 @@ public class JRubyVisitor extends NoopVisitor {
String fname = helper.getName(node);
Collection<String> params = getParams(node);
addCallToReceiverVar(node, fname);
context.processSpecialFuncCall(fname, params, node.getPosition().getStartLine());
context.processSpecialFuncCall(fname, params, node.getPosition().getStartLine()+1);
return super.visitCallNode(node);
}
@ -143,7 +142,7 @@ public class JRubyVisitor extends NoopVisitor {
public Object visitUnaryCallNode(UnaryCallNode node) {
String fname = helper.getName(node);
Collection<String> params = new ArrayList<>();
context.processSpecialFuncCall(fname, params, node.getPosition().getStartLine());
context.processSpecialFuncCall(fname, params, node.getPosition().getStartLine()+1);
return super.visitUnaryCallNode(node);
}
@ -157,8 +156,8 @@ public class JRubyVisitor extends NoopVisitor {
@Override
public Object visitDefnNode(DefnNode node) {
FunctionEntity method = context.foundMethodDeclarator(node.getName(),node.getPosition().getStartLine());
method.setLine(node.getPosition().getStartLine());
FunctionEntity method = context.foundMethodDeclarator(node.getName(),node.getPosition().getStartLine()+1);
method.setLine(node.getPosition().getStartLine()+1);
super.visitDefnNode(node);
context.exitLastedEntity();
@ -175,8 +174,8 @@ public class JRubyVisitor extends NoopVisitor {
String className = ((INameNode) varNode).getName();
Entity entity = context.foundEntityWithName(GenericName.build(className));
if (entity != null && entity instanceof ContainerEntity) {
FunctionEntity method = context.foundMethodDeclarator(((ContainerEntity) entity), node.getName(),node.getPosition().getStartLine());
method.setLine(node.getPosition().getStartLine());
FunctionEntity method = context.foundMethodDeclarator(((ContainerEntity) entity), node.getName(),node.getPosition().getStartLine()+1);
method.setLine(node.getPosition().getStartLine()+1);
handled = true;
}
@ -184,16 +183,16 @@ public class JRubyVisitor extends NoopVisitor {
String varName = ((INameNode) varNode).getName();
Entity var = context.foundEntityWithName(GenericName.build(varName));
if (var != null && var instanceof ContainerEntity) {
FunctionEntity method = context.foundMethodDeclarator(((ContainerEntity) var), node.getName(),node.getPosition().getStartLine());
method.setLine(node.getPosition().getStartLine());
FunctionEntity method = context.foundMethodDeclarator(((ContainerEntity) var), node.getName(),node.getPosition().getStartLine()+1);
method.setLine(node.getPosition().getStartLine()+1);
handled = true;
}
}
if (!handled) {
// fallback to add it to last container
FunctionEntity method = context.foundMethodDeclarator(node.getName(),node.getPosition().getStartLine());
method.setLine(node.getPosition().getStartLine());
FunctionEntity method = context.foundMethodDeclarator(node.getName(),node.getPosition().getStartLine()+1);
method.setLine(node.getPosition().getStartLine()+1);
}
super.visitDefsNode(node);
context.exitLastedEntity();
@ -202,31 +201,31 @@ public class JRubyVisitor extends NoopVisitor {
@Override
public Object visitGlobalVarNode(GlobalVarNode node) {
context.foundVarDefinition(context.globalScope(), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(context.globalScope(), node.getName(),node.getPosition().getStartLine()+1);
return super.visitGlobalVarNode(node);
}
@Override
public Object visitInstVarNode(InstVarNode node) {
context.foundVarDefinition(context.currentType(), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(context.currentType(), node.getName(),node.getPosition().getStartLine()+1);
return super.visitInstVarNode(node);
}
@Override
public Object visitClassVarAsgnNode(ClassVarAsgnNode node) {
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine()+1);
return super.visitClassVarAsgnNode(node);
}
@Override
public Object visitClassVarDeclNode(ClassVarDeclNode node) {
context.foundVarDefinition(context.currentType(), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(context.currentType(), node.getName(),node.getPosition().getStartLine()+1);
return super.visitClassVarDeclNode(node);
}
@Override
public Object visitClassVarNode(ClassVarNode node) {
context.foundVarDefinition(context.currentType(), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(context.currentType(), node.getName(),node.getPosition().getStartLine()+1);
return super.visitClassVarNode(node);
}
@ -237,25 +236,26 @@ public class JRubyVisitor extends NoopVisitor {
@Override
public Object visitDVarNode(DVarNode node) {
context.foundVarDefinition(context.lastContainer(), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(context.lastContainer(), node.getName(),node.getPosition().getStartLine()+1);
return super.visitDVarNode(node);
}
@Override
public Object visitDAsgnNode(DAsgnNode node) {
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine()+1);
expressionUsage.foundExpression(node);
return super.visitDAsgnNode(node);
}
@Override
public Object visitGlobalAsgnNode(GlobalAsgnNode node) {
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine()+1);
return super.visitGlobalAsgnNode(node);
}
@Override
public Object visitInstAsgnNode(InstAsgnNode node) {
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine()+1);
return super.visitInstAsgnNode(node);
}
@ -268,7 +268,7 @@ public class JRubyVisitor extends NoopVisitor {
@Override
public Object visitLocalAsgnNode(LocalAsgnNode node) {
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine());
context.foundVarDefinition(helper.getScopeOfVar(node,context), node.getName(),node.getPosition().getStartLine()+1);
return super.visitLocalAsgnNode(node);
}
@ -278,7 +278,4 @@ public class JRubyVisitor extends NoopVisitor {
return super.visit(node);
}
public void done() {
context.done();
}
}

View File

@ -24,17 +24,17 @@ SOFTWARE.
package depends.format.detail;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import depends.format.AbstractFormatDependencyDumper;
import depends.matrix.core.DependencyDetail;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.DependencyPair;
import depends.matrix.core.DependencyValue;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
public class DetailTextFormatDependencyDumper extends AbstractFormatDependencyDumper{
ArrayList<String> files;
@Override
@ -67,7 +67,7 @@ public class DetailTextFormatDependencyDumper extends AbstractFormatDependencyDu
writer.println("======="+files.get(src) + " -> " + files.get(dst) + "=========");
for (DependencyValue dependency:dependencyPair.getDependencies()) {
for (DependencyDetail item:dependency.getDetails()) {
writer.println("["+dependency.getType()+"]"+item);
writer.println("["+dependency.getType()+"]"+item.getSrc() + "->" + item.getDest());
}
}
}

View File

@ -24,6 +24,7 @@ SOFTWARE.
package depends.generator;
import depends.entity.CandidateTypes;
import depends.entity.Entity;
import depends.entity.EntityNameBuilder;
import depends.entity.FileEntity;
@ -32,6 +33,7 @@ import depends.matrix.core.DependencyDetail;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.LocationInfo;
import depends.matrix.transform.OrderedMatrixGenerator;
import depends.relations.Relation;
import multilang.depends.util.file.path.EmptyFilenameWritter;
import multilang.depends.util.file.path.FilenameWritter;
import multilang.depends.util.file.strip.EmptyLeadingNameStripper;
@ -39,16 +41,22 @@ import multilang.depends.util.file.strip.ILeadingNameStrippper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static depends.deptypes.DependencyType.POSSIBLE_DEP;
public abstract class DependencyGenerator {
private static Logger logger = LoggerFactory.getLogger(DependencyGenerator.class);
private boolean outputSelfDependencies;
public abstract String getType();
public DependencyMatrix identifyDependencies(EntityRepo entityRepo, List<String> typeFilter) {
System.out.println("dependencie data generating...");
DependencyMatrix dependencyMatrix = build(entityRepo, typeFilter);
entityRepo.clear();
System.out.println("reorder dependency matrix...");
dependencyMatrix = new OrderedMatrixGenerator(dependencyMatrix).build();
System.out.println("Dependencies data generating done successfully...");
@ -56,7 +64,76 @@ public abstract class DependencyGenerator {
return dependencyMatrix;
}
public abstract DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter);
/**
* Build the dependency matrix (without re-mapping file id)
* @param entityRepo which contains entities and relations
* @return the generated dependency matrix
*/
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(0, typeFilter,outputSelfDependencies);
Iterator<Entity> iterator = entityRepo.entityIterator();
System.out.println("Start create dependencies matrix....");
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (outputLevelMatch(entity)){
dependencyMatrix.addNode(nameOf(entity),entity.getId());
}
int entityFrom = upToOutputLevelEntityId(entityRepo, entity);
if (entityFrom==-1) continue;
for (Relation relation:entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
List<Entity> relatedEntities = expandEntity(relatedEntity);
String possibleDependencyFlag = relation.possible()? POSSIBLE_DEP :"";
relatedEntities.forEach(theEntity->{
if (theEntity.getId()>=0) {
int entityTo = upToOutputLevelEntityId(entityRepo,theEntity);
if (entityTo!=-1) {
DependencyDetail detail = buildDescription(entity, theEntity, relation.getFromLine());
detail = rewriteDetail(detail);
dependencyMatrix.addDependency(relation.getType()+possibleDependencyFlag, entityFrom,entityTo,1,detail);
}
}
});
}
}
System.out.println("Finish create dependencies matrix....");
return dependencyMatrix;
}
private List<Entity> expandEntity(Entity relatedEntity) {
List<Entity> entities = new ArrayList<>();
if (relatedEntity instanceof CandidateTypes) {
entities = Collections.unmodifiableList((List) ((CandidateTypes) relatedEntity).getCandidateTypes());
}else {
entities.add(relatedEntity);
}
return entities;
}
private DependencyDetail rewriteDetail(DependencyDetail detail) {
if (detail==null) return null;
String srcFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getSrc().getFile())
);
String dstFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getDest().getFile()));
return new DependencyDetail(
new LocationInfo(detail.getSrc().getObject(),
detail.getSrc().getType(),
srcFile, detail.getSrc().getLineNumber())
,
new LocationInfo(detail.getDest().getObject(),
detail.getDest().getType(),
dstFile, detail.getDest().getLineNumber()));
}
protected abstract int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity);
protected abstract String nameOf(Entity entity);
protected abstract boolean outputLevelMatch(Entity entity);
protected ILeadingNameStrippper stripper = new EmptyLeadingNameStripper();
protected FilenameWritter filenameWritter = new EmptyFilenameWritter();
@ -73,14 +150,26 @@ public abstract class DependencyGenerator {
Entity fromFile = fromEntity.getAncestorOfType(FileEntity.class);
Entity toFile = toEntity.getAncestorOfType(FileEntity.class);
// If the toEntity is above the file level (e.g. a package), then toFile will be null.
if (toFile == null) return null;
return new DependencyDetail(
new LocationInfo(fromObject,fromFile.getQualifiedName(),fromLineNumber),
new LocationInfo(toObject,toFile.getQualifiedName(),toEntity.getLine()));
new LocationInfo(stripper.stripFilename(fromObject),typeOf(fromEntity),stripper.stripFilename(fromFile.getQualifiedName()),fromLineNumber),
new LocationInfo(stripper.stripFilename(toObject),typeOf(toEntity),stripper.stripFilename(toFile.getQualifiedName()),toEntity.getLine()));
}
private String typeOf(Entity entity) {
return entity.getClass().getSimpleName().replace("Entity","").toLowerCase();
}
public void setFilenameRewritter(FilenameWritter filenameWritter) {
this.filenameWritter = filenameWritter;
}
public void setGenerateDetail(boolean generateDetail) {
this.generateDetail = generateDetail;
}
public void setOutputSelfDependencies(boolean outputSelfDependencies) {
this.outputSelfDependencies = outputSelfDependencies;
}
}

View File

@ -24,88 +24,29 @@ SOFTWARE.
package depends.generator;
import depends.entity.CandidateTypes;
import depends.entity.Entity;
import depends.entity.FileEntity;
import depends.entity.TypeEntity;
import depends.entity.repo.EntityRepo;
import depends.matrix.core.DependencyDetail;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.LocationInfo;
import depends.relations.Relation;
import java.util.Iterator;
import java.util.List;
public class FileDependencyGenerator extends DependencyGenerator{
/**
* Build the dependency matrix (without re-mapping file id)
* @param entityRepo which contains entities and relations
* @return the generated dependency matrix
*/
@Override
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(typeFilter);
Iterator<Entity> iterator = entityRepo.entityIterator();
System.out.println("Start create dependencies matrix....");
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (entity instanceof FileEntity){
String name = stripper.stripFilename(entity.getDisplayName());
name = filenameWritter.reWrite(name);
dependencyMatrix.addNode(name,entity.getId());
}
int fileEntityFrom = getFileEntityIdNoException(entityRepo, entity);
if (fileEntityFrom==-1) continue;
for (Relation relation:entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
if (relatedEntity instanceof CandidateTypes) {
List<TypeEntity> candidateTypes = ((CandidateTypes)relatedEntity).getCandidateTypes();
for (TypeEntity candidateType:candidateTypes) {
if (candidateType.getId()>=0) {
int fileEntityTo = getFileEntityIdNoException(entityRepo,candidateType);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity,candidateType,relation.getFromLine());
detail = rewriteDetail(detail);
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}else {
if (relatedEntity.getId()>=0) {
int fileEntityTo = getFileEntityIdNoException(entityRepo,relatedEntity);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity, relatedEntity, relation.getFromLine());
detail = rewriteDetail(detail);
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}
}
System.out.println("Finish create dependencies matrix....");
return dependencyMatrix;
protected String nameOf(Entity entity) {
String name = stripper.stripFilename(entity.getDisplayName());
return filenameWritter.reWrite(name);
}
private DependencyDetail rewriteDetail(DependencyDetail detail) {
if (detail==null) return null;
String srcFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getSrc().getFile())
);
String dstFile = filenameWritter.reWrite(
stripper.stripFilename(detail.getDest().getFile()));
return new DependencyDetail(
new LocationInfo(detail.getSrc().getObject(),
srcFile, detail.getSrc().getLineNumber())
,
new LocationInfo(detail.getDest().getObject(),
dstFile, detail.getDest().getLineNumber()));
@Override
protected boolean outputLevelMatch(Entity entity) {
return (entity instanceof FileEntity);
}
private int getFileEntityIdNoException(EntityRepo entityRepo, Entity entity) {
@Override
public String getType() {
return "file";
}
@Override
protected int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity) {
Entity ancestor = entity.getAncestorOfType(FileEntity.class);
if (ancestor==null) {
return -1;

View File

@ -25,57 +25,30 @@ SOFTWARE.
package depends.generator;
import depends.entity.Entity;
import depends.entity.EntityNameBuilder;
import depends.entity.FileEntity;
import depends.entity.FunctionEntity;
import depends.entity.EntityNameBuilder;
import depends.entity.repo.EntityRepo;
import depends.matrix.core.DependencyMatrix;
import depends.relations.Relation;
import java.util.Iterator;
import java.util.List;
public class FunctionDependencyGenerator extends DependencyGenerator {
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(typeFilter);
Iterator<Entity> iterator = entityRepo.entityIterator();
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (entity instanceof FunctionEntity) {
String name = getFunctionEntityDisplayName((FunctionEntity)entity);
dependencyMatrix.addNode(name,entity.getId());
}
int entityFrom = getFunctionEntityIdNoException(entity);
if (entityFrom == -1)
continue;
for (Relation relation : entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
if (relatedEntity.getId() >= 0) {
int entityTo = getFunctionEntityIdNoException(relation.getEntity());
if (entityTo == -1)
continue;
dependencyMatrix.addDependency(relation.getType(), entityFrom, entityTo, 1,buildDescription(entity,
relation.getEntity(),relation.getFromLine()));
}
}
}
return dependencyMatrix;
@Override
protected boolean outputLevelMatch(Entity entity) {
return (entity instanceof FunctionEntity);
}
private String getFunctionEntityDisplayName(FunctionEntity entity) {
@Override
protected String nameOf(Entity entity) {
FileEntity file = (FileEntity) entity.getAncestorOfType(FileEntity.class);
String name = stripper.stripFilename(file.getRawName().uniqName());
name = filenameWritter.reWrite(name);
String functionName = EntityNameBuilder.build(entity);
functionName = stripper.stripFilename(functionName);
name = name + "("+functionName+")";
return name;
}
private int getFunctionEntityIdNoException(Entity entity) {
@Override
protected int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity) {
Entity ancestor = entity.getAncestorOfType(FunctionEntity.class);
if (ancestor == null)
return -1;
@ -83,4 +56,9 @@ public class FunctionDependencyGenerator extends DependencyGenerator {
return ancestor.getId();
}
@Override
public String getType() {
return "method";
}
}

View File

@ -26,68 +26,16 @@ package depends.generator;
import depends.entity.*;
import depends.entity.repo.EntityRepo;
import depends.matrix.core.DependencyDetail;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.LocationInfo;
import depends.relations.Relation;
import java.util.Iterator;
import java.util.List;
public class StructureDependencyGenerator extends DependencyGenerator{
/**
* Build the dependency matrix (without re-mapping file id)
* @param entityRepo which contains entities and relations
* @return the generated dependency matrix
*/
@Override
public DependencyMatrix build(EntityRepo entityRepo,List<String> typeFilter) {
DependencyMatrix dependencyMatrix = new DependencyMatrix(typeFilter);
Iterator<Entity> iterator = entityRepo.entityIterator();
System.out.println("Start create dependencies matrix....");
while(iterator.hasNext()) {
Entity entity = iterator.next();
if (!entity.inScope()) continue;
if (isStructureEntityType(entity)){
String name = entity.getQualifiedName() + "|" + entity.getClass().getSimpleName().replace("Entity","");
dependencyMatrix.addNode(name,entity.getId());
}
int fileEntityFrom = getStructureEntityIdNoException(entity);
if (fileEntityFrom==-1) continue;
for (Relation relation:entity.getRelations()) {
Entity relatedEntity = relation.getEntity();
if (relatedEntity==null) continue;
if (relatedEntity instanceof CandidateTypes) {
List<TypeEntity> candidateTypes = ((CandidateTypes)relatedEntity).getCandidateTypes();
for (TypeEntity candidateType:candidateTypes) {
if (candidateType.getId()>=0) {
int fileEntityTo = getStructureEntityIdNoException(candidateType);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity,candidateType,relation.getFromLine());
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}else {
if (relatedEntity.getId()>=0) {
int fileEntityTo = getStructureEntityIdNoException(relatedEntity);
if (fileEntityTo!=-1) {
DependencyDetail detail = buildDescription(entity, relatedEntity, relation.getFromLine());
dependencyMatrix.addDependency(relation.getType(), fileEntityFrom,fileEntityTo,1,detail);
}
}
}
}
}
System.out.println("Finish create dependencies matrix....");
return dependencyMatrix;
protected String nameOf(Entity entity) {
return entity.getQualifiedName() + "|" + entity.getClass().getSimpleName().replace("Entity","");
}
private boolean isStructureEntityType(Entity entity) {
@Override
protected boolean outputLevelMatch(Entity entity) {
if (entity instanceof FileEntity) return false;
if (entity instanceof TypeEntity) return true; //package included
if (entity instanceof VarEntity && entity.getParent() instanceof TypeEntity) return true;
@ -95,7 +43,13 @@ public class StructureDependencyGenerator extends DependencyGenerator{
return false;
}
private int getStructureEntityIdNoException(Entity entity) {
@Override
public String getType() {
return "structure";
}
@Override
protected int upToOutputLevelEntityId(EntityRepo entityRepo, Entity entity) {
Entity ancestor = getAncestorOfType(entity);
if (ancestor==null) {
return -1;
@ -106,7 +60,7 @@ public class StructureDependencyGenerator extends DependencyGenerator{
public Entity getAncestorOfType(Entity fromEntity) {
while(fromEntity!=null) {
if (isStructureEntityType(fromEntity))
if (outputLevelMatch(fromEntity))
return fromEntity;
if (fromEntity.getParent()==null) return null;
fromEntity = fromEntity.getParent();

View File

@ -24,27 +24,28 @@ SOFTWARE.
package depends.matrix.core;
import multilang.depends.util.file.path.FilenameWritter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import multilang.depends.util.file.path.FilenameWritter;
import static depends.deptypes.DependencyType.POSSIBLE_DEP;
public class DependencyMatrix {
private HashMap<String, DependencyPair> dependencyPairs = new HashMap<>();
private final boolean outputSelfDependencies;
private HashMap<String, DependencyPair> dependencyPairs = new HashMap<>();
private ArrayList<String> nodes = new ArrayList<>();
private HashMap<Integer,String> nodeIdToName = new HashMap<>();
private Integer relationCount=0;
private List<String> typeFilter;
public DependencyMatrix() {
}
public DependencyMatrix(int size) {
dependencyPairs = new HashMap<>(size);
}
public DependencyMatrix(List<String> typeFilter) {
public DependencyMatrix(int size, List<String> typeFilter,boolean outputSelfDependencies) {
dependencyPairs = new HashMap<>(size);
this.typeFilter = typeFilter;
this.outputSelfDependencies = outputSelfDependencies;
}
public Collection<DependencyPair> getDependencyPairs() {
return dependencyPairs.values();
}
@ -57,7 +58,10 @@ public class DependencyMatrix {
public void addDependency(String depType, Integer from, Integer to, int weight,List<DependencyDetail> details) {
if (typeFilter!=null && (!typeFilter.contains(depType)))
return;
if(from.equals(to) || from == -1 || to == -1) {
if (!outputSelfDependencies && from.equals(to) ){
return;
}
if( from == -1 || to == -1) {
return;
}
if (dependencyPairs.get(DependencyPair.key(from,to))==null) {
@ -65,31 +69,29 @@ public class DependencyMatrix {
}
DependencyPair dependencyPair = dependencyPairs.get(DependencyPair.key(from,to));
dependencyPair.addDependency(depType,weight,details);
relationCount+=weight;
}
public void addDependency(String depType, Integer from, Integer to, int weight,DependencyDetail detail) {
if (typeFilter!=null && (!typeFilter.contains(depType)))
if (typeFilter!=null && (!typeFilter.contains(depType.replace(POSSIBLE_DEP,""))))
return;
if (!outputSelfDependencies && from.equals(to) ){
return;
}
if( from == -1 || to == -1) {
return;
if(from.equals(to) || from == -1 || to == -1) {
return;
}
if (dependencyPairs.get(DependencyPair.key(from,to))==null) {
dependencyPairs.put(DependencyPair.key(from,to),new DependencyPair(from,to));
}
DependencyPair dependencyPair = dependencyPairs.get(DependencyPair.key(from,to));
dependencyPair.addDependency(depType,weight,detail);
relationCount+=weight;
}
public ArrayList<String> getNodes() {
return nodes;
}
public Integer relationCount() {
return relationCount;
}
public DependencyMatrix reWriteFilenamePattern(FilenameWritter filenameRewritter) {
this.nodeIdToName = new HashMap<>();
for (int i=0;i<nodes.size();i++) {
@ -103,4 +105,8 @@ public class DependencyMatrix {
public String getNodeName(Integer key) {
return nodeIdToName.get(key);
}
public boolean isOutputSelfDependencies(){
return outputSelfDependencies;
}
}

View File

@ -5,12 +5,14 @@ import java.io.Serializable;
public class LocationInfo implements Serializable {
String object;
String file;
String type;
Integer lineNumber;
public LocationInfo(String object, String file, Integer lineNumber){
public LocationInfo(String object, String type, String file, Integer lineNumber){
if (lineNumber ==null) lineNumber = 0;
this.object = object;
this.file = file;
this.lineNumber = lineNumber;
this.type = type;
}
public String getObject() {
@ -21,12 +23,16 @@ public class LocationInfo implements Serializable {
return file;
}
public String getType() {
return type;
}
public Integer getLineNumber() {
return lineNumber;
}
@Override
public String toString(){
return object + "(" + file + ":"+ lineNumber +")";
return object + "<" + type +">" + "(" + file + ":"+ lineNumber +")";
}
}

View File

@ -61,7 +61,7 @@ public class MatrixLevelReducer {
return o1.compareTo(o2);
}
});
DependencyMatrix ordered = new DependencyMatrix();
DependencyMatrix ordered = new DependencyMatrix(0,null,false);
for (int id=0;id<reMappedNodes.size();id++) {
nodesMap.put(reMappedNodes.get(id), id);
ordered.addNode(reMappedNodes.get(id), id);

View File

@ -23,14 +23,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import depends.matrix.core.DependencyMatrix;
import depends.matrix.core.DependencyPair;
import depends.matrix.core.DependencyValue;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
public class OrderedMatrixGenerator {
private DependencyMatrix matrix;
public OrderedMatrixGenerator(DependencyMatrix matrix) {
@ -46,7 +46,7 @@ public class OrderedMatrixGenerator {
}
});
DependencyMatrix ordered = new DependencyMatrix((int)(matrix.getDependencyPairs().size()/0.75+1));
DependencyMatrix ordered = new DependencyMatrix((int)(matrix.getDependencyPairs().size()/0.75+1),null,matrix.isOutputSelfDependencies());
HashMap<String, Integer> nodesMap = new HashMap<>();
for (int id=0;id<reMappedNodes.size();id++) {
nodesMap.put(reMappedNodes.get(id), id);

View File

@ -26,8 +26,9 @@ package depends.relations;
import depends.entity.*;
import depends.entity.repo.BuiltInType;
import depends.entity.repo.EntityRepo;
import depends.entity.repo.NullBuiltInType;
import depends.extractor.AbstractLangProcessor;
import depends.extractor.UnsolvedBindings;
import depends.extractor.empty.EmptyBuiltInType;
import depends.importtypes.Import;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -37,7 +38,7 @@ import java.util.*;
public class BindingResolver implements IBindingResolver{
private BuiltInType buildInTypeManager = new NullBuiltInType();
private BuiltInType buildInTypeManager = new EmptyBuiltInType();
private ImportLookupStrategy importLookupStrategy;
private Set<UnsolvedBindings> unsolvedSymbols = new HashSet<>();
private EntityRepo repo;
@ -47,17 +48,18 @@ public class BindingResolver implements IBindingResolver{
private boolean isDuckTypingDeduce = true;
private static Logger logger = LoggerFactory.getLogger(IBindingResolver.class);
public BindingResolver(EntityRepo repo, ImportLookupStrategy importLookupStrategy, BuiltInType buildInTypeManager,
public BindingResolver(AbstractLangProcessor langProcessor,
boolean isCollectUnsolvedBindings, boolean isDuckTypingDeduce) {
this.repo = repo;
this.importLookupStrategy = importLookupStrategy;
this.buildInTypeManager = buildInTypeManager;
this.repo = langProcessor.getEntityRepo();
this.importLookupStrategy = langProcessor.getImportLookupStrategy();
this.buildInTypeManager = langProcessor.getBuiltInType();
this.isCollectUnsolvedBindings = isCollectUnsolvedBindings;
this.isDuckTypingDeduce = isDuckTypingDeduce;
unsolvedSymbols= new HashSet<>();
importLookupStrategy.setBindingResolver(this);
}
@Override
public Set<UnsolvedBindings> resolveAllBindings(boolean isEagerExpressionResolve) {
System.out.println("Resolve type bindings....");
@ -137,9 +139,6 @@ public class BindingResolver implements IBindingResolver{
if (buildInTypeManager.isBuiltInType(rawName.getName())) {
return TypeEntity.buildInType;
}
if (buildInTypeManager.isBuiltInTypePrefix(rawName.getName())) {
return TypeEntity.buildInType;
}
// qualified name will first try global name directly
if (rawName.startsWith(".")) {
rawName = rawName.substring(1);
@ -213,7 +212,7 @@ public class BindingResolver implements IBindingResolver{
return precendenceEntity;
}
if (nameIndex == -1) {
System.err.println("error");
System.err.println("No expected symbols: names"+Arrays.toString(names) +", index=" + nameIndex);
return null;
}
//If it is not an entity with types (not a type, var, function), fall back to itself

View File

@ -35,11 +35,13 @@ public class Relation {
private Location location;
private String type;
private Entity toEntity;
private boolean possibleDependency;
public Relation(String type, Entity toEntity,Location location) {
public Relation(String type, Entity toEntity,Location location, boolean possibleDependency) {
this.toEntity = toEntity;
this.type = type;
this.location = location;
this.possibleDependency = possibleDependency;
}
public String getType() {
return type;
@ -57,4 +59,8 @@ public class Relation {
if (location==null) return null;
return location.getLine();
}
public boolean possible() {
return this.possibleDependency;
}
}

View File

@ -41,11 +41,11 @@ public class RelationCounter {
private boolean callAsImpl;
private AbstractLangProcessor langProcessor;
public RelationCounter(EntityRepo repo, boolean callAsImpl, AbstractLangProcessor langProcessor, IBindingResolver bindingResolver) {
public RelationCounter(EntityRepo repo, AbstractLangProcessor langProcessor, IBindingResolver bindingResolver) {
this.entities = repo.getFileEntities();
this.bindingResolver = bindingResolver;
this.repo = repo;
this.callAsImpl = callAsImpl;
this.callAsImpl = langProcessor.supportCallAsImpl();
this.langProcessor = langProcessor;
}
@ -79,7 +79,7 @@ public class RelationCounter {
if (var.getType()!=null)
entity.addRelation(buildRelation(entity,DependencyType.CONTAIN,var.getType(),var.getLocation()));
for (Entity type:var.getResolvedTypeParameters()) {
var.addRelation(buildRelation(var, DependencyType.PARAMETER,type,type.getLocation()));
var.addRelation(buildRelation(var, DependencyType.PARAMETER,type));
}
}
for (Entity type:entity.getResolvedAnnotations()) {
@ -102,12 +102,13 @@ public class RelationCounter {
continue;
}
Entity referredEntity = expression.getReferredEntity();
addRelationFromExpression(entity, expression, referredEntity);
addRelationFromExpression(entity, expression, referredEntity, false);
}
entity.clearExpressions();
}
private void addRelationFromExpression(ContainerEntity entity, Expression expression, Entity referredEntity) {
private void addRelationFromExpression(ContainerEntity entity, Expression expression, Entity referredEntity, boolean possibleDependency) {
if (referredEntity==null) {
return;
@ -117,7 +118,7 @@ public class RelationCounter {
}
if (referredEntity instanceof MultiDeclareEntities) {
for (Entity e:((MultiDeclareEntities)referredEntity).getEntities()) {
addRelationFromExpression(entity,expression,e);
addRelationFromExpression(entity,expression,e, true);
}
return;
}
@ -127,7 +128,7 @@ public class RelationCounter {
/* if it is a FunctionEntityProto, add Relation to all Impl Entities*/
if (callAsImpl && referredEntity instanceof FunctionEntityProto) {
if (entity.getAncestorOfType(FileEntity.class).getId().equals(referredEntity.getAncestorOfType(FileEntity.class).getId())){
entity.addRelation(buildRelation(entity,DependencyType.CALL,referredEntity,expression.getLocation()));
entity.addRelation(buildRelation(entity,DependencyType.CALL,referredEntity,expression.getLocation(), possibleDependency));
}else {
Entity multiDeclare = repo.getEntity(referredEntity.getQualifiedName());
if (multiDeclare instanceof MultiDeclareEntities) {
@ -135,56 +136,63 @@ public class RelationCounter {
List<Entity> entities = m.getEntities().stream().filter(item -> (item instanceof FunctionEntityImpl))
.collect(Collectors.toList());
for (Entity e : entities) {
entity.addRelation(expression, buildRelation(entity, DependencyType.IMPLLINK, e, expression.getLocation()));
entity.addRelation(expression, buildRelation(entity, DependencyType.LINK, e, expression.getLocation(), true));
matched = true;
}
}
}
}
entity.addRelation(buildRelation(entity,DependencyType.CALL,referredEntity,expression.getLocation()));
entity.addRelation(buildRelation(entity,DependencyType.CALL,referredEntity,expression.getLocation(), possibleDependency));
matched = true;
}
if (expression.isCreate()) {
entity.addRelation(buildRelation(entity,DependencyType.CREATE,referredEntity,expression.getLocation()));
entity.addRelation(buildRelation(entity,DependencyType.CREATE,referredEntity,expression.getLocation(), possibleDependency));
matched = true;
}
if (expression.isThrow()) {
entity.addRelation(buildRelation(entity,DependencyType.THROW,referredEntity,expression.getLocation()));
entity.addRelation(buildRelation(entity,DependencyType.THROW,referredEntity,expression.getLocation(), possibleDependency));
matched = true;
}
if (expression.isCast()) {
entity.addRelation(buildRelation(entity,DependencyType.CAST,referredEntity,expression.getLocation()));
entity.addRelation(buildRelation(entity,DependencyType.CAST,referredEntity,expression.getLocation(), possibleDependency));
matched = true;
}
if (!matched) {
if (callAsImpl && repo.getEntity(referredEntity.getQualifiedName()) instanceof MultiDeclareEntities &&
(referredEntity instanceof VarEntity ||referredEntity instanceof FunctionEntity)) {
if (entity.getAncestorOfType(FileEntity.class).getId().equals(referredEntity.getAncestorOfType(FileEntity.class).getId())){
entity.addRelation(buildRelation(entity,DependencyType.USE,referredEntity,expression.getLocation()));
entity.addRelation(buildRelation(entity,DependencyType.USE,referredEntity,expression.getLocation(), possibleDependency));
}else {
MultiDeclareEntities m = (MultiDeclareEntities) (repo.getEntity(referredEntity.getQualifiedName()));
for (Entity e : m.getEntities()) {
if (e == referredEntity) {
entity.addRelation(expression, buildRelation(entity, DependencyType.USE, e, expression.getLocation()));
entity.addRelation(expression, buildRelation(entity, DependencyType.USE, e, expression.getLocation(), true));
} else {
entity.addRelation(expression, buildRelation(entity, DependencyType.IMPLLINK, e, expression.getLocation()));
entity.addRelation(expression, buildRelation(entity, DependencyType.LINK, e, expression.getLocation(), true));
}
matched = true;
}
}
}
else {
entity.addRelation(expression,buildRelation(entity,DependencyType.USE,referredEntity,expression.getLocation()));
entity.addRelation(expression,buildRelation(entity,DependencyType.USE,referredEntity,expression.getLocation(), possibleDependency));
}
}
}
private Relation buildRelation(Entity from, String type, Entity referredEntity) {
return buildRelation(from,type,referredEntity,from.getLocation());
private Relation buildRelation(Entity from, String type, Entity referredEntity, boolean possibleDependency) {
return buildRelation(from,type,referredEntity,from.getLocation(), possibleDependency);
}
private Relation buildRelation(ContainerEntity from, String type, Entity referredEntity) {
return buildRelation(from,type,referredEntity, false);
}
private Relation buildRelation(Entity from, String type, Entity referredEntity,Location location) {
return buildRelation(from,type,referredEntity, location,false);
}
private Relation buildRelation(Entity from, String type, Entity referredEntity,Location location, boolean possibleDependency) {
if (referredEntity instanceof AliasEntity) {
if (from.getAncestorOfType(FileEntity.class).equals(referredEntity.getAncestorOfType(FileEntity.class))) {
AliasEntity alias = ((AliasEntity) referredEntity);
@ -193,9 +201,11 @@ public class RelationCounter {
}
}
}
if (referredEntity instanceof CandidateTypes)
possibleDependency = true;
if (this.langProcessor==null)
return new Relation(type,referredEntity,location);
return new Relation(langProcessor.getRelationMapping(type),referredEntity,location);
return new Relation(type,referredEntity,location, possibleDependency);
return new Relation(langProcessor.getRelationMapping(type),referredEntity,location, possibleDependency);
}
private void computeTypeRelations(TypeEntity type) {

View File

@ -24,27 +24,27 @@ public abstract class ParserTest {
protected void init(){
entityRepo = langProcessor.getEntityRepo();
bindingResolver = new BindingResolver(langProcessor.getEntityRepo(),langProcessor.getImportLookupStrategy(),langProcessor.getBuiltInType(),true,false);
bindingResolver = new BindingResolver(langProcessor,true,false);
langProcessor.bindingResolver = bindingResolver;
TemporaryFile.reset();
}
protected void init(boolean duckTypingDeduce){
entityRepo = langProcessor.getEntityRepo();
bindingResolver = new BindingResolver(langProcessor.getEntityRepo(),langProcessor.getImportLookupStrategy(),langProcessor.getBuiltInType(),false,duckTypingDeduce);
bindingResolver = new BindingResolver(langProcessor,false,duckTypingDeduce);
langProcessor.bindingResolver = bindingResolver;
TemporaryFile.reset();
}
public Set<UnsolvedBindings> resolveAllBindings() {
Set<UnsolvedBindings> result = bindingResolver.resolveAllBindings(langProcessor.isEagerExpressionResolve());
new RelationCounter(entityRepo,false,langProcessor, bindingResolver).computeRelations();
new RelationCounter(entityRepo,langProcessor, bindingResolver).computeRelations();
return result;
}
protected Set<UnsolvedBindings> resolveAllBindings(boolean callAsImpl) {
Set<UnsolvedBindings> result = bindingResolver.resolveAllBindings(langProcessor.isEagerExpressionResolve());
new RelationCounter(entityRepo,callAsImpl,langProcessor, bindingResolver).computeRelations();
new RelationCounter(entityRepo,langProcessor, bindingResolver).computeRelations();
return result;
}

View File

@ -17,8 +17,8 @@ public class AliasTest extends CppParserTest{
@Test
public void test_genericTypes() throws IOException {
String src = "./src/test/resources/cpp-code-examples/Alias.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("bar"), DependencyType.CALL, "F.foo");
}
@ -26,8 +26,8 @@ public class AliasTest extends CppParserTest{
@Test
public void test_refer_to_alias_type_should_work() throws IOException {
String src = "./src/test/resources/cpp-code-examples/AliasType.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("C"), DependencyType.INHERIT, "A");
}
@ -40,8 +40,8 @@ public class AliasTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("bar"), DependencyType.CALL, "foo");

View File

@ -19,8 +19,8 @@ public class ConstructFunctionReturnValueTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
//assertEquals(1,repo.getEntity("UnderTest").getRelations().size());
@ -33,8 +33,8 @@ public class ConstructFunctionReturnValueTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
//assertEquals(1,repo.getEntity("UnderTest").getRelations().size());

View File

@ -1,5 +1,6 @@
package depends.extractor.cpp;
import depends.deptypes.DependencyType;
import multilang.depends.util.file.FileUtil;
import org.junit.Before;
import org.junit.Test;
@ -20,8 +21,8 @@ public class ContainRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
assertEquals(1, entityRepo.getEntity("UnderTest").getRelations().size());
@ -35,8 +36,8 @@ public class ContainRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(FileUtil.uniqFilePath(src));
}
resolveAllBindings();
assertEquals(2, entityRepo.getEntity("UnderTest").getRelations().size());
@ -50,8 +51,8 @@ public class ContainRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("UnderTest"), DependencyType.CONTAIN, "Member");
@ -67,8 +68,8 @@ public class ContainRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
}

View File

@ -17,8 +17,8 @@ public class CppExpressionTest extends CppParserTest{
@Test
public void test_expressions() throws IOException {
String src = "./src/test/resources/cpp-code-examples/Expressions.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
Entity e = entityRepo.getEntity("foo");
this.assertContainsRelation(e, DependencyType.PARAMETER,"ClassA");
@ -35,8 +35,8 @@ public class CppExpressionTest extends CppParserTest{
@Test
public void test_should_not_count_expr_duplicated() throws IOException {
String src = "./src/test/resources/cpp-code-examples/DupExpressions.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
Entity e = entityRepo.getEntity("foo");
assertEquals(4,e.getRelations().size());

View File

@ -15,8 +15,8 @@ public class CppParameterParserTest extends CppParserTest{
@Test
public void test_parameter() throws IOException {
String src = "./src/test/resources/cpp-code-examples/FunctionParameters.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
assertEquals(4, entityRepo.getEntity("FunctionParameters.function_with_parameters_same_type").getRelations().size());
}

View File

@ -17,7 +17,7 @@ public abstract class CppParserTest extends ParserTest{
macroRepo = new MacroEhcacheRepo(entityRepo);
}
public CppFileParser createParser(String src) {
return new CdtCppFileParser(src, entityRepo, preprocessorHandler, bindingResolver,macroRepo );
public CppFileParser createParser() {
return new CdtCppFileParser(entityRepo, preprocessorHandler, bindingResolver,macroRepo );
}
}

View File

@ -21,8 +21,8 @@ public class DuplicateDeclarationTest extends CppParserTest {
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
Entity e = entityRepo.getEntity("X.invoke");

View File

@ -21,8 +21,8 @@ public class ForwardDeclareTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
//TODO: to be complete

View File

@ -19,8 +19,8 @@ public class GenericTypeTest extends CppParserTest {
@Test
public void test_templateSpecializationOfStruct() throws IOException {
String src = "./src/test/resources/cpp-code-examples/template/TempateStructure.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
assertNotNull(entityRepo.getEntity("hash"));
}
@ -28,8 +28,8 @@ public class GenericTypeTest extends CppParserTest {
@Test
public void test_genericTypesVarParameterReference() throws IOException {
String src = "./src/test/resources/cpp-code-examples/template/GenericTypes.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("xStack"), DependencyType.PARAMETER, "X");
}
@ -37,8 +37,8 @@ public class GenericTypeTest extends CppParserTest {
@Test
public void test_genericTypesExtends() throws IOException {
String src = "./src/test/resources/cpp-code-examples/template/GenericTypes.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("XStack"), DependencyType.INHERIT, "Stack");
}
@ -46,8 +46,8 @@ public class GenericTypeTest extends CppParserTest {
@Test
public void test_GenericTypeEmbededShouldBeIdentified() throws IOException {
String src = "./src/test/resources/cpp-code-examples/template/EmbededTemplates.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("GenericTypeEmbededTest"), DependencyType.CONTAIN, "MyHashMap");
this.assertContainsRelation(entityRepo.getEntity("GenericTypeEmbededTest.data"), DependencyType.PARAMETER, "MyList");
@ -57,8 +57,8 @@ public class GenericTypeTest extends CppParserTest {
@Test
public void test_TemplateWithDots() throws IOException {
String src = "./src/test/resources/cpp-code-examples/template/TemplateWithDots.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
assertNotNull(entityRepo.getEntity("foo.t2"));
}
@ -66,8 +66,8 @@ public class GenericTypeTest extends CppParserTest {
@Test
public void test_TemplateInReturn() throws IOException {
String src = "./src/test/resources/cpp-code-examples/template/TemplateInReturnValue.cpp";
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
FunctionEntity func = (FunctionEntity) entityRepo.getEntity("get");
this.assertContainsRelation(func, DependencyType.RETURN, "std.tuple_element.type");

View File

@ -24,8 +24,8 @@ public class ImplementRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser =createParser(src);
parser.parse();
CppFileParser parser =createParser();
parser.parse(src);
}
resolveAllBindings();
MultiDeclareEntities multiDeclare = (MultiDeclareEntities)( entityRepo.getEntity("foo"));

View File

@ -30,8 +30,8 @@ public class IncludeRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
File f = new File(srcs[0]);
@ -49,8 +49,8 @@ public class IncludeRelationTest extends CppParserTest{
List<String> includePaths = new ArrayList<>();
includePaths.add("./src/test/resources/cpp-code-examples/includesTest/path/");
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
File f = new File(srcs[0]);
@ -65,8 +65,8 @@ public class IncludeRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
assertEquals("abc",((AliasEntity) entityRepo.getEntity("abc_t")).getOriginType().getRawName().uniqName());
@ -82,8 +82,8 @@ public class IncludeRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
this.assertContainsRelation(this.entityRepo.getEntity("foo"), DependencyType.CALL, "bar");
@ -99,8 +99,8 @@ public class IncludeRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
this.assertContainsRelation(this.entityRepo.getEntity(FileUtil.uniqFilePath(srcs[0])), DependencyType.IMPORT, FileUtil.uniqFilePath(srcs[1]));

View File

@ -22,8 +22,8 @@ public class MacroRelationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
Entity e = entityRepo.getEntity("foo");

View File

@ -24,8 +24,8 @@ public class MacroTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
@ -40,8 +40,8 @@ public class MacroTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
@ -56,8 +56,8 @@ public class MacroTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();

View File

@ -20,8 +20,8 @@ public class ParseErrorTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
}
@ -33,11 +33,11 @@ public class ParseErrorTest extends CppParserTest{
};
for (String src:srcs) {
CdtCppFileParser parser = (CdtCppFileParser)createParser(src);
CdtCppFileParser parser = (CdtCppFileParser)createParser();
Map<String, String> macroMap = new HashMap<>();
macroMap.put("AP_DECLARE(x)","x");
parser.parse(true,macroMap);
parser.parse(src,macroMap);
}
resolveAllBindings();
}

View File

@ -26,8 +26,8 @@ public class RelationInSameFileTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings(true);
Entity bar = entityRepo.getEntity(FileUtil.uniqFilePath(srcs[0]));

View File

@ -26,8 +26,8 @@ public class RelationToImplementationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings(true);
Entity bar = entityRepo.getEntity("bar");
@ -53,8 +53,8 @@ public class RelationToImplementationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings(true);
Entity bar = entityRepo.getEntity("baz");
@ -77,8 +77,8 @@ public class RelationToImplementationTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings(true);
Entity bar = entityRepo.getEntity("qux");

View File

@ -19,8 +19,8 @@ public class TypeDefTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("foo"), DependencyType.PARAMETER, "MyInt");

View File

@ -21,8 +21,8 @@ public class UsingTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
Entity e = entityRepo.getEntity("foo");
@ -39,8 +39,8 @@ public class UsingTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
Entity e = entityRepo.getEntity("bar");

View File

@ -21,8 +21,8 @@ public class extendsTest extends CppParserTest{
};
for (String src:srcs) {
CppFileParser parser = createParser(src);
parser.parse();
CppFileParser parser = createParser();
parser.parse(src);
}
resolveAllBindings();
Entity e = entityRepo.getEntity("B");

View File

@ -18,8 +18,8 @@ public class GoFunctionsTest extends GolangParserTest {
@Test
public void test_could_parse_function() throws IOException {
String src = "./src/test/resources/go-code-examples/func.go";
GoFileParser parser =createParser(src);
parser.parse();
GoFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
assertNotNull(entityRepo.getEntity("main"));
}
@ -28,8 +28,8 @@ public class GoFunctionsTest extends GolangParserTest {
@Ignore
public void test_could_parse_struct_type() throws IOException {
String src = "./src/test/resources/go-code-examples/struct.go";
GoFileParser parser =createParser(src);
parser.parse();
GoFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
assertNotNull(entityRepo.getEntity("Books"));
}
@ -37,8 +37,8 @@ public class GoFunctionsTest extends GolangParserTest {
@Ignore
public void test_could_parse_struct_members() throws IOException {
String src = "./src/test/resources/go-code-examples/struct.go";
GoFileParser parser =createParser(src);
parser.parse();
GoFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
assertNotNull(entityRepo.getEntity("Books"));
TypeEntity book = (TypeEntity)entityRepo.getEntity("Books");

View File

@ -9,8 +9,8 @@ public abstract class GolangParserTest extends ParserTest{
super.init();
}
public GoFileParser createParser(String src) {
return new GoFileParser(src,entityRepo, bindingResolver);
public GoFileParser createParser() {
return new GoFileParser(entityRepo, bindingResolver);
}
}

View File

@ -17,8 +17,8 @@ public class InheritTypeTest extends JavaParserTest {
@Test
public void should_handle_inherited_type_correctly() throws IOException {
String src = "./src/test/resources/java-code-examples/InheritTest.java";
JavaFileParser parser =createParser(src);
parser.parse();
JavaFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
assertEquals(1,entityRepo.getEntity("InheritTest").getRelations().size());
}

View File

@ -17,8 +17,8 @@ public class JavaAnnotationParserTest extends JavaParserTest {
@Test
public void test_could_parse_annotationType() throws IOException {
String src = "./src/test/resources/java-code-examples/AnnotationTest.java";
JavaFileParser parser =createParser(src);
parser.parse();
JavaFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
assertEquals(1,entityRepo.getEntity("AnnotationTest.value").getRelations().size());
}
@ -26,8 +26,8 @@ public class JavaAnnotationParserTest extends JavaParserTest {
@Test
public void test_could_detect_annotation_in_class_level() throws IOException {
String src = "./src/test/resources/java-code-examples/AnnotationTest.java";
JavaFileParser parser =createParser(src);
parser.parse();
JavaFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("TheClass"), DependencyType.ANNOTATION, "AnnotationTest");
}
@ -35,8 +35,8 @@ public class JavaAnnotationParserTest extends JavaParserTest {
@Test
public void test_could_detect_annotation_in_function_level() throws IOException {
String src = "./src/test/resources/java-code-examples/AnnotationTest.java";
JavaFileParser parser =createParser(src);
parser.parse();
JavaFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("TheFunction.foo"), DependencyType.ANNOTATION, "AnnotationTest");
}
@ -44,8 +44,8 @@ public class JavaAnnotationParserTest extends JavaParserTest {
@Test
public void test_could_detect_no_annotation_in_function_level() throws IOException {
String src = "./src/test/resources/java-code-examples/AnnotationTest.java";
JavaFileParser parser =createParser(src);
parser.parse();
JavaFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
this.assertNotContainsRelation(entityRepo.getEntity("TheFunction.bar"), DependencyType.ANNOTATION, "AnnotationTest");
}
@ -53,8 +53,8 @@ public class JavaAnnotationParserTest extends JavaParserTest {
@Test
public void test_could_detect_annotation_in_miscs() throws IOException {
String src = "./src/test/resources/java-code-examples/AnnotationTest.java";
JavaFileParser parser =createParser(src);
parser.parse();
JavaFileParser parser =createParser();
parser.parse(src);
resolveAllBindings();
this.assertContainsRelation(entityRepo.getEntity("TheClass.TheClass"), DependencyType.ANNOTATION, "AnnotationTest");
this.assertContainsRelation(entityRepo.getEntity("TheEnum"), DependencyType.ANNOTATION, "AnnotationTest");

View File

@ -17,8 +17,8 @@ public class JavaCallExpressionTest extends JavaParserTest {
@Test
public void test() throws IOException {
String src = "./src/test/resources/java-code-examples/SimpleExpressionCallTest.java";
JavaFileParser parser = createParser(src);
parser.parse();
JavaFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
}

View File

@ -17,8 +17,8 @@ public class JavaComplexExpressionTest extends JavaParserTest {
@Test
public void test_complexExpression() throws IOException {
String src = "./src/test/resources/java-code-examples/ComplexExpressionTest.java";
JavaFileParser parser = createParser(src);
parser.parse();
JavaFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
ContainerEntity entity = (ContainerEntity)(entityRepo.getEntity("ComplexExpressionTest.other"));
assertEquals(3,entity.getRelations().size());

View File

@ -1,10 +1,10 @@
package depends.extractor.java;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class JavaCylicInheritTest extends JavaParserTest{
@Before
public void setUp() {
@ -14,10 +14,8 @@ public class JavaCylicInheritTest extends JavaParserTest{
@Test(timeout=3000L)
public void test_cyclic_should_not_occur_inifinite_test() throws IOException {
String src = "./src/test/resources/java-code-examples/CyclicInherit.java";
JavaFileParser parser = createParser(src);
parser.parse();
JavaFileParser parser = createParser();
parser.parse(src);
resolveAllBindings();
}
}

Some files were not shown because too many files have changed in this diff Show More