aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.viatra.solver.language.parent/org.eclipse.viatra.solver.language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java
blob: dfffc7ef74e19c3929688c9eee29e5abad78dd10 (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
package org.eclipse.viatra.solver.language.resource;

import java.util.Iterator;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.viatra.solver.language.model.problem.Assertion;
import org.eclipse.viatra.solver.language.model.problem.Atom;
import org.eclipse.viatra.solver.language.model.problem.Conjunction;
import org.eclipse.viatra.solver.language.model.problem.ImplicitVariable;
import org.eclipse.viatra.solver.language.model.problem.Literal;
import org.eclipse.viatra.solver.language.model.problem.NegativeLiteral;
import org.eclipse.viatra.solver.language.model.problem.Node;
import org.eclipse.viatra.solver.language.model.problem.Problem;
import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
import org.eclipse.viatra.solver.language.model.problem.Statement;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.DefaultLocationInFileProvider;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.IScopeProvider;
import org.eclipse.xtext.util.ITextRegion;

import com.google.inject.Inject;

public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider {
	@Inject
	private IQualifiedNameProvider qualifiedNameProvider;

	@Inject
	private IScopeProvider scopeProvider;

	@Override
	protected ITextRegion doGetTextRegion(EObject obj, RegionDescription query) {
		if (obj instanceof Node) {
			return getNodeTextRegion((Node) obj, query);
		}
		if (obj instanceof ImplicitVariable) {
			return getVariableTextRegion((ImplicitVariable) obj, query);
		}
		return super.doGetTextRegion(obj, query);
	}

	protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) {
		ITextRegion newNodeRegion = getNewNodeTextRegion(node, query);
		if (newNodeRegion != null) {
			return newNodeRegion;
		}
		return getNodeFirstReferenceTextRegion(node, query);
	}
	
	protected ITextRegion getNewNodeTextRegion(Node node, RegionDescription query) {
		QualifiedName nodeName = qualifiedNameProvider.getFullyQualifiedName(node);
		if (nodeName == null || nodeName.getSegmentCount() <= 1) {
			return null;
		}
		if (ProblemDerivedStateComputer.NEW_NODE.equals(nodeName.getLastSegment())) {
			QualifiedName className = nodeName.skipLast(1);
			IScope classScope = scopeProvider.getScope(node, ProblemPackage.Literals.ASSERTION__RELATION);
			IEObjectDescription description = classScope.getSingleElement(className);
			if (description == null) {
				return null;
			}
			EObject classDeclaration = description.getEObjectOrProxy();
			if (!classDeclaration.eIsProxy()) {
				return doGetTextRegion(classDeclaration, query);
			}
		}
		return null;
	}

	protected ITextRegion getNodeFirstReferenceTextRegion(Node node, RegionDescription query) {
		Problem problem = EcoreUtil2.getContainerOfType(node, Problem.class);
		if (problem == null) {
			return ITextRegion.EMPTY_REGION;
		}
		for (Statement statement : problem.getStatements()) {
			if (statement instanceof Assertion) {
				Assertion assertion = (Assertion) statement;
				int index = assertion.getArguments().indexOf(node);
				if (index >= 0) {
					return doGetLocationOfFeature(assertion, ProblemPackage.Literals.ASSERTION__ARGUMENTS, index,
							query);
				}
			}
		}
		return ITextRegion.EMPTY_REGION;
	}

	protected ITextRegion getVariableTextRegion(ImplicitVariable variable, RegionDescription query) {
		EObject container = variable.eContainer();
		if (container instanceof Conjunction) {
			return getFirstReferenceToVariableInConjunction(variable, (Conjunction) container, query);
		}
		if (container instanceof NegativeLiteral) {
			return getFirstReferenceToVariableInNegativeLiteral(variable, (NegativeLiteral) container, query);
		}
		return ITextRegion.EMPTY_REGION;
	}

	protected ITextRegion getFirstReferenceToVariableInConjunction(ImplicitVariable variable, Conjunction conjunction,
			RegionDescription query) {
		Iterator<Literal> iterator = conjunction.getLiterals().iterator();
		ITextRegion found = ITextRegion.EMPTY_REGION;
		while (found == ITextRegion.EMPTY_REGION && iterator.hasNext()) {
			Literal literal = iterator.next();
			if (literal instanceof Atom) {
				found = getFirstReferenceToVariableInAtom(variable, (Atom) literal, query);
			} else if (literal instanceof NegativeLiteral) {
				found = getFirstReferenceToVariableInNegativeLiteral(variable, (NegativeLiteral) literal, query);
			}
		}
		return found;
	}

	protected ITextRegion getFirstReferenceToVariableInNegativeLiteral(ImplicitVariable variable,
			NegativeLiteral literal, RegionDescription query) {
		return getFirstReferenceToVariableInAtom(variable, literal.getAtom(), query);
	}

	protected ITextRegion getFirstReferenceToVariableInAtom(ImplicitVariable variable, Atom atom,
			RegionDescription query) {
		int index = atom.getArguments().indexOf(variable);
		if (index >= 0) {
			return doGetLocationOfFeature(atom, ProblemPackage.Literals.ATOM__ARGUMENTS, index, query);
		}
		return ITextRegion.EMPTY_REGION;
	}
}