35
38
<xsl:variable name="i" select="document($specs_file)"></xsl:variable>
37
40
<xsl:template name="err">
38
42
<xsl:param name="m"/>
39
43
<xsl:param name="n"/>
40
44
<xsl:param name="a"/>
41
45
<xsl:param name="s"/>
42
46
<xsl:message terminate="yes">
43
Error <xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if>
45
select="$n"/>/<xsl:value-of
46
select="$a"/>: <xsl:value-of select="$s"/>
47
Error <xsl:if test="$f != ''">in <xsl:value-of select ="$f"/>:</xsl:if>
48
<xsl:if test="$m != ''"><xsl:value-of select ="$m"/>:</xsl:if>
49
<xsl:value-of select="$n"/>
50
<xsl:if test="$a != ''">/<xsl:value-of
51
select ="$a"/></xsl:if>: <xsl:value-of select="$s"/>
55
<xsl:template name="find_spec">
56
<xsl:variable name="curModule" select="ancestor::erlref/module"/>
57
<xsl:variable name="mod" select="@mod"/>
58
<xsl:variable name="name" select="@name"/>
59
<xsl:variable name="arity" select="@arity"/>
60
<xsl:variable name="clause_i" select="@clause_i"/>
61
<xsl:variable name="spec0" select=
62
"$i/module[@name=$curModule]/spec
63
[name=$name and arity=$arity
64
and (string-length($mod) = 0 or module = $mod)]"/>
65
<xsl:variable name="spec" select="$spec0[string-length($clause_i) = 0
66
or position() = $clause_i]"/>
68
<xsl:if test="count($spec) != 1">
69
<xsl:variable name="why">
71
<xsl:when test="count($spec) > 1">ambiguous spec</xsl:when>
72
<xsl:when test="count($spec) = 0">unknown spec</xsl:when>
75
<xsl:call-template name="err">
76
<xsl:with-param name="f" select="$curModule"/>
77
<xsl:with-param name="m" select="$mod"/>
78
<xsl:with-param name="n" select="$name"/>
79
<xsl:with-param name="a" select="$arity"/>
80
<xsl:with-param name="s" select="$why"/>
83
<xsl:copy-of select="$spec"/>
50
86
<xsl:template name="spec_name">
51
<xsl:variable name="curModule" select="ancestor::erlref/module"/>
52
<xsl:variable name="mod" select="@mod"/>
53
87
<xsl:variable name="name" select="@name"/>
54
88
<xsl:variable name="arity" select="@arity"/>
55
<xsl:variable name="clause" select="@clause"/>
56
<xsl:variable name="spec0" select=
57
"$i/module[@name=$curModule]/spec
58
[name=$name and arity=$arity
59
and (string-length($mod) = 0 or module = $mod)]"/>
60
<xsl:variable name="spec" select="$spec0[string-length($clause) = 0
61
or position() = $clause]"/>
62
<xsl:if test="count($spec) = 0">
63
<xsl:call-template name="err">
64
<xsl:with-param name="m" select="$mod"/>
65
<xsl:with-param name="n" select="$name"/>
66
<xsl:with-param name="a" select="$arity"/>
67
<xsl:with-param name="s">unknown spec</xsl:with-param>
89
<xsl:variable name="spec0">
90
<xsl:call-template name="find_spec"/>
92
<xsl:variable name="spec" select="exsl:node-set($spec0)/spec"/>
72
95
<xsl:when test="ancestor::cref">
77
100
<xsl:when test="ancestor::erlref">
101
<xsl:apply-templates select="$spec/contract/clause/head"/>
102
<xsl:text> .br</xsl:text>
107
<xsl:template match="head">
108
<xsl:text> .nf </xsl:text>
109
<xsl:text> .B </xsl:text>
110
<xsl:apply-templates/>
111
<xsl:text> .br</xsl:text>
112
<xsl:text> .fi</xsl:text>
115
<!-- The *last* <name name="..." arity=".."/> -->
116
<xsl:template match="name" mode="types">
117
<xsl:variable name="name" select="@name"/>
118
<xsl:variable name="arity" select="@arity"/>
119
<xsl:variable name="spec0">
120
<xsl:call-template name="find_spec"/>
122
<xsl:variable name="spec" select="exsl:node-set($spec0)/spec"/>
123
<xsl:variable name="clause" select="$spec/contract/clause"/>
125
<xsl:variable name="type_desc" select="../type_desc"/>
126
<!-- $type is data types to be presented as guards ("local types") -->
127
<xsl:variable name="type"
128
select="../type[string-length(@name) > 0
129
or string-length(@variable) > 0]"/>
130
<xsl:variable name="type_variables"
131
select ="$type[string-length(@variable) > 0]"/>
132
<xsl:variable name="local_types"
133
select ="$type[string-length(@name) > 0]"/>
134
<xsl:variable name="output_subtypes" select="count($type_variables) = 0"/>
136
<!-- It is assumed there is no support for overloaded specs
137
(there is no spec with more than one clause) -->
138
<xsl:if test="count($clause/guard) > 0 or count($type) > 0">
139
<xsl:text> .RS</xsl:text>
140
<xsl:text> .LP</xsl:text>
141
<xsl:text> Types: </xsl:text>
142
<xsl:text> .RS 3</xsl:text>
145
<xsl:when test="$output_subtypes">
146
<xsl:call-template name="subtype">
147
<xsl:with-param name="subtype" select="$clause/guard/subtype"/>
148
<xsl:with-param name="type_desc" select="$type_desc"/>
149
<xsl:with-param name="local_types" select="$local_types"/>
153
<xsl:call-template name="type_variables">
154
<xsl:with-param name="type_variables" select="$type_variables"/>
155
<xsl:with-param name="type_desc" select="$type_desc"/>
156
<xsl:with-param name="local_types" select="$local_types"/>
157
<xsl:with-param name="fname" select="$name"/>
158
<xsl:with-param name="arity" select="$arity"/>
164
<xsl:call-template name="local_type">
165
<xsl:with-param name="type_desc" select="$type_desc"/>
166
<xsl:with-param name="local_types" select="$local_types"/>
168
<xsl:text> .RE</xsl:text>
170
<xsl:text> .RE</xsl:text>
175
<!-- Handle <type variable="..." name_i="..."/> -->
176
<xsl:template name="type_variables">
177
<xsl:param name="type_variables"/>
178
<xsl:param name="type_desc"/>
179
<xsl:param name="local_types"/>
180
<xsl:param name="fname"/>
181
<xsl:param name="arity"/>
183
<xsl:variable name="names" select="../name[string-length(@arity) > 0]"/>
184
<xsl:for-each select="$type_variables">
185
<xsl:variable name="name_i">
79
<xsl:when test="string(@with_guards) = 'no'">
80
<xsl:apply-templates select="$spec/contract/clause/head"/>
187
<xsl:when test="string-length(@name_i) > 0">
188
<xsl:value-of select="@name_i"/>
83
<xsl:call-template name="contract">
84
<xsl:with-param name="contract" select="$spec/contract"/>
191
<xsl:value-of select="count($names)"/>
88
<xsl:text> .br</xsl:text>
93
<xsl:template name="contract">
94
<xsl:param name="contract"/>
95
<xsl:call-template name="clause">
96
<xsl:with-param name="clause" select="$contract/clause"/>
100
<xsl:template name="clause">
101
<xsl:param name="clause"/>
102
<xsl:variable name="type_desc" select="../type_desc"/>
103
<xsl:for-each select="$clause">
104
<xsl:apply-templates select="head"/>
105
<xsl:if test="count(guard) > 0">
106
<xsl:call-template name="guard">
107
<xsl:with-param name="guard" select="guard"/>
108
<xsl:with-param name="type_desc" select="$type_desc"/>
195
<xsl:variable name="spec0">
196
<xsl:for-each select="$names[position() = $name_i]">
197
<xsl:call-template name="find_spec"/>
200
<xsl:variable name="spec" select="exsl:node-set($spec0)/spec"/>
201
<xsl:variable name="clause" select="$spec/contract/clause"/>
202
<xsl:variable name="variable" select="@variable"/>
203
<xsl:variable name="subtype"
204
select="$clause/guard/subtype[typename = $variable]"/>
206
<xsl:if test="count($subtype) = 0">
207
<xsl:call-template name="err">
208
<xsl:with-param name="f" select="ancestor::erlref/module"/>
209
<xsl:with-param name="n" select="$fname"/>
210
<xsl:with-param name="a" select="$arity"/>
211
<xsl:with-param name="s">unknown type variable <xsl:value-of select="$variable"/>
109
213
</xsl:call-template>
216
<xsl:call-template name="subtype">
217
<xsl:with-param name="subtype" select="$subtype"/>
218
<xsl:with-param name="type_desc" select="$type_desc"/>
114
<xsl:template match="head">
115
<xsl:text> .nf </xsl:text>
116
<xsl:text> .B </xsl:text>
117
<xsl:apply-templates/>
118
<xsl:text> .br</xsl:text>
119
<xsl:text> .fi</xsl:text>
122
<xsl:template name="guard">
123
<xsl:param name="guard"/>
124
<xsl:param name="type_desc"/>
125
<xsl:text> .RS</xsl:text>
126
<xsl:text> .TP</xsl:text>
127
<xsl:text> Types</xsl:text>
128
<xsl:call-template name="subtype">
129
<xsl:with-param name="subtype" select="$guard/subtype"/>
130
<xsl:with-param name="type_desc" select="$type_desc"/>
132
<xsl:text> .RE</xsl:text>
135
223
<xsl:template name="subtype">
136
224
<xsl:param name="subtype"/>
137
225
<xsl:param name="type_desc"/>
138
227
<xsl:for-each select="$subtype">
139
228
<xsl:variable name="tname" select="typename"/>
140
<xsl:variable name="tdesc" select="$type_desc[@name = $tname]"/>
141
<xsl:text> </xsl:text>
142
<xsl:apply-templates select="string"/>
143
<xsl:text> .br</xsl:text>
144
<xsl:apply-templates select="$type_desc[@name = $tname]"/>
229
<xsl:variable name="string" select="string"/>
230
<xsl:if test="string-length($string) > 0">
231
<xsl:text> </xsl:text>
232
<xsl:apply-templates select="$string"/>
233
<xsl:text> .br</xsl:text>
234
<xsl:apply-templates select="$type_desc[@variable = $tname]"/>
239
<xsl:template name="local_type">
240
<xsl:param name="type_desc"/>
241
<xsl:param name="local_types"/>
243
<xsl:for-each select ="$local_types">
244
<xsl:text> </xsl:text>
245
<xsl:call-template name="type_name">
246
<xsl:with-param name="mode" select="'local_type'"/>
248
<xsl:text> .br</xsl:text>
249
<xsl:variable name="tname" select="@name"/>
250
<xsl:variable name="tnvars" select="@n_vars"/>
251
<xsl:apply-templates select=
252
"$type_desc[@name = $tname
253
and (@n_vars = $tnvars
254
or string-length(@n_vars) = 0 and
255
string-length($tnvars) = 0)]"/>
164
275
<xsl:apply-templates/>
167
<xsl:template match="typehead">
168
<xsl:text> .nf </xsl:text>
169
<xsl:text> .B </xsl:text>
170
<xsl:apply-templates/>
171
<xsl:text> .br</xsl:text>
172
<xsl:text> .fi</xsl:text>
175
<xsl:template match="local_defs">
176
<xsl:text> .RS</xsl:text>
177
<xsl:apply-templates/>
178
<xsl:text> .RE</xsl:text>
181
<xsl:template match="local_def">
182
<xsl:text> </xsl:text>
183
<xsl:apply-templates/>
184
<xsl:text> .br</xsl:text>
187
278
<xsl:template name="type_name">
279
<xsl:param name="mode"/> <!-- '' if <datatype> -->
188
280
<xsl:variable name="curModule" select="ancestor::erlref/module"/>
189
281
<xsl:variable name="mod" select="@mod"/>
190
282
<xsl:variable name="name" select="@name"/>
191
<xsl:variable name="n_vars">
193
<xsl:when test="string-length(@n_vars) > 0">
194
<xsl:value-of select="@n_vars"/>
197
<xsl:value-of select="0"/>
283
<xsl:variable name="n_vars" select="@n_vars"/>
203
286
<xsl:when test="string-length($name) > 0">
204
287
<xsl:variable name="type" select=
205
288
"$i/module[@name=$curModule]/type
206
[name=$name and n_vars=$n_vars
290
and (string-length($n_vars) = 0 or n_vars = $n_vars)
207
291
and (string-length($mod) = 0 or module = $mod)]"/>
209
293
<xsl:if test="count($type) != 1">
294
<xsl:variable name="why">
296
<xsl:when test="count($type) > 1">ambiguous type</xsl:when>
297
<xsl:when test="count($type) = 0">unknown type</xsl:when>
210
300
<xsl:call-template name="err">
301
<xsl:with-param name="f" select="$curModule"/>
211
302
<xsl:with-param name="m" select="$mod"/>
212
303
<xsl:with-param name="n" select="$name"/>
213
304
<xsl:with-param name="a" select="$n_vars"/>
214
<xsl:with-param name="s">unknown type</xsl:with-param>
305
<xsl:with-param name="s" select="$why"/>
215
306
</xsl:call-template>
217
<xsl:apply-templates select="$type/typedecl"/>
309
<xsl:when test="$mode = ''">
310
<xsl:apply-templates select="$type/typedecl"/>
312
<xsl:when test="$mode = 'local_type'">
313
<xsl:apply-templates select="$type/typedecl" mode="local_type"/>
317
<xsl:otherwise> <!-- <datatype> with <name> -->
220
318
<xsl:text> .nf </xsl:text>
221
319
<xsl:text> .B </xsl:text>
222
320
<xsl:apply-templates/>
327
<xsl:template match="typehead">
328
<xsl:text> .nf </xsl:text>
329
<xsl:apply-templates/>
330
<xsl:text> .br</xsl:text>
331
<xsl:text> .fi</xsl:text>
334
<xsl:template match="typehead" mode="local_type">
335
<xsl:text>.nf </xsl:text>
336
<xsl:apply-templates/>
337
<xsl:text> .fi</xsl:text>
340
<!-- Not used right now -->
341
<xsl:template match="local_defs">
342
<xsl:text> .RS</xsl:text>
343
<xsl:apply-templates/>
344
<xsl:text> .RE</xsl:text>
347
<xsl:template match="local_def">
348
<xsl:text> </xsl:text>
349
<xsl:apply-templates/>
350
<xsl:text> .br</xsl:text>
353
<!-- The name of data types -->
354
<xsl:template match="marker">
355
<xsl:if test="string-length(.) != 0">
356
<xsl:text>\fB</xsl:text><xsl:apply-templates/><xsl:text>\fR\&</xsl:text>
229
360
<!-- Used both in <datatype> and in <func>! -->
230
361
<xsl:template match="anno">
231
362
<xsl:variable name="curModule" select="ancestor::erlref/module"/>
232
363
<xsl:variable name="anno" select="normalize-space(text())"/>
233
364
<xsl:variable name="namespec"
234
select="ancestor::desc/preceding-sibling::name"/>
365
select="ancestor::type_desc/preceding-sibling::name
366
| ancestor::desc/preceding-sibling::name"/>
235
367
<xsl:if test="count($namespec) = 0 and string-length($specs_file) > 0">
236
368
<xsl:call-template name="err">
237
<xsl:with-param name="s">cannot find 'name' (<xsl:value-of select="$anno"/>)
242
<xsl:variable name="mod" select="$namespec/@mod"/>
243
<xsl:variable name="name" select="$namespec/@name"/>
244
<xsl:variable name="arity" select="$namespec/@arity"/>
245
<xsl:variable name="clause" select="$namespec/@clause"/>
246
<xsl:variable name="tmp_n_vars" select="$namespec/@n_vars"/>
247
<xsl:variable name="n_vars">
249
<xsl:when test="string-length($tmp_n_vars) > 0">
250
<xsl:value-of select="$tmp_n_vars"/>
253
<xsl:value-of select="0"/>
369
<xsl:with-param name="f" select="$curModule"/>
370
<xsl:with-param name="s">cannot find tag 'name' (anno <xsl:value-of select="$anno"/>)
375
<!-- Search "local types" as well -->
376
<xsl:variable name="local_types"
377
select="ancestor::desc/preceding-sibling::type
378
[string-length(@name) > 0]
379
| ancestor::type_desc/preceding-sibling::type
380
[string-length(@name) > 0]"/>
381
<xsl:variable name="has_anno_in_local_type">
382
<xsl:for-each select="$local_types">
383
<xsl:call-template name="anno_name">
384
<xsl:with-param name="curModule" select="$curModule"/>
385
<xsl:with-param name="anno" select="$anno"/>
390
<xsl:variable name="has_anno">
391
<xsl:for-each select="$namespec">
392
<xsl:call-template name="anno_name">
393
<xsl:with-param name="curModule" select="$curModule"/>
394
<xsl:with-param name="anno" select="$anno"/>
399
<xsl:if test="$has_anno = '' and $has_anno_in_local_type = ''">
400
<xsl:call-template name="err">
401
<xsl:with-param name="f" select="$curModule"/>
402
<xsl:with-param name="m" select="$namespec/@mod"/>
403
<xsl:with-param name="n" select="$namespec/@name"/>
404
<xsl:with-param name="a" select="'-'"/>
405
<xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/>
409
<xsl:value-of select="$anno"/>
412
<xsl:template name="anno_name">
413
<xsl:param name="curModule"/>
414
<xsl:param name="anno"/>
415
<xsl:variable name="mod" select="@mod"/>
416
<xsl:variable name="name" select="@name"/>
417
<xsl:variable name="arity" select="@arity"/>
418
<xsl:variable name="n_vars" select="@n_vars"/>
419
<xsl:variable name="clause_i" select="@clause_i"/>
257
421
<xsl:variable name="spec0" select=
258
422
"$i/module[@name=$curModule]/spec
259
423
[name=$name and arity=$arity
260
424
and (string-length($mod) = 0 or module = $mod)]"/>
261
425
<xsl:variable name="spec_annos" select=
262
"$spec0[string-length($clause) = 0
263
or position() = $clause]/anno[.=$anno]"/>
426
"$spec0[string-length($clause_i) = 0
427
or position() = $clause_i]/anno[.=$anno]"/>
264
428
<xsl:variable name="type_annos" select=
265
429
"$i/module[@name=$curModule]/type
266
[name=$name and n_vars=$n_vars
431
and (string-length($n_vars) = 0 or n_vars=$n_vars)
267
432
and (string-length($mod) = 0 or module = $mod)]/anno[.=$anno]"/>
269
<xsl:if test="count($spec_annos) = 0
270
and count($type_annos) = 0
271
and string-length($specs_file) > 0">
272
<xsl:variable name="n">
274
<xsl:when test="string-length($arity) = 0">
275
<xsl:value-of select="$n_vars"/>
278
<xsl:value-of select="$arity"/>
282
<xsl:call-template name="err">
283
<xsl:with-param name="m" select="$mod"/>
284
<xsl:with-param name="n" select="$name"/>
285
<xsl:with-param name="a" select="$n"/>
286
<xsl:with-param name="s">unknown annotation <xsl:value-of select="$anno"/>
433
<xsl:if test="count($spec_annos) != 0
434
or count($type_annos) != 0
435
or string-length($specs_file) = 0">
436
<xsl:value-of select="true()"/>
290
<xsl:value-of select="$anno"/>
293
440
<!-- Used for indentation of formatted types and specs -->