aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/Alloy-Solver2/hu.bme.mit.inf.dslreasoner.alloy.language/src/hu/bme/mit/inf/dslreasoner/scoping/AlloyLanguageScopeProvider.xtend
blob: b2333f51badabe63e27626d3cb5f53b11fc5c0b3 (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
/*
 * generated by Xtext
 */
package hu.bme.mit.inf.dslreasoner.scoping

import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSDefinition
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSDocument
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSEnumDeclaration
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSFunctionCall
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSQuantifiedEx
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSReference
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSRelationDeclaration
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSRelationDefinition
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSSignatureBody
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSSum
import java.util.ArrayList
import java.util.Collections
import java.util.HashSet
import java.util.LinkedList
import java.util.List
import java.util.Set
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.Scopes
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation.html#scoping
 * on how and when to use it 
 *
 */
class AlloyLanguageScopeProvider extends AbstractDeclarativeScopeProvider {
	
	def public IScope scope_ALSReference_referred(ALSReference alsReferecnce, EReference ref) {
		val Set<ALSRelationDeclaration> declarations = new HashSet
		
		val parent = alsReferecnce.getAllParents(ALSDocument).head as ALSDocument
		val signatures = parent.signatureBodies.map[ALSSignatureBody x|x.declarations].flatten
		declarations+=parent.enumDeclarations
		declarations+=signatures
		declarations+=parent.enumDeclarations.map[ALSEnumDeclaration x | x.literal].flatten
		declarations+=parent.signatureBodies.map[ALSSignatureBody x|x.fields].flatten
		
		declarations+=alsReferecnce.getAllParents(ALSQuantifiedEx).map[ALSQuantifiedEx x | x.variables].flatten
		declarations+=alsReferecnce.getAllParents(ALSSum).map[ALSSum x | x.variables].flatten
		declarations+=alsReferecnce.getAllParents(ALSRelationDefinition).map[ALSRelationDefinition x | x.variables].flatten
		
//		println("---")
//		println(declarations.map[it.name].join(", "))
		
		return Scopes.scopeFor(declarations)
	}
	//{ALSFunctionCall} (/*functionName=ALSID |*/ referredDefinition=[ALSDefinition]) 
	def public IScope scope_ALSFunctionCall_referredDefinition(ALSFunctionCall call, EReference ref) {
		val parent = call.<ALSDocument>getAllParents(ALSDocument).head as ALSDocument
		val list = new LinkedList<ALSDefinition>
		list += parent.relationDefinitions
		list += parent.functionDefinitions
		//list.forEach[println(it.name + " " + it.eContainer)]
		return Scopes.scopeFor(list)
	}
	
	def <X extends EObject> List<X> getAllParents(EObject object, Class<X> type) {
		if(object.eContainer == null) {
			return Collections.EMPTY_LIST
		} else {
			val container = object.eContainer;
			val previousParents = container.getAllParents(type)
			if(type.isInstance(container)){
				val res = new ArrayList(previousParents)
				res+= container as X
				return res	
			}
			else return previousParents
			
		}
	}
}