Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.sourceforge.jenesis4java.impl.MStatement Maven / Gradle / Ivy
package net.sourceforge.jenesis4java.impl;
/*
* #%L
* Jenesis 4 Java Code Generator
* %%
* Copyright (C) 2000 - 2015 jenesis4java
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
/**
* Copyright (C) 2008, 2010 Richard van Nieuwenhoven - ritchie [at] gmx [dot] at
* Copyright (C) 2000, 2001 Paul Cody Johnston - [email protected]
* This file is part of Jenesis4java. Jenesis4java is free software: you can
* redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
* Jenesis4java is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
* You should have received a copy of the GNU Lesser General Public License
* along with Jenesis4java. If not, see .
*/
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import net.sourceforge.jenesis4java.*;
import net.sourceforge.jenesis4java.impl.util.BlockStyle;
import net.sourceforge.jenesis4java.impl.util.BlockUtil;
import net.sourceforge.jenesis4java.impl.util.ListTypeSelector;
import net.sourceforge.jenesis4java.impl.util.VisitorUtils;
/**
* Standard {@code Statement} implementations.
*/
abstract class MStatement extends MVM.MCodeable implements Statement {
/**
* BLOCK STATEMENT
*/
static class BlockStatement extends MStatement implements Block {
List vs;
BlockStatement(MVM vm) {
super(vm);
vs = new ArrayList<>();
}
@Override
public List getStatements() {
return ListTypeSelector.select(vs);
}
@Override
public Statement insertStatement(int index, Expression expression) {
ExpressionStatement expressionStatement = new MStatement.MExpressionStatement((MVM) vm(), expression);
vs.add(index, expressionStatement);
return expressionStatement;
}
@Override
public void insertStatement(int index, Statement statement) {
vs.add(index, statement);
}
@Override
public boolean isBlockWithAbruptCompletion() {
return BlockUtil.isBlockWithAbruptCompletion(getStatements());
}
@Override
public Break newBreak() {
Break x = new MBreak(vm);
vs.add(x);
return x;
}
@Override
public Continue newContinue() {
Continue x = new MContinue(vm);
vs.add(x);
return x;
}
@Override
public Let newDeclarationLet(Type type) {
Let x = new MStatement.MLet(vm, type);
int index = 0;
while (index < vs.size() && vs.get(index) instanceof Let) {
index++;
}
vs.add(index, x);
return x;
}
@Override
public DoWhile newDoWhile(Expression predicate) {
DoWhile x = new MDoWhile(vm, predicate);
vs.add(x);
return x;
}
@Override
public Empty newEmpty() {
Empty x = new MEmpty(vm);
vs.add(x);
return x;
}
@Override
public For newFor() {
For x = new MFor(vm);
vs.add(x);
return x;
}
@Override
public If newIf(Expression predicate) {
If x = new MIf(vm, predicate);
vs.add(x);
return x;
}
@Override
public Let newLet(Type type) {
Let x = new MLet(vm, type);
vs.add(x);
return x;
}
@Override
public LocalBlock newLocalBlock() {
LocalBlock x = new MLocalBlock(vm);
vs.add(x);
return x;
}
@Override
public LocalClass newLocalClass(String name) {
LocalClass x = new MDeclaration.MLocalClass(vm, name);
vs.add(x);
return x;
}
@Override
public Return newReturn() {
Return x = new MReturn(vm);
vs.add(x);
return x;
}
@Override
public ExpressionStatement newStmt(Expression expr) {
ExpressionStatement x = new MExpressionStatement(vm, expr);
vs.add(x);
return x;
}
@Override
public Switch newSwitch(Expression integer) {
Switch x = new MSwitch(vm, integer);
vs.add(x);
return x;
}
@Override
public Synchronized newSynchronized(Expression mutex) {
Synchronized x = new MSynchronized(vm, mutex);
vs.add(x);
return x;
}
@Override
public Throw newThrow(Expression throwable) {
Throw x = new MThrow(vm, throwable);
vs.add(x);
return x;
}
@Override
public Try newTry() {
Try x = new MTry(vm);
vs.add(x);
return x;
}
@Override
public While newWhile(Expression predicate) {
While x = new MWhile(vm, predicate);
vs.add(x);
return x;
}
@Override
public void removeStmt(Statement statement) {
if (vs != null) {
vs.remove(statement);
}
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
VisitorUtils.visit(vs, this, visitor);
}
void writeBlock(CodeWriter out, BlockStyle style) {
// write it
style.toCode(out, getStatements(), comment);
}
}
/**
* GOTO STATMENTS
*/
abstract static class GotoStatement extends MStatement {
final String kwd;
String target;
GotoStatement(MVM vm, String kwd) {
super(vm);
this.kwd = kwd;
}
public String getGoto() {
return target;
}
public GotoStatement setGoto(String target) {
this.target = target;
return this;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write(kwd);
if (target != null) {
out.space().write(target);
}
out.write(';');
appendTrailingComment(out);
return out;
}
}
/**
* BREAK STATEMENT
*/
static class MBreak extends GotoStatement implements Break {
MBreak(MVM vm) {
super(vm, "break");
}
@Override
public MBreak setGoto(String target) {
super.setGoto(target);
return this;
}
}
/**
* CASE STATEMENT
*/
static class MCase extends MConditionalStatement implements Case {
MCase(MVM vm, Expression expr) {
super(vm);
setPredicate(expr);
}
@Override
public Expression getConstant() {
return getPredicate();
}
@Override
public MCase setConstant(Expression expr) {
setPredicate(expr);
return this;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("case ").write(e).write(':');
appendTrailingComment(out);
out.indentLine();
out.write(getStatements());
out.dedentLine();
return out;
}
}
/**
* CONDITIONAL STATEMENT
*/
abstract static class MConditionalStatement extends BlockStatement implements ConditionalStatement {
Expression e;
public MConditionalStatement(MVM vm) {
super(vm);
}
public MConditionalStatement(MVM vm, Expression e) {
super(vm);
this.e = e;
}
@Override
public Expression getPredicate() {
return e;
}
@Override
public MConditionalStatement setPredicate(Expression e) {
this.e = e;
return this;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
e = VisitorUtils.visit(e, this, visitor);
}
}
/**
* CONTINUE STATEMENT
*/
static class MContinue extends GotoStatement implements Continue {
MContinue(MVM vm) {
super(vm, "continue");
}
@Override
public MContinue setGoto(String target) {
super.setGoto(target);
return this;
}
}
/**
* DEFAULT STATEMENT
*/
static class MDefault extends BlockStatement implements Default {
MDefault(MVM vm) {
super(vm);
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("default:");
writeBlock(out, vm.getStyle("default"));
return out;
}
}
/**
* DO WHILE STATEMENT
*/
static class MDoWhile extends MConditionalStatement implements DoWhile {
public MDoWhile(MVM vm, Expression e) {
super(vm, e);
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("do");
writeBlock(out, vm.getStyle("do"));
out.write("while (").write(e).write(");");
return out;
}
}
/**
* ELSE STATEMENT
*/
static class MElse extends BlockStatement implements Else {
MElse(MVM vm) {
super(vm);
}
@Override
public CodeWriter toCode(CodeWriter out) {
appendCommentsAndLabel(out);
if (!out.isLineNew()) {
out.space();
}
out.write("else");
writeBlock(out, vm.getStyle("else"));
return out;
}
}
/**
* ELSE IF STATEMENT
*/
static class MElseIf extends MConditionalStatement implements ElseIf {
MElseIf(MVM vm, Expression e) {
super(vm, e);
}
@Override
public CodeWriter toCode(CodeWriter out) {
appendCommentsAndLabel(out);
if (!out.isLineNew()) {
out.space();
}
out.write("else if (").write(e).write(')');
writeBlock(out, vm.getStyle("else-if"));
return out;
}
}
/**
* EMPTY STATEMENT
*/
static class MEmpty extends MStatement implements Empty {
MEmpty(MVM vm) {
super(vm);
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write(';');
appendTrailingComment(out);
return out;
}
}
/**
* EXPRESSIONABLE STATEMENT
*/
abstract static class MExpressionableStatement extends MStatement {
Expression e;
MExpressionableStatement(MVM vm) {
super(vm);
}
public Expression getExpression() {
return e;
}
public MExpressionableStatement setExpression(Expression e) {
this.e = e;
return this;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
e = VisitorUtils.visit(e, this, visitor);
}
}
/**
* EXPRESSION STATEMENT
*/
static class MExpressionStatement extends MExpressionableStatement implements ExpressionStatement {
MExpressionStatement(MVM vm, Expression e) {
super(vm);
setExpression(e);
}
@Override
public MExpressionStatement setExpression(Expression e) {
super.setExpression(e);
return this;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write(getExpression()).write(';');
appendTrailingComment(out);
return out;
}
}
/**
* CATCH STATEMENT
*/
static class MFinally extends BlockStatement implements Finally {
MFinally(MVM vm) {
super(vm);
}
@Override
public CodeWriter toCode(CodeWriter out) {
appendCommentsAndLabel(out);
if (!out.isLineNew()) {
out.space();
}
out.write("finally");
writeBlock(out, vm.getStyle("finally"));
return out;
}
}
/**
* FOR STATEMENT
*/
static class MFor extends MConditionalStatement implements For {
List initExpressions = new ArrayList<>();
List vu = new ArrayList<>();
MFor(MVM vm) {
super(vm);
}
@Override
public MFor addInit(Expression e) {
initExpressions.add(e);
return this;
}
@Override
public MFor addUpdate(Expression e) {
vu.add(e);
return this;
}
@Override
public List getInits() {
return ListTypeSelector.select(initExpressions);
}
@Override
public List getUpdates() {
return ListTypeSelector.select(vu);
}
@Override
public Let setInit(Type type) {
Let let = new MForInitLet(vm, type);
initExpressions.add(let);
return let;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("for (");
write(initExpressions, out);
out.write(';');
if (e != null) {
out.space().write(e);
}
out.write(';');
if (!vu.isEmpty()) {
out.space();
write(vu, out);
}
out.write(')');
writeBlock(out, vm.getStyle("for"));
return out;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
VisitorUtils.visit(initExpressions, this, visitor);
VisitorUtils.visit(vu, this, visitor);
}
private void write(List v, CodeWriter out) {
for (int i = 0; i < v.size(); i++) {
if (i > 0) {
out.write(", ");
}
out.write(v.get(i));
}
}
}
/**
* LET STATEMENT
*/
static class MForInitLet extends MLet {
MForInitLet(MVM vm, Type type) {
super(vm, type);
}
@Override
public CodeWriter toCode(CodeWriter out) {
// queue up the comment
out.queue(comment);
if (isFinal) {
out.write("final").space();
}
out.write(type).space();
for (int i = 0; i < v.size(); i++) {
if (i > 0) {
out.write(',').space();
}
out.write(v.get(i));
}
return out;
}
}
/**
* IF STATEMENT
*/
static class MIf extends MConditionalStatement implements If {
List elseIfs = new ArrayList<>();
Else _else;
MIf(MVM vm, Expression e) {
super(vm, e);
}
@Override
public Else getElse() {
if (_else == null) {
_else = new MElse(vm);
}
return _else;
}
@Override
public List getElseIfs() {
return ListTypeSelector.select(elseIfs);
}
@Override
public ElseIf newElseIf(Expression e) {
ElseIf ei = new MElseIf(vm, e);
elseIfs.add(ei);
return ei;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("if (").write(e).write(')');
writeBlock(out, vm.getStyle("if"));
for (ElseIf elseIf : elseIfs) {
out.write(elseIf);
}
if (_else != null && !_else.getStatements().isEmpty()) {
out.write(_else);
}
return out;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
VisitorUtils.visit(elseIfs, this, visitor);
_else = VisitorUtils.visit(_else, this, visitor);
}
}
/**
* LET STATEMENT
*/
static class MLet extends MExpressionableStatement implements Let {
Type type;
boolean isFinal;
List v = new ArrayList<>();
MLet(MVM vm, Type type) {
super(vm);
this.type = type;
}
@Override
public MLet addAssign(Assign assign) {
v.add(assign);
return this;
}
@Override
public MLet addAssign(String name, Expression expr) {
v.add(new MExpression.MAssign(vm, Assign.S, new MExpression.MVariable(vm, name), expr));
return this;
}
@Override
public List getAssigns() {
return ListTypeSelector.select(v);
}
@Override
public Type getType() {
return type;
}
@Override
public boolean isFinal() {
return isFinal;
}
@Override
public MLet isFinal(boolean value) {
isFinal = value;
return this;
}
@Override
public MLet setType(Type type) {
this.type = type;
return this;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
if (isFinal) {
out.write("final").space();
}
out.write(type).space();
for (int i = 0; i < v.size(); i++) {
if (i > 0) {
out.write(',').space();
}
out.write(v.get(i));
}
out.write(';');
appendTrailingComment(out);
return out;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
type = VisitorUtils.visit(type, this, visitor);
VisitorUtils.visit(v, this, visitor);
}
}
/**
* LOCAL BLOCK STATEMENT k
*/
static class MLocalBlock extends BlockStatement implements LocalBlock {
public MLocalBlock(MVM vm) {
super(vm);
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
writeBlock(out, vm.getStyle("local-class"));
return out;
}
}
/**
* RETURN STATEMENT
*/
static class MReturn extends MExpressionableStatement implements Return {
MReturn(MVM vm) {
super(vm);
}
@Override
public MReturn setExpression(Expression e) {
super.setExpression(e);
return this;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("return");
if (e != null) {
out.space().write(e);
}
out.write(';');
appendTrailingComment(out);
return out;
}
}
/**
* SWITCH STATEMENT
*/
static class MSwitch extends MConditionalStatement implements Switch {
boolean triggered;
Default d;
MSwitch(MVM vm, Expression e) {
super(vm, e);
}
@Override
public List getCases() {
return ListTypeSelector.select(vs, Case.class);
}
@Override
public Default getDefault() {
if (d == null) {
d = new MDefault(vm);
}
return d;
}
@Override
public Case newCase(Expression constant) {
Case c = new MCase(vm, constant);
vs.add(c);
return c;
}
@Override
public CodeWriter toCode(CodeWriter out) {
if (!triggered) {
// add in the default if its not null
if (d != null) {
vs.add(d);
}
triggered = true;
}
super.toCode(out);
out.write("switch (").write(e).write(')');
writeBlock(out, vm.getStyle("switch"));
return out;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
d = VisitorUtils.visit(d, this, visitor);
}
}
/**
* SYNCHRONIZED STATEMENT
*/
static class MSynchronized extends BlockStatement implements Synchronized {
Expression mutex;
MSynchronized(MVM vm, Expression mutex) {
super(vm);
this.mutex = mutex;
}
@Override
public Expression getMutex() {
return mutex;
}
@Override
public MSynchronized setMutex(Expression mutex) {
this.mutex = mutex;
return this;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("synchronized ").write('(').write(mutex).write(')');
writeBlock(out, vm.getStyle("synchronized"));
return out;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
mutex = VisitorUtils.visit(mutex, this, visitor);
}
}
static class MConstructorForwarding extends MStatement implements ConstructorForwarding {
private final Constructor.ForwardingTarget target;
private final List arguments = new ArrayList<>();
private String qualifier;
MConstructorForwarding(MVM vm, Constructor.ForwardingTarget target) {
super(vm);
this.target = target;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
if (qualifier != null) {
out.write(qualifier).write('.');
}
if (target == Constructor.ForwardingTarget.THIS) {
out.write("this(");
} else if (target == Constructor.ForwardingTarget.SUPER){
out.write("super(");
}
String separator = "";
for (Expression argument : arguments) {
out.write(separator);
out.write(argument);
separator = ", ";
}
out.write(");");
appendTrailingComment(out);
return out;
}
@Override
public ConstructorForwarding addArg(boolean value) {
return addArg(value ? vm.newTrue() : vm.newFalse());
}
@Override
public ConstructorForwarding addArg(double value) {
return addArg(vm.newDouble(value));
}
@Override
public ConstructorForwarding addArg(Expression arg) {
arguments.add(arg);
return this;
}
@Override
public ConstructorForwarding addArg(float value) {
return addArg(vm.newFloat(value));
}
@Override
public ConstructorForwarding addArg(int value) {
return addArg(vm.newInt(value));
}
@Override
public ConstructorForwarding addArg(long value) {
return addArg(vm.newLong(value));
}
@Override
public ConstructorForwarding addArg(String value) {
return addArg(vm.newString(value));
}
@Override
public ConstructorForwarding addVariableArg(String variableName) {
return addArg(vm.newVar(variableName));
}
@Override
public List getArgs() {
return ListTypeSelector.select(arguments, Expression.class);
}
@Override
public void removeArg(int index) {
if (index < 0 || index >= arguments.size()) {
throw new IllegalArgumentException("Cannot remove argument with index " + index);
}
arguments.remove(index);
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
VisitorUtils.visit(arguments, this, visitor);
}
@Override
public Constructor.ForwardingTarget getTarget() {
return target;
}
@Override
public void setQualifier(String qualifier) {
this.qualifier = qualifier;
}
@Override
public Expression getQualifier() {
if (qualifier != null) {
return vm.newClassLiteral(qualifier);
} else {
return null;
}
}
}
/**
* THROW STATEMENT
*/
static class MThrow extends MStatement implements Throw {
Expression e;
MThrow(MVM vm, Expression e) {
super(vm);
this.e = e;
}
@Override
public Expression getThrowable() {
return e;
}
@Override
public MThrow setThrowable(Expression e) {
this.e = e;
return this;
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("throw ").write(e).write(';');
appendTrailingComment(out);
return out;
}
@Override
public void visit(ReplacingVisitor visitor) {
super.visit(visitor);
e = VisitorUtils.visit(e, this, visitor);
}
}
/**
* WHILE STATEMENT
*/
static class MWhile extends MConditionalStatement implements While {
public MWhile(MVM vm, Expression e) {
super(vm, e);
}
@Override
public CodeWriter toCode(CodeWriter out) {
super.toCode(out);
out.write("while (").write(e).write(')');
writeBlock(out, vm.getStyle("while"));
return out;
}
}
private String label;
MStatement(MVM vm) {
super(vm);
}
@Override
public Comment comment(String text) {
comment = new MComment.MSingleLineComment(vm, text);
return comment;
}
@Override
public String getLabel() {
return label;
}
@Override
public boolean isAbruptCompletionStatement() {
return this instanceof Return || //
this instanceof Break || //
this instanceof Throw || //
this instanceof Continue;
}
@Override
public MStatement setLabel(String label) {
this.label = label;
return this;
}
private List collectComments() {
final List collectedComments = new LinkedList<>();
visit(new ConditionalVisitor() {
@Override
public boolean visit(Codeable current, Codeable parent) {
if (current instanceof Expression) {
Expression expression = (Expression) current;
if (expression.getComment() != null) {
collectedComments.add(expression.getComment());
}
return true;
} else if (current instanceof MForInitLet) {
// special case where we need to traverse a stmt
MExpressionableStatement expression = (MExpressionableStatement) current;
if (expression.getComment() != null) {
collectedComments.add(expression.getComment());
}
return true;
} else {
return false;
}
}
});
return collectedComments;
}
@Override
public CodeWriter toCode(CodeWriter out) {
// always start a statement on a new line
out.ensureNewLine();
appendCommentsAndLabel(out);
return out;
}
void appendCommentsAndLabel(CodeWriter out) {
// write the comment of the statement
if (comment != null && comment.getType() != Comment.TRAILING) {
out.write(comment);
out.ensureNewLine();
}
// write the comment of inner expressions
List commentsFromInnerExpressions = collectComments();
for (Comment expressionComment : commentsFromInnerExpressions) {
if (expressionComment.getType() != Comment.TRAILING) {
out.write(expressionComment);
out.ensureNewLine();
}
}
// and the label, if there is one.
if (label != null) {
out.ensureNewLine();
out.write(label).write(':').space();
}
}
CodeWriter appendTrailingComment(CodeWriter out) {
if (comment != null && comment.getType() == Comment.TRAILING) {
out.write(comment);
}
List commentsFromInnerExpressions = collectComments();
for (Comment expressionComment : commentsFromInnerExpressions) {
if (expressionComment.getType() == Comment.TRAILING) {
out.write(expressionComment);
}
}
return out;
}
}