use of kalang.ast.ParameterNode in project kalang by kasonyang.
the class Ast2Class method visitMethodNode.
@Override
public Object visitMethodNode(MethodNode node) {
int access = node.getModifier();
md = classWriter.visitMethod(access, internalName(node.getName()), getMethodDescriptor(node), methodSignature(node), internalName(node.getExceptionTypes()));
if (node.getType() instanceof ObjectType) {
annotationNullable(md, (ObjectType) node.getType());
}
annotation(md, node.getAnnotations());
this.methodStartLabel = new Label();
this.methodEndLabel = new Label();
if (AstUtil.isStatic(node.getModifier())) {
varIdCounter = 0;
} else {
varIdCounter = 1;
}
BlockStmt body = node.getBody();
ParameterNode[] parameters = node.getParameters();
for (int i = 0; i < parameters.length; i++) {
ParameterNode p = parameters[i];
visit(p);
if (p.getType() instanceof ObjectType) {
md.visitParameterAnnotation(i, getClassDescriptor(getNullableAnnotation((ObjectType) p.getType())), true).visitEnd();
}
}
md.visitLabel(methodStartLabel);
if (body != null) {
visit(body);
if (node.getType().equals(VOID_TYPE)) {
md.visitInsn(RETURN);
}
md.visitLabel(methodEndLabel);
try {
md.visitMaxs(0, 0);
} catch (Exception ex) {
ex.printStackTrace(System.err);
// throw new RuntimeException("exception when visit method:" + node.name, ex);
}
}
md.visitEnd();
return null;
}
use of kalang.ast.ParameterNode in project kalang by kasonyang.
the class AstBuilder method getNodeById.
@Nullable
private AstNode getNodeById(@Nonnull String name, @Nullable Token token) {
// find local var
LocalVarNode var = this.getNamedLocalVar(name);
if (var != null) {
VarExpr ve = new VarExpr(var, getVarObjectType(var));
if (token != null)
mapAst(ve, token);
return ve;
}
// find parameters
ParameterNode paramNode = this.getNamedParameter(name);
if (paramNode != null) {
ParameterExpr ve = new ParameterExpr(paramNode, this.getVarObjectType(paramNode));
if (token != null)
mapAst(ve, token);
return ve;
}
// find field
ExprNode fieldExpr = this.getObjectFieldExpr(new ThisExpr(this.getThisType()), name, ParserRuleContext.EMPTY);
if (fieldExpr == null)
fieldExpr = this.getStaticFieldExpr(new ClassReference(thisClazz), name, ParserRuleContext.EMPTY);
if (fieldExpr != null)
return fieldExpr;
ExprNode outerClassInstanceExpr = this.getOuterClassInstanceExpr(new ThisExpr(this.getThisType()));
while (outerClassInstanceExpr != null) {
ExprNode fe = this.getObjectFieldExpr(outerClassInstanceExpr, name, ParserRuleContext.EMPTY);
if (fe == null)
fe = this.getStaticFieldExpr(new ClassReference(thisClazz), name, ParserRuleContext.EMPTY);
if (fe != null)
return fe;
outerClassInstanceExpr = this.getOuterClassInstanceExpr(outerClassInstanceExpr);
}
String resolvedTypeName = this.typeNameResolver.resolve(name, topClass, thisClazz);
if (resolvedTypeName != null) {
ClassReference clsRef = new ClassReference(requireAst(resolvedTypeName, token));
if (token != null)
mapAst(clsRef, token);
return clsRef;
}
return null;
}
use of kalang.ast.ParameterNode in project kalang by kasonyang.
the class ClassNodeMetaBuilder method visitClassDef.
@Override
public Object visitClassDef(KalangParser.ClassDefContext ctx) {
thisClazz.annotations.addAll(astBuilder.getAnnotations(ctx.annotation()));
thisClazz.modifier = astBuilder.parseModifier(ctx.varModifier());
List<Token> gnrTypes = ctx.genericTypes;
if (gnrTypes != null && !gnrTypes.isEmpty()) {
for (Token g : gnrTypes) {
// TODO suport generic type bounds in syntax
GenericType gt = new GenericType(g.getText(), Types.getRootType(), null, NullableKind.NONNULL);
thisClazz.declareGenericType(gt);
}
}
ObjectType superType = null;
if (ctx.parentClass != null) {
ObjectType parentClass = astBuilder.parseClassType(ctx.parentClass);
if (parentClass != null) {
superType = parentClass;
}
} else {
superType = Types.getRootType();
}
if (Modifier.isInterface(thisClazz.modifier)) {
// TODO update syntax to support:interface extends T1,T2...
thisClazz.addInterface(superType);
} else {
thisClazz.setSuperType(superType);
}
if (ctx.interfaces != null && ctx.interfaces.size() > 0) {
for (KalangParser.ClassTypeContext itf : ctx.interfaces) {
ObjectType itfClz = astBuilder.parseClassType(itf);
if (itfClz != null) {
thisClazz.addInterface(itfClz);
}
}
}
if (this.isDeclaringNonStaticInnerClass()) {
ClassNode parentClass = thisClazz.enclosingClass;
if (parentClass == null) {
throw Exceptions.unexceptedValue(parentClass);
}
thisClazz.createField(Types.getClassType(parentClass), "this$0", Modifier.PRIVATE | ModifierConstant.SYNTHETIC);
}
visit(ctx.classBody());
if (!ModifierUtil.isInterface(thisClazz.modifier) && !AstUtil.containsConstructor(thisClazz) && !AstUtil.createEmptyConstructor(thisClazz)) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, "failed to create constructor with no parameters", ctx);
}
MethodNode[] methods = thisClazz.getDeclaredMethodNodes();
for (int i = 0; i < methods.length; i++) {
MethodNode node = methods[i];
BlockStmt body = node.getBody();
if (body != null) {
if (AstUtil.isConstructor(node)) {
// constructor
if (this.isDeclaringNonStaticInnerClass()) {
ClassNode enclosingClass = thisClazz.enclosingClass;
if (enclosingClass == null) {
throw Exceptions.unexceptedValue(enclosingClass);
}
ParameterNode outerInstanceParam = node.createParameter(0, Types.getClassType(enclosingClass), "this$0");
ExprNode parentFieldExpr = astBuilder.getObjectFieldExpr(new ThisExpr(Types.getClassType(thisClazz)), "this$0", ParserRuleContext.EMPTY);
if (parentFieldExpr == null) {
throw Exceptions.unexceptedValue(parentFieldExpr);
}
body.statements.add(1, new ExprStmt(new AssignExpr((AssignableExpr) parentFieldExpr, new ParameterExpr(outerInstanceParam))));
}
}
}
}
for (FieldNode fieldNode : thisClazz.getFields()) {
int mdf = fieldNode.modifier;
if (!AstUtil.hasGetter(thisClazz, fieldNode)) {
AstUtil.createGetter(thisClazz, fieldNode, mdf);
}
if (!AstUtil.hasSetter(thisClazz, fieldNode)) {
AstUtil.createSetter(thisClazz, fieldNode, mdf);
}
fieldNode.modifier = ModifierUtil.setPrivate(mdf);
}
return null;
}
use of kalang.ast.ParameterNode in project kalang by kasonyang.
the class AstUtil method createSetter.
public static void createSetter(ClassNode clazz, FieldDescriptor field, int accessModifier) {
String fn = field.getName();
String setterName = "set" + NameUtil.firstCharToUpperCase(fn);
boolean isStatic = isStatic(field.getModifier());
if (isStatic) {
accessModifier |= Modifier.STATIC;
}
MethodNode setter = clazz.createMethodNode(Types.VOID_TYPE, setterName, accessModifier);
// setter.offset = field.offset;
ParameterNode param = setter.createParameter(field.getType(), field.getName());
BlockStmt body = setter.getBody();
FieldExpr fe;
ExprNode paramVal = new ParameterExpr(param);
ClassReference cr = new ClassReference(clazz);
if (isStatic) {
fe = new StaticFieldExpr(cr, field);
} else {
fe = new ObjectFieldExpr(new ThisExpr(Types.getClassType(clazz)), field);
}
body.statements.add(new ExprStmt(new AssignExpr(fe, paramVal)));
}
use of kalang.ast.ParameterNode in project kalang by kasonyang.
the class AstUtil method createEmptyConstructor.
public static boolean createEmptyConstructor(ClassNode clazzNode) {
ObjectType supType = clazzNode.getSuperType();
if (supType == null) {
throw new RuntimeException("super type is null:" + clazzNode.name);
}
ConstructorDescriptor[] constructors = supType.getConstructorDescriptors(clazzNode);
ConstructorDescriptor m = MethodUtil.getConstructorDescriptor(constructors, null);
if (m != null) {
MethodNode mm = clazzNode.createMethodNode(Types.VOID_TYPE, m.getName(), m.getModifier());
for (Type e : m.getExceptionTypes()) mm.addExceptionType(e);
ParameterDescriptor[] pds = m.getParameterDescriptors();
for (ParameterDescriptor pd : pds) {
ParameterNode p = mm.createParameter(pd.getType(), pd.getName());
// TODO update mm.createParameter
p.modifier = pd.getModifier();
}
BlockStmt body = mm.getBody();
ParameterNode[] parameters = mm.getParameters();
ExprNode[] params = new ExprNode[parameters.length];
for (int i = 0; i < params.length; i++) {
params[i] = new ParameterExpr(parameters[i]);
}
body.statements.add(new ExprStmt(new ObjectInvokeExpr(new SuperExpr(clazzNode), m, params)));
return true;
} else {
return false;
}
}
Aggregations