Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion liquidjava-verifier/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

<groupId>io.github.liquid-java</groupId>
<artifactId>liquidjava-verifier</artifactId>
<version>0.0.14</version>
<version>0.0.15</version>
<name>liquidjava-verifier</name>
<description>LiquidJava Verifier</description>
<url>https://github.com/liquid-java/liquidjava</url>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ public class LJDiagnostic extends RuntimeException {
private final String accentColor;
private final String customMessage;
private String file;
private ErrorPosition position;
private SourcePosition position;
private static final String PIPE = " | ";

public LJDiagnostic(String title, String message, SourcePosition pos, String accentColor, String customMessage) {
this.title = title;
this.message = message;
this.file = (pos != null && pos.getFile() != null) ? pos.getFile().getPath() : null;
this.position = ErrorPosition.fromSpoonPosition(pos);
this.position = pos;
this.accentColor = accentColor;
this.customMessage = customMessage;
}
Expand All @@ -41,14 +41,14 @@ public String getDetails() {
return ""; // to be overridden by subclasses
}

public ErrorPosition getPosition() {
public SourcePosition getPosition() {
return position;
}

public void setPosition(SourcePosition pos) {
if (pos == null)
return;
this.position = ErrorPosition.fromSpoonPosition(pos);
this.position = pos;
this.file = pos.getFile().getPath();
}

Expand Down Expand Up @@ -82,7 +82,7 @@ public String toString() {

// location
if (file != null && position != null) {
sb.append("\n").append(file).append(":").append(position.lineStart()).append(Colors.RESET).append("\n");
sb.append("\n").append(file).append(":").append(position.getLine()).append(Colors.RESET).append("\n");
}

return sb.toString();
Expand All @@ -100,8 +100,8 @@ public String getSnippet() {
// before and after lines for context
int contextBefore = 2;
int contextAfter = 2;
int startLine = Math.max(1, position.lineStart() - contextBefore);
int endLine = Math.min(lines.size(), position.lineEnd() + contextAfter);
int startLine = Math.max(1, position.getLine() - contextBefore);
int endLine = Math.min(lines.size(), position.getEndLine() + contextAfter);

// calculate padding for line numbers
int padding = String.valueOf(endLine).length();
Expand All @@ -115,9 +115,9 @@ public String getSnippet() {
sb.append(Colors.GREY).append(lineNumStr).append(PIPE).append(line).append(Colors.RESET).append("\n");

// add error markers on the line(s) with the error
if (i >= position.lineStart() && i <= position.lineEnd()) {
int colStart = (i == position.lineStart()) ? position.colStart() : 1;
int colEnd = (i == position.lineEnd()) ? position.colEnd() : rawLine.length();
if (i >= position.getLine() && i <= position.getEndLine()) {
int colStart = (i == position.getLine()) ? position.getColumn() : 1;
int colEnd = (i == position.getEndLine()) ? position.getEndColumn() : rawLine.length();

if (colStart > 0 && colEnd > 0) {
int tabsBeforeStart = (int) rawLine.substring(0, Math.max(0, colStart - 1)).chars()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,32 +104,31 @@ public void addVarToContext(RefinedVariable var) {
var.addSuperTypes(type.getSuperclass(), type.getSuperInterfaces());
}

public RefinedVariable addVarToContext(String simpleName, CtTypeReference<?> type, Predicate c,
CtElement placementInCode) {
public RefinedVariable addVarToContext(String simpleName, CtTypeReference<?> type, Predicate c, CtElement element) {
RefinedVariable vi = new Variable(simpleName, type, c);
vi.addPlacementInCode(PlacementInCode.createPlacement(placementInCode));
vi.addPlacementInCode(element);
vi.addSuperTypes(type.getSuperclass(), type.getSuperInterfaces());
addVarToContext(vi);
return vi;
}

public RefinedVariable addInstanceToContext(String simpleName, CtTypeReference<?> type, Predicate c,
CtElement placementInCode) {
CtElement element) {
RefinedVariable vi = new VariableInstance(simpleName, type, c);
vi.addPlacementInCode(PlacementInCode.createPlacement(placementInCode));
vi.addPlacementInCode(element);
if (!ctxInstanceVars.contains(vi))
addInstanceVariable(vi);
return vi;
}

public void addRefinementToVariableInContext(String name, CtTypeReference<?> type, Predicate et,
CtElement placementInCode) {
CtElement element) {
if (hasVariable(name)) {
RefinedVariable vi = getVariableByName(name);
vi.setRefinement(et);
vi.addPlacementInCode(PlacementInCode.createPlacement(placementInCode));
vi.addPlacementInCode(element);
} else {
addVarToContext(name, type, et, placementInCode);
addVarToContext(name, type, et, element);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
import java.util.Map;
import java.util.Set;

import liquidjava.utils.Utils;
import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtParameter;

public class ContextHistory {
private static ContextHistory instance;

private Map<String, Map<String, Set<RefinedVariable>>> fileScopeVars; // file -> (scope -> variables in scope)
private Set<RefinedVariable> instanceVars;
private Set<RefinedVariable> globalVars;
private Map<String, Set<String>> fileScopes;
private Set<RefinedVariable> localVars;
private Set<GhostState> ghosts;
private Set<AliasWrapper> aliases;
private Set<RefinedVariable> globalVars;

private ContextHistory() {
fileScopeVars = new HashMap<>();
instanceVars = new HashSet<>();
fileScopes = new HashMap<>();
localVars = new HashSet<>();
globalVars = new HashSet<>();
ghosts = new HashSet<>();
aliases = new HashSet<>();
Expand All @@ -33,48 +34,41 @@ public static ContextHistory getInstance() {
}

public void clearHistory() {
fileScopeVars.clear();
instanceVars.clear();
fileScopes.clear();
localVars.clear();
globalVars.clear();
ghosts.clear();
aliases.clear();
}

public void saveContext(CtElement element, Context context) {
SourcePosition pos = element.getPosition();
if (pos == null || pos.getFile() == null)
String file = Utils.getFile(element);
if (file == null)
return;

// add variables in scope for this position
String file = pos.getFile().getAbsolutePath();
// add scope
String scope = getScopePosition(element);
fileScopeVars.putIfAbsent(file, new HashMap<>());
fileScopeVars.get(file).put(scope, new HashSet<>(context.getCtxVars()));
fileScopes.putIfAbsent(file, new HashSet<>());
fileScopes.get(file).add(scope);

// add other elements in context
instanceVars.addAll(context.getCtxInstanceVars());
// add variables, ghosts and aliases
localVars.addAll(context.getCtxVars());
localVars.addAll(context.getCtxInstanceVars());
globalVars.addAll(context.getCtxGlobalVars());
ghosts.addAll(context.getGhostStates());
aliases.addAll(context.getAliases());
}

public String getScopePosition(CtElement element) {
private String getScopePosition(CtElement element) {
CtElement startElement = element instanceof CtParameter<?> ? element.getParent() : element;
SourcePosition annPosition = Utils.getFirstLJAnnotationPosition(startElement);
SourcePosition pos = element.getPosition();
SourcePosition innerPosition = pos;
if (element instanceof CtExecutable<?> executable) {
if (executable.getBody() != null)
innerPosition = executable.getBody().getPosition();
}
return String.format("%d:%d-%d:%d", innerPosition.getLine(), innerPosition.getColumn() + 1, pos.getEndLine(),
return String.format("%d:%d-%d:%d", annPosition.getLine(), annPosition.getColumn(), pos.getEndLine(),
pos.getEndColumn());
}

public Map<String, Map<String, Set<RefinedVariable>>> getFileScopeVars() {
return fileScopeVars;
}

public Set<RefinedVariable> getInstanceVars() {
return instanceVars;
public Set<RefinedVariable> getLocalVars() {
return localVars;
}

public Set<RefinedVariable> getGlobalVars() {
Expand All @@ -88,4 +82,8 @@ public Set<GhostState> getGhosts() {
public Set<AliasWrapper> getAliases() {
return aliases;
}

public Map<String, Set<String>> getFileScopes() {
return fileScopes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ public class GhostState extends GhostFunction {

private GhostFunction parent;
private Predicate refinement;
private final String file;

public GhostState(String name, List<CtTypeReference<?>> list, CtTypeReference<?> returnType, String prefix) {
public GhostState(String name, List<CtTypeReference<?>> list, CtTypeReference<?> returnType, String prefix,
String file) {
super(name, list, returnType, prefix);
this.file = file;
}

public void setGhostParent(GhostFunction parent) {
Expand All @@ -28,4 +31,8 @@ public GhostFunction getParent() {
public Predicate getRefinement() {
return refinement;
}

public String getFile() {
return file;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@
import java.util.List;
import java.util.Set;
import liquidjava.rj_language.Predicate;
import liquidjava.utils.Utils;
import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.reference.CtTypeReference;

public abstract class RefinedVariable extends Refined {
private final List<CtTypeReference<?>> supertypes;
private PlacementInCode placementInCode;
private boolean isParameter;
private SourcePosition annPosition;

public RefinedVariable(String name, CtTypeReference<?> type, Predicate c) {
super(name, type, c);
supertypes = new ArrayList<>();
isParameter = false;
}

public abstract Predicate getMainRefinement();
Expand All @@ -34,14 +40,23 @@ public void addSuperTypes(CtTypeReference<?> ts, Set<CtTypeReference<?>> sts) {
supertypes.add(ct);
}

public void addPlacementInCode(PlacementInCode s) {
placementInCode = s;
public void addPlacementInCode(CtElement element) {
placementInCode = PlacementInCode.createPlacement(element);
annPosition = Utils.getFirstLJAnnotationPosition(element);
}

public void addPlacementInCode(PlacementInCode placement) {
placementInCode = placement;
}

public PlacementInCode getPlacementInCode() {
return placementInCode;
}

public SourcePosition getAnnPosition() {
return annPosition;
}

@Override
public int hashCode() {
final int prime = 31;
Expand All @@ -65,4 +80,12 @@ public boolean equals(Object obj) {
return supertypes.equals(other.supertypes);
}
}

public void setIsParameter(boolean b) {
isParameter = b;
}

public boolean isParameter() {
return isParameter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import liquidjava.processor.facade.GhostDTO;
import liquidjava.processor.refinement_checker.general_checkers.MethodsFunctionsChecker;
import liquidjava.rj_language.Predicate;
import liquidjava.rj_language.parsing.RefinementsParser;
import liquidjava.utils.Utils;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.cu.SourcePosition;
Expand All @@ -28,8 +27,8 @@
import spoon.reflect.reference.CtTypeReference;

public class ExternalRefinementTypeChecker extends TypeChecker {
String prefix;
Diagnostics diagnostics = Diagnostics.getInstance();
private String prefix;
private final Diagnostics diagnostics = Diagnostics.getInstance();

public ExternalRefinementTypeChecker(Context context, Factory factory) {
super(context, factory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public Optional<Predicate> getRefinementFromAnnotation(CtElement element) throws
if (ref.isPresent()) {
Predicate p = new Predicate(ref.get(), element);
if (!p.getExpression().isBooleanExpression()) {
SourcePosition position = Utils.getAnnotationPosition(element, ref.get());
SourcePosition position = Utils.getLJAnnotationPosition(element, ref.get());
throw new InvalidRefinementError(position, "Refinement predicate must be a boolean expression",
ref.get());
}
Expand Down Expand Up @@ -152,7 +152,7 @@ private void createStateSet(CtNewArray<String> e, int set, CtElement element) th
CtLiteral<String> s = (CtLiteral<String>) ce;
String f = s.getValue();
GhostState gs = new GhostState(f, g.getParametersTypes(), factory.Type().BOOLEAN_PRIMITIVE,
g.getPrefix());
g.getPrefix(), Utils.getFile(element));
gs.setGhostParent(g);
gs.setRefinement(Predicate.createEquals(ip, Predicate.createLit(Integer.toString(order), Types.INT)));
// open(THIS) -> state1(THIS) == 1
Expand Down Expand Up @@ -189,7 +189,7 @@ private void createStateGhost(String string, CtElement element, SourcePosition p
List<CtTypeReference<?>> param = Collections.singletonList(factory.Type().createReference(qn));

CtTypeReference<?> r = factory.Type().createReference(gd.returnType());
GhostState gs = new GhostState(gd.name(), param, r, qn);
GhostState gs = new GhostState(gd.name(), param, r, qn, Utils.getFile(element));
context.addToGhostClass(sn, gs);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ private Predicate handleFunctionRefinements(RefinedFunction f, CtElement method,
c = oc.get().substituteVariable(Keys.WILDCARD, paramName);
param.putMetadata(Keys.REFINEMENT, c);
RefinedVariable v = rtc.getContext().addVarToContext(param.getSimpleName(), param.getType(), c, param);
v.setIsParameter(true);
rtc.getMessageFromAnnotation(param).ifPresent(v::setMessage);
if (v instanceof Variable)
f.addArgRefinements((Variable) v);
Expand Down
Loading