1 package de.fhdw.wtf.walker.tasks;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.LinkedList;
8 import java.util.Map;
9
10 import de.fhdw.wtf.common.ast.Attribute;
11 import de.fhdw.wtf.common.ast.Constructor;
12 import de.fhdw.wtf.common.ast.ConstructorOrOperation;
13 import de.fhdw.wtf.common.ast.Group;
14 import de.fhdw.wtf.common.ast.Model;
15 import de.fhdw.wtf.common.ast.Name;
16 import de.fhdw.wtf.common.ast.Operation;
17 import de.fhdw.wtf.common.ast.type.ClassType;
18 import de.fhdw.wtf.common.ast.type.ProductElementType;
19 import de.fhdw.wtf.common.ast.visitor.ConstructorOrOperationExceptionVisitor;
20 import de.fhdw.wtf.common.exception.walker.DuplicateConstructorException;
21 import de.fhdw.wtf.common.exception.walker.InvalidOverloadingException;
22 import de.fhdw.wtf.common.exception.walker.TaskException;
23 import de.fhdw.wtf.common.task.TaskExecutor;
24 import de.fhdw.wtf.walker.walker.SimpleWalkerTask;
25
26
27
28
29
30
31
32 public final class OverloadingCheck extends SimpleWalkerTask {
33
34
35
36
37 private final Map<Name, Collection<Operation>> classOperationMap;
38
39
40
41
42
43 private final Map<ClassType, Collection<Constructor>> previouslyFoundConstructors;
44
45
46
47
48
49
50
51
52
53 private OverloadingCheck(final Model m, final TaskExecutor taskmanager) {
54 super(m, taskmanager);
55 this.classOperationMap = new HashMap<>();
56 this.previouslyFoundConstructors = new HashMap<>();
57 }
58
59
60
61
62
63
64
65
66
67
68 public static OverloadingCheck create(final Model m, final TaskExecutor taskmanager) {
69 return new OverloadingCheck(m, taskmanager);
70 }
71
72 @Override
73 public void handleGroup(final Group g) throws TaskException {
74
75 }
76
77 @Override
78 public void handleClass(final ClassType c) throws TaskException {
79
80 }
81
82 @Override
83 public void handleAttribute(final Attribute a, final ClassType owner) throws TaskException {
84
85 }
86
87 @Override
88 public void handleConstructorOrOperation(final ConstructorOrOperation coo, final ClassType owner)
89 throws TaskException {
90 coo.accept(new ConstructorOrOperationExceptionVisitor<TaskException>() {
91
92 @Override
93 public void handleOperation(final Operation operation) throws TaskException {
94 Collection<Operation> operations = OverloadingCheck.this.classOperationMap.get(owner.getName());
95 if (operations == null) {
96 operations = new ArrayList<>();
97 OverloadingCheck.this.classOperationMap.put(owner.getName(), operations);
98 }
99 for (final Operation current : operations) {
100 if (current.getName().equals(operation.getName())) {
101 if (current.getParameters().getElements().size() == operation.getParameters().getElements()
102 .size()) {
103 boolean isEqual = true;
104 final Iterator<ProductElementType> iteratorCurrent =
105 current.getParameters().getPrototype().getElements().iterator();
106 final Iterator<ProductElementType> iteratorO =
107 operation.getParameters().getPrototype().getElements().iterator();
108 while (isEqual && iteratorCurrent.hasNext()) {
109 isEqual = iteratorCurrent.next().getType().equals(iteratorO.next().getType());
110 }
111 if (isEqual) {
112 throw InvalidOverloadingException.create(
113 operation.getFirstToken(),
114 operation.getLastToken());
115 }
116 }
117 }
118 }
119 operations.add(operation);
120
121 }
122
123 @Override
124 public void handleConstructor(final Constructor constructor) throws TaskException {
125 OverloadingCheck.this.throwDuplicateConstructorExceptionIfExistsAlready(constructor, owner);
126 OverloadingCheck.this.addConstructorToPreviouslyFoundConstructors(constructor, owner);
127
128 }
129 });
130
131 }
132
133 @Override
134 public void finalizeTask() throws TaskException {
135
136 }
137
138 @Override
139 public void beginTask() throws TaskException {
140
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154 private void throwDuplicateConstructorExceptionIfExistsAlready(final Constructor constructor, final ClassType owner)
155 throws DuplicateConstructorException {
156 if (this.previouslyFoundConstructors.containsKey(owner)) {
157 final Iterator<Constructor> previouslyFoundConstructorsIterator =
158 this.previouslyFoundConstructors.get(owner).iterator();
159 while (previouslyFoundConstructorsIterator.hasNext()) {
160 final Constructor current = previouslyFoundConstructorsIterator.next();
161 if (current.getParameters().equals(constructor.getParameters())) {
162 throw DuplicateConstructorException.create(constructor);
163 }
164 }
165 }
166
167 }
168
169
170
171
172
173
174
175
176
177
178 private void addConstructorToPreviouslyFoundConstructors(final Constructor constructor, final ClassType owner) {
179 if (this.previouslyFoundConstructors.containsKey(owner)) {
180 this.previouslyFoundConstructors.get(owner).add(constructor);
181 } else {
182 final Collection<Constructor> list = new LinkedList<>();
183 list.add(constructor);
184 this.previouslyFoundConstructors.put(owner, list);
185 }
186
187 }
188
189 }