/
TypeResolver.java
208 lines (172 loc) · 7.29 KB
/
TypeResolver.java
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
package play;
import play.PlayScriptParser.*;
/**
* 第二遍扫描。把变量、类继承、函数声明的类型都解析出来。
* 也就是所有用到typeTpe的地方。
*
* 实际运行时,把变量添加到符号表,是分两步来做的。
* 第一步,是把类成员变量和函数的参数加进去
*
* 第二步,是在变量引用消解的时候再添加。这个时候是边Enter符号表,边消解,会避免变量引用到错误的定义。
*
*/
public class TypeResolver extends PlayScriptBaseListener {
private AnnotatedTree at = null;
//是否把本地变量加入符号表
private boolean enterLocalVariable = false;
public TypeResolver(AnnotatedTree at) {
this.at = at;
}
public TypeResolver(AnnotatedTree at, boolean enterLocalVariable) {
this.at = at;
this.enterLocalVariable = enterLocalVariable;
}
//设置所声明的变量的类型
@Override
public void exitVariableDeclarators(VariableDeclaratorsContext ctx) {
Scope scope = at.enclosingScopeOfNode(ctx);
//Aaaaaaaaaaayou同学请看这里。
if (scope instanceof Class || enterLocalVariable ){
// 设置变量类型
Type type = (Type) at.typeOfNode.get(ctx.typeType());
for (VariableDeclaratorContext child : ctx.variableDeclarator()) {
Variable variable = (Variable) at.symbolOfNode.get(child.variableDeclaratorId());
variable.type = type;
}
}
}
//把类成员变量的声明加入符号表
@Override
public void enterVariableDeclaratorId(VariableDeclaratorIdContext ctx) {
String idName = ctx.IDENTIFIER().getText();
Scope scope = at.enclosingScopeOfNode(ctx);
//第一步只把类的成员变量入符号表。在变量消解时,再把本地变量加入符号表,一边Enter,一边消解。
//Aaaaaaaaaaayou同学请看这里。
//2021-3-4 添加了函数参数,上次修改不小心丢掉了这个场景:-(
if (scope instanceof Class || enterLocalVariable || ctx.parent instanceof FormalParameterContext) {
Variable variable = new Variable(idName, scope, ctx);
//变量查重
if (Scope.getVariable(scope, idName) != null) {
at.log("Variable or parameter already Declared: " + idName, ctx);
}
scope.addSymbol(variable);
at.symbolOfNode.put(ctx, variable);
}
}
//设置函数的返回值类型
@Override
public void exitFunctionDeclaration(FunctionDeclarationContext ctx) {
Function function = (Function) at.node2Scope.get(ctx);
if (ctx.typeTypeOrVoid() != null) {
function.returnType = at.typeOfNode.get(ctx.typeTypeOrVoid());
}
else{
//TODO 如果是类的构建函数,返回值应该是一个类吧?
}
//函数查重,检查名称和参数(这个时候参数已经齐了)
Scope scope = at.enclosingScopeOfNode(ctx);
Function found = Scope.getFunction(scope,function.name,function.getParamTypes());
if (found != null && found != function){
at.log("Function or method already Declared: " + ctx.getText(), ctx);
}
}
//设置函数的参数的类型,这些参数已经在enterVariableDeclaratorId中作为变量声明了,现在设置它们的类型
@Override
public void exitFormalParameter(FormalParameterContext ctx) {
// 设置参数类型
Type type = at.typeOfNode.get(ctx.typeType());
Variable variable = (Variable) at.symbolOfNode.get(ctx.variableDeclaratorId());
variable.type = (Type) type;
// 添加到函数的参数列表里
Scope scope = at.enclosingScopeOfNode(ctx);
if (scope instanceof Function) { //TODO 从目前的语法来看,只有function才会使用FormalParameter
((Function) scope).parameters.add(variable);
}
}
//设置类的父类
@Override
public void enterClassDeclaration(ClassDeclarationContext ctx) {
Class theClass = (Class) at.node2Scope.get(ctx);
//设置父类
if (ctx.EXTENDS() != null){
String parentClassName = ctx.typeType().getText();
Type type = at.lookupType(parentClassName);
if (type != null && type instanceof Class){
theClass.setParentClass ( (Class)type);
}
else{
at.log("unknown class: " + parentClassName, ctx);
}
}
}
@Override
public void exitTypeTypeOrVoid(TypeTypeOrVoidContext ctx) {
if (ctx.VOID() != null) {
at.typeOfNode.put(ctx, VoidType.instance());
} else if (ctx.typeType() != null) {
at.typeOfNode.put(ctx, (Type) at.typeOfNode.get(ctx.typeType()));
}
}
@Override
public void exitTypeType(TypeTypeContext ctx) {
// 冒泡,将下级的属性标注在本级
if (ctx.classOrInterfaceType() != null) {
Type type = (Type) at.typeOfNode.get(ctx.classOrInterfaceType());
at.typeOfNode.put(ctx, type);
} else if (ctx.functionType() != null) {
Type type = (Type) at.typeOfNode.get(ctx.functionType());
at.typeOfNode.put(ctx, type);
} else if (ctx.primitiveType() != null) {
Type type = (Type) at.typeOfNode.get(ctx.primitiveType());
at.typeOfNode.put(ctx, type);
}
}
@Override
public void enterClassOrInterfaceType(ClassOrInterfaceTypeContext ctx) {
if (ctx.IDENTIFIER() != null) {
Scope scope = at.enclosingScopeOfNode(ctx);
String idName = ctx.getText();
Class theClass = at.lookupClass(scope, idName);
at.typeOfNode.put(ctx, theClass);
}
}
@Override
public void exitFunctionType(FunctionTypeContext ctx) {
DefaultFunctionType functionType = new DefaultFunctionType();
at.types.add(functionType);
at.typeOfNode.put(ctx, functionType);
functionType.returnType = (Type) at.typeOfNode.get(ctx.typeTypeOrVoid());
// 参数的类型
if (ctx.typeList() != null) {
TypeListContext tcl = (TypeListContext) ctx.typeList();
for (TypeTypeContext ttc : tcl.typeType()) {
Type type = (Type) at.typeOfNode.get(ttc);
functionType.paramTypes.add(type);
}
}
}
@Override
public void exitPrimitiveType(PrimitiveTypeContext ctx) {
Type type = null;
if (ctx.BOOLEAN() != null) {
type = PrimitiveType.Boolean;
} else if (ctx.INT() != null) {
type = PrimitiveType.Integer;
} else if (ctx.LONG() != null) {
type = PrimitiveType.Long;
} else if (ctx.FLOAT() != null) {
type = PrimitiveType.Float;
} else if (ctx.DOUBLE() != null) {
type = PrimitiveType.Double;
} else if (ctx.BYTE() != null) {
type = PrimitiveType.Byte;
} else if (ctx.SHORT() != null) {
type = PrimitiveType.Short;
} else if (ctx.CHAR() != null) {
type = PrimitiveType.Char;
}else if (ctx.STRING() != null) {
type = PrimitiveType.String;
}
at.typeOfNode.put(ctx, type);
}
}