Implement a more sorphisticated execution strategy for static blocks. Tested with...
[IRC.git] / Robust / src / IR / MethodDescriptor.java
1 package IR;
2 import IR.Tree.Modifiers;
3 import IR.Tree.ExpressionNode;
4 import java.util.Vector;
5
6 /**
7  * Descriptor
8  *
9  * represents a symbol in the language (var name, function name, etc).
10  */
11
12 public class MethodDescriptor extends Descriptor {
13
14   protected Modifiers modifier;
15   protected TypeDescriptor returntype;
16   protected String identifier;
17   protected Vector params;
18   protected SymbolTable paramtable;
19   protected ClassDescriptor cd;
20   protected VarDescriptor thisvd;
21   protected boolean isglobal;
22   protected boolean isstaticblock;  // flag to indicate if this is a static block
23   protected boolean isinvokedbystatic;  // flag to indicate if this method is invoked by some static block
24
25   public MethodDescriptor(Modifiers m, TypeDescriptor rt, String identifier) {
26     super(identifier);
27     this.modifier=m;
28     this.returntype=rt;
29     this.identifier=identifier;
30     this.safename = "___" + name + "___";
31     this.uniqueid=count++;
32     params=new Vector();
33     paramtable=new SymbolTable();
34     thisvd=null;
35     isstaticblock = false;
36   }
37
38   public Modifiers getModifiers() {
39     return modifier;
40   }
41
42   public boolean matches(MethodDescriptor md) {
43     /* Check the name */
44     if (!identifier.equals(md.identifier))
45       return false;
46     if (numParameters()!=md.numParameters())
47       return false;
48     for(int i=0; i<numParameters(); i++) {
49       Descriptor d1=getParameter(i);
50       Descriptor d2=md.getParameter(i);
51       TypeDescriptor td1=(d1 instanceof TagVarDescriptor) ? ((TagVarDescriptor)d1).getType() : ((VarDescriptor)d1).getType();
52       TypeDescriptor td2=(d2 instanceof TagVarDescriptor) ? ((TagVarDescriptor)d2).getType() : ((VarDescriptor)d2).getType();
53       if (!td1.equals(td2))
54         return false;
55     }
56     return true;
57   }
58
59   public MethodDescriptor(Modifiers m, String identifier) {
60     this(m, identifier, false);
61   }
62
63   public MethodDescriptor(Modifiers m, String identifier, boolean isglobal) {
64     super(identifier);
65     this.isglobal=isglobal;
66     this.modifier=m;
67     this.returntype=null;
68     this.identifier=identifier;
69     this.safename = "___" + name + "___";
70     this.uniqueid=count++;
71     params=new Vector();
72     paramtable=new SymbolTable();
73     thisvd=null;
74     isstaticblock = false;
75   }
76
77
78   public boolean isGlobal() {
79     return isglobal;
80   }
81   
82   public boolean isStaticBlock() {
83     return isstaticblock;
84   }
85   
86   public void setAsStaticBlock() {
87     isstaticblock = true;
88   }
89   
90   public boolean isInvokedByStatic() {
91     return this.isinvokedbystatic;
92   }
93   
94   public void setIsInvokedByStatic(boolean isinvokedbystatic) {
95     this.isinvokedbystatic = isinvokedbystatic;
96   }
97
98   public void setThis(VarDescriptor vd) {
99     thisvd=vd;
100     paramtable.add(vd);
101   }
102
103   public VarDescriptor getThis() {
104     return thisvd;
105   }
106
107   public String getClassMethodName() {
108     return cd+"."+name;
109   }
110
111   public String getSafeMethodDescriptor() {
112     String st="";
113     for(int i=0; i<numParameters(); i++) {
114       st+=getParamType(i).getSafeDescriptor();
115       if ((i+1)<numParameters())
116         st+="_";
117     }
118     return st;
119   }
120
121   public boolean isStatic() {
122     return modifier.isStatic();
123   }
124
125   public boolean isConstructor() {
126     return (returntype==null);
127   }
128
129   public TypeDescriptor getReturnType() {
130     return returntype;
131   }
132
133   public void setClassDesc(ClassDescriptor cd) {
134     this.cd=cd;
135   }
136
137   public ClassDescriptor getClassDesc() {
138     return cd;
139   }
140
141   public SymbolTable getParameterTable() {
142     return paramtable;
143   }
144
145   public void addParameter(TypeDescriptor type, String paramname) {
146     if (paramname.equals("this"))
147       throw new Error("Can't have parameter named this");
148     VarDescriptor vd=new VarDescriptor(type, paramname);
149
150     params.add(vd);
151     if (paramtable.getFromSameScope(paramname)!=null) {
152       throw new Error("Parameter "+paramname+" already defined");
153     }
154     paramtable.add(vd);
155   }
156
157   public void addTagParameter(TypeDescriptor type, String paramname) {
158     if (paramname.equals("this"))
159       throw new Error("Can't have parameter named this");
160     TagVarDescriptor vd=new TagVarDescriptor(null, paramname);
161
162     params.add(vd);
163     if (paramtable.getFromSameScope(paramname)!=null) {
164       throw new Error("Parameter "+paramname+" already defined");
165     }
166     paramtable.add(vd);
167   }
168
169   public int numParameters() {
170     return params.size();
171   }
172
173   public Descriptor getParameter(int i) {
174     return (Descriptor) params.get(i);
175   }
176
177   public String getParamName(int i) {
178     return ((Descriptor)params.get(i)).getSymbol();
179   }
180
181   public TypeDescriptor getParamType(int i) {
182     Descriptor d=(Descriptor)params.get(i);
183     if (d instanceof VarDescriptor)
184       return ((VarDescriptor)params.get(i)).getType();
185     else if (d instanceof TagVarDescriptor)
186       return new TypeDescriptor(TypeDescriptor.TAG);
187     else throw new Error();
188   }
189
190   public String toString() {
191     String st="";
192     String type="";
193     if (cd!=null)
194       type=cd+".";
195     if (returntype!=null)
196       st=modifier.toString()+returntype.toString()+" "+type+identifier+"(";
197     else
198       st=modifier.toString()+" "+type+identifier+"(";
199     for(int i=0; i<params.size(); i++) {
200       st+=getParamType(i)+" "+getParamName(i);
201       if ((i+1)!=params.size())
202         st+=", ";
203     }
204     st+=")";
205     return st;
206   }
207 }