Skip to content

Commit

Permalink
🦄 refactor: Redesign ast 13
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed Nov 29, 2024
1 parent bb3a2c0 commit 8b94791
Show file tree
Hide file tree
Showing 18 changed files with 314 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public BaseTs2JavaAst(ITs2JavaAst<?, ?> parent, AST ast, Memo memo) {
type = TypeDescription.ForLoadedType.of(void.class);
}

protected static Size mergeSize(Size... sizes) {
protected static Size aggregateSize(Size... sizes) {
int sizeImpact = 0;
int maximalSize = 0;
for (Size size : sizes) {
Expand All @@ -50,10 +50,8 @@ protected static Size mergeSize(Size... sizes) {
return new Size(sizeImpact, maximalSize);
}

protected static Size mergeSize(Size leftSize, Size rightSize) {
return new Size(
leftSize.getSizeImpact() + rightSize.getSizeImpact(),
Math.max(leftSize.getMaximalSize(), rightSize.getMaximalSize()));
protected static Size aggregateSize(Size leftSize, Size rightSize) {
return leftSize.aggregate(rightSize);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public Ts2JavaAstClass(ITs2JavaAst<?, ?> parent, Swc4jAstClass ast, Ts2JavaMemoD
public Size apply(MethodVisitor methodVisitor, Implementation.Context context) {
return body.stream()
.map((classMember) -> classMember.apply(methodVisitor, context))
.reduce(BaseTs2JavaAst::mergeSize)
.reduce(BaseTs2JavaAst::aggregateSize)
.orElse(Size.ZERO);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ public class Ts2JavaAstClassMethod
implements ITs2JavaAstClassMember<Swc4jAstClassMethod, Ts2JavaMemoDynamicType> {
protected final Ts2JavaAstFunction function;

public Ts2JavaAstClassMethod(ITs2JavaAst<?, ?> parent, Swc4jAstClassMethod ast, Ts2JavaMemoDynamicType memo) {
public Ts2JavaAstClassMethod(
ITs2JavaAst<?, ?> parent,
Swc4jAstClassMethod ast,
Ts2JavaMemoDynamicType memo) {
super(parent, ast, memo);
if (ast.isStatic()) {
throw new Ts2JavaAstException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ public Ts2JavaAstFunction(
Swc4jAstAccessibility accessibility) {
super(parent, ast, memo);
this.accessibility = accessibility;
type = ast.getReturnType()
.map(Ts2JavaAstTsTypeAnn::getTypeDescription)
.orElse(TypeDescription.ForLoadedType.of(void.class));
memoFunction = new Ts2JavaMemoFunction()
.setStatic(_static);
.setStatic(_static)
.setReturnType(type);
this.name = name;
body = ast.getBody().map(stmt -> new Ts2JavaAstBlockStmt(this, stmt, memoFunction));
}
Expand All @@ -68,18 +72,14 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context context) {
@Override
public void compile() {
final Visibility visibility = Ts2JavaAstAccessibility.getVisibility(accessibility);
final TypeDescription returnType = ast.getReturnType()
.map(Ts2JavaAstTsTypeAnn::getTypeDescription)
.orElse(TypeDescription.ForLoadedType.of(void.class));
memoFunction.setReturnType(returnType);
ast.getParams().stream()
.map(Ts2JavaAstParam::getLocalVariable)
.forEach(memoFunction::addLocalVariable);
final TypeList parameters = memoFunction.getParameters();
final int initialOffset = memoFunction.getMaxOffset();
memoFunction.pushLexicalScope();
body.ifPresent(Ts2JavaAstBlockStmt::compile);
memo.setBuilder(memo.getBuilder().defineMethod(name, returnType, visibility)
memo.setBuilder(memo.getBuilder().defineMethod(name, type, visibility)
.withParameters(parameters.toArray(new TypeDescription[0]))
.intercept(Implementation.Simple.of(
(implementationTarget, instrumentedMethod) -> new StackManipulation.Simple(this::apply),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import com.caoccao.javet.buddy.ts2java.ast.BaseTs2JavaAst;
import com.caoccao.javet.buddy.ts2java.ast.interfaces.*;
import com.caoccao.javet.buddy.ts2java.ast.memo.Ts2JavaMemoFunction;
import com.caoccao.javet.buddy.ts2java.compiler.JavaClassCast;
import com.caoccao.javet.buddy.ts2java.compiler.JavaLocalVariable;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstIdent;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess;
Expand All @@ -44,10 +46,12 @@ public class Ts2JavaAstIdent
public Ts2JavaAstIdent(
ITs2JavaAst<?, ?> parent,
Swc4jAstIdent ast,
TypeDescription type,
Ts2JavaMemoFunction memo) {
super(parent, ast, memo);
optional = ast.isOptional();
sym = ast.getSym();
this.type = type;
}

@Override
Expand All @@ -56,7 +60,11 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context context) {
JavaLocalVariable localVariable = memo.getLocalVariable(sym);
MethodVariableAccess methodVariableAccess = MethodVariableAccess.of(localVariable.getType());
StackManipulation stackManipulation = methodVariableAccess.loadFrom(localVariable.getOffset());
return stackManipulation.apply(methodVisitor, context);
Size size = stackManipulation.apply(methodVisitor, context);
Size sizeCast = JavaClassCast.getUpCastStackManipulation(localVariable.getType(), type)
.map(s -> s.apply(methodVisitor, context))
.orElse(Size.ZERO);
return aggregateSize(size, sizeCast);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ public class Ts2JavaAstParenExpr
public Ts2JavaAstParenExpr(
ITs2JavaAst<?, ?> parent,
Swc4jAstParenExpr ast,
TypeDescription type,
Ts2JavaMemoFunction memo) {
super(parent, ast, memo);
expr = ITs2JavaAstExpr.cast(this, ast.getExpr(), memo);
expr = ITs2JavaAstExpr.cast(this, ast.getExpr(), type, memo);
this.type = type;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ public class Ts2JavaAstUnaryExpr
public Ts2JavaAstUnaryExpr(
ITs2JavaAst<?, ?> parent,
Swc4jAstUnaryExpr ast,
TypeDescription type,
Ts2JavaMemoFunction memo) {
super(parent, ast, memo);
arg = ITs2JavaAstExpr.cast(this, ast.getArg(), memo);
arg = ITs2JavaAstExpr.cast(this, ast.getArg(), type, memo);
op = ast.getOp();
this.type = type;
}

@Override
Expand All @@ -55,13 +57,13 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context context) {
switch (op) {
case Bang:
if (!(arg instanceof ITs2JavaBangFlippable)) {
final int opcode = getOpcodeNegative(arg.getType());
final int opcode = getOpcodeNegative();
methodVisitor.visitInsn(opcode);
}
break;
case Minus: {
if (!(arg instanceof ITs2JavaMinusFlippable)) {
final int opcode = getOpcodeNegative(arg.getType());
final int opcode = getOpcodeNegative();
methodVisitor.visitInsn(opcode);
}
break;
Expand Down Expand Up @@ -125,29 +127,24 @@ public Swc4jAstUnaryOp getOp() {
return op;
}

protected int getOpcodeNegative(TypeDescription type) {
if (type.represents(int.class)
|| type.represents(byte.class)
|| type.represents(char.class)
|| type.represents(boolean.class)
|| type.represents(short.class)) {
protected int getOpcodeNegative() {
if (arg.getType().represents(int.class)
|| arg.getType().represents(byte.class)
|| arg.getType().represents(char.class)
|| arg.getType().represents(boolean.class)
|| arg.getType().represents(short.class)) {
return Opcodes.INEG;
} else if (type.represents(long.class)) {
} else if (arg.getType().represents(long.class)) {
return Opcodes.LNEG;
} else if (type.represents(float.class)) {
} else if (arg.getType().represents(float.class)) {
return Opcodes.FNEG;
} else if (type.represents(double.class)) {
} else if (arg.getType().represents(double.class)) {
return Opcodes.DNEG;
} else {
throw new Ts2JavaAstException(
ast,
ast.getArg(),
SimpleFreeMarkerFormat.format("Minus cannot be applied to type ${type}.",
SimpleMap.of("type", type.getName())));
SimpleMap.of("type", arg.getType().getName())));
}
}

@Override
public TypeDescription getType() {
return arg.getType();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
import com.caoccao.javet.buddy.ts2java.ast.interfaces.ITs2JavaAstTsLit;
import com.caoccao.javet.buddy.ts2java.ast.interfaces.abilities.ITs2JavaBangFlippable;
import com.caoccao.javet.buddy.ts2java.ast.memo.Ts2JavaMemoFunction;
import com.caoccao.javet.buddy.ts2java.exceptions.Ts2JavaAstException;
import com.caoccao.javet.swc4j.ast.expr.lit.Swc4jAstBool;
import com.caoccao.javet.utils.SimpleFreeMarkerFormat;
import com.caoccao.javet.utils.SimpleMap;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.bytecode.StackManipulation;
Expand All @@ -38,10 +41,17 @@ public class Ts2JavaAstBool
public Ts2JavaAstBool(
ITs2JavaAst<?, ?> parent,
Swc4jAstBool ast,
TypeDescription type,
Ts2JavaMemoFunction memo) {
super(parent, ast, memo);
if (!type.represents(boolean.class)) {
throw new Ts2JavaAstException(
ast,
SimpleFreeMarkerFormat.format("Bool type ${type} is not supported.",
SimpleMap.of("type", type.getName())));
}
value = ast.isValue();
type = TypeDescription.ForLoadedType.of(boolean.class);
this.type = TypeDescription.ForLoadedType.of(boolean.class);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,27 @@
import com.caoccao.javet.swc4j.ast.interfaces.ISwc4jAstExpr;
import com.caoccao.javet.utils.SimpleFreeMarkerFormat;
import com.caoccao.javet.utils.SimpleMap;
import net.bytebuddy.description.type.TypeDescription;

public interface ITs2JavaAstExpr<AST extends ISwc4jAstExpr, Memo extends Ts2JavaMemo>
extends ITs2JavaAstVarDeclOrExpr<AST, Memo>, ITs2JavaAstPat<AST, Memo>, ITs2JavaAstJsxExpr<AST, Memo>,
ITs2JavaAstCallee<AST, Memo>, ITs2JavaAstBlockStmtOrExpr<AST, Memo>, ITs2JavaAstAssignTarget<AST, Memo> {
static ITs2JavaAstExpr<?, ?> cast(
ITs2JavaAst<?, ?> parent,
ISwc4jAstExpr ast,
TypeDescription type,
Ts2JavaMemoFunction memo) {
switch (ast.getType()) {
case Bool:
return new Ts2JavaAstBool(parent, ast.as(Swc4jAstBool.class), memo);
return new Ts2JavaAstBool(parent, ast.as(Swc4jAstBool.class), type, memo);
case Ident:
return new Ts2JavaAstIdent(parent, ast.as(Swc4jAstIdent.class), memo);
return new Ts2JavaAstIdent(parent, ast.as(Swc4jAstIdent.class), type, memo);
case Number:
return new Ts2JavaAstNumber(parent, ast.as(Swc4jAstNumber.class), null, memo);
return new Ts2JavaAstNumber(parent, ast.as(Swc4jAstNumber.class), type, memo);
case ParenExpr:
return cast(parent, ast.as(Swc4jAstParenExpr.class).unParenExpr(), memo);
return cast(parent, ast.as(Swc4jAstParenExpr.class).unParenExpr(), type, memo);
case UnaryExpr:
return new Ts2JavaAstUnaryExpr(parent, ast.as(Swc4jAstUnaryExpr.class), memo);
return new Ts2JavaAstUnaryExpr(parent, ast.as(Swc4jAstUnaryExpr.class), type, memo);
case BinExpr:
default:
throw new Ts2JavaAstException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public Ts2JavaAstBlockStmt(
public Size apply(MethodVisitor methodVisitor, Implementation.Context context) {
return stmts.stream()
.map((stmt) -> stmt.apply(methodVisitor, context))
.reduce(BaseTs2JavaAst::mergeSize)
.reduce(BaseTs2JavaAst::aggregateSize)
.orElse(Size.ZERO);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public Ts2JavaAstReturnStmt(
Swc4jAstReturnStmt ast,
Ts2JavaMemoFunction memo) {
super(parent, ast, memo);
arg = ast.getArg().map(arg -> ITs2JavaAstExpr.cast(this, arg, memo));
type = memo.getReturnType();
arg = ast.getArg().map(arg -> ITs2JavaAstExpr.cast(this, arg, type, memo));
}

@Override
Expand All @@ -53,7 +54,7 @@ public Size apply(MethodVisitor methodVisitor, Implementation.Context context) {
.map(stackManipulation -> stackManipulation.apply(methodVisitor, context))
.orElse(Size.ZERO);
Size sizeReturn = MethodReturn.of(memo.getReturnType()).apply(methodVisitor, context);
return mergeSize(sizeArg, sizeCast, sizeReturn);
return aggregateSize(sizeArg, sizeCast, sizeReturn);
}
return Size.ZERO;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
import java.util.stream.Collectors;

public class BaseTestTs2Java {
protected TsClassX tsClass;

public BaseTestTs2Java() {
tsClass = null;
}

protected void disableLogging() {
Ts2JavaX.disableLogging();
Ts2JavaAstClassFunction.setMethodVisitor(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@

import com.caoccao.javet.buddy.ts2java.BaseTestTs2Java;
import com.caoccao.javet.buddy.ts2java.TsClass;
import com.caoccao.javet.buddy.ts2java.TsClassX;
import com.caoccao.javet.buddy.ts2java.TsMethodArgument;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;

import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class TestBasicOperations extends BaseTestTs2Java {
/*
Expand Down Expand Up @@ -161,22 +160,6 @@ public void testAdd_JI_J() throws Exception {
assertEquals(1L + 2, tsClass.invoke(1L, 2));
}

@Test
public void testBoolean() throws Exception {
TsClassX tsClass = new TsClassX("return true;", boolean.class);
assertTrue((boolean) tsClass.invoke());
tsClass = new TsClassX("return false;", boolean.class);
assertFalse((boolean) tsClass.invoke());
tsClass = new TsClassX("return !true;", boolean.class);
assertFalse((boolean) tsClass.invoke());
tsClass = new TsClassX("return !false;", boolean.class);
assertTrue((boolean) tsClass.invoke());
tsClass = new TsClassX("return !(!true);", boolean.class);
assertTrue((boolean) tsClass.invoke());
tsClass = new TsClassX("return !(!false);", boolean.class);
assertFalse((boolean) tsClass.invoke());
}

@Test
public void testDivide_II_I() throws Exception {
TsClass tsClass = new TsClass(
Expand Down Expand Up @@ -246,28 +229,6 @@ public void testMultiply_II_I() throws Exception {
assertEquals(3 * 2, tsClass.invoke(3, 2));
}

@Test
public void testNumber() throws Exception {
TsClassX tsClass = new TsClassX("return 1;", int.class);
assertEquals(1, tsClass.invoke());
tsClass = new TsClassX("return (1);", int.class);
assertEquals(1, tsClass.invoke());
tsClass = new TsClassX("return -1;", int.class);
assertEquals(-1, tsClass.invoke());
tsClass = new TsClassX("return -(1);", int.class);
assertEquals(-1, tsClass.invoke());
tsClass = new TsClassX("return -(-1);", int.class);
assertEquals(1, tsClass.invoke());
tsClass = new TsClassX("return +1;", int.class);
assertEquals(1, tsClass.invoke());
tsClass = new TsClassX("return +(+1);", int.class);
assertEquals(1, tsClass.invoke());
tsClass = new TsClassX("return +(-1);", int.class);
assertEquals(-1, tsClass.invoke());
tsClass = new TsClassX("return a;", int.class, TsMethodArgument.of("a", int.class));
assertEquals(1, tsClass.invoke(1));
}

@Test
public void testPow_DD_D() throws Exception {
assertEquals(8D, pow(2D, 3D), 0.001D);
Expand Down
Loading

0 comments on commit 8b94791

Please sign in to comment.