Skip to content

Commit

Permalink
Combines TypeCollector with GraphBuilder.
Browse files Browse the repository at this point in the history
	Change on 2016/11/25 by kstanger <kstanger@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=140195243
  • Loading branch information
kstanger authored and Keith Stanger committed Dec 1, 2016
1 parent ddbd817 commit 9074582
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 153 deletions.
3 changes: 1 addition & 2 deletions cycle_finder/Makefile
Expand Up @@ -41,8 +41,7 @@ JAVA_SOURCES = \
com/google/devtools/cyclefinder/NameList.java \
com/google/devtools/cyclefinder/Options.java \
com/google/devtools/cyclefinder/ReferenceGraph.java \
com/google/devtools/cyclefinder/Tarjans.java \
com/google/devtools/cyclefinder/TypeCollector.java
com/google/devtools/cyclefinder/Tarjans.java

RESOURCES = \
com/google/devtools/cyclefinder/CycleFinder.properties \
Expand Down
Expand Up @@ -129,9 +129,10 @@ private File stripIncompatible(
}

public List<List<Edge>> findCycles() throws IOException {
final TypeCollector typeCollector = new TypeCollector();
Parser parser = createParser(options);
final CaptureFields captureFields = new CaptureFields();
final GraphBuilder graphBuilder =
new GraphBuilder(captureFields, NameList.createFromFiles(options.getWhitelistFiles()));

List<String> sourceFiles = options.getSourceFiles();
File strippedDir = stripIncompatible(sourceFiles, parser);
Expand All @@ -140,7 +141,7 @@ public List<List<Edge>> findCycles() throws IOException {
@Override
public void handleParsedUnit(String path, CompilationUnit unit) {
new LambdaTypeElementAdder(unit).run();
typeCollector.visitAST(unit);
graphBuilder.visitAST(unit);
new OuterReferenceResolver(unit).run();
captureFields.collect(unit);
}
Expand All @@ -154,10 +155,7 @@ public void handleParsedUnit(String path, CompilationUnit unit) {
}

// Construct the graph and find cycles.
ReferenceGraph graph = new GraphBuilder(
typeCollector, captureFields, NameList.createFromFiles(options.getWhitelistFiles()))
.constructGraph()
.getGraph();
ReferenceGraph graph = graphBuilder.constructGraph().getGraph();
for (ReferenceGraph component : graph.getStronglyConnectedComponents(getSeedNodes(graph))) {
handleStronglyConnectedComponent(component);
}
Expand Down
Expand Up @@ -14,13 +14,21 @@

package com.google.devtools.cyclefinder;

import com.google.common.base.Strings;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.devtools.j2objc.ast.AnonymousClassDeclaration;
import com.google.devtools.j2objc.ast.ClassInstanceCreation;
import com.google.devtools.j2objc.ast.CompilationUnit;
import com.google.devtools.j2objc.ast.MethodInvocation;
import com.google.devtools.j2objc.ast.TreeVisitor;
import com.google.devtools.j2objc.ast.TypeDeclaration;
import com.google.devtools.j2objc.jdt.BindingConverter;
import com.google.devtools.j2objc.util.ElementUtil;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
Expand All @@ -38,14 +46,12 @@
*/
public class GraphBuilder {

private final Map<String, TypeNode> allTypes;
private final Map<String, TypeNode> allTypes = new HashMap<>();
private final CaptureFields captureFields;
private final NameList whitelist;
private final ReferenceGraph graph = new ReferenceGraph();

public GraphBuilder(
TypeCollector typeCollector, CaptureFields captureFields, NameList whitelist) {
this.allTypes = typeCollector.getTypes();
public GraphBuilder(CaptureFields captureFields, NameList whitelist) {
this.captureFields = captureFields;
this.whitelist = whitelist;
}
Expand All @@ -70,6 +76,41 @@ private void addEdge(Edge e) {
}
}

private void addNode(TypeNode node) {
allTypes.put(node.getSignature(), node);
}

private void visitType(ITypeBinding type) {
if (type == null) {
return;
}
type = getElementType(type);
if (allTypes.containsKey(type.getKey()) || type.isPrimitive() || type.isRawType()) {
return;
}
if (hasNestedWildcard(type)) {
// Avoid infinite recursion caused by nested wildcard types.
return;
}
addNode(new TypeNode(type, getNameForType(type)));
followType(type);
}

private void followType(ITypeBinding type) {
visitType(type.getSuperclass());
visitType(type.getDeclaringClass());
for (IVariableBinding field : type.getDeclaredFields()) {
ITypeBinding fieldType = field.getType();
for (ITypeBinding typeParam : fieldType.getTypeArguments()) {
visitType(typeParam);
}
visitType(fieldType);
}
for (ITypeBinding interfaze : type.getInterfaces()) {
visitType(interfaze);
}
}

private void addFieldEdges() {
for (TypeNode node : allTypes.values()) {
ITypeBinding type = node.getTypeBinding();
Expand Down Expand Up @@ -195,4 +236,67 @@ private void addAnonymousClassCaptureEdges() {
}
}
}

private static String getNameForType(ITypeBinding type) {
String name = type.getName();
return Strings.isNullOrEmpty(name) ? type.getKey() : name;
}

private static boolean hasWildcard(ITypeBinding type) {
if (type.isWildcardType()) {
return true;
}
for (ITypeBinding typeParam : type.getTypeArguments()) {
if (hasWildcard(typeParam)) {
return true;
}
}
return false;
}

private static boolean hasNestedWildcard(ITypeBinding type) {
ITypeBinding bound = type.getBound();
if (bound != null && hasWildcard(bound)) {
return true;
}
for (ITypeBinding typeParam : type.getTypeArguments()) {
if (hasNestedWildcard(typeParam)) {
return true;
}
}
return false;
}

public void visitAST(final CompilationUnit unit) {
unit.accept(new TreeVisitor() {

@Override
public boolean visit(TypeDeclaration node) {
ITypeBinding binding = BindingConverter.unwrapTypeElement(node.getTypeElement());
addNode(new TypeNode(binding, getNameForType(binding)));
followType(binding);
return true;
}

@Override
public boolean visit(AnonymousClassDeclaration node) {
ITypeBinding binding = BindingConverter.unwrapTypeElement(node.getTypeElement());
addNode(new TypeNode(binding, "anonymous:" + node.getLineNumber()));
followType(binding);
return true;
}

@Override
public boolean visit(ClassInstanceCreation node) {
visitType(BindingConverter.unwrapTypeMirrorIntoTypeBinding(node.getTypeMirror()));
return true;
}

@Override
public boolean visit(MethodInvocation node) {
visitType(BindingConverter.unwrapTypeMirrorIntoTypeBinding(node.getTypeMirror()));
return true;
}
});
}
}

This file was deleted.

0 comments on commit 9074582

Please sign in to comment.