use of com.ge.research.osate.verdict.dsl.type.VerdictType in project VERDICT by ge-high-assurance.
the class ThreatModelUtil method getTypes.
/**
* Build a map from type names to types. Traverses all files
* in the current project looking for property declarations, which
* are used to populate fields for the built-in types.
*
* Built-in types are system, connection, and port (also portDirection).
*
* This method is not very efficient, and it gets called several times
* on every keystroke. Fortunately there still seems to be reasonably fast.
* A crucial optimization will be caching the results because the set of
* properties does not change that frequently.
*
* @param obj an AST node context, used to get access to project files
* @param indexProvider an index provider, may be obtained through Guice
* @return the constructed type map
*/
public static LinkedHashMap<String, VerdictType> getTypes(EObject obj, ResourceDescriptionsProvider indexProvider) {
LinkedHashMap<String, VerdictType> types = new LinkedHashMap<>();
// Three main built-in types
BuiltInType connection = new BuiltInType("connection");
BuiltInType port = new BuiltInType("port");
BuiltInType system = new BuiltInType("system");
addBuiltin(types, connection);
addBuiltin(types, port);
addBuiltin(types, system);
// Connection fields
connection.addField("inPort", port);
connection.addField("outPort", port);
connection.addField("source", system);
connection.addField("dest", system);
// Port direction
BuiltInType portDir = new BuiltInType("portDirection");
portDir.addValue("in");
portDir.addValue("out");
// Port fields
port.addField("direction", portDir);
port.addField("connections", connection.getListType());
// System fields
system.addField("subcomponents", system.getListType());
system.addField("connections", connection.getListType());
system.addField("ports", port.getListType());
// Get the path to the current resource, used to get the project path
String[] resSegments = obj.eResource().getURI().segments();
// Iterate through all resources
IResourceDescriptions index = indexProvider.getResourceDescriptions(obj.eResource());
descLoop: for (IEObjectDescription desc : index.getExportedObjectsByType(Aadl2Package.eINSTANCE.getPropertySet())) {
// Get the path to the resource we are examining
String[] propsResSegments = desc.getEObjectURI().segments();
// The project is determined by the first two URI segments
for (int i = 0; i < Math.min(2, Math.min(resSegments.length, propsResSegments.length)); i++) {
if (!resSegments[i].equals(propsResSegments[i])) {
continue descLoop;
}
}
// Load the resource into EMF-land; dynamically loads if necessary
Resource res = obj.eResource().getResourceSet().getResource(desc.getEObjectURI(), true);
if (res != null) {
// Search the AST
TreeIterator<EObject> it = res.getAllContents();
while (it.hasNext()) {
EObject next = it.next();
if (next instanceof PropertySet) {
PropertySet props = (PropertySet) next;
// Iterate the declared properties
for (Element elem : props.getOwnedElements()) {
if (elem instanceof Property) {
Property prop = (Property) elem;
// Make sure type information is present
if (prop.getPropertyType() != null) {
// the types for which the property is a field
for (MetaclassReference meta : prop.getAppliesToMetaclasses()) {
// Get type name, lowercase it because it is a class name
String appliesToMetaclass = meta.getMetaclass().getName().toLowerCase();
// Hopefully this is a type that we have accounted for
if (types.containsKey(appliesToMetaclass)) {
((BuiltInType) types.get(appliesToMetaclass)).addField(prop.getName(), new AadlTypeWrapper(prop.getName(), prop.getPropertyType()));
} else {
// If we get this error message, then perhaps need to add
// some built-in types
System.err.println("could not find built in type: " + appliesToMetaclass);
}
}
}
}
}
// Discard all children of the property set
it.prune();
}
}
}
}
// Prevent synchronization issues
portDir.lock();
connection.lock();
port.lock();
system.lock();
return types;
}
use of com.ge.research.osate.verdict.dsl.type.VerdictType 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.VerdictType 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.VerdictType 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