Skip to content

Commit

Permalink
Use AutoValue for value types in DataFlow class.
Browse files Browse the repository at this point in the history
RELNOTES: none
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=119103876
  • Loading branch information
eaftan authored and cushon committed Apr 8, 2016
1 parent 79ac029 commit 73a22d4
Showing 1 changed file with 79 additions and 118 deletions.
197 changes: 79 additions & 118 deletions core/src/main/java/com/google/errorprone/dataflow/DataFlow.java
Expand Up @@ -16,6 +16,7 @@


package com.google.errorprone.dataflow; package com.google.errorprone.dataflow;


import com.google.auto.value.AutoValue;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
Expand All @@ -39,8 +40,6 @@
import org.checkerframework.dataflow.cfg.ControlFlowGraph; import org.checkerframework.dataflow.cfg.ControlFlowGraph;
import org.checkerframework.dataflow.cfg.UnderlyingAST; import org.checkerframework.dataflow.cfg.UnderlyingAST;


import java.util.Objects;

import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.ProcessingEnvironment;


/** /**
Expand All @@ -49,13 +48,13 @@
* @author konne@google.com (Konstantin Weitz) * @author konne@google.com (Konstantin Weitz)
*/ */
public final class DataFlow { public final class DataFlow {

/** /**
* A pair of Analysis and ControlFlowGraph. * A pair of Analysis and ControlFlowGraph.
*/ */
public static interface Result<A extends AbstractValue<A>, S extends Store<S>, public static interface Result<A extends AbstractValue<A>, S extends Store<S>,
T extends TransferFunction<A, S>> { T extends TransferFunction<A, S>> {
Analysis<A, S, T> getAnalysis(); Analysis<A, S, T> getAnalysis();

ControlFlowGraph getControlFlowGraph(); ControlFlowGraph getControlFlowGraph();
} }


Expand All @@ -70,45 +69,47 @@ public static interface Result<A extends AbstractValue<A>, S extends Store<S>,
* *
* TODO(user): Write a test that checks these assumptions * TODO(user): Write a test that checks these assumptions
*/ */
private static LoadingCache<AnalysisParams, Analysis<?, ?, ?>> analysisCache = private static final LoadingCache<AnalysisParams, Analysis<?, ?, ?>> analysisCache =
CacheBuilder.newBuilder().build( CacheBuilder.newBuilder()
new CacheLoader<AnalysisParams, Analysis<?, ?, ?>>() { .build(
@Override new CacheLoader<AnalysisParams, Analysis<?, ?, ?>>() {
public Analysis<?, ?, ?> load(AnalysisParams key) { @Override
final ProcessingEnvironment env = key.getEnvironment(); public Analysis<?, ?, ?> load(AnalysisParams key) {
final ControlFlowGraph cfg = key.getCFG(); final ProcessingEnvironment env = key.environment();
final TransferFunction<?, ?> transfer = key.getTransferFunction(); final ControlFlowGraph cfg = key.cfg();

final TransferFunction<?, ?> transfer = key.transferFunction();
@SuppressWarnings({"unchecked", "rawtypes"})
final Analysis<?, ?, ?> analysis = new Analysis(env, transfer); @SuppressWarnings({"unchecked", "rawtypes"})
analysis.performAnalysis(cfg); final Analysis<?, ?, ?> analysis = new Analysis(env, transfer);
return analysis; analysis.performAnalysis(cfg);
} return analysis;
}); }

});
private static LoadingCache<CFGParams, ControlFlowGraph> cfgCache =
CacheBuilder.newBuilder().maximumSize(1).build( private static final LoadingCache<CfgParams, ControlFlowGraph> cfgCache =
new CacheLoader<CFGParams, ControlFlowGraph>() { CacheBuilder.newBuilder()
@Override .maximumSize(1)
public ControlFlowGraph load(CFGParams key) { .build(
final TreePath methodPath = key.getMethodPath(); new CacheLoader<CfgParams, ControlFlowGraph>() {
final MethodTree method = (MethodTree) methodPath.getLeaf(); @Override
final BlockTree body = method.getBody(); public ControlFlowGraph load(CfgParams key) {
final TreePath bodyPath = new TreePath(methodPath, body); final TreePath methodPath = key.methodPath();
final ClassTree classTree = null; final MethodTree method = (MethodTree) methodPath.getLeaf();
final UnderlyingAST ast = new UnderlyingAST.CFGMethod(method, classTree); final BlockTree body = method.getBody();
final ProcessingEnvironment env = key.getEnvironment(); final TreePath bodyPath = new TreePath(methodPath, body);

final ClassTree classTree = null;
analysisCache.invalidateAll(); final UnderlyingAST ast = new UnderlyingAST.CFGMethod(method, classTree);
CompilationUnitTree root = bodyPath.getCompilationUnit(); final ProcessingEnvironment env = key.environment();
// TODO(user), replace with faster build(bodyPath, env, ast, false, false);
return CFGBuilder.build(root, env, ast, false, false); analysisCache.invalidateAll();
} CompilationUnitTree root = bodyPath.getCompilationUnit();
}); // TODO(user), replace with faster build(bodyPath, env, ast, false, false);
return CFGBuilder.build(root, env, ast, false, false);
}
});


// TODO(user), remove once we merge jdk8 specific's with core // TODO(user), remove once we merge jdk8 specific's with core
public static <T> TreePath findPathFromEnclosingNodeToTopLevel(TreePath path, public static <T> TreePath findPathFromEnclosingNodeToTopLevel(TreePath path, Class<T> klass) {
Class<T> klass) {
while (path != null && !(klass.isInstance(path.getLeaf()))) { while (path != null && !(klass.isInstance(path.getLeaf()))) {
path = path.getParentPath(); path = path.getParentPath();
} }
Expand All @@ -125,12 +126,13 @@ public static <T> TreePath findPathFromEnclosingNodeToTopLevel(TreePath path,
* the analysis result is the same. * the analysis result is the same.
* - for all contexts, the analysis result is the same. * - for all contexts, the analysis result is the same.
*/ */
public static <A extends AbstractValue<A>, S extends Store<S>, public static <A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>>
T extends TransferFunction<A, S>> Result<A, S, T> Result<A, S, T> methodDataflow(TreePath methodPath, Context context, T transfer) {
methodDataflow(TreePath methodPath, Context context, T transfer) {
final Tree leaf = methodPath.getLeaf(); final Tree leaf = methodPath.getLeaf();
Preconditions.checkArgument(leaf instanceof MethodTree, Preconditions.checkArgument(
"Leaf of methodPath must be of type MethodTree, but was %s", leaf.getClass().getName()); leaf instanceof MethodTree,
"Leaf of methodPath must be of type MethodTree, but was %s",
leaf.getClass().getName());


final MethodTree method = (MethodTree) leaf; final MethodTree method = (MethodTree) leaf;
Preconditions.checkNotNull(method.getBody(), Preconditions.checkNotNull(method.getBody(),
Expand All @@ -139,8 +141,8 @@ public static <T> TreePath findPathFromEnclosingNodeToTopLevel(TreePath path,
methodPath.getCompilationUnit().getSourceFile().getName()); methodPath.getCompilationUnit().getSourceFile().getName());


final ProcessingEnvironment env = JavacProcessingEnvironment.instance(context); final ProcessingEnvironment env = JavacProcessingEnvironment.instance(context);
final ControlFlowGraph cfg = cfgCache.getUnchecked(new CFGParams(methodPath, env)); final ControlFlowGraph cfg = cfgCache.getUnchecked(CfgParams.create(methodPath, env));
final AnalysisParams aparams = new AnalysisParams(transfer, cfg, env); final AnalysisParams aparams = AnalysisParams.create(transfer, cfg, env);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
final Analysis<A, S, T> analysis = (Analysis<A, S, T>) analysisCache.getUnchecked(aparams); final Analysis<A, S, T> analysis = (Analysis<A, S, T>) analysisCache.getUnchecked(aparams);


Expand All @@ -165,8 +167,10 @@ public ControlFlowGraph getControlFlowGraph() {
T extends TransferFunction<A, S>> A T extends TransferFunction<A, S>> A
expressionDataflow(TreePath exprPath, Context context, T transfer) { expressionDataflow(TreePath exprPath, Context context, T transfer) {
final Tree leaf = exprPath.getLeaf(); final Tree leaf = exprPath.getLeaf();
Preconditions.checkArgument(leaf instanceof ExpressionTree, Preconditions.checkArgument(
"Leaf of exprPath must be of type ExpressionTree, but was %s", leaf.getClass().getName()); leaf instanceof ExpressionTree,
"Leaf of exprPath must be of type ExpressionTree, but was %s",
leaf.getClass().getName());


final ExpressionTree expr = (ExpressionTree) leaf; final ExpressionTree expr = (ExpressionTree) leaf;
final TreePath enclosingMethodPath = final TreePath enclosingMethodPath =
Expand All @@ -189,88 +193,45 @@ public ControlFlowGraph getControlFlowGraph() {
return methodDataflow(enclosingMethodPath, context, transfer).getAnalysis().getValue(expr); return methodDataflow(enclosingMethodPath, context, transfer).getAnalysis().getValue(expr);
} }


private static final class CFGParams { @AutoValue
final ProcessingEnvironment env; abstract static class CfgParams {
final TreePath methodPath; abstract TreePath methodPath();

public ProcessingEnvironment getEnvironment() {
return env;
}


public TreePath getMethodPath() { // Should not be used for hashCode or equals
return methodPath; private ProcessingEnvironment environment;
}


public CFGParams(TreePath methodPath, ProcessingEnvironment env) { private static CfgParams create(TreePath methodPath, ProcessingEnvironment environment) {
this.env = env; CfgParams cp = new AutoValue_DataFlow_CfgParams(methodPath);
this.methodPath = methodPath; cp.environment = environment;
return cp;
} }


@Override ProcessingEnvironment environment() {
public int hashCode() { return environment;
return Objects.hash(methodPath);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CFGParams other = (CFGParams) obj;
return Objects.equals(methodPath, other.methodPath);
} }
} }


private static final class AnalysisParams { @AutoValue
private final ProcessingEnvironment env; abstract static class AnalysisParams {
private final ControlFlowGraph cfg;
private final TransferFunction<?, ?> transfer;


public AnalysisParams(TransferFunction<?, ?> trans, ControlFlowGraph cfg, abstract TransferFunction<?, ?> transferFunction();
ProcessingEnvironment env) {
this.env = env;
this.cfg = cfg;
this.transfer = trans;
}

public ProcessingEnvironment getEnvironment() {
return env;
}


public ControlFlowGraph getCFG() { abstract ControlFlowGraph cfg();
return cfg;
}


@SuppressWarnings("rawtypes") // Should not be used for hashCode or equals
public TransferFunction getTransferFunction() { private ProcessingEnvironment environment;
return transfer;
}


@Override private static AnalysisParams create(
public int hashCode() { TransferFunction<?, ?> transferFunction,
return Objects.hash(cfg, transfer); ControlFlowGraph cfg,
ProcessingEnvironment environment) {
AnalysisParams ap = new AutoValue_DataFlow_AnalysisParams(transferFunction, cfg);
ap.environment = environment;
return ap;
} }


@Override ProcessingEnvironment environment() {
public boolean equals(Object obj) { return environment;
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
AnalysisParams other = (AnalysisParams) obj;
return Objects.equals(cfg, other.cfg)
&& Objects.equals(transfer, other.transfer);
} }
} }
} }

0 comments on commit 73a22d4

Please sign in to comment.