use of com.ge.research.osate.verdict.dsl.type.VerdictVariable in project VERDICT by ge-high-assurance.
the class ThreatModelUtil method getScope.
/**
* Get all variables in scope for an expression.
*
* Searches up the AST for variable introductions, starting from the
* immediate parent of obj.
*
* Note that if scoping a quantification, you cannot pass the object
* directly because this might include the newly-introduced variable
* in its own scope! See getContainerForClasses() for obtaining the
* correct parent to use for scoping.
*
* @param obj the context for which to find scope.
* @param indexProvider the index provider, may be obtained from Guice
* @return the list of variables that are in scope
*/
public static List<VerdictVariable> getScope(EObject obj, ResourceDescriptionsProvider indexProvider) {
// Get type information
LinkedHashMap<String, VerdictType> types = getTypes(obj, indexProvider);
List<VerdictVariable> vars = new ArrayList<>();
// Traverse upward until we find the enclosing threat model
while (!(obj instanceof ThreatModel || obj == null)) {
obj = obj.eContainer();
if (obj instanceof ThreatModel) {
// Threat model introduces a system
ThreatModel threatModel = (ThreatModel) obj;
vars.add(VerdictVariableImpl.fromIntro(threatModel.getIntro(), types));
} else if (obj instanceof Forall) {
// Forall introduces a variable
Forall forall = (Forall) obj;
vars.add(VerdictVariableImpl.fromIntro(forall.getIntro(), types));
} else if (obj instanceof Exists) {
// Exists introduces a variable
Exists exists = (Exists) obj;
vars.add(VerdictVariableImpl.fromIntro(exists.getIntro(), types));
}
}
return vars;
}
use of com.ge.research.osate.verdict.dsl.type.VerdictVariable in project VERDICT by ge-high-assurance.
the class ThreatModelUtil method getVarType.
/**
* Get the type of a variable/field.
*
* First finds the type of the variable by looking it up in the
* scope. Then finds the type of each variable by looking it up
* in the fields of the previous type.
*
* If at any point something is out of scope or does not type-check,
* then the returned type will be empty.
*
* @param varField the Var AST object to type
* @param indexProvider the index provider, may be obtained from Guice
* @return see FieldTypeResult
*/
public static FieldTypeResult getVarType(Var varField, ResourceDescriptionsProvider indexProvider) {
FieldTypeResult result = new FieldTypeResult();
// Get correct parent for scoping
EObject scopeParent = getContainerForClasses(varField, VAR_FIELD_SCOPE_PARENT_CLASSES);
// ID is always present
result.varName = varField.getId();
// Get all variables in scope
List<VerdictVariable> vars = ThreatModelUtil.getScope(scopeParent, indexProvider);
// Get the variable corresponding to the ID
// Empty if that ID is not in scope
result.var = vars.stream().filter(var -> var.getId().equals(result.varName)).findFirst();
if (!result.var.isPresent()) {
return result;
} else {
if (!result.var.get().getType().isPresent()) {
// yet have a type because the user is still editing the var/field
return result;
} else {
// Check type iteratively for all fields and their children
// Invariant: "type" holds the type of the rightmost var/field that has been processed
VerdictType type = result.var.get().getType().get();
if (varField.getIds() != null) {
for (String fieldName : varField.getIds()) {
// Find the field of the current type for the next field name
Optional<VerdictField> field = type.getFields().stream().filter(f -> f.getName().equals(fieldName)).findFirst();
if (field.isPresent()) {
// Well-typed, advance to the next field
type = field.get().getType();
result.fieldIndex++;
} else {
// Not well-typed, crash and burn
result.lastField = fieldName;
return result;
}
}
}
// All fields type-check and "type" holds the rightmost type
result.type = Optional.of(type);
return result;
}
}
}
use of com.ge.research.osate.verdict.dsl.type.VerdictVariable in project VERDICT by ge-high-assurance.
the class VerdictProposalProvider method complete_Var.
@Override
public void complete_Var(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
// Completes with variables that are in scope (introduced by intro clauses, i.e. forall and exists)
EObject scopeParent = ThreatModelUtil.getContainerForClasses(model, ThreatModelUtil.VAR_FIELD_SCOPE_PARENT_CLASSES);
if (scopeParent != null && scopeParent.eResource() != null && scopeParent.eResource().getResourceSet() != null) {
// Get all variables in scope
List<VerdictVariable> scope = ThreatModelUtil.getScope(scopeParent, indexProvider);
for (VerdictVariable var : scope) {
acceptor.accept(createCompletionProposal(var.getId(), context));
}
}
if (model != null) {
// Get equal/contains parent
EObject container = model;
while (container != null && !(container instanceof ThreatEqualContains)) {
container = container.eContainer();
}
if (container instanceof ThreatEqualContains) {
ThreatEqualContains equalContains = (ThreatEqualContains) container;
List<String> suggestions = null;
if (equalContains.isEqual() && equalContains.getLeft() != null && equalContains.getLeft().eResource() != null && equalContains.getLeft().eResource().getResourceSet() != null) {
// We know the left side, so predict based on that
ThreatModelUtil.FieldTypeResult res = ThreatModelUtil.getVarType(equalContains.getLeft(), indexProvider);
if (res.type.isPresent()) {
suggestions = res.type.get().getValueSuggestions();
}
}
if (equalContains.isEqual() && equalContains.getRight() != null && equalContains.getRight().eResource() != null && equalContains.getRight().eResource().getResourceSet() != null) {
// We know the right side, so predict based on that
ThreatModelUtil.FieldTypeResult res = ThreatModelUtil.getVarType(equalContains.getRight(), indexProvider);
if (res.type.isPresent()) {
suggestions = res.type.get().getValueSuggestions();
}
}
if (suggestions != null) {
for (String suggestion : suggestions) {
// Higher priority (1100) to make them display above the vars
acceptor.accept(createCompletionProposal(suggestion, null, null, 1100, context.getPrefix(), context));
}
}
}
}
}
use of com.ge.research.osate.verdict.dsl.type.VerdictVariable in project VERDICT by ge-high-assurance.
the class VerdictJavaValidator method checkIntro.
/**
* Check that the new ID doesn't shadow a previously-introduced variable
* and that the type of the introduced variable is valid
*
* @param intro
*/
@Check(CheckType.FAST)
public void checkIntro(Intro intro) {
EObject scopeParent = ThreatModelUtil.getContainerForClasses(intro, ThreatModelUtil.INTRO_SCOPE_PARENT_CLASSES);
// Check that the new ID doesn't shadow a previously-introduced variable
String id = intro.getId();
// Find a variable in scope with the same ID
Optional<VerdictVariable> shadowVar = ThreatModelUtil.getScope(scopeParent, indexProvider).stream().filter(v -> v.getId().equals(id)).findFirst();
if (shadowVar.isPresent()) {
warning("Shadowing var: " + id, VerdictPackage.Literals.INTRO__ID);
}
// Check that the type of the introduced variable is valid
Optional<VerdictType> type = ThreatModelUtil.getIntroType(intro, indexProvider);
if (!type.isPresent()) {
error("Invalid type: " + intro.getType(), VerdictPackage.Literals.INTRO__TYPE);
}
}
Aggregations