Analysis.jrag 4.03 KB
Newer Older
Niklas Fors's avatar
Niklas Fors committed
1
2
3
import java.util.*;


Niklas Fors's avatar
Niklas Fors committed
4
aspect TypeAnalysis {
5
6
	public abstract TypeUse Component.getTypeUse();

Niklas Fors's avatar
Niklas Fors committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
	syn TypeDecl TypeUse.decl() = lookupType(getID());
	inh TypeDecl TypeUse.lookupType(String name);
	eq Program.getChild().lookupType(String name) {
		for (TypeDecl td: getTypeDecls()) {
			if (td.getID().equals(name)) {
				return td;
			}
		}
		return null;
	}
	syn boolean TypeDecl.isAlreadyDeclared()
		= lookupType(getID()) != this;
	inh TypeDecl TypeDecl.lookupType(String name);
}
Niklas Fors's avatar
Niklas Fors committed
21

Niklas Fors's avatar
Niklas Fors committed
22
aspect ComponentAnalysis {
Niklas Fors's avatar
Niklas Fors committed
23
24
	syn boolean Component.isTargetOfDirectedRelation() = false;
	eq RelationComponent.isTargetOfDirectedRelation() = isTargetOfRightDirection();
25
26
27
28
29
	inh boolean RelationComponent.isTargetOfRightDirection();
	eq Relation.getRight().isTargetOfRightDirection()
		= getDirection() instanceof RightDirection;
	eq Program.getChild().isTargetOfRightDirection() = false;

Niklas Fors's avatar
Niklas Fors committed
30
	syn String Component.name() = getID();
Niklas Fors's avatar
Niklas Fors committed
31

32
33
	syn TypeDecl Component.toTypeDecl() = enclosingTypeDecl();
	eq RelationComponent.toTypeDecl() = getTypeUse().decl();
Niklas Fors's avatar
Niklas Fors committed
34
35
36
	inh TypeDecl Component.enclosingTypeDecl();
	eq TypeDecl.getChild().enclosingTypeDecl() = this;
	eq Program.getChild().enclosingTypeDecl() = null;
37
38
39
40
41
	
	inh RelationComponent RelationComponent.otherSide();
	eq Relation.getLeft().otherSide() = getRight();
	eq Relation.getRight().otherSide() = getLeft();
	eq Program.getChild().otherSide() = null;
42

43
	syn TypeDecl RelationComponent.ofTypeDecl() = otherSide().toTypeDecl();
Niklas Fors's avatar
Niklas Fors committed
44
45

	syn boolean Component.isAlreadyDeclared()
Niklas Fors's avatar
Niklas Fors committed
46
		= !isTargetOfDirectedRelation()
47
			&& toTypeDecl() != null
Niklas Fors's avatar
Niklas Fors committed
48
			&& lookupComponent(toTypeDecl(), name()) != this;
Niklas Fors's avatar
Niklas Fors committed
49
	inh Component Component.lookupComponent(TypeDecl td, String name);
50
51
52
53
54
55
56
57
58
59
60
61
	eq Program.getChild().lookupComponent(TypeDecl td, String name)
		= lookupComponentSyn(td, name);
	syn Component Program.lookupComponentSyn(TypeDecl td, String name) {
		// Check super type first to find duplicates (shadowing is not allowed)
		if (td.hasSuper() && td.getSuper().decl() != null) {
			Component c = lookupComponentSyn(td.getSuper().decl(), name);
			if (c != null) return c;
		}

		for (Component c: td.getComponents()) {
			if (c.name().equals(name)) {
				return c;
Niklas Fors's avatar
Niklas Fors committed
62
63
			}
		}
64
		
Niklas Fors's avatar
Niklas Fors committed
65
		for (Relation r: getRelations()) {
66
67
68
69
			Component c = r.getLeft().lookup(td, name);
			if (c != null) return c;
			c = r.getRight().lookup(td, name);
			if (c != null) return c;
Niklas Fors's avatar
Niklas Fors committed
70
		}
71

Niklas Fors's avatar
Niklas Fors committed
72
73
		return null;
	}
74
75

	syn RelationComponent RelationComponent.lookup(TypeDecl td, String name)
Niklas Fors's avatar
Niklas Fors committed
76
		= !isTargetOfDirectedRelation() && toTypeDecl() == td && name().equals(name)
77
78
79
80
81
82
83
84
		? this
		: null;


	coll Set<RelationComponent> TypeDecl.relationComponents()
		[new HashSet<RelationComponent>()]
		root Program;
	RelationComponent contributes this
Niklas Fors's avatar
Niklas Fors committed
85
		when !isTargetOfDirectedRelation() && toTypeDecl() != null
86
87
		to TypeDecl.relationComponents()
		for toTypeDecl();
88
89
90
91
92
93
94
95
96
97

	syn Set<OneRelationComponent> TypeDecl.oneRelationComponents() {
		Set<OneRelationComponent> set = new HashSet<>();
		for (RelationComponent rc: relationComponents()) {
			if (rc instanceof OneRelationComponent) {
				set.add((OneRelationComponent) rc);
			}
		}
		return set;
	}
Niklas Fors's avatar
Niklas Fors committed
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
aspect Constructors {
	syn Collection<Component> TypeDecl.componentsTransitive() {
		ArrayList<Component> list = new ArrayList<>();
		if (hasSuper() && getSuper().decl() != null) {
			list.addAll(getSuper().decl().componentsTransitive());
		}
		for (Component c: getComponents()) {
			list.add(c);
		}
		return list;
	}

	syn boolean TypeDecl.needsConstructor() {
		if (componentsTransitive().isEmpty()) {
			return false;
		}
		if (!relationComponents().isEmpty()) {
			return true;
		}
		return hasSuper()
			&& getSuper().decl() != null
			&& getSuper().decl().needsConstructor();
	}
}

Niklas Fors's avatar
Niklas Fors committed
125
aspect Utils {
126
	public String SimpleTypeUse.toString() {
Niklas Fors's avatar
Niklas Fors committed
127
128
		return getID();
	}
129
130
131
132
133
134
135
136
137
138
139
140
141
	public String ParameterizedTypeUse.toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(getID()).append("<");
		int i = 0;
		for (TypeUse u: getTypeUses()) {
			sb.append(u.toString());
			if (++i < getNumTypeUse()) {
				sb.append(", ");
			}
		}
		sb.append(">");
		return sb.toString();
	}
Niklas Fors's avatar
Niklas Fors committed
142
143
144
145
	public String TypeDecl.toString() {
		return getID();
	}
}