aboutsummaryrefslogtreecommitdiffstats
path: root/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.components/src/hu/bme/mit/inf/dslreasoner/faulttree/components/scoping/CftLanguageScopeProvider.xtend
blob: f295f116ade6ba8eabe1acf282650a0cff64f8f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * generated by Xtext 2.16.0
 */
package hu.bme.mit.inf.dslreasoner.faulttree.components.scoping

import com.google.common.collect.Lists
import com.google.inject.Inject
import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.ComponentInstance
import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.EventReference
import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.LookupDefinition
import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.MappingDefinition
import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.TransformationDefinition
import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.Variable
import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.impl.MappingDefinitionImpl
import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentDefinition
import org.eclipse.emf.common.notify.Notifier
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.EcoreUtil2
import org.eclipse.xtext.resource.EObjectDescription
import org.eclipse.xtext.resource.IResourceDescriptions
import org.eclipse.xtext.resource.IResourceDescriptionsProvider
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import org.eclipse.xtext.scoping.impl.SimpleScope

import static hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.CftLanguagePackage.Literals.*

/**
 * This class contains custom scoping description.
 * 
 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
 * on how and when to use it.
 */
class CftLanguageScopeProvider extends AbstractCftLanguageScopeProvider {
	public static val SINGLETON_VARIABLE_PREFIX = "_"
	
	@Inject IResourceDescriptionsProvider resourceDescriptionsProvider
	@Inject CftLanguageImportedNamespaceAwareLocalScopeProvider importedNamespaceProvider

	override getScope(EObject context, EReference reference) {
		switch (reference) {
			case LOOKUP_DEFINITION__MAPPING:
				getRuleDefinitionsScope(context, reference)
			case LOOKUP_DEFINITION__ARGUMENTS:
				getMappingParametersScope(context)
			case EVENT_REFERENCE__COMPONENT:
				getComponentInstancesScope(context)
			case EVENT_REFERENCE__EVENT:
				getEventDeclarationsScope(context)
			default:
				super.getScope(context, reference)
		}
	}

	protected def getRuleDefinitionsScope(EObject context, EReference referece) {
		val transformationDefinition = EcoreUtil2.getContainerOfType(context, TransformationDefinition)
		if (transformationDefinition === null) {
			return IScope.NULLSCOPE
		}
		val resourceDescriptions = getResourceDescriptions(transformationDefinition)
		val mappingDefinitionDescriptions = toMappingDefinitionDescriptions(resourceDescriptions,
			transformationDefinition.mappingDefinitions)
		val ruleDefinitionsScope = new SimpleScope(IScope.NULLSCOPE, mappingDefinitionDescriptions)
		importedNamespaceProvider.createImportNormalizedScope(ruleDefinitionsScope, context, referece)
	}

	protected def toMappingDefinitionDescriptions(IResourceDescriptions resourceDescriptions,
		Iterable<? extends MappingDefinition> ruleDefinitions) {
		val mappingDefinitionDescriptions = Lists.newArrayListWithExpectedSize(ruleDefinitions.size)
		for (ruleDefinition : ruleDefinitions) {
			val pattern = ruleDefinition.safelyGetPattern
			if (pattern !== null) {
				val patternName = resourceDescriptions.getExportedObjectsByObject(pattern).head?.qualifiedName
				if (patternName !== null) {
					mappingDefinitionDescriptions += EObjectDescription.create(patternName, ruleDefinition)
				}
			}

		}
		mappingDefinitionDescriptions
	}
	
	private def safelyGetPattern(MappingDefinition mappingDefinition) {
		switch (mappingDefinition) {
			MappingDefinitionImpl: mappingDefinition.basicGetPattern
			case null: null
			default: mappingDefinition.pattern
		}
	}

	private def getResourceDescriptions(Notifier notifier) {
		val resourceSet = EcoreUtil2.getResourceSet(notifier)
		if (resourceSet === null) {
			new IResourceDescriptions.NullImpl
		} else {
			resourceDescriptionsProvider.getResourceDescriptions(resourceSet)
		}
	}
	
	protected def getMappingParametersScope(EObject context) {
		val mappingDefinition = EcoreUtil2.getContainerOfType(context, MappingDefinition)
		if (mappingDefinition === null) {
			return IScope.NULLSCOPE
		}
		val variables = mappingDefinition.parameters.filter [
			!name.startsWith(SINGLETON_VARIABLE_PREFIX)
		]
		Scopes.scopeFor(variables)
	}

	protected def getComponentInstancesScope(EObject context) {
		val mappingDefinition = EcoreUtil2.getContainerOfType(context, MappingDefinition)
		if (mappingDefinition === null) {
			return IScope.NULLSCOPE
		}
		val componentInstances = <Variable>newArrayList
		componentInstances.addAll(mappingDefinition.lookupDefinitions)
		if (mappingDefinition.componentInstance !== null) {
			componentInstances += mappingDefinition.componentInstance
		}
		Scopes.scopeFor(componentInstances)
	}

	protected def getEventDeclarationsScope(EObject context) {
		val variable = EcoreUtil2.getContainerOfType(context, EventReference)?.component
		val events = switch (variable) {
			ComponentInstance:
				variable.componentType?.allEventDeclarations
			LookupDefinition:
				variable.mapping?.componentInstance?.componentType?.allEventDeclarations
			default:
				null
		}
		if (events === null) {
			return IScope.NULLSCOPE
		}
		Scopes.scopeFor(events)
	}

	private def getAllEventDeclarations(ComponentDefinition componentDefinition) {
		val eventDeclarations = newArrayList
		eventDeclarations.addAll(componentDefinition.inputEvents)
		eventDeclarations.addAll(componentDefinition.eventDefinitions)
		eventDeclarations
	}
}