io.vertx.codetrans.lang.jphp.JPhpWriter Maven / Gradle / Ivy
package io.vertx.codetrans.lang.jphp;
import com.sun.source.tree.LambdaExpressionTree;
import io.vertx.codegen.type.*;
import io.vertx.codetrans.CodeModel;
import io.vertx.codetrans.CodeWriter;
import io.vertx.codetrans.MethodSignature;
import io.vertx.codetrans.TypeArg;
import io.vertx.codetrans.expression.*;
import io.vertx.codetrans.statement.StatementModel;
import javax.lang.model.element.TypeElement;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
class JPhpWriter extends CodeWriter {
private JPhpCodeBuilder builder;
public JPhpWriter(JPhpCodeBuilder builder) {
super(builder);
this.builder = builder;
}
public void renderIdentifier(String name, VariableScope scope) {
append("$");
append(name);
}
private final Field f;
{
try {
f = ParenthesizedModel.class.getDeclaredField("expression");
f.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private boolean isStringModel(ExpressionModel expression) throws IllegalAccessException {
if (expression instanceof BinaryExpressionModel) {
BinaryExpressionModel m = (BinaryExpressionModel) expression;
ExpressionModel left = m.getLeft();
ExpressionModel right = m.getRight();
return isStringModel(left) || isStringModel(right);
} else if (expression instanceof StringLiteralModel) {
return true;
} else if (expression instanceof ParenthesizedModel) {
ExpressionModel o = (ExpressionModel) f.get(expression);
return isStringModel(o);
} else if (expression instanceof JPhpCodeBuilder.JPhpIdentifierModel) {
return ((JPhpCodeBuilder.JPhpIdentifierModel) expression).getKind() == ClassKind.STRING;
}
return false;
}
private void renderA(JPhpCodeBuilder.A expression) {
append("\"");
expression.render(this);
append("\"");
}
@Override
public void renderBinary(BinaryExpressionModel expression) {
try {
String op = expression.getOp();
boolean isString = isStringModel(expression);
// append("/*111" + isString + "," + expression.getLeft().getClass() + "," + expression.getRight().getClass() + "*/");
if (op.equals("+") && isString) {
ExpressionModel left = expression.getLeft();
ExpressionModel right = expression.getRight();
if (left instanceof JPhpCodeBuilder.A) {
renderA((JPhpCodeBuilder.A) left);
} else {
left.render(this);
}
append(".");
if (right instanceof JPhpCodeBuilder.A) {
renderA((JPhpCodeBuilder.A) right);
} else {
right.render(this);
}
} else {
super.renderBinary(expression);
}
} catch (Throwable t) {
t.printStackTrace();
}
}
@Override
public void renderStringLiteral(List> parts) {
try {
boolean back = false;
boolean first = true;
for (Iterator> it = parts.iterator(); it.hasNext(); ) {
Object part = it.next();
if (part instanceof String || part instanceof StringLiteralModel || part instanceof JPhpCodeBuilder.A) {
if (!first) {
append(".");
}
if (!back) {
append('"');
back = true;
}
if (part instanceof String) {
renderChars((String) part);
} else {
ExpressionModel m = (ExpressionModel) part;
m.render(this);
}
} else {
if (back) {
append('"');
back = false;
append(".");
}
if (!first && part instanceof BinaryExpressionModel) {
append("(");
}
ExpressionModel m = (ExpressionModel) part;
m.render(this);
if (!first && part instanceof BinaryExpressionModel) {
append(")");
}
}
first = false;
}
if (back) {
append('"');
}
} catch (Throwable t) {
t.printStackTrace();
}
// if (part instanceof JPhpCodeBuilder.A) {
// ((JPhpCodeBuilder.A) part).render(this);
// } else if (part instanceof IdentifierModel) {
// IdentifierModel identifier = (IdentifierModel) part;
// append("${");
// append(identifier.name);
// append("}");
// } else if (part instanceof ExpressionModel) {
// System.err.println(part.getClass());
//// append("/*");
//// append(part.getClass().getSimpleName());
//// append("*/");
// append("\".");
// if (!(part instanceof ParenthesizedModel)) {
// append("(");
// }
// ((ExpressionModel) part).render(this);
// append("/*end*/");
// if (!(part instanceof ParenthesizedModel)) {
// append(")");
// }
// if (hasNext) {
// append(".\"");
// }
// } else {
// renderChars(part.toString());
// }
// }
// append('"');
}
@Override
public void renderStatement(StatementModel statement) {
statement.render(this);
append(";\n");
}
@Override
public void renderTryCatch(StatementModel tryBlock, StatementModel catchBlock) {
append("try {\n");
indent();
tryBlock.render(this);
unindent();
append("} catch(Exception $throwable) {\n");
indent();
catchBlock.render(this);
unindent();
append("}\n");
}
@Override
public void renderMethodReference(ExpressionModel expression, MethodSignature signature) {
if (!(expression instanceof ThisModel)) {
append("array(");
expression.render(this);
append(", ");
}
renderStringLiteral(signature.getName());
if (!(expression instanceof ThisModel)) {
append(")");
}
}
@Override
public void renderNew(ExpressionModel expression, TypeInfo type, List argumentModels) {
expression.render(this);
append(".newInstance(");
for (int i = 0; i < argumentModels.size(); i++) {
if (i > 0) {
append(", ");
}
argumentModels.get(i).render(this);
}
append(')');
}
@Override
public void renderListAdd(ExpressionModel list, ExpressionModel value) {
list.render(this);
append("[] = ");
value.render(this);
}
@Override
public void renderListSize(ExpressionModel list) {
append("sizeof(");
list.render(this);
append(")");
}
@Override
public void renderListGet(ExpressionModel list, ExpressionModel index) {
list.render(this);
append("[");
index.render(this);
append("]");
}
@Override
public void renderListLiteral(List arguments) {
append("array(");
Iterator it = arguments.iterator();
while (it.hasNext()) {
append("");
append(" ");
it.next().render(this);
if (it.hasNext()) {
append(", ");
}
}
append(")");
}
@Override
public void renderMapGet(ExpressionModel map, ExpressionModel key) {
map.render(this);
append("[");
key.render(this);
append("]");
}
@Override
public void renderMapPut(ExpressionModel map, ExpressionModel key, ExpressionModel value) {
map.render(this);
append("[");
key.render(this);
append("] = ");
value.render(this);
}
@Override
public CodeWriter indent() {
super.indent();
return super.indent();
}
@Override
public CodeWriter unindent() {
super.unindent();
return super.unindent();
}
@Override
public void renderMapForEach(ExpressionModel map, String keyName, TypeInfo keyType, String valueName, TypeInfo valueType, LambdaExpressionTree.BodyKind bodyKind, CodeModel block) {
append("foreach (");
map.render(this);
append(" as $");
append(keyName);
append(" => ");
append("$");
append(valueName);
append(") {\n").indent();
block.render(this);
unindent();
append("}\n");
}
@Override
public void renderJsonObject(JsonObjectLiteralModel model) {
renderJsonObject(model.getMembers());
}
@Override
public void renderJsonArray(JsonArrayLiteralModel jsonArray) {
renderJsonArray(jsonArray.getValues());
}
@Override
public void renderDataObject(DataObjectLiteralModel model) {
renderJsonObject(model.getMembers());
}
@Override
public void renderToDataObject(JsonObjectModel model, ClassTypeInfo type) {
model.render(this);
}
@Override
public void renderDataObjectToJson(IdentifierModel model) {
model.render(this);
}
private void renderJsonObject(Iterable members) {
append("array(\n");
indent();
for (Iterator iterator = members.iterator(); iterator.hasNext(); ) {
Member member = iterator.next();
String name = member.getName();
append("\"");
renderChars(name);
append("\" => ");
if (member instanceof Member.Single) {
((Member.Single) member).getValue().render(this);
} else if (member instanceof Member.Sequence) {
renderJsonArray(((Member.Sequence) member).getValues());
} else if (member instanceof Member.Entries) {
renderJsonObject(((Member.Entries) member).entries());
}
if (iterator.hasNext()) {
append(',');
}
append('\n');
}
unindent().append(")");
}
private void renderJsonArray(List values) {
append("[\n").indent();
for (int i = 0; i < values.size(); i++) {
values.get(i).render(this);
if (i < values.size() - 1) {
append(',');
}
append('\n');
}
unindent().append(']');
}
@Override
public void renderJsonObjectAssign(ExpressionModel expression, String name, ExpressionModel value) {
expression.render(this);
append("[\"");
append(name);
append("\"]");
append(" = ");
value.render(this);
}
@Override
public void renderDataObjectAssign(ExpressionModel expression, String name, ExpressionModel value) {
renderJsonObjectAssign(expression, name, value);
}
@Override
public void renderJsonObjectToString(ExpressionModel expression) {
renderJson(expression);
}
private void renderJson(ExpressionModel expression) {
append("json_encode(");
expression.render(this);
append(")");
}
@Override
public void renderJsonArrayToString(ExpressionModel expression) {
renderJson(expression);
}
@Override
public void renderJsonObjectMemberSelect(ExpressionModel expression, Class> type, String name) {
expression.render(this);
append("[\"");
append(name);
append("\"]");
}
@Override
public void renderDataObjectMemberSelect(ExpressionModel expression, String name) {
renderJsonObjectMemberSelect(expression, Object.class, name);
}
@Override
public void renderJsonObjectSize(ExpressionModel expression) {
append("sizeof(");
expression.render(this);
append(")");
}
@Override
public void renderJsonArraySize(ExpressionModel expression) {
append("sizeof(");
expression.render(this);
append(")");
}
@Override
public void renderNewMap() {
append("array()");
}
@Override
public void renderNewList() {
append("array()");
}
@Override
public void renderAsyncResultSucceeded(TypeInfo resultType, String name) {
append("$").append(name).append(" != null");
}
@Override
public void renderAsyncResultFailed(TypeInfo resultType, String name) {
append("$").append(name).append("_err != null");
}
@Override
public void renderAsyncResultCause(TypeInfo resultType, String name) {
append("$").append(name).append("_err");
}
@Override
public void renderAsyncResultValue(TypeInfo resultType, String name) {
append("$").append(name);
}
@Override
public void renderLambda(LambdaExpressionTree.BodyKind bodyKind, List parameterTypes, List parameterNames, CodeModel body) {
append("function (");
for (int i = 0; i < parameterNames.size(); i++) {
if (i > 0) {
append(", ");
}
append("$");
append(parameterNames.get(i));
}
append(") {\n");
indent();
body.render(this);
if (bodyKind == LambdaExpressionTree.BodyKind.EXPRESSION) {
append(";\n");
}
unindent();
append("}");
}
@Override
public void renderEnumConstant(EnumTypeInfo type, String constant) {
append('"');
append(constant);
append('"');
}
@Override
public void renderSystemOutPrintln(ExpressionModel expression) {
append("echo ");
if (expression instanceof StringLiteralModel) {
StringLiteralModel str = (StringLiteralModel) expression;
append("\"");
renderChars(str.getValue());
append("\\n\"");
} else {
expression.render(this);
append(".\"\\n\"");
}
}
@Override
public void renderMethodInvocation(ExpressionModel expression, TypeInfo receiverType, MethodSignature method, TypeInfo returnType, List typeArguments, List argumentModels, List argumentTypes) {
List parameterTypes = method.getParameterTypes();
for (int i = 0; i < parameterTypes.size(); i++) {
TypeInfo parameterType = parameterTypes.get(i);
TypeInfo argumentType = argumentTypes.get(i);
if (io.vertx.codetrans.Helper.isHandler(parameterType) && io.vertx.codetrans.Helper.isInstanceOfHandler(argumentType)) {
ExpressionModel expressionModel = argumentModels.get(i);
argumentModels.set(i, builder.render(expressionModel::render));
}
}
//
if (expression instanceof JPhpCodeBuilder.JPhpIdentifierModel && ((JPhpCodeBuilder.JPhpIdentifierModel) expression).getKind() == ClassKind.STRING) {
if (method.getName().equals("startsWith")) {
append("substr(");
expression.render(this);
append(", 0, strlen(");
argumentModels.get(0).render(this);
append(")) === ");
argumentModels.get(0).render(this);
if (argumentModels.size() > 1) {
append("/*wrong arg num*/");
}
} else if (method.getName().equals("length")) {
append("strlen(");
expression.render(this);
append(")");
} else {
append("/*string method").append(method.getName()).append("*/");
}
} else {
if (!(expression instanceof ThisModel)) {
expression.render(this);
renderJoiner(expression);
}
append(method.getName());
append('(');
for (int i = 0; i < argumentModels.size(); i++) {
if (i > 0) {
append(", ");
}
argumentModels.get(i).render(this);
}
append(')');
}
}
@Override
public void renderSystemErrPrintln(ExpressionModel expression) {
renderSystemOutPrintln(expression);
}
@Override
public void renderThrow(String throwableType, ExpressionModel reason) {
append("throw new ");
append(throwableType.replace(".", "\\"));
append("(");
if (reason != null) {
reason.render(this);
}
append(")");
}
@Override
public void renderThis() {
append("$this");
}
@Override
public void renderApiType(ApiTypeInfo apiType) {
append(apiType.getSimpleName());
}
@Override
public void renderJavaType(ClassTypeInfo apiType) {
append("Java::type(\"");
append(apiType.getPackageName());
append(".");
append(apiType.getSimpleName());
append("\")");
}
private void renderJoiner(ExpressionModel expression) {
if (expression instanceof ApiTypeModel) {
append("::");
} else if (expression instanceof ClassModel) {
append("->");
} else {
append("->");
}
}
public void renderMemberSelect(ExpressionModel expression, String identifier) {
expression.render(this);
renderJoiner(expression);
append(identifier);
}
@Override
public void renderJsonArrayAdd(ExpressionModel expression, ExpressionModel value) {
renderListAdd(expression, value);
}
@Override
public void renderInstanceOf(ExpressionModel expression, TypeElement type) {
expression.render(this);
append(".getClass().getSimpleName() == '");
append(type.getSimpleName());
append("'");
}
@Override
public void renderAssign(ExpressionModel variable, ExpressionModel expression) {
if (expression instanceof JPhpCodeBuilder.JPhpIdentifierModel) {
JPhpCodeBuilder.JPhpIdentifierModel e = (JPhpCodeBuilder.JPhpIdentifierModel) expression;
if (e.getScope() == VariableScope.FIELD && builder.defineFunction) {
append("global $").append(e.name).append(";");
}
}
variable.render(this);
append(" = ");
expression.render(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy