framework.src.org.checkerframework.qualframework.base.dataflow.QualAnalysis Maven / Gradle / Ivy
package org.checkerframework.qualframework.base.dataflow;
import org.checkerframework.dataflow.analysis.Analysis;
import org.checkerframework.dataflow.cfg.node.Node;
import org.checkerframework.framework.flow.CFAbstractAnalysis;
import org.checkerframework.framework.flow.CFStore;
import org.checkerframework.framework.flow.CFTransfer;
import org.checkerframework.framework.flow.CFValue;
import org.checkerframework.qualframework.base.QualifiedTypeMirror;
import org.checkerframework.qualframework.base.TypeMirrorConverter;
import org.checkerframework.qualframework.util.QualifierContext;
import javax.lang.model.type.TypeMirror;
/**
* Checkers should extend a QualAnalysis to customize the TransferFunction for their checker.
*
* Currently, the underlying Checker Framework's dataflow does not use this class directly for running the analysis;
* It only directly uses the QualTransfer. QualAnalysis, QualStore and QualValue act as one way adapters from the
* qual system to the underlying atm system.
*
* For dataflow to actually use this analysis we would need to add functionality for tracking fields and
* the other functionality that is currently in CFAbstractAnalysis. We could add methods
* in this class that call back to an CFAbstractAnalysis adapter, like other shims in the system.
*
* Because the checker-framework does not directly use this class, adding properties
* (like initialization) to the QualStore or QualValue will currently have no effect.
*
*/
public class QualAnalysis extends Analysis, QualStore, QualTransfer> {
private CFAbstractAnalysis adapter;
private final QualifierContext context;
private final TypeMirrorConverter converter;
public QualAnalysis(QualifierContext context) {
super(context.getProcessingEnvironment());
this.context = context;
this.converter = context.getCheckerAdapter().getTypeMirrorConverter();
}
public QualTransfer createTransferFunction() {
return new QualTransfer(this);
}
public QualStore createEmptyStore(boolean sequentialSemantics) {
return new QualStore<>(this, adapter.createEmptyStore(sequentialSemantics));
}
public QualStore createCopiedStore(QualStore qualStore) {
return new QualStore<>(this, adapter.createCopiedStore(qualStore.getUnderlyingStore().copy()));
}
public QualValue createAbstractValue(QualifiedTypeMirror type) {
return new QualValue(type, this);
}
@Override
public QualValue getValue(Node n) {
return new QualValue<>(converter.getQualifiedType(adapter.getValue(n).getType()), this);
}
public QualValue createSingleAnnotationValue(Q qual, TypeMirror underlyingType) {
CFValue atm = adapter.createSingleAnnotationValue(converter.getAnnotation(qual), underlyingType);
return new QualValue<>(converter.getQualifiedType(atm.getType()), this);
}
public QualifierContext getContext() {
return context;
}
// **********************************************************************
// Methods for CF adaption.
// **********************************************************************
public void setAdapter(CFAbstractAnalysis adapter) {
this.adapter = adapter;
}
/*package*/ QualStore createCopiedStore(CFStore cfStore) {
return new QualStore<>(this, cfStore.copy());
}
/*package*/ QualStore createStore(CFStore cfStore) {
return new QualStore<>(this, cfStore);
}
/*package*/ CFAbstractAnalysis getCFAnalysis() {
return adapter;
}
/*package*/ TypeMirrorConverter getConverter() {
return converter;
}
}