SemanticAdaptationScopeProvider.xtend 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*******************************************************************************
  2. * Copyright (c) 2015 itemis AG (http://www.itemis.eu) and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *******************************************************************************/
  8. package be.uantwerpen.ansymo.semanticadaptation.scoping
  9. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Adaptation
  10. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.AlgebraicLoopSolution
  11. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Component
  12. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Connection
  13. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.DataRule
  14. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Declaration
  15. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.FMU
  16. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.For
  17. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.FunctionDeclaration
  18. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.If
  19. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.InOutRules
  20. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.OutputFunction
  21. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Port
  22. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptation
  23. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.SemanticAdaptationPackage
  24. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.StateTransitionFunction
  25. import be.uantwerpen.ansymo.semanticadaptation.semanticAdaptation.Variable
  26. import com.google.common.base.Predicate
  27. import com.google.inject.Inject
  28. import java.util.LinkedList
  29. import java.util.List
  30. import org.eclipse.emf.common.util.BasicEList
  31. import org.eclipse.emf.common.util.EList
  32. import org.eclipse.emf.ecore.EObject
  33. import org.eclipse.emf.ecore.EReference
  34. import org.eclipse.emf.ecore.resource.Resource
  35. import org.eclipse.xtext.EcoreUtil2
  36. import org.eclipse.xtext.resource.IEObjectDescription
  37. import org.eclipse.xtext.scoping.IGlobalScopeProvider
  38. import org.eclipse.xtext.scoping.IScope
  39. import org.eclipse.xtext.scoping.Scopes
  40. import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider
  41. import org.eclipse.xtext.scoping.impl.IScopeWrapper
  42. /**
  43. * This class contains custom scoping description.
  44. *
  45. * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
  46. * on how and when to use it.
  47. */
  48. class SemanticAdaptationScopeProvider extends AbstractDeclarativeScopeProvider {
  49. // comment out getScope for per-type scope
  50. /* provides a global scope for all elements!
  51. * overrides all the remainder of this class
  52. */
  53. override getScope(EObject context, EReference reference) {
  54. if (reference === SemanticAdaptationPackage.Literals.IMPORT__MODULE) {
  55. return getGlobalScope(context.eResource, reference)
  56. }
  57. val module = EcoreUtil2.getContainerOfType(context, SemanticAdaptation)
  58. var result = IScope.NULLSCOPE
  59. for (import : module.imports) {
  60. if (!import.module.eIsProxy)
  61. result = getModuleScope(context, reference, import.module, result)
  62. }
  63. result = getModuleScope(context, reference, module, result)
  64. //println(Scopes.scopeFor(context.eResource.allContents.toList, result))
  65. return Scopes.scopeFor(context.eResource.allContents.toList, result)
  66. }
  67. // todo: only correct src and tgt references
  68. def scope_Connection_src(Connection context, EReference r) {
  69. return __getImportedScope(context, r).__addScope(__getAllPorts(context))
  70. }
  71. def scope_Connection_tgt(Connection context, EReference r) {
  72. return __getImportedScope(context, r).__addScope(__getAllPorts(context))
  73. }
  74. def scope_Port_target(Port context, EReference r) {
  75. return __getImportedScope(context, r).__addScope(__getAllPorts(context))
  76. }
  77. def scope_AlgebraicLoopSolution_signals(AlgebraicLoopSolution context, EReference r) {
  78. return __getImportedScope(context, r).__addScope(__getAllPorts(context))
  79. }
  80. def scope_Variable_ref(Variable context, EReference r) {
  81. //println(context.eContainer())
  82. //var scope = __getImportedScope(context, r)
  83. var EList<EObject> elements = __getAllPorts(context)
  84. val outputfunction = EcoreUtil2.getContainerOfType(context, OutputFunction)
  85. if (outputfunction !== null) {
  86. val rule = outputfunction.eContainer as DataRule
  87. if (rule.statetransitionfunction !== null) {
  88. elements += rule.statetransitionfunction.statements
  89. }
  90. }
  91. elements += context.__getFrom(If, "ifstatements", Declaration, true).flatten
  92. elements += context.__getFrom(If, "ifstatements", FunctionDeclaration, true).flatten
  93. elements += context.__getFrom(For, "iterator", null, true).flatten
  94. elements += context.__getFromElement(StateTransitionFunction, "statements", Declaration)
  95. elements += context.__getFromElement(StateTransitionFunction, "statements", FunctionDeclaration)
  96. elements += context.__getFromElement(InOutRules, "globalvars")
  97. elements += context.__getFromElement(InOutRules, "iterationvars")
  98. elements += context.__getFromElement(Adaptation, "params")
  99. return __getImportedScope(context, r).__addScope(elements)
  100. }
  101. def scope_Adaptation_instances(Adaptation context, EReference r) {
  102. return __getImportedScope(context, r)
  103. }
  104. def scope_Adaptation_ports(Adaptation context, EReference r) {
  105. return __getImportedScope(context, r)
  106. }
  107. def scope_CompositeFMU_instances(SemanticAdaptation context, EReference r) {
  108. return __getImportedScope(context, r)
  109. }
  110. /*def scope_Step_fmu(Step context, EReference r) {
  111. return Scopes.scopeFor(EcoreUtil2.getContainerOfType(context, Adaptation).inner.instances, IScope.NULLSCOPE)
  112. }*/
  113. /*def EObject __getAncestorOfType(EObject object, Class<?> type) { // same as EcoreUtil2.getContainerOfType
  114. val parent = object.eContainer
  115. if (parent == null) {
  116. return null
  117. }
  118. if (type.isAssignableFrom(parent.class)) {
  119. return parent
  120. } else{
  121. return __getAncestorOfType(object.eContainer, type)
  122. }
  123. }*/
  124. def __addScope(IScope scope, EList elements) {
  125. return Scopes.scopeFor(elements, scope)
  126. }
  127. def __getAllPorts(EObject context) {
  128. val module = EcoreUtil2.getContainerOfType(context, SemanticAdaptation)
  129. var elementlist = new BasicEList<EObject>;
  130. for (Component element : module.elements) {
  131. if (element instanceof FMU) {
  132. elementlist += element.inports+element.outports
  133. }
  134. }
  135. return elementlist
  136. }
  137. def __getFromElement(EObject context, Class<? extends EObject> containertype, String featurename, Class<? extends EObject> featuretype) {
  138. /*val object = EcoreUtil2.getContainerOfType(context, containertype)
  139. if (object != null) {
  140. val feature = object.eClass.EAllStructuralFeatures.findFirst(f | f.name.equals(featurename))
  141. if (feature != null) {
  142. val featurevalue = object.eGet(feature)
  143. if (featurevalue instanceof EList) {
  144. if (featuretype != null) {
  145. return featurevalue.filter(v | featuretype.isInstance(v))
  146. } else {
  147. return featurevalue
  148. }
  149. } else {
  150. if (featuretype == null || featuretype.isInstance(featurevalue)) {
  151. val featurevaluelist = new BasicEList()
  152. featurevaluelist.add(featurevalue)
  153. return featurevaluelist
  154. }
  155. }
  156. } else {
  157. throw new Exception("Feature " + featurename + " not found in object of type " + containertype.name)
  158. }
  159. }
  160. return new BasicEList<EObject>()*/
  161. return context.__getFrom(containertype, featurename, featuretype, false).flatten
  162. }
  163. def __getFromElement(EObject context, Class<? extends EObject> containertype, String featurename) {
  164. return context.__getFromElement(containertype, featurename, null)
  165. }
  166. /**
  167. * Look from context to root for elements
  168. * @params:
  169. * context: element to start from
  170. * containertype: type of elements that have a feature that needs to be found
  171. * featurename: name of feature that must be a feature of containertype
  172. * featuretype: only take features of featuretype
  173. * all: if true: go through all instances of container type; if false: only the first encounter from context to root
  174. *
  175. * @returns:
  176. * all: list of lists of found elements (from context to root)
  177. * !all: list of found elements (first encounter from context to root)
  178. */
  179. def List<? extends List<? extends EObject>> __getFrom(EObject context, Class<? extends EObject> containertype, String featurename, Class<? extends EObject> featuretype, boolean all) {
  180. val List<List<EObject>> listOfElementLists = new LinkedList<List<EObject>>()
  181. for (object : EcoreUtil2.getAllContainers(context)) {
  182. if (containertype.isInstance(object)) {
  183. val List<EObject> listOfElements = new LinkedList<EObject>()
  184. val feature = object.eClass.EAllStructuralFeatures.findFirst(f | f.name.equals(featurename))
  185. if (feature !== null) {
  186. val featurevalue = object.eGet(feature)
  187. if (featurevalue instanceof EList) {
  188. if (featuretype !== null) {
  189. listOfElements.addAll(featurevalue.filter(v | featuretype.isInstance(v)).map(v | v as EObject))
  190. } else {
  191. listOfElements.addAll(featurevalue)
  192. }
  193. } else if (featurevalue instanceof EObject) {
  194. if (featuretype === null || featuretype.isInstance(featurevalue)) {
  195. listOfElements.add(featurevalue)
  196. }
  197. } else {
  198. throw new Exception("todo")
  199. }
  200. } else {
  201. throw new Exception("Feature " + featurename + " not found in object of type " + containertype.name)
  202. }
  203. listOfElementLists.add(listOfElements)
  204. if (!all) {
  205. return listOfElementLists
  206. }
  207. }
  208. }
  209. return listOfElementLists
  210. }
  211. @Inject
  212. private IGlobalScopeProvider globalScopeProvider;
  213. def protected IScope getGlobalScope(Resource context, EReference reference) {
  214. return getGlobalScope(context, reference, null);
  215. }
  216. def protected IScope getGlobalScope(Resource context, EReference reference, Predicate<IEObjectDescription> filter) {
  217. return wrap(globalScopeProvider.getScope(context, reference, filter));
  218. }
  219. private IScopeWrapper scopeWrapper;
  220. def public void setWrapper(IScopeWrapper wrapper) {
  221. this.scopeWrapper = wrapper;
  222. }
  223. def protected IScope wrap(IScope scope) {
  224. if (scopeWrapper!==null){
  225. return scopeWrapper.wrap(scope)
  226. } else {
  227. return scope
  228. }
  229. }
  230. def __getImportedScope(EObject context, EReference reference) {
  231. if (reference === SemanticAdaptationPackage.Literals.IMPORT__MODULE) {
  232. return getGlobalScope(context.eResource, reference)
  233. }
  234. val module = EcoreUtil2.getContainerOfType(context, SemanticAdaptation)
  235. var result = IScope.NULLSCOPE
  236. for (import : module.imports) {
  237. if (!import.module.eIsProxy)
  238. result = getModuleScope(context, reference, import.module, result)
  239. }
  240. result = getModuleScope(context, reference, module, result)
  241. return result//getDefinitionScope(context, reference, result)
  242. }
  243. def getModuleScope(EObject context, EReference reference, SemanticAdaptation module, IScope parent) {
  244. // FMUs and ports are visible
  245. val allDefinitions = module.elements.filter(FMU) + __getAllPorts(module)
  246. //println(allDefinitions)
  247. return Scopes.scopeFor(allDefinitions, parent)
  248. }
  249. /*def getDefinitionScope(EObject context, EReference reference, IScope parent) {
  250. val containingDef = EcoreUtil2.getContainerOfType(context, Definition)
  251. if (containingDef === null) {
  252. return parent
  253. }
  254. return Scopes.scopeFor(containingDef.args, parent)
  255. }*/
  256. //class SemanticAdaptationScopeProvider extends AbstractGlobalScopeDelegatingScopeProvider {
  257. // override getScope(EObject context, EReference reference) {
  258. // if (reference === SemanticAdaptationPackage.Literals.IMPORT__MODULE) {
  259. // return super.getGlobalScope(context.eResource, reference)
  260. // }
  261. // val module = EcoreUtil2.getContainerOfType(context, Module)
  262. // var result = IScope.NULLSCOPE
  263. // for (import : module.imports) {
  264. // if (!import.module.eIsProxy)
  265. // result = getModuleScope(context, reference, import.module, result)
  266. // }
  267. // result = getModuleScope(context, reference, module, result)
  268. // return getDefinitionScope(context, reference, result)
  269. // }
  270. //
  271. // def getModuleScope(EObject context, EReference reference, Module module, IScope parent) {
  272. // val allDefinitions = module.statements.filter(Definition)
  273. // if (context instanceof FunctionCall) {
  274. // return Scopes.scopeFor(allDefinitions.filter[context.args.size == args.size], parent)
  275. // } else {
  276. // return Scopes.scopeFor(allDefinitions, parent)
  277. // }
  278. // }
  279. //
  280. // def getDefinitionScope(EObject context, EReference reference, IScope parent) {
  281. // val containingDef = EcoreUtil2.getContainerOfType(context, Definition)
  282. // if (containingDef === null) {
  283. // return parent
  284. // }
  285. // return Scopes.scopeFor(containingDef.args, parent)
  286. // }
  287. }