Source code: mlsub/typing/MonotypeConstructor.java
1 /**************************************************************************/
2 /* B O S S A */
3 /* A simple imperative object-oriented research language */
4 /* (c) Daniel Bonniot 1999 */
5 /* */
6 /* This program is free software; you can redistribute it and/or modify */
7 /* it under the terms of the GNU General Public License as published by */
8 /* the Free Software Foundation; either version 2 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /**************************************************************************/
12
13 // File : MonotypeConstructor.java
14 // Created : Thu Jul 22 09:15:17 1999 by bonniot
15 //$Modified: Tue Aug 29 17:23:23 2000 by Daniel Bonniot $
16
17 package mlsub.typing;
18
19 import java.util.*;
20
21 import mlsub.typing.lowlevel.*;
22
23 /**
24 * A monotype, build by application of
25 * a type constructor to type parameters.
26 */
27 public final class MonotypeConstructor extends Monotype
28 {
29 /**
30 * Constructs a monotype by application of the type constructor
31 * to the type parameters.
32 *
33 * @param tc the type constructor
34 * @param parameters the type parameters
35 */
36 public MonotypeConstructor(TypeConstructor tc, Monotype[] parameters)
37 throws BadSizeEx
38 {
39 this.tc = tc;
40 this.parameters = parameters;
41 if(parameters != null && parameters.length == 0)
42 throw new Error("Not optimal");
43
44 // variance is not known yet for java classes
45 // ill-formedness shall be discovered later, hopefully
46 if (tc.variance != null)
47 {
48 int len = (parameters==null ? 0 : parameters.length);
49 if (tc.arity() != len)
50 throw new BadSizeEx(tc.arity(), len);
51 }
52 }
53
54 /**
55 * Constructs a monotype by application of the type constructor
56 * to one type parameter.
57 *
58 * @param tc the type constructor
59 * @param parameter the type parameter
60 */
61 public static MonotypeConstructor apply (TypeConstructor tc,
62 Monotype parameter)
63 throws BadSizeEx
64 {
65 return new MonotypeConstructor(tc, new Monotype[]{ parameter });
66 }
67
68 /**
69 Return the head type constructor if this monotype is
70 of a known variance, or null.
71 */
72 public TypeConstructor head()
73 {
74 return tc;
75 }
76
77 public TypeConstructor getTC()
78 {
79 return tc;
80 }
81
82 public Monotype[] getTP()
83 {
84 return parameters;
85 }
86
87 /**
88 Returns true if this monotype is only made of
89 top-level, rigid type constructors
90 */
91 public boolean isRigid()
92 {
93 return tc.isRigid() && Monotype.isRigid(parameters);
94 }
95
96 /**
97 * Perform type symbol substitution inside the monotype.
98 *
99 * Does not need to create a new object, but must not
100 * imperatively modify the monotype.
101 *
102 * @param map a map from TypeSymbols to TypeSymbols
103 * @return a monotype with substitution performed
104 */
105 Monotype substitute(Map map)
106 {
107 Object newTC = map.get(tc);
108
109 return new MonotypeConstructor
110 ((newTC==null ? tc : (TypeConstructor) newTC),
111 Monotype.substitute(map, parameters));
112 }
113
114 /****************************************************************
115 * low-level interface
116 ****************************************************************/
117
118 public int getId() { throw new Error(); }
119 public void setId(int value) { throw new Error(); }
120
121 public Kind getKind() { return tc.variance; }
122 public void setKind(Kind value) {
123 if (tc.variance == value)
124 return;
125 else
126 throw new Error("SetKind in " + this +": " + value + " != " + tc.variance);
127 }
128
129 public boolean equals(Object o)
130 {
131 if(!(o instanceof MonotypeConstructor))
132 return false;
133 MonotypeConstructor that = (MonotypeConstructor) o;
134
135 return
136 tc.equals(that.tc)
137 && (parameters==null && that.parameters==null
138 || parameters.equals(that.parameters));
139 }
140
141 public String toString()
142 {
143 return tc.toString(parameters);
144 }
145
146 public String toString(boolean isNull, String suffix)
147 {
148 return tc.toString(parameters, isNull, suffix);
149 }
150
151 public TypeConstructor tc;
152 Monotype[] parameters;
153
154 /****************************************************************
155 * Simplification
156 ****************************************************************/
157
158 void tag(int variance)
159 {
160 Engine.tag(tc, variance);
161 if (tc.variance instanceof Variance)
162 ((Variance) tc.variance).tag(parameters, variance);
163 else
164 // Nullness Kind
165 parameters[0].tag(variance);
166 }
167
168 Monotype canonify()
169 {
170 tc = (TypeConstructor) Engine.canonify(tc);
171
172 parameters = Monotype.canonify(parameters);
173 return this;
174 }
175 }