Advertisement
Guest User

Untitled

a guest
Jan 16th, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.53 KB | None | 0 0
  1. module sqat::series2::A2_CheckArch
  2.  
  3. import sqat::series2::Dicto;
  4. import lang::java::jdt::m3::Core;
  5. import Message;
  6. import ParseTree;
  7. import IO;
  8. import String;
  9.  
  10.  
  11. /*
  12.  
  13. This assignment has two parts:
  14. - write a dicto file (see example.dicto for an example)
  15. containing 3 or more architectural rules for Pacman
  16. 1. BoardPannel.java must import java.awt.Color;
  17. 2. nl.tudelft.jpacman.level.Pellet must inherit nl.tudelft.jpacman.board.Unit
  18. 3. nl.tudelft.jpacman.board.Board must invoke nl.tudelft.jpacman.board.Board.getHeight
  19.  
  20. - write an evaluator for the Dicto language that checks for
  21. violations of these rules.
  22.  
  23. Part 1
  24.  
  25. An example is: ensure that the game logic component does not
  26. depend on the GUI subsystem. Another example could relate to
  27. the proper use of factories.
  28.  
  29. Make sure that at least one of them is violated (perhaps by
  30. first introducing the violation).
  31.  
  32. Explain why your rule encodes "good" design.
  33.  
  34. Part 2:
  35.  
  36. Complete the body of this function to check a Dicto rule
  37. against the information on the M3 model (which will come
  38. from the pacman project).
  39.  
  40. A simple way to get started is to pattern match on variants
  41. of the rules, like so:
  42.  
  43. switch (rule) {
  44. case (Rule)`<Entity e1> cannot depend <Entity e2>`: ...
  45. case (Rule)`<Entity e1> must invoke <Entity e2>`: ...
  46. ....
  47. }
  48.  
  49. Implement each specific check for each case in a separate function.
  50. If there's a violation, produce an error in the `msgs` set.
  51. Later on you can factor out commonality between rules if needed.
  52.  
  53. The messages you produce will be automatically marked in the Java
  54. file editors of Eclipse (see Plugin.rsc for how it works).
  55.  
  56. Tip:
  57. - for info on M3 see series2/A1a_StatCov.rsc.
  58.  
  59. Questions
  60. - how would you test your evaluator of Dicto rules? (sketch a design)
  61. - come up with 3 rule types that are not currently supported by this version
  62. of Dicto (and explain why you'd need them).
  63. */
  64.  
  65.  
  66.  
  67. // from Entity get location
  68. loc getLocationFromEntity(Entity e) {
  69. if(contains("<e>", "::")) {
  70. return |java+method:///| + replaceAll(replaceAll("<e>", ".", "/"), "::", "/");
  71. }
  72. return |java+class:///| + replaceAll("<e>", ".", "/");
  73. }
  74.  
  75.  
  76. // INVOKES
  77.  
  78. // check which methods are invoked in given methode
  79. set[loc] methodInvokeMethods(loc method, M3 m3) {
  80. set[loc] methodList = {};
  81. for(<loc from, loc to> <- m3.methodInvocation) {
  82. if((split("///", split("(", from.uri)[0])[-1]) == (split("///", split("(", method.uri)[0])[-1])) {
  83. methodList += to;
  84. }
  85. }
  86. return methodList;
  87. }
  88.  
  89. // check which methods are invoked in given class
  90. set[loc] classInvokeMethods(loc class, M3 m3) {
  91. set[loc] methodsInvoked = {};
  92. set[loc] methodsInClass = {};
  93. for(<loc name, loc src> <- m3.declarations) {
  94. if(split(".", split("/", src.uri)[-1])[0] == split("/", class.uri)[-1]) {
  95. methodsInClass += name;
  96. }
  97. }
  98. for(loc method <- methodsInClass) {
  99. methodsInvoked += methodInvokeMethods(method, m3);
  100. }
  101. return methodsInvoked;
  102. }
  103.  
  104. set[loc] invokeHelper (loc loc1, M3 m3) {
  105.  
  106. set[loc] methods;
  107. if(isMethod(loc1)) {
  108. methods = methodInvokeMethods(loc1, m3);
  109. } else {
  110. methods = classInvokeMethods(loc1, m3);
  111. }
  112.  
  113. return methods;
  114. }
  115.  
  116. Message mustInvoke(Entity e1, Entity e2, M3 m3) {
  117. loc loc1 = getLocationFromEntity(e1);
  118. loc loc2 = getLocationFromEntity(e2);
  119. if(!isMethod(loc2)) {
  120. return warning("not a method", loc2);
  121. }
  122.  
  123. set[loc] methods = invokeHelper(loc1, m3);
  124.  
  125. for(loc l <- methods) {
  126. if((split("///", loc2.uri)[-1]) == (split("(", split("///", l.uri)[-1])[0])) {
  127. return warning("Accept must invoke", loc1);
  128. }
  129. }
  130. return warning("Decline <e1> does not invoke <e2>", loc1);
  131. }
  132.  
  133. Message cannotInvoke(Entity e1, Entity e2, M3 m3) {
  134. loc loc1 = getLocationFromEntity(e1);
  135. loc loc2 = getLocationFromEntity(e2);
  136. if(!isMethod(loc2)) {
  137. return warning("not a method", loc2);
  138. }
  139.  
  140. set[loc] methods = invokeHelper(loc1, m3);
  141.  
  142. for(loc l <- methods) {
  143. if((split("///", loc2.uri)[-1]) == (split("///", split("(", l.uri)[0])[-1])) {
  144. return warning("Decline <e1> invokes <e2>", loc1);
  145. }
  146. }
  147. return warning("Accept cannot invoke", loc1);
  148. }
  149.  
  150. Message canOnlyInvoke(Entity e1, Entity e2, M3 m3) {
  151. loc loc1 = getLocationFromEntity(e1);
  152. loc loc2 = getLocationFromEntity(e2);
  153. if(!isMethod(loc2)) {
  154. return warning("not a method", loc2);
  155. }
  156.  
  157. set[loc] methods = invokeHelper(loc1, m3);
  158.  
  159. for(loc l <- methods) {
  160. if((split("///", loc2.uri)[-1]) != (split("///", split("(", l.uri)[0])[-1])) {
  161. return warning("Decline <e1> invokes <e2>", loc1);
  162. }
  163. }
  164. return warning("Accept can only invoke", loc1);
  165. }
  166.  
  167. // INHERIT
  168.  
  169. set[loc] inheritance(loc file, m3) {
  170. set[loc] foundInherits = {};
  171. for(<loc from, loc to> <- m3.extends) {
  172. if(from == file) {
  173. foundInherits += to;
  174. }
  175. }
  176. return foundInherits;
  177. }
  178.  
  179. Message mustInherit(Entity e1, Entity e2, M3 m3) {
  180. loc loc1 = getLocationFromEntity(e1);
  181. loc loc2 = getLocationFromEntity(e2);
  182. if(isMethod(loc1)) {
  183. return warning("<e1> not a class", loc1);
  184. }
  185. if(isMethod(loc2)) {
  186. return warning("<e2> not a class", loc2);
  187. }
  188. if(loc2 notin inheritance(loc1, m3)) {
  189. return warning("Decline <e1> does not inherit from <e2>", loc1);
  190. }
  191. return warning("Accept must inherit", loc1);
  192. }
  193.  
  194.  
  195.  
  196.  
  197. set[Message] eval(start[Dicto] dicto, M3 m3) = eval(dicto.top, m3);
  198.  
  199. set[Message] eval((Dicto)`<Rule* rules>`, M3 m3)
  200. = ( {} | it + eval(r, m3) | r <- rules );
  201.  
  202. set[Message] eval(Rule rule, M3 m3) {
  203. set[Message] msgs = {};
  204.  
  205. // to be done
  206.  
  207. switch (rule) {
  208. case (Rule)`<Entity e1> must invoke <Entity e2>`: msgs += mustInvoke(e1, e2, m3);
  209. case (Rule)`<Entity e1> cannot invoke <Entity e2>`: msgs += cannotInvoke(e1, e2, m3);
  210. case (Rule)`<Entity e1> can only invoke <Entity e2>`: msgs += canOnlyInvoke(e1, e2, m3);
  211. case (Rule)`<Entity e1> must inherit <Entity e2>`: msgs += mustInherit(e1, e2, m3);
  212. case (Rule)`<Entity e1> cannot inherit <Entity e2>`: msgs += cannotInherit(e1, e2, m3);
  213. case (Rule)`<Entity e1> can only inherit <Entity e2>`: msgs += canOnlyInherit(e1, e2, m3);
  214. case (Rule)`<Entity e1> must import <Entity e2>`: msgs += mustImport(e1, e2, m3);
  215. case (Rule)`<Entity e1> cannot import <Entity e2>`: msgs += cannotImport(e1, e2, m3);
  216. case (Rule)`<Entity e1> can only import <Entity e2>`: msgs += canOnlyImport(e1, e2, m3);
  217.  
  218. }
  219.  
  220. return msgs;
  221. }
  222.  
  223. M3 jpacmanM3() = createM3FromEclipseProject(|project://jpacman-framework/src|);
  224.  
  225. set[Message] runDicto() {
  226. return eval(parse(#start[Dicto], |project://sqat-analysis/src/sqat/series2/example.dicto|), jpacmanM3());
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement