summaryrefslogtreecommitdiff
path: root/sources/scalac/symtab/classfile/Signatures.java
blob: 9676882aed0a8359a538e63955f65bcba5f9c4d1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
**                                                                      **
** $Id$
\*                                                                      */

package scalac.symtab.classfile;

import scalac.*;
import scalac.symtab.*;
import scalac.util.*;
import java.util.*;
import Type.*;

public class Signatures {

    /** signature constants
     */
    Name BYTE_SIG = Name.fromString("B");
    Name SHORT_SIG = Name.fromString("S");
    Name CHAR_SIG = Name.fromString("C");
    Name INT_SIG = Name.fromString("I");
    Name LONG_SIG = Name.fromString("J");
    Name FLOAT_SIG = Name.fromString("F");
    Name DOUBLE_SIG = Name.fromString("D");
    Name BOOLEAN_SIG = Name.fromString("Z");
    Name VOID_SIG = Name.fromString("V");
    Name CLASS_SIG = Name.fromString("L");
    Name ARRAY_SIG = Name.fromString("[");
    Name ARGBEGIN_SIG = Name.fromString("(");
    Name ARGEND_SIG = Name.fromString(")");

    Global global;
    JavaTypeFactory make;


    public Signatures(Global global, JavaTypeFactory make) {
        this.make = make;
        this.global = global;
    }

    /** the type represented by signature[offset..].
     */
    protected byte[] signature;
    protected int sigp;
    protected int limit;

    public Type sigToType(byte[] sig, int offset, int len) {
        signature = sig;
        sigp = offset;
        limit = offset + len;
        return sigToType();
    }

    protected Type sigToType() {
        switch (signature[sigp]) {
            case 'B':
                sigp++;
                return make.byteType();
            case 'C':
                sigp++;
                return make.charType();
            case 'D':
                sigp++;
                return make.doubleType();
            case 'F':
                sigp++;
                return make.floatType();
            case 'I':
                sigp++;
                return make.intType();
            case 'J':
                sigp++;
                return make.longType();
            case 'L':
                sigp++;
                int start = sigp;
                while (signature[sigp] != ';')
                    sigp++;
                return make.classType(Name.fromAscii(signature, start, (sigp++) - start));
            case 'S':
                sigp++;
                return make.shortType();
            case 'V':
                sigp++;
                return make.voidType();
            case 'Z':
                sigp++;
                return make.booleanType();
            case '[':
                sigp++;
                while (('0' <= signature[sigp]) && (signature[sigp] <= '9'))
                    sigp++;
                return make.arrayType(sigToType());
            case '(':
                return make.methodType(sigToTypes(')'), sigToType(), Type.EMPTY_ARRAY);
            default:
                global.error("bad signature: " +
                    SourceRepresentation.ascii2string(signature, sigp, 1));
                return Type.ErrorType;
        }
    }

    protected Type[] sigToTypes(char terminator) {
        sigp++;
        return sigToTypes(terminator, 0);
    }

    protected Type[] sigToTypes(char terminator, int i) {
        if (signature[sigp] == terminator) {
            sigp++;
            return new Type[i];
        } else {
            Type    t = sigToType();
            Type[]  vec = sigToTypes(terminator, i+1);
            vec[i] = t;
            return vec;
        }
    }
}