Project

General

Profile

root / trunk / compiler / ooasCompiler / src / org / momut / ooas / visitors / OoaTypesVisitor.java @ 9

1
/**
2
  *
3
  *                      OOAS Compiler
4
  *
5
  *       Copyright 2015, AIT Austrian Institute of Technology.
6
  * This code is based on the C# Version of the OOAS Compiler, which is
7
  * copyright 2015 by the Institute of Software Technology, Graz University
8
  * of Technology with portions copyright by the AIT Austrian Institute of
9
  * Technology. All rights reserved.
10
  *
11
  * SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
12
  *
13
  * If you modify the file please update the list of contributors below to in-
14
  * clude your name. Please also stick to the coding convention of using TABs
15
  * to do the basic (block-level) indentation and spaces for anything after
16
  * that. (Enable the display of special chars and it should be pretty obvious
17
  * what this means.) Also, remove all trailing whitespace.
18
  *
19
  * Contributors:
20
  *               Willibald Krenn (AIT)
21
  *               Stephan Zimmerer (AIT)
22
  *               Markus Demetz (AIT)
23
  *               Christoph Czurda (AIT)
24
  *
25
  */
26

    
27

    
28
package org.momut.ooas.visitors;
29

    
30
import java.util.HashSet;
31

    
32
import org.momut.ooas.ast.AstNodeTypeEnum;
33
import org.momut.ooas.ast.IAst;
34
import org.momut.ooas.ast.identifiers.Identifier;
35
import org.momut.ooas.ast.identifiers.IdentifierKind;
36
import org.momut.ooas.ast.identifiers.MainModule;
37
import org.momut.ooas.ast.identifiers.TypeIdentifier;
38
import org.momut.ooas.ast.types.ListType;
39
import org.momut.ooas.ast.types.MapType;
40
import org.momut.ooas.ast.types.OoActionSystemType;
41
import org.momut.ooas.ast.types.TupleType;
42
import org.momut.ooas.ast.types.Type;
43
import org.momut.ooas.parser.ParserError;
44
import org.momut.ooas.parser.ParserState;
45
import org.momut.ooas.utils.exceptions.ArgumentException;
46

    
47
/// <summary>
48
/// Requires: ResolveOpaque
49
///
50
/// Checks whether types have been defined in a sane way (no self refs etc.)
51
/// </summary>
52
public final class OoaTypesVisitor extends OoaCompleteAstTraversalVisitor
53
{
54
        private void Error(Type aType, String p)
55
        {
56
                ParserError error = new ParserError(m_ParserState.filename,
57
                                aType.identifier().line(), aType.identifier().column(), p);
58
                m_ParserState.AddErrorMessage(error);
59
        }
60

    
61
        HashSet<Type> typesSeen = new HashSet<Type>();
62

    
63

    
64
        @Override
65
        public void visit(MainModule mainModule)
66
        {
67
                for (Identifier x: mainModule.symbolTable().symbolList())
68
                {
69
                        if (x.kind() == IdentifierKind.TypeIdentifier)
70
                                x.Accept(this);
71
                }
72
        }
73

    
74
        @Override
75
        protected void VisitAstElement(IAst element, IAst parent)
76
        {
77
                if (element.nodeType() != AstNodeTypeEnum.type)
78
                        m_visited.add(element);
79

    
80
                super.VisitAstElement(element, parent);
81
        }
82

    
83

    
84
        @Override
85
        public void visit(TypeIdentifier typeIdentifier)
86
        {
87
                typesSeen.clear();
88
                super.visit(typeIdentifier);
89
        }
90

    
91

    
92
        private interface Action<T extends Type> {
93
                void doIt(T param);
94
        }
95

    
96
        /* Does the check for recursion */
97
        private <T extends Type> void CheckForRecursion(T aType, String Message, Action<T> toCall)
98
        {
99
                if (typesSeen.contains(aType))
100
                {
101
                        Error(aType, Message);
102
                        return;
103
                }
104
                typesSeen.add(aType);
105
                try
106
                {
107
                        toCall.doIt(aType);
108
                }
109
                finally
110
                {
111
                        typesSeen.remove(aType);
112
                }
113
        }
114

    
115
        /* see whether a tuple-type includes itself */
116
        public void HackUntilCSharp4(TupleType t)
117
        { super.visit(t); }
118

    
119
        @Override
120
        public void visit(TupleType tupleType)
121
        {
122
                this.<TupleType>CheckForRecursion(tupleType,
123
                                String.format("Tuple contains itself: '%s' (Recursive definitions not allowed.)",
124
                                                tupleType.toString()),
125
                                new Action<TupleType>(){
126
                                        @Override
127
                                        public void doIt(TupleType param) {
128
                                                HackUntilCSharp4(param);
129
                                }}); // (x) => HackUntilCSharp4(x));
130
        }
131

    
132
        /* see whether a list-type includes itself */
133
        public void HackUntilCSharp4(ListType t)
134
        { super.visit(t); }
135

    
136
        @Override
137
        public void visit(ListType listType)
138
        {
139
                this.<ListType>CheckForRecursion(listType,
140
                                String.format("List contains itself: '%s' (Recursive definitions not allowed.)",
141
                                                listType.toString()),
142
                                new Action<ListType>(){
143
                                        @Override
144
                                        public void doIt(ListType param) {
145
                                                HackUntilCSharp4(param);
146
                                }}); // (x) => HackUntilCSharp4(x));
147
        }
148

    
149
        /* see whether a map-type includes itself */
150
        public void HackUntilCSharp4(MapType t)
151
        { super.visit(t); }
152
        @Override
153
        public void visit(MapType mapType)
154
        {
155
                this.<MapType>CheckForRecursion(mapType,
156
                                String.format("Map contains itself: '%s' (Recursive definitions not allowed.)",
157
                                                mapType.toString()),
158
                                new Action<MapType>(){
159
                                        @Override
160
                                        public void doIt(MapType param) {
161
                                                HackUntilCSharp4(param);
162
                                        }}); // (x) => HackUntilCSharp4(x));
163
        }
164

    
165
        @Override
166
        public void visit(OoActionSystemType ooActionSystemType)
167
        {
168
                // do not go into classes..
169
        }
170

    
171
        public OoaTypesVisitor(ParserState aState)
172
        {
173
                super (aState, true);
174
                if (aState == null)
175
                        throw new ArgumentException();
176
        }
177
}