use of kalang.core.ObjectType in project kalang by kasonyang.
the class Ast2Class method visitClassNode.
@Override
public Object visitClassNode(ClassNode node) {
ClassNode oldClass = this.clazz;
this.clazz = node;
String oldClassInternalName = this.classInternalName;
this.classInternalName = internalName(clazz);
ClassWriter oldClassWriter = this.classWriter;
this.classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
annotation(classWriter, clazz.getAnnotations());
String parentName = "java.lang.Object";
ObjectType superType = node.getSuperType();
if (superType != null) {
parentName = superType.getName();
}
String[] interfaces = null;
if (node.getInterfaces().length > 0) {
interfaces = internalName(node.getInterfaces());
}
int access = node.modifier;
classWriter.visit(V1_6, access, internalName(node.name), classSignature(node), internalName(parentName), interfaces);
String fileName = node.fileName;
if (fileName != null && !fileName.isEmpty()) {
classWriter.visitSource(fileName, null);
}
visitChildren(node);
// clinit
if (!node.staticInitStmts.isEmpty()) {
md = classWriter.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
visitAll(node.staticInitStmts);
md.visitInsn(RETURN);
md.visitMaxs(1, 1);
}
if (node.enclosingClass != null) {
this.classWriter.visitInnerClass(this.internalName(node), this.internalName(node.enclosingClass), NameUtil.getSimpleClassName(node.name), node.modifier);
}
for (ClassNode ic : node.classes) {
classWriter.visitInnerClass(internalName(ic), internalName(node), NameUtil.getSimpleClassName(ic.name), ic.modifier);
}
classWriter.visitEnd();
if (outputManager != null) {
try {
try (OutputStream os = outputManager.createOutputStream(node.name)) {
os.write(this.classWriter.toByteArray());
}
} catch (IOException ex) {
throw new RuntimeException(ex);
}
} else {
LOG.log(Level.WARNING, "outputManager is null");
}
this.clazz = oldClass;
this.classInternalName = oldClassInternalName;
this.classWriter = oldClassWriter;
return null;
}
use of kalang.core.ObjectType in project kalang by kasonyang.
the class AstBuilder method getVarObjectType.
private Type getVarObjectType(VarObject p) {
Type type = this.overrideTypes.get(p);
if (type == null)
type = p.getType();
// TODO handle other object type
if (type instanceof ClassType) {
Integer ns = nullState.get(p);
NullableKind nullable;
if (ns == null) {
nullable = ((ObjectType) type).getNullable();
} else if (ns == NULLSTATE_MUST_NONNULL) {
nullable = NullableKind.NONNULL;
} else if (ns == NULLSTATE_UNKNOWN) {
nullable = NullableKind.UNKNOWN;
} else if (ns == NULLSTATE_MUST_NULL || ns == NULLSTATE_NULLABLE) {
nullable = NullableKind.NULLABLE;
} else {
throw Exceptions.unexceptedValue(ns);
}
return Types.getClassType((ClassType) type, nullable);
} else {
return type;
}
}
use of kalang.core.ObjectType in project kalang by kasonyang.
the class AstBuilder method getObjectFieldLikeExpr.
protected ExprNode getObjectFieldLikeExpr(ExprNode expr, String fieldName, @Nullable ParserRuleContext rule) {
ExprNode ret;
Type type = expr.getType();
if (!(type instanceof ObjectType)) {
AstBuilder.this.handleSyntaxError("unsupported type", rule == null ? ParserRuleContext.EMPTY : rule);
return null;
}
ObjectType exprType = (ObjectType) type;
if ((exprType instanceof ArrayType) && fieldName.equals("length")) {
ret = new ArrayLengthExpr(expr);
} else {
try {
ret = ObjectFieldExpr.create(expr, fieldName, thisClazz);
} catch (FieldNotFoundException ex) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, "field not found:" + fieldName, rule);
ret = new UnknownFieldExpr(expr, exprType.getClassNode(), fieldName);
}
}
if (rule != null)
mapAst(ret, rule);
return ret;
}
use of kalang.core.ObjectType in project kalang by kasonyang.
the class AstBuilder method parseClassType.
@Nullable
protected ObjectType parseClassType(KalangParser.ClassTypeContext ctx) {
NullableKind nullable = ctx.nullable == null ? NullableKind.NONNULL : NullableKind.NULLABLE;
Token rawTypeToken = ctx.rawClass;
List<String> classNameParts = new LinkedList();
for (Token p : ctx.paths) {
classNameParts.add(p.getText());
}
if (ctx.innerClass != null) {
classNameParts.add(rawTypeToken.getText() + "$" + ctx.innerClass.getText());
} else {
classNameParts.add(rawTypeToken.getText());
}
String rawType = String.join(".", classNameParts);
for (GenericType gt : thisClazz.getGenericTypes()) {
if (rawType.equals(gt.getName()))
return gt;
}
ObjectType clazzType = requireClassType(rawType, rawTypeToken);
if (clazzType == null)
return null;
ClassNode clazzNode = clazzType.getClassNode();
GenericType[] clzDeclaredGenericTypes = clazzNode.getGenericTypes();
List<KalangParser.ParameterizedElementTypeContext> parameterTypes = ctx.parameterTypes;
if (parameterTypes != null && !parameterTypes.isEmpty()) {
Type[] typeArguments = new Type[parameterTypes.size()];
if (parameterTypes != null && parameterTypes.size() > 0) {
if (clzDeclaredGenericTypes.length != parameterTypes.size()) {
diagnosisReporter.report(Diagnosis.Kind.ERROR, "wrong number of type arguments", ctx);
return null;
}
for (int i = 0; i < typeArguments.length; i++) {
typeArguments[i] = parseParameterizedElementType(parameterTypes.get(i));
// TODO should return null?
if (typeArguments[i] == null)
return null;
}
}
return Types.getClassType(clazzType.getClassNode(), typeArguments, nullable);
} else {
return Types.getClassType(clazzType.getClassNode(), nullable);
}
}
use of kalang.core.ObjectType in project kalang by kasonyang.
the class AstBuilder method visitForEachStat.
@Override
public Object visitForEachStat(KalangParser.ForEachStatContext ctx) {
BlockStmt block = newBlock();
ExprNode expr = this.visitExpression(ctx.expression());
Type exprType = expr.getType();
List<TerminalNode> idsCtx = ctx.Identifier();
VarExpr indexVarExpr = null;
TerminalNode varId;
if (idsCtx.size() == 1) {
varId = idsCtx.get(0);
} else {
TerminalNode indexId = idsCtx.get(0);
LocalVarNode indexVar = this.declareLocalVar(indexId.getText(), Types.INT_TYPE, Modifier.FINAL, ctx);
if (indexVar == null)
return null;
block.statements.add(new VarDeclStmt(indexVar));
indexVarExpr = new VarExpr(indexVar);
varId = idsCtx.get(1);
}
LoopStmt loopStmt;
if (exprType instanceof ArrayType) {
LocalVarNode localVarNode = this.declareLocalVar(varId.getText(), ((ArrayType) exprType).getComponentType(), Modifier.FINAL, ctx);
if (localVarNode == null)
return null;
VarExpr localVariable = new VarExpr(localVarNode);
block.statements.add(new VarDeclStmt(localVarNode));
LocalVarNode lenVar = this.declareTempLocalVar(Types.INT_TYPE);
LocalVarNode counterVar = this.declareTempLocalVar(Types.INT_TYPE);
// var len
block.statements.add(new VarDeclStmt(lenVar));
// var i
block.statements.add(new VarDeclStmt(counterVar));
VarExpr counterVarExpr = new VarExpr(counterVar);
VarExpr lenVarExpr = new VarExpr(lenVar);
block.statements.add(new ExprStmt(new AssignExpr(lenVarExpr, new ArrayLengthExpr(expr))));
// l = array.length
block.statements.add(new ExprStmt(new AssignExpr(counterVarExpr, new ConstExpr(0))));
// i=0
ExprNode cnd = new CompareExpr(counterVarExpr, lenVarExpr, CompareExpr.OP_LT);
BlockStmt loopBody = this.newBlock();
loopBody.statements.add(new ExprStmt(new AssignExpr(localVariable, new ElementExpr(expr, counterVarExpr))));
if (indexVarExpr != null) {
loopBody.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, counterVarExpr)));
}
loopBody.statements.add(visitStat(ctx.stat()));
popBlock();
BlockStmt updateBs = newBlock();
// increment counter
updateBs.statements.add(new ExprStmt(new AssignExpr(counterVarExpr, new MathExpr(counterVarExpr, new ConstExpr(1), MathExpr.OP_ADD))));
popBlock();
loopStmt = new LoopStmt(cnd, null, loopBody, updateBs);
} else {
ObjectType iterType = Types.getIterableClassType();
if (iterType.isAssignableFrom(exprType)) {
ObjectInvokeExpr getIterableExpr;
try {
getIterableExpr = ObjectInvokeExpr.create(expr, "iterator", null);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
LocalVarNode iterableVarNode = this.declareTempLocalVar(getIterableExpr.getType());
block.statements.add(new VarDeclStmt(iterableVarNode));
VarExpr iterableVarExpr = new VarExpr(iterableVarNode);
block.statements.add(new ExprStmt(new AssignExpr(iterableVarExpr, getIterableExpr)));
// set index = 0
if (indexVarExpr != null) {
block.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, new ConstExpr(0))));
}
ObjectInvokeExpr cnd;
try {
cnd = ObjectInvokeExpr.create(iterableVarExpr, "hasNext", null);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
BlockStmt loopBody = this.newBlock();
ObjectInvokeExpr nextInvokeExpr;
try {
nextInvokeExpr = ObjectInvokeExpr.create(iterableVarExpr, "next", null);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
LocalVarNode localVarNode = this.declareLocalVar(varId.getText(), nextInvokeExpr.getType(), Modifier.FINAL, ctx);
if (localVarNode == null)
return null;
VarExpr localVariable = new VarExpr(localVarNode);
loopBody.statements.add(new VarDeclStmt(localVarNode));
loopBody.statements.add(new ExprStmt(new AssignExpr(localVariable, new CastExpr(localVariable.getType(), nextInvokeExpr))));
loopBody.statements.add(visitStat(ctx.stat()));
popBlock();
BlockStmt updateBs = newBlock();
if (indexVarExpr != null) {
// do index++
updateBs.statements.add(new ExprStmt(new AssignExpr(indexVarExpr, new MathExpr(indexVarExpr, new ConstExpr(1), BinaryExpr.OP_ADD))));
}
popBlock();
loopStmt = new LoopStmt(cnd, null, loopBody, updateBs);
} else {
this.handleSyntaxError("require array type or iterable type", ctx.expression());
loopStmt = null;
}
}
popBlock();
if (loopStmt != null)
block.statements.add(loopStmt);
return block;
}
Aggregations