use of kalang.ast.VarExpr in project kalang by kasonyang.
the class SemanticAnalyzer method validateAssign.
public boolean validateAssign(AssignableExpr to, ExprNode from, OffsetRange offset) {
if (to instanceof VarExpr) {
LocalVarNode varObject = ((VarExpr) to).getVar();
if (Modifier.isFinal(varObject.modifier)) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, String.format("%s is readonly", varObject.getName()), offset);
return false;
}
} else if (to instanceof FieldExpr) {
FieldDescriptor field = ((FieldExpr) to).getField();
if (Modifier.isFinal(field.getModifier())) {
this.diagnosisReporter.report(Diagnosis.Kind.ERROR, String.format("%s is readonly", field.getName()), offset);
return false;
}
}
Type toType = to.getType();
Type fromType = from.getType();
if (!toType.isAssignableFrom(fromType)) {
diagnosisReporter.report(Diagnosis.Kind.ERROR, String.format("incompatible types: %s cannot be converted to %s", fromType, toType), offset);
return false;
}
return true;
}
use of kalang.ast.VarExpr in project kalang by kasonyang.
the class AstBuilder method visitLocalVarDecl.
@Override
public Statement visitLocalVarDecl(LocalVarDeclContext ctx) {
MultiStmt ms = new MultiStmt();
for (VarDeclContext v : ctx.varDecl()) {
TypeContext varType = v.varType;
Type exceptedType = varType == null ? null : parseType(varType);
ExprNode initExpr = null;
ExpressionContext initExprContext = v.expression();
if (initExprContext != null) {
if (initExprContext instanceof LiteralExprContext) {
initExpr = this.parseLiteral(((LiteralExprContext) initExprContext).literal(), exceptedType);
} else {
initExpr = visitExpression(initExprContext);
}
}
VarInfo varInfo = varDecl(v, initExpr == null ? Types.getRootType() : initExpr.getType());
LocalVarNode localVar = this.declareLocalVar(varInfo.name, varInfo.type, varInfo.modifier, ctx);
if (localVar == null)
return null;
VarDeclStmt vds = new VarDeclStmt(localVar);
ms.statements.add(vds);
if (initExpr != null) {
AssignExpr assignExpr = new AssignExpr(new VarExpr(localVar), initExpr);
mapAst(assignExpr, v);
ms.statements.add(new ExprStmt(assignExpr));
}
mapAst(localVar, ctx);
}
return ms;
}
use of kalang.ast.VarExpr in project kalang by kasonyang.
the class AstBuilder method onAssign.
private void onAssign(ExprNode to, ExprNode expr) {
removeOverrideType(to);
if (to instanceof VarExpr) {
((VarExpr) to).removeOverrideType();
} else if (to instanceof ParameterExpr) {
((ParameterExpr) to).removeOverrideType();
}
VarObject key = getOverrideTypeKey(to);
if (key != null) {
Type toType = to.getType();
if (toType instanceof ObjectType) {
Type type = expr.getType();
int ns;
if (Types.NULL_TYPE.equals(type)) {
ns = NULLSTATE_MUST_NULL;
} else if (type instanceof ObjectType) {
ns = getNullState(((ObjectType) type).getNullable());
} else {
throw Exceptions.unexceptedValue(type);
}
nullState.put(key, ns);
}
}
}
use of kalang.ast.VarExpr 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.VarExpr in project kalang by kasonyang.
the class AstBuilder method visitMapExpr.
@Override
public MultiStmtExpr visitMapExpr(KalangParser.MapExprContext ctx) {
Type keyType = ctx.keyType != null ? requireClassType(ctx.keyType) : Types.getRootType();
Type valueType = ctx.valueType != null ? requireClassType(ctx.valueType) : Types.getRootType();
if (keyType == null || valueType == null)
return null;
LocalVarNode vo = declareTempLocalVar(Types.getClassType(Types.getMapImplClassType().getClassNode(), new Type[] { keyType, valueType }));
VarDeclStmt vds = new VarDeclStmt(vo);
NewObjectExpr newExpr;
try {
newExpr = new NewObjectExpr(Types.getMapImplClassType());
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
List<Statement> stmts = new LinkedList<>();
stmts.add(vds);
stmts.add(new ExprStmt(new AssignExpr(new VarExpr(vo), newExpr)));
VarExpr ve = new VarExpr(vo);
List<TerminalNode> ids = ctx.Identifier();
for (int i = 0; i < ids.size(); i++) {
ExpressionContext e = ctx.expression(i);
ExprNode v = (ExprNode) visit(e);
ConstExpr k = new ConstExpr(ctx.Identifier(i).getText());
ExprNode[] args = new ExprNode[] { k, v };
InvocationExpr iv;
try {
iv = ObjectInvokeExpr.create(ve, "put", args);
} catch (MethodNotFoundException | AmbiguousMethodException ex) {
throw Exceptions.unexceptedException(ex);
}
ExprStmt es = new ExprStmt(iv);
stmts.add(es);
}
MultiStmtExpr mse = new MultiStmtExpr(stmts, ve);
mapAst(mse, ctx);
return mse;
}
Aggregations