Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features to enable PICO #444

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e33175a
addDeepPreference to cfi
AndrewShf Dec 1, 2022
38c4b0b
delete redundant if statements
AndrewShf Dec 6, 2022
ce6cdaa
corresponding changes in CFI about enforce-targetlocations
AndrewShf Dec 21, 2022
68682b2
use getProcessingEnv
AndrewShf Dec 21, 2022
e0d08e4
fix inference initialization crash
AndrewShf Jan 9, 2023
30e76d4
disable all targetlocation constraints for the dataflow typesystem
AndrewShf Jan 13, 2023
c3b7c95
bug fix
AndrewShf Jan 16, 2023
e9bb117
Merge branch 'add_deep_preference' into local-features
AndrewShf Jan 25, 2023
4704bf5
change addDeclarationConstraints and handleWasRawDeclaredTypes privat…
AndrewShf Jan 31, 2023
e4dc688
Merge branch 'private_to_protected' into local-features
AndrewShf Jan 31, 2023
df5d7e0
get default type for new class tree
AndrewShf Feb 28, 2023
09ffa38
fix assertion failure
AndrewShf Feb 28, 2023
f6279cf
workaround if it's an anonymous class
AndrewShf Mar 2, 2023
fb56232
get direct super types of the defaultType
AndrewShf Mar 3, 2023
493963a
fix the case when the anonymous class's directSuper type is an interface
AndrewShf Mar 3, 2023
b4072e4
Merge branch 'slot_default_type' into local-features
AndrewShf Mar 6, 2023
bd9cbbc
add makeDefaultsExplicit option
AndrewShf Mar 30, 2023
71ec2d7
Merge branch 'makeDefaultsExplicit' into local-features
AndrewShf Mar 30, 2023
a0a9e74
add makeDefaultsExplicit option
AndrewShf Mar 30, 2023
9c092de
Merge branch 'makeDefaultsExplicit' into local-features
AndrewShf Jun 6, 2023
683fbfc
Merge branch 'master' into local-features
Ao-senXiong Apr 7, 2024
ac9a1a9
Merge branch 'master' into local-features
Ao-senXiong Apr 8, 2024
a2a1f61
Fixed compile bugs
Ao-senXiong Apr 8, 2024
d47647f
Merge branch 'master' into PICO-pull-in
Ao-senXiong Apr 11, 2024
01b0edd
Merge branch 'master' into PICO-pull-in
Ao-senXiong Apr 13, 2024
8ad0c5a
Merge branch 'master' into PICO-pull-in
Ao-senXiong Apr 24, 2024
93635f8
Apply spotless
Ao-senXiong Apr 24, 2024
799c0fd
Add back missing arguments
Ao-senXiong Apr 24, 2024
f30f5a8
Change CI target branch
Ao-senXiong May 30, 2024
0910b3d
Merge branch 'master' into PICO-pull-in
Ao-senXiong Jun 27, 2024
d62668f
Revert change of targe branch
Ao-senXiong Jun 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/checkers/inference/InferenceLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,9 @@ public void infer() {

Mode mode = Mode.valueOf(InferenceOptions.mode);
if (InferenceOptions.makeDefaultsExplicit
&& (mode == Mode.ROUNDTRIP || mode == Mode.ROUNDTRIP_TYPECHECK)) {
&& (mode == Mode.ROUNDTRIP
|| mode == Mode.ROUNDTRIP_TYPECHECK
|| mode == Mode.INFER)) {
// Two conditions have to be met to make defaults explicit:
// 1. the command-line flag `makeDefaultsExplicit` is provided
// 2. the inference solution will be written back to the source code (roundtrip `mode`)
Expand Down
69 changes: 58 additions & 11 deletions src/checkers/inference/InferenceVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
import org.checkerframework.framework.type.AnnotatedTypeParameterBounds;
import org.checkerframework.framework.util.AnnotatedTypes;
import org.checkerframework.javacutil.*;
import org.checkerframework.javacutil.TreeUtils;
import org.plumelib.util.ArraysPlume;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -79,12 +81,11 @@ public class InferenceVisitor<
protected final boolean infer;

protected final Checker realChecker;

/**
/*
* Map from type-use location to a list of qualifiers which cannot be used on that location.
* This is used to create the inequality constraint in inference.
*/
protected final Map<TypeUseLocation, Set<AnnotationMirror>> locationToIllegalQuals;
protected final Map<TypeUseLocation, AnnotationMirrorSet> locationToIllegalQuals;

public InferenceVisitor(
Checker checker, InferenceChecker ichecker, Factory factory, boolean infer) {
Expand Down Expand Up @@ -307,6 +308,50 @@ public void mainIsNoneOf(
}
}

private void addDeepPreferenceImpl(
AnnotatedTypeMirror ty,
AnnotationMirror goal,
int weight,
java.util.List<AnnotatedTypeMirror> visited,
Tree node) {
if (infer) {
if (visited.contains(ty)) {
return;
}
visited.add(ty);

final SlotManager slotManager = InferenceMain.getInstance().getSlotManager();
Slot el = slotManager.getSlot(ty);

if (el == null) {
logger.warning(
"InferenceVisitor::addDeepPreferenceImpl: no annotation in type: " + ty);
} else {
addPreference(ty, goal, weight);
}

if (ty.getKind() == TypeKind.DECLARED) {
AnnotatedDeclaredType declaredType = (AnnotatedDeclaredType) ty;
for (AnnotatedTypeMirror typearg : declaredType.getTypeArguments()) {
addDeepPreferenceImpl(typearg, goal, weight, visited, node);
}
} else if (ty.getKind() == TypeKind.ARRAY) {
AnnotatedArrayType arrayType = (AnnotatedArrayType) ty;
addDeepPreferenceImpl(arrayType.getComponentType(), goal, weight, visited, node);
} else if (ty.getKind() == TypeKind.TYPEVAR) {
AnnotatedTypeVariable atv = (AnnotatedTypeVariable) ty;
addDeepPreferenceImpl(atv.getUpperBound(), goal, weight, visited, node);
addDeepPreferenceImpl(atv.getLowerBound(), goal, weight, visited, node);
}
}
// Else, do nothing
}

public void addDeepPreference(
AnnotatedTypeMirror ty, AnnotationMirror goal, int weight, Tree node) {
addDeepPreferenceImpl(ty, goal, weight, new LinkedList<>(), node);
}

public void addPreference(AnnotatedTypeMirror type, AnnotationMirror anno, int weight) {
if (infer) {
ConstraintManager cManager = InferenceMain.getInstance().getConstraintManager();
Expand Down Expand Up @@ -983,18 +1028,18 @@ protected void checkConstructorResult(
* @return a mapping from type-use locations to a set of qualifiers which cannot be applied to
* that location
*/
protected Map<TypeUseLocation, Set<AnnotationMirror>> createMapForIllegalQuals() {
Map<TypeUseLocation, Set<AnnotationMirror>> locationToIllegalQuals = new HashMap<>();
protected Map<TypeUseLocation, AnnotationMirrorSet> createMapForIllegalQuals() {
Map<TypeUseLocation, AnnotationMirrorSet> locationToIllegalQuals = new HashMap<>();
// First, init each type-use location to contain all type qualifiers.
Set<Class<? extends Annotation>> supportQualifiers =
atypeFactory.getSupportedTypeQualifiers();
Set<AnnotationMirror> supportedAnnos = new AnnotationMirrorSet();
AnnotationMirrorSet supportedAnnos = new AnnotationMirrorSet();
for (Class<? extends Annotation> qual : supportQualifiers) {
supportedAnnos.add(
new AnnotationBuilder(atypeFactory.getProcessingEnv(), qual).build());
}
for (TypeUseLocation location : TypeUseLocation.values()) {
locationToIllegalQuals.put(location, new HashSet<>(supportedAnnos));
locationToIllegalQuals.put(location, new AnnotationMirrorSet(supportedAnnos));
}
// Then, delete some qualifiers which can be applied to that type-use location.
// this leaves only qualifiers not allowed on that location.
Expand All @@ -1005,7 +1050,7 @@ protected Map<TypeUseLocation, Set<AnnotationMirror>> createMapForIllegalQuals()
// the qualifier can be written on any type use.
if (tls == null) {
for (TypeUseLocation location : TypeUseLocation.values()) {
Set<AnnotationMirror> amSet = locationToIllegalQuals.get(location);
AnnotationMirrorSet amSet = locationToIllegalQuals.get(location);
amSet.remove(
AnnotationUtils.getAnnotationByName(
supportedAnnos, qual.getCanonicalName()));
Expand All @@ -1015,14 +1060,14 @@ protected Map<TypeUseLocation, Set<AnnotationMirror>> createMapForIllegalQuals()
for (TypeUseLocation location : tls.value()) {
if (location == TypeUseLocation.ALL) {
for (TypeUseLocation val : TypeUseLocation.values()) {
Set<AnnotationMirror> amSet = locationToIllegalQuals.get(val);
AnnotationMirrorSet amSet = locationToIllegalQuals.get(val);
amSet.remove(
AnnotationUtils.getAnnotationByName(
supportedAnnos, qual.getCanonicalName()));
}
break;
}
Set<AnnotationMirror> amSet = locationToIllegalQuals.get(location);
AnnotationMirrorSet amSet = locationToIllegalQuals.get(location);
amSet.remove(
AnnotationUtils.getAnnotationByName(
supportedAnnos, qual.getCanonicalName()));
Expand All @@ -1037,7 +1082,6 @@ protected void validateVariablesTargetLocation(Tree tree, AnnotatedTypeMirror ty
super.validateVariablesTargetLocation(tree, type);
return;
}

if (ignoreTargetLocations) {
return;
}
Expand Down Expand Up @@ -1068,6 +1112,9 @@ protected void validateVariablesTargetLocation(Tree tree, AnnotatedTypeMirror ty
break;
case ENUM_CONSTANT:
location = TypeUseLocation.CONSTRUCTOR_RESULT;
// TODO: Add ? mainIsNoneOf(type,
// targetLocationToAnno.get(TypeUseLocation.FIELD).toArray(mirrors),
// "type.invalid.annotations.on.location", tree);
break;
default:
throw new BugInCF("Location not matched");
Expand Down
4 changes: 2 additions & 2 deletions src/checkers/inference/VariableAnnotator.java
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ public Void visitDeclared(final AnnotatedDeclaredType adt, final Tree tree) {
return null;
}

private boolean handleWasRawDeclaredTypes(AnnotatedDeclaredType adt) {
protected boolean handleWasRawDeclaredTypes(AnnotatedDeclaredType adt) {
if (adt.isUnderlyingTypeRaw() && adt.getTypeArguments().size() != 0) {
// the type arguments should be wildcards AND if I get the real type of "tree"
// it corresponds to the declaration of adt.getUnderlyingType
Expand Down Expand Up @@ -1855,7 +1855,7 @@ public AnnotationMirror getClassDeclVarAnnot(TypeElement ele) {
return null;
}

private void addDeclarationConstraints(Slot declSlot, Slot instanceSlot) {
protected void addDeclarationConstraints(Slot declSlot, Slot instanceSlot) {
constraintManager.addSubtypeConstraint(instanceSlot, declSlot);
}

Expand Down
18 changes: 18 additions & 0 deletions src/checkers/inference/util/SlotDefaultTypeResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.sun.source.tree.AnnotatedTypeTree;
import com.sun.source.tree.ArrayTypeTree;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.ParameterizedTypeTree;
import com.sun.source.tree.PrimitiveTypeTree;
import com.sun.source.tree.Tree;
Expand Down Expand Up @@ -181,5 +182,22 @@ public Void visitAnnotatedType(AnnotatedTypeTree tree, Void unused) {

return super.visitAnnotatedType(tree, unused);
}

@Override
public Void visitNewClass(NewClassTree tree, Void unused) {
AnnotatedTypeMirror defaultType = getDefaultTypeFor(tree);
if (InferenceUtil.isAnonymousClass(tree)) {
// don't associate the identifier with the defaultType if it's an anonymousclass
// should associate the identifier with the direct super type of the defaultType.
// choose the last one of the directSupertypes, which is either the direct super
// class
// or implemented interface
List<? extends AnnotatedTypeMirror> superTypes = defaultType.directSupertypes();
defaultTypes.put(tree.getIdentifier(), superTypes.get(superTypes.size() - 1));
} else {
defaultTypes.put(tree.getIdentifier(), defaultType);
}
return super.visitNewClass(tree, unused);
}
}
}
5 changes: 5 additions & 0 deletions tests/checkers/inference/test/CFInferenceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public boolean useHacks() {
return SystemPlume.getBooleanSystemProperty("use.hacks");
}

public boolean makeDefaultsExplicit() {
return false;
}

public abstract IPair<String, List<String>> getSolverNameAndOptions();

public List<String> getAdditionalInferenceOptions() {
Expand Down Expand Up @@ -66,6 +70,7 @@ public void run() {
solverArgs.first,
solverArgs.second,
useHacks(),
makeDefaultsExplicit(),
shouldEmitDebugInfo,
getPathToAfuScripts(),
getPathToInferenceScript());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class ImmutableInferenceTestConfiguration implements InferenceTestConfigu
private final String solver;
private final Map<String, String> solverArgs;
private final boolean shouldUseHacks;
private final boolean makeDefaultsExplicit;
private final String pathToAfuScripts;
private final String pathToInferenceScript;
private final TestConfiguration initialConfig;
Expand All @@ -28,6 +29,7 @@ public ImmutableInferenceTestConfiguration(
String solver,
Map<String, String> solverArgs,
boolean shouldUseHacks,
boolean makeDefaultsExplicit,
String pathToAfuScripts,
String pathToInferenceScript,
TestConfiguration initialConfig) {
Expand All @@ -38,6 +40,7 @@ public ImmutableInferenceTestConfiguration(
this.solver = solver;
this.solverArgs = solverArgs;
this.shouldUseHacks = shouldUseHacks;
this.makeDefaultsExplicit = makeDefaultsExplicit;
this.pathToAfuScripts = pathToAfuScripts;
this.initialConfig = initialConfig;
this.pathToInferenceScript = pathToInferenceScript;
Expand Down Expand Up @@ -76,6 +79,10 @@ public boolean shouldUseHacks() {
return shouldUseHacks;
}

public boolean makeDefaultsExplicit() {
return makeDefaultsExplicit;
}

public String getPathToAfuScripts() {
return pathToAfuScripts;
}
Expand Down
2 changes: 2 additions & 0 deletions tests/checkers/inference/test/InferenceTestConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public interface InferenceTestConfiguration {

boolean shouldUseHacks();

boolean makeDefaultsExplicit();

String getPathToAfuScripts();

String getPathToInferenceScript();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class InferenceTestConfigurationBuilder {
private File testDataDir = null;
private String solver = null;
private boolean shouldUseHacks;
private boolean makeDefaultsExplicit;
private String pathToAfuScripts = "";
private String pathToInferenceScript = "";

Expand Down Expand Up @@ -60,6 +61,11 @@ public InferenceTestConfigurationBuilder setShouldUseHacks(boolean shouldUseHack
return this;
}

public InferenceTestConfigurationBuilder setMakeDefaultsExplicit(boolean makeDefaultsExplicit) {
this.makeDefaultsExplicit = makeDefaultsExplicit;
return this;
}

public InferenceTestConfigurationBuilder setPathToAfuScripts(String pathToAfuScripts) {
this.pathToAfuScripts = pathToAfuScripts;
return this;
Expand Down Expand Up @@ -166,6 +172,7 @@ public InferenceTestConfiguration build() {
solver,
new LinkedHashMap<>(solverArgs.getOptions()),
shouldUseHacks,
makeDefaultsExplicit,
pathToAfuScripts,
pathToInferenceScript,
initialConfiguration);
Expand Down Expand Up @@ -196,6 +203,7 @@ public static InferenceTestConfiguration buildDefaultConfiguration(
String solverName,
List<String> solverOptions,
boolean shouldUseHacks,
boolean makeDefaultsExplicit,
boolean shouldEmitDebugInfo,
String pathToAfuScripts,
String pathToInferenceScript) {
Expand All @@ -216,6 +224,7 @@ public static InferenceTestConfiguration buildDefaultConfiguration(
.setAnnotatedSourceDir(defaultAnnotatedSourceDir)
.setSolver(solverName)
.setShouldUseHacks(shouldUseHacks)
.setMakeDefaultsExplicit(makeDefaultsExplicit)
.setPathToAfuScripts(pathToAfuScripts)
.setPathToInferenceScript(pathToInferenceScript);

Expand Down
3 changes: 3 additions & 0 deletions tests/checkers/inference/test/InferenceTestExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ public static InferenceResult infer(InferenceTestConfiguration configuration) {
if (configuration.shouldUseHacks()) {
options.add("--hacks");
}
if (configuration.makeDefaultsExplicit()) {
options.add("--makeDefaultsExplicit");
}

options.add("--jaifFile=" + configuration.getOutputJaif().getAbsolutePath());

Expand Down
Loading