浏览代码

Fixes for conformance function that recurses over ComplexAttributes

Yentl Van Tendeloo 8 年之前
父节点
当前提交
bb75c86684

二进制
bootstrap/bootstrap.m.gz


+ 44 - 1
bootstrap/conformance_scd.alc

@@ -243,6 +243,32 @@ String function conformance_scd(model : Element):
 			if (attr_value < list_len(allInstances(model, metamodel_element))):
 				return "Upper cardinality violated for class: " + metamodel_element!
 
+	// Check all ComplexAttributes recursively
+	Element all_complex_types
+	Element complex_instances
+	String complex_instance
+	String complex_type
+	String result
+	all_complex_types = allInstances(model["metamodel"]["metamodel"], "ComplexAttribute")
+	log("Got complex types: " + set_to_string(all_complex_types))
+	while (read_nr_out(all_complex_types) > 0):
+		complex_type = set_pop(all_complex_types)
+		complex_instances = allInstances(model, complex_type)
+
+		log("Instances: " + set_to_string(complex_instances))
+
+		while (read_nr_out(complex_instances) > 0):
+			complex_instance = set_pop(complex_instances)
+			log("Got complex instance: " + complex_instance)
+
+			complex_type = read_attribute(model["metamodel"], read_type(model, complex_instance), "type")
+			result = check_location_conformance(model["model"][complex_instance], complex_type)
+
+			if (result != "OK"):
+				return ((("Complex attribute doesn't match for: " + complex_instance) + "\n Message: ") + result)!
+			else:
+				log("OK for " + complex_instance)
+
 	// Structure seems fine, now do static semantics
 	if (dict_in(metamodel, "constraints")):
 		Element constraint_function
@@ -251,6 +277,23 @@ String function conformance_scd(model : Element):
 	else:
 		return "OK"!
 
+String function check_location_conformance(instance_location : String, type_location : String):
+	// Check whether the instance is typed by the type
+	Element instance
+	Element type
+	log("INSTANCE " + instance_location)
+	log("TYPE     " + type_location)
+
+	instance = import_node(instance_location)
+	type = import_node(type_location)
+	log(" --> " + cast_e2s(instance))
+	log(" --> " + cast_e2s(type))
+
+	if (element_neq(instance["metamodel"], type)):
+		return "Instance not statically typed by specified metamodel"!
+	
+	return conformance_scd(instance)!
+
 Element function set_model_constraints(model : Element, func : Element):
 	if (dict_in(model, "constraints")):
 		dict_delete(model, "constraints")
@@ -279,7 +322,7 @@ Element function generate_bottom_type_mapping(model : Element):
 	return model!
 
 String function model_info(model : Element, name : String):
-	return name!
+	//return name!
 	// For more detailed information
 	String result
 	result = ""

+ 0 - 1
bootstrap/metamodels.alc

@@ -310,7 +310,6 @@ Void function initialize_AL(scd_location : String, export_location : String):
 	instantiate_link(model, "Inheritance", "", "call_params", "dict_link")
 	instantiate_link(model, "Inheritance", "", "call_last_param", "dict_link")
 
-	instantiate_attribute(model, "Statement_next", "target_lower_cardinality", 1)
 	instantiate_attribute(model, "if_else", "target_lower_cardinality", 1)
 	instantiate_attribute(model, "return_value", "target_lower_cardinality", 1)
 	instantiate_attribute(model, "param_next_param", "target_lower_cardinality", 1)

+ 8 - 2
bootstrap/modelling.alc

@@ -406,12 +406,13 @@ Void function add_AL_links(model : Element, list : Element, element : Element, t
 	dict_add(model["model"], link_name, link)
 	dict_add(model["type_mapping"], link_name, (type + "_") + linkname)
 
+	log("Added element " + link_name)
 	// The name link
 	link = read_out(link, 0)
 	link_name = "__" + cast_id2s(link)
 
 	dict_add(model["model"], link_name, link)
-	dict_add(model["type_mapping"], link_name, ((type + "_") + linkname) + "_name")
+	dict_add(model["type_mapping"], link_name, "dict_link_name")
 	
 	// The name node
 	link = read_edge_dst(link)
@@ -419,7 +420,10 @@ Void function add_AL_links(model : Element, list : Element, element : Element, t
 
 	if (bool_not(set_in_node(model["model"], link))):
 		dict_add(model["model"], link_name, link)
-		dict_add(model["type_mapping"], link_name, "String")
+		dict_add(model["type_mapping"], link_name, "StringAttr")
+		log("And assigned name")
+	else:
+		log("But didn't assign name")
 
 	// Now add the destination to the worker list
 	set_add(list, create_tuple(element[linkname], expected_type))
@@ -496,6 +500,8 @@ String function add_AL(model : Element, element : Element):
 				add_AL_links(model, todo, elem, type, "next_param", "param")
 			elif (type == "funcdef"):
 				add_AL_links(model, todo, elem, type, "body", "")
+				// TODO this should be added, but is not the same as "param"
+				//add_AL_links(model, todo, elem, type, "params", "")
 				add_AL_links(model, todo, elem, type, "next", "")
 			elif (type == "call"):
 				add_AL_links(model, todo, elem, type, "func", "")

+ 1 - 1
bootstrap/object_operations.alc

@@ -266,5 +266,5 @@ String function read_type(model : Element, name : String):
 			log("Type mapping: " + dict_to_string(model["type_mapping"]))
 			return ""!
 	else:
-		log("Couldn't find " + name)
+		log("Couldn't find type of " + name)
 		return ""!

+ 7 - 13
integration/test_constructors_models.py

@@ -68,7 +68,7 @@ bottom = [
 bottom_link_al = [
         "model",
         "instantiate_node", "1", "ComplexAttribute", "ActionLanguage",
-        "instantiate_attribute", "1", "ActionLanguage", "type", "models/ActionLanguage_new",
+        "instantiate_attribute", "1", "ActionLanguage", "type", "models/ActionLanguage",
 
         "model_define_attribute", "1", "Element", "constraint", True, "ActionLanguage",
         "exit",
@@ -180,7 +180,6 @@ action_language = [
         "instantiate_link", "2", "Inheritance", "", "call_params", "dict_link",
         "instantiate_link", "2", "Inheritance", "", "call_last_param", "dict_link",
 
-        "instantiate_attribute", "2", "Statement_next", "target_lower_cardinality", 1,
         "instantiate_attribute", "2", "if_else", "target_lower_cardinality", 1,
         "instantiate_attribute", "2", "return_value", "target_lower_cardinality", 1,
         "instantiate_attribute", "2", "param_next_param", "target_lower_cardinality", 1,
@@ -192,15 +191,10 @@ action_language = [
     ]
 
 def add_constraint(model, element, code):
-    location = "constraints/%s_%s" % (model, element)
-    print(locals())
-    return [
-            "model",
-            "add_code_model", "2", location,
-           ] + get_constructor(code) + [
-            "instantiate_attribute", model, element, "constraint", location,
-            "exit",
-        ]
+    return ["model",
+            "instantiate_attribute_code", model, element, "constraint"] + \
+                get_constructor(code) + \
+            ["exit",]
 
 instantiate_scd = [
         "model",
@@ -392,7 +386,7 @@ class TestConstructorsModels(unittest.TestCase):
                     add_constraint("1", "String", code_string) + \
                     add_constraint("1", "Location", code_location) + \
                     add_constraint("1", "Boolean", code_boolean) + \
-                    add_constraint("1", "ActionLanguage_new", code_complex_attribute) + \
+                    add_constraint("1", "ActionLanguage", code_complex_attribute) + \
                     conformance_check("models/SimpleClassDiagrams_new") + ["return", False]
         self.assertTrue(run_barebone(commands, ["OK"], 1))
 
@@ -404,7 +398,7 @@ class TestConstructorsModels(unittest.TestCase):
                     add_constraint("1", "String", code_string) + \
                     add_constraint("1", "Location", code_location) + \
                     add_constraint("1", "Boolean", code_boolean) + \
-                    add_constraint("1", "ActionLanguage_new", code_complex_attribute) + \
+                    add_constraint("1", "ActionLanguage", code_complex_attribute) + \
                     instantiate_scd + \
                     add_constraint("3", "Natural", code_natural) + \
                     conformance_check("models/PetriNets_new") + \