SemanticAdaptationCanonicalGenerator.xtend 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. /*
  2. * generated by Xtext 2.10.0
  3. */
  4. package be.uantwerpen.ansymo.semanticadaptation.generator
  5. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
  6. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BoolLiteral
  7. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.BuiltinFunction
  8. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Close
  9. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Connection
  10. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DeclaredParameter
  11. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Expression
  12. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InnerFMUDeclarationFull
  13. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IntLiteral
  14. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.IsSet
  15. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
  16. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.RealLiteral
  17. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
  18. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptationFactory
  19. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleParamDeclaration
  20. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SingleVarDeclaration
  21. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StringLiteral
  22. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
  23. import java.io.ByteArrayOutputStream
  24. import java.util.HashMap
  25. import org.eclipse.emf.ecore.EObject
  26. import org.eclipse.emf.ecore.resource.Resource
  27. import org.eclipse.xtext.EcoreUtil2
  28. import org.eclipse.xtext.generator.AbstractGenerator
  29. import org.eclipse.xtext.generator.IFileSystemAccess2
  30. import org.eclipse.xtext.generator.IGeneratorContext
  31. /**
  32. * Generates code from your model files on save.
  33. *
  34. * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
  35. */
  36. class SemanticAdaptationCanonicalGenerator extends AbstractGenerator {
  37. String CANONICAL_EXT = ".BASE.sa"
  38. String NAME_SUFFIX = "_BASE"
  39. override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
  40. println("Generating canonical semantic adaptation for file " + resource.URI.toFileString() + "...")
  41. println("Resource URI information:")
  42. println("\t resource.URI.lastSegment = " + resource.URI.lastSegment())
  43. println("\t resource.URI.trimFileExtension = " + resource.URI.trimFileExtension())
  44. println("______________________________File Read______________________________")
  45. var outputByteArray = new ByteArrayOutputStream()
  46. resource.save(outputByteArray, null)
  47. println(outputByteArray.toString())
  48. outputByteArray.close()
  49. println("__________________________________________________________________________")
  50. // Create file name for the canonical sa file
  51. var fileNameWithoutExt = resource.URI.trimFileExtension().lastSegment()
  52. var canonicalFileName = fileNameWithoutExt + CANONICAL_EXT
  53. println("canonicalFileName = " + canonicalFileName)
  54. // Create in memory representation of canonical SA file
  55. var adaptations = resource.allContents.toIterable.filter(SemanticAdaptation).last.elements.filter(Adaptation);
  56. if (adaptations.size > 1){
  57. throw new Exception("Only one semantic adaptation is supported per .sa file")
  58. }
  59. var adaptation = adaptations.head
  60. println("Checking if file is already a canonical version...")
  61. if (adaptation.name.indexOf(NAME_SUFFIX) == -1){
  62. println("It is not.")
  63. adaptation.name = adaptation.name + NAME_SUFFIX
  64. adaptation.canonicalize
  65. outputByteArray = new ByteArrayOutputStream()
  66. adaptation.eResource.save(outputByteArray,null)
  67. println("______________________________Generated file______________________________")
  68. println(outputByteArray.toString())
  69. println("__________________________________________________________________________")
  70. fsa.generateFile(canonicalFileName, outputByteArray.toString())
  71. println("File " + canonicalFileName + " written.")
  72. outputByteArray.close()
  73. println("Generating canonical semantic adaptation for file " + resource.URI + "... DONE.")
  74. } else {
  75. println("It is already a canonical version.")
  76. println("Nothing to do.")
  77. }
  78. }
  79. def canonicalize(Adaptation sa){
  80. //inferUnits(sa)
  81. // Type inference
  82. genericDeclarationInferenceAlgorithm(sa ,
  83. [// getField
  84. element | {
  85. if (element instanceof SingleParamDeclaration) {
  86. return element.type
  87. } else if (element instanceof Port){
  88. return element.type
  89. } else if (element instanceof SingleVarDeclaration){
  90. return element.type
  91. } else {
  92. throw new Exception("Unexpected element type: " + element)
  93. }
  94. }
  95. ],
  96. [// setField
  97. element, value | {
  98. if (element instanceof SingleParamDeclaration) {
  99. element.type = value as String
  100. } else if (element instanceof Port){
  101. element.type = value as String
  102. } else if (element instanceof SingleVarDeclaration){
  103. element.type = value as String
  104. } else {
  105. throw new Exception("Unexpected element type: " + element)
  106. }
  107. }
  108. ],
  109. [// inferField
  110. element | {
  111. if (element instanceof SingleParamDeclaration) {
  112. return extractTypeFromExpression(element.expr, element.name)
  113. } else if (element instanceof Port){
  114. return getPortType(element)
  115. } else if (element instanceof SingleVarDeclaration){
  116. return extractTypeFromExpression(element.expr, element.name)
  117. } else {
  118. throw new Exception("Unexpected element type: " + element)
  119. }
  120. }
  121. ]
  122. )
  123. // TODO Add input ports
  124. // Add in params
  125. addInParams(sa)
  126. }
  127. def genericDeclarationInferenceAlgorithm(Adaptation sa,
  128. (EObject)=>Object getField,
  129. (EObject, Object)=>void setField,
  130. (EObject)=>Object inferField
  131. ){
  132. println("Running generic inference algorithm...")
  133. /*
  134. * Dumbest (and simplest) algorithm for this is a fixed point computation:
  135. * 1. Look for every var/port declaration
  136. * 2. If that var has a XXX already, nothing else to be done.
  137. * 3. If that var has no XXX declared, then
  138. * 3.1 If var/port has an initial value or connection, then
  139. * 3.1.1 If the initial_value/connection has a XXX declared, then var gets that XXX.
  140. * 3.1.2 Otherwise, nothing else to be done.
  141. * 3.2 If var/port has no initial value or connection then this either is a missing feature, or an error.
  142. * 3.3 If something has changed, go to 1. Otherwise, end.
  143. */
  144. var fixedPoint = false
  145. var untypedElementsCounter = 0
  146. while (! fixedPoint){
  147. fixedPoint = true
  148. untypedElementsCounter = 0
  149. println("Inferring parameter fields...")
  150. for (paramDeclarations : sa.params) {
  151. for (paramDeclaration : paramDeclarations.declarations) {
  152. println("Computing field for param " + paramDeclaration.name)
  153. if(getField.apply(paramDeclaration) !== null){
  154. println("Already has been inferred: " + getField.apply(paramDeclaration))
  155. } else {
  156. println("Has not been inferred yet.")
  157. //var inferredTypeAttempt = extractTypeFromExpression(paramDeclaration.expr, paramDeclaration.name)
  158. var inferredTypeAttempt = inferField.apply(paramDeclaration)
  159. if (inferredTypeAttempt !== null){
  160. //paramDeclaration.type = inferredTypeAttempt
  161. setField.apply(paramDeclaration, inferredTypeAttempt)
  162. fixedPoint = false
  163. println("Got new field: " + inferredTypeAttempt)
  164. } else {
  165. untypedElementsCounter++
  166. println("Cannot infer field now.")
  167. }
  168. }
  169. }
  170. }
  171. if(sa.inner !== null){
  172. if(sa.inner instanceof InnerFMUDeclarationFull){
  173. var innerFMUFull = sa.inner as InnerFMUDeclarationFull
  174. for(fmu : innerFMUFull.fmus){
  175. println("Inferring port fields of FMU " + fmu.name)
  176. for (port : EcoreUtil2.getAllContentsOfType(fmu, Port)) {
  177. if(getField.apply(port) !== null){
  178. println("Already has a type: " + port.type)
  179. //} else if(inferPortType(port)) {
  180. } else {
  181. // TODO Refactor this with the above code, to check and infer field of generic type.
  182. var inferredTypeAttempt = inferField.apply(port)
  183. if (inferredTypeAttempt !== null){
  184. setField.apply(port, inferredTypeAttempt)
  185. fixedPoint = false
  186. println("Got new field: " + inferredTypeAttempt)
  187. } else {
  188. untypedElementsCounter++
  189. println("Cannot infer field now.")
  190. }
  191. }
  192. }
  193. }
  194. if (innerFMUFull.connection.size > 0){
  195. println("Inferring port fields using internal scenario bindings.")
  196. for (binding : innerFMUFull.connection){
  197. if (getField.apply(binding.src.port) !== null && getField.apply(binding.tgt.port) !== null){
  198. println("Both ports have fields already.")
  199. //} else if (inferPortTypeViaConnection(binding)){
  200. } else {
  201. var inferredTypeAttempt = inferPortFieldViaConnection(binding, getField, setField, inferField)
  202. if (inferredTypeAttempt !== null){
  203. setField.apply(binding, inferredTypeAttempt)
  204. fixedPoint = false
  205. untypedElementsCounter--
  206. println("Got new field: " + inferredTypeAttempt)
  207. } else {
  208. println("Cannot infer field from binding now.")
  209. }
  210. }
  211. }
  212. }
  213. } else {
  214. throw new Exception("Field inference only supported for InnerFMUDeclarationFull.")
  215. }
  216. }
  217. println("Inferring external port fields...")
  218. for (port : sa.inports) {
  219. //if (port.type !== null){
  220. if (getField.apply(port) !== null){
  221. println("Already has a field: " + getField.apply(port))
  222. //if (pushPortType(port)){
  223. if (pushPortField(port, getField, setField, inferField)){
  224. fixedPoint = false
  225. untypedElementsCounter--
  226. }
  227. //} else if (inferPortType(port)){
  228. } else {
  229. // TODO Refactor this with the above code, to check and infer field of generic type.
  230. var inferredTypeAttempt = inferField.apply(port)
  231. if (inferredTypeAttempt !== null){
  232. setField.apply(port, inferredTypeAttempt)
  233. fixedPoint = false
  234. println("Got new field: " + inferredTypeAttempt)
  235. } else {
  236. untypedElementsCounter++
  237. println("Cannot infer field now.")
  238. }
  239. }
  240. }
  241. for (port : sa.outports) {
  242. //if (port.type !== null){
  243. // TODO Refactor this with the above code, the treatment to external output ports is the exact same as for external input ports.
  244. if (getField.apply(port) !== null){
  245. println("Already has a field: " + getField.apply(port))
  246. //if (pushPortType(port)){
  247. if (pushPortField(port, getField, setField, inferField)){
  248. fixedPoint = false
  249. untypedElementsCounter--
  250. }
  251. //} else if (inferPortType(port)){
  252. } else {
  253. // TODO Refactor this with the above code, to check and infer field of generic type.
  254. var inferredTypeAttempt = inferField.apply(port)
  255. if (inferredTypeAttempt !== null){
  256. setField.apply(port, inferredTypeAttempt)
  257. fixedPoint = false
  258. println("Got new field: " + inferredTypeAttempt)
  259. } else {
  260. untypedElementsCounter++
  261. println("Cannot infer field now.")
  262. }
  263. }
  264. }
  265. println("Inferring all other declaration fields...")
  266. for (varDeclaration : EcoreUtil2.getAllContentsOfType(sa, SingleVarDeclaration)) {
  267. println("Computing type for declaration " + varDeclaration.name)
  268. //if(varDeclaration.type !== null){
  269. if(getField.apply(varDeclaration) !== null){
  270. println("Already has a field: " + getField.apply(varDeclaration))
  271. } else {
  272. //var inferredTypeAttempt = extractTypeFromExpression(varDeclaration.expr, varDeclaration.name)
  273. var inferredTypeAttempt = inferField.apply(varDeclaration)
  274. if (inferredTypeAttempt !== null){
  275. //varDeclaration.type = inferredTypeAttempt
  276. setField.apply(varDeclaration, inferredTypeAttempt)
  277. fixedPoint = false
  278. println("Got new type: " + inferredTypeAttempt)
  279. } else {
  280. untypedElementsCounter++
  281. println("Cannot infer field now.")
  282. }
  283. }
  284. }
  285. println("Ended iteration with unfielded elements remaining: " + untypedElementsCounter)
  286. } // while (! fixedPoint)
  287. if (untypedElementsCounter > 0){
  288. throw new Exception("Could not infer all fields. There are " + untypedElementsCounter + " unfielded elements.")
  289. }
  290. println("Running generic inference algorithm... DONE")
  291. }
  292. def inferTypes(Adaptation sa){
  293. println("Inferring types...")
  294. /*
  295. * Dumbest (and simplest) algorithm for this is a fixed point computation:
  296. * 1. Look for every var/port declaration
  297. * 2. If that var has a type already, nothing else to be done.
  298. * 3. If that var has no type declared, then
  299. * 3.1 If var/port has an initial value or connection, then
  300. * 3.1.1 If the initial_value/connection has a type declared, then var gets that type.
  301. * 3.1.2 Otherwise, nothing else to be done.
  302. * 3.2 If var/port has no initial value or connection then this either is a missing feature, or an error.
  303. * 3.3 If something has changed, go to 1. Otherwise, end.
  304. */
  305. var fixedPoint = false
  306. var untypedElementsCounter = 0
  307. while (! fixedPoint){
  308. fixedPoint = true
  309. untypedElementsCounter = 0
  310. println("Inferring parameter types...")
  311. for (paramDeclarations : sa.params) {
  312. for (paramDeclaration : paramDeclarations.declarations) {
  313. println("Computing type for param " + paramDeclaration.name)
  314. if(paramDeclaration.type !== null){
  315. println("Already has a type: " + paramDeclaration.type)
  316. } else {
  317. println("Has no type.")
  318. var inferredTypeAttempt = extractTypeFromExpression(paramDeclaration.expr, paramDeclaration.name)
  319. if (inferredTypeAttempt !== null){
  320. paramDeclaration.type = inferredTypeAttempt
  321. fixedPoint = false
  322. println("Got new type: " + paramDeclaration.type)
  323. } else {
  324. untypedElementsCounter++
  325. println("Cannot infer type now.")
  326. }
  327. }
  328. }
  329. }
  330. if(sa.inner !== null){
  331. if(sa.inner instanceof InnerFMUDeclarationFull){
  332. var innerFMUFull = sa.inner as InnerFMUDeclarationFull
  333. for(fmu : innerFMUFull.fmus){
  334. println("Inferring port types of FMU " + fmu.name)
  335. for (port : EcoreUtil2.getAllContentsOfType(fmu, Port)) {
  336. if(port.type !== null){
  337. println("Already has a type: " + port.type)
  338. } else if(inferPortType(port)) {
  339. fixedPoint = false
  340. } else {
  341. untypedElementsCounter++
  342. }
  343. }
  344. }
  345. if (innerFMUFull.connection.size > 0){
  346. println("Inferring port types using internal scenario bindings.")
  347. for (binding : innerFMUFull.connection){
  348. if (binding.src.port.type !== null && binding.tgt.port.type !== null){
  349. println("Both ports have types already.")
  350. } else if (inferPortTypeViaConnection(binding)){
  351. fixedPoint = false
  352. untypedElementsCounter--
  353. }
  354. }
  355. }
  356. } else {
  357. throw new Exception("Type inference only supported for InnerFMUDeclarationFull.")
  358. }
  359. }
  360. println("Inferring external port types...")
  361. for (port : sa.inports) {
  362. if (port.type !== null){
  363. println("Already has a type: " + port.type)
  364. if (pushPortType(port)){
  365. fixedPoint = false
  366. untypedElementsCounter--
  367. }
  368. } else if (inferPortType(port)){
  369. fixedPoint = false
  370. } else {
  371. untypedElementsCounter++
  372. }
  373. }
  374. for (port : sa.outports) {
  375. if (port.type !== null){
  376. println("Already has a type: " + port.type)
  377. if (pushPortType(port)){
  378. fixedPoint = false
  379. untypedElementsCounter--
  380. }
  381. } else if (inferPortType(port)){
  382. fixedPoint = false
  383. } else {
  384. untypedElementsCounter++
  385. }
  386. }
  387. println("Inferring all other declaration types...")
  388. for (varDeclaration : EcoreUtil2.getAllContentsOfType(sa, SingleVarDeclaration)) {
  389. println("Computing type for declaration " + varDeclaration.name)
  390. if(varDeclaration.type !== null){
  391. println("Already has a type: " + varDeclaration.type)
  392. } else {
  393. var inferredTypeAttempt = extractTypeFromExpression(varDeclaration.expr, varDeclaration.name)
  394. if (inferredTypeAttempt !== null){
  395. varDeclaration.type = inferredTypeAttempt
  396. fixedPoint = false
  397. println("Got new type: " + varDeclaration.type)
  398. } else {
  399. untypedElementsCounter++
  400. println("Cannot infer type now.")
  401. }
  402. }
  403. }
  404. println("Ended iteration with untyped elements remaining: " + untypedElementsCounter)
  405. } // while (! fixedPoint)
  406. if (untypedElementsCounter > 0){
  407. throw new Exception("Could not infer all types. There are " + untypedElementsCounter + " untyped elements.")
  408. }
  409. println("Inferring types... DONE")
  410. }
  411. def extractTypeFromExpression(Expression expression, String declarationName){
  412. if (expression instanceof IntLiteral){
  413. return "Integer"
  414. } else if (expression instanceof RealLiteral){
  415. return "Real"
  416. } else if (expression instanceof BoolLiteral){
  417. return "Bool"
  418. } else if (expression instanceof StringLiteral){
  419. return "String"
  420. } else if (expression instanceof Variable){
  421. var varRef = expression as Variable
  422. if (varRef.ref instanceof Port){
  423. var decl = varRef.ref as Port
  424. if (decl.type !== null){
  425. return decl.type
  426. }
  427. } else if(varRef.ref instanceof SingleParamDeclaration){
  428. var decl = varRef.ref as SingleParamDeclaration
  429. if (decl.type !== null){
  430. return decl.type
  431. }
  432. } else if(varRef.ref instanceof SingleVarDeclaration){
  433. var decl = varRef.ref as SingleVarDeclaration
  434. if (decl.type !== null){
  435. return decl.type
  436. }
  437. } else if(varRef.ref instanceof DeclaredParameter){
  438. throw new Exception("Type cannot be inferred for references to DeclaredParameter (for now). Please specify the explicit type of declaration " + declarationName)
  439. } else {
  440. throw new Exception("Unexpected kind of Variable expression found.")
  441. }
  442. } else if(expression instanceof BuiltinFunction){
  443. if (expression instanceof IsSet || expression instanceof Close){
  444. return "Bool"
  445. } else {
  446. return "Real"
  447. }
  448. } else {
  449. throw new Exception("Initial value for declaration " + declarationName + " must be literal or var ref for now. Got instead " + expression + ". If you want complex expressions, give it an explicit type.")
  450. }
  451. return null
  452. }
  453. def inferPortFieldViaConnection(Connection binding,
  454. (EObject)=>Object getField,
  455. (EObject, Object)=>void setField,
  456. (EObject)=>Object inferField
  457. ){
  458. var Object resultField = null
  459. if (getField.apply(binding.src.port) !== null && getField.apply(binding.tgt.port) !== null){
  460. throw new Exception("Wrong way of using this function. It assumes type is not inferred yet.")
  461. } else if (getField.apply(binding.src.port) !== null){
  462. //binding.tgt.port.type = binding.src.port.type
  463. resultField = getField.apply(binding.src.port)
  464. println("Target port "+ binding.tgt.port.name +" got new type: " + resultField)
  465. } else if (getField.apply(binding.tgt.port) !== null){
  466. //binding.src.port.type = binding.tgt.port.type
  467. resultField = getField.apply(binding.tgt.port)
  468. println("Target port "+ binding.src.port.name +" got new type: " + resultField)
  469. }
  470. return resultField
  471. }
  472. def inferPortTypeViaConnection(Connection binding){
  473. var typeInferred = false
  474. if (binding.src.port.type !== null && binding.tgt.port.type !== null){
  475. throw new Exception("Wrong way of using this function. It assumes type is not inferred yet.")
  476. } else if (binding.src.port.type !== null){
  477. binding.tgt.port.type = binding.src.port.type
  478. println("Target port "+ binding.tgt.port.name +" got new type: " + binding.tgt.port.type)
  479. } else if (binding.tgt.port.type !== null){
  480. binding.src.port.type = binding.tgt.port.type
  481. println("Target port "+ binding.src.port.name +" got new type: " + binding.src.port.type)
  482. }
  483. return typeInferred
  484. }
  485. def pushPortField(Port port,
  486. (EObject)=>Object getField,
  487. (EObject, Object)=>void setField,
  488. (EObject)=>Object inferField){
  489. var typeInferred = false
  490. println("Pushing field of port " + port.name + " to its bindings.")
  491. if(getField.apply(port) === null){
  492. println("Has no field to be pushed.")
  493. // TODO Throw exception wrong usage
  494. } else {
  495. println("Pushing field: " + getField.apply(port))
  496. if(port.sourcedependency !== null){
  497. println("Has a source dependency: " + port.sourcedependency.port.name)
  498. if(getField.apply(port.sourcedependency.port) === null){
  499. //port.sourcedependency.port.type = port.type
  500. setField.apply(port.sourcedependency.port, getField.apply(port))
  501. println("Port " + port.sourcedependency.port.name + " got new type: " + getField.apply(port.sourcedependency.port))
  502. typeInferred = true
  503. } else {
  504. println("Source port already has field.")
  505. }
  506. } else {
  507. println("Has no source dependency.")
  508. }
  509. if (port.targetdependency !== null) {
  510. println("Has a target dependency: " + port.targetdependency.port.name)
  511. if(getField.apply(port.targetdependency.port) === null){
  512. println("Dependency has no field yet.")
  513. //port.targetdependency.port.type = port.type
  514. setField.apply(port.targetdependency.port, getField.apply(port))
  515. println("Port " + port.targetdependency.port.name + " got new type: " + getField.apply(port.targetdependency.port))
  516. typeInferred = true
  517. } else {
  518. println("Target port already has field.")
  519. }
  520. } else {
  521. println("Has no target dependency.")
  522. }
  523. }
  524. return typeInferred
  525. }
  526. def pushPortType(Port port){
  527. var typeInferred = false
  528. println("Pushing type of port " + port.name + " to its bindings.")
  529. if(port.type === null){
  530. println("Has no type to be pushed.")
  531. } else {
  532. println("Pushing type: " + port.type)
  533. if(port.sourcedependency !== null){
  534. println("Has a source dependency: " + port.sourcedependency.port.name)
  535. if(port.sourcedependency.port.type === null){
  536. port.sourcedependency.port.type = port.type
  537. println("Port " + port.sourcedependency.port.name + " got new type: " + port.sourcedependency.port.type)
  538. typeInferred = true
  539. } else {
  540. println("Source port already has type.")
  541. }
  542. } else {
  543. println("Has no source dependency.")
  544. }
  545. if (port.targetdependency !== null) {
  546. println("Has a target dependency: " + port.targetdependency.port.name)
  547. if(port.targetdependency.port.type === null){
  548. println("Dependency has no type yet.")
  549. port.targetdependency.port.type = port.type
  550. println("Port " + port.targetdependency.port.name + " got new type: " + port.targetdependency.port.type)
  551. typeInferred = true
  552. } else {
  553. println("Target port already has type.")
  554. }
  555. } else {
  556. println("Has no target dependency, or type has already been inferred from source dependency.")
  557. }
  558. }
  559. return typeInferred
  560. }
  561. def getPortType(Port port){
  562. var typeInferred = false
  563. println("Computing type for port " + port.name)
  564. //println("Object: " + port)
  565. var String returnType = null
  566. if(port.type !== null){
  567. throw new Exception("Wrong way of using this function. It assumes type is not inferred yet.")
  568. } else {
  569. println("Has no type.")
  570. println("Attempting to infer type from units.")
  571. if (port.unity !== null){
  572. returnType = "Real"
  573. println("Got new type: " + returnType)
  574. typeInferred = true
  575. } else {
  576. println("Attempting to infer type from bindings.")
  577. if(port.sourcedependency !== null){
  578. println("Has a source dependency: " + port.sourcedependency.port.name)
  579. if(port.sourcedependency.port.type === null){
  580. println("Dependency has no type yet.")
  581. } else {
  582. returnType = port.sourcedependency.port.type
  583. println("Got new type: " + returnType)
  584. typeInferred = true
  585. }
  586. } else {
  587. println("Has no source dependency.")
  588. }
  589. if (port.targetdependency !== null && !typeInferred) {
  590. println("Has a target dependency: " + port.targetdependency.owner.name + "." + port.targetdependency.port.name)
  591. if(port.targetdependency.port.type === null){
  592. //println("Port object: " + port.targetdependency.port)
  593. println("Dependency has no type yet.")
  594. } else {
  595. returnType = port.targetdependency.port.type
  596. println("Got new type: " + port.type)
  597. typeInferred = true
  598. }
  599. } else {
  600. println("Has no target dependency, or type has already been inferred from source dependency.")
  601. }
  602. }
  603. }
  604. return returnType
  605. }
  606. def inferPortType(Port port){
  607. var typeInferred = false
  608. println("Computing type for port " + port.name)
  609. //println("Object: " + port)
  610. if(port.type !== null){
  611. throw new Exception("Wrong way of using this function. It assumes type is not inferred yet.")
  612. } else {
  613. println("Has no type.")
  614. println("Attempting to infer type from units.")
  615. if (port.unity !== null){
  616. port.type = "Real"
  617. println("Got new type: " + port.type)
  618. typeInferred = true
  619. } else {
  620. println("Attempting to infer type from bindings.")
  621. if(port.sourcedependency !== null){
  622. println("Has a source dependency: " + port.sourcedependency.port.name)
  623. if(port.sourcedependency.port.type === null){
  624. println("Dependency has no type yet.")
  625. } else {
  626. port.type = port.sourcedependency.port.type
  627. println("Got new type: " + port.type)
  628. typeInferred = true
  629. }
  630. } else {
  631. println("Has no source dependency.")
  632. }
  633. if (port.targetdependency !== null && !typeInferred) {
  634. println("Has a target dependency: " + port.targetdependency.owner.name + "." + port.targetdependency.port.name)
  635. if(port.targetdependency.port.type === null){
  636. //println("Port object: " + port.targetdependency.port)
  637. println("Dependency has no type yet.")
  638. } else {
  639. port.type = port.targetdependency.port.type
  640. println("Got new type: " + port.type)
  641. typeInferred = true
  642. }
  643. } else {
  644. println("Has no target dependency, or type has already been inferred from source dependency.")
  645. }
  646. }
  647. }
  648. return typeInferred
  649. }
  650. def addInParams(Adaptation adaptation) {
  651. println("Adding input parameters...")
  652. val PARAM_PREFIX = "INIT_"
  653. var inputPort_to_parameterDeclaration_Map = new HashMap<Port, SingleParamDeclaration>(adaptation.inports.size)
  654. for (inputPortDeclaration : adaptation.inports) {
  655. println("Generating parameter for port " + inputPortDeclaration.name)
  656. var paramname = PARAM_PREFIX + inputPortDeclaration.name.toUpperCase()
  657. var paramAlreadyDeclared = false
  658. for(paramDeclarations : adaptation.params){
  659. for(paramDeclaration : paramDeclarations.declarations){
  660. if(paramDeclaration.name == paramname){
  661. paramAlreadyDeclared = true
  662. }
  663. }
  664. }
  665. if (paramAlreadyDeclared){
  666. println("Parameter " + paramname + " already declared for port " + inputPortDeclaration.name)
  667. } else {
  668. println("Declaring new parameter " + paramname + " for port " + inputPortDeclaration.name)
  669. var factory = SemanticAdaptationFactory.eINSTANCE
  670. if (adaptation.params.size == 0){
  671. adaptation.params.add(factory.createParamDeclarations())
  672. }
  673. var paramDeclaration = factory.createSingleParamDeclaration()
  674. // TODO Continue here after solving problem with ports.
  675. //adaptation.params.head.declarations.add()
  676. }
  677. }
  678. println("Adding input parameters... DONE")
  679. }
  680. }