From 74112099527d643c5f2763a60ff359cfba71a196 Mon Sep 17 00:00:00 2001 From: tdurieux Date: Tue, 5 Jul 2016 10:44:27 +0200 Subject: [PATCH] feat(builder): WIP Builder proposal --- .../spoon/reflect/builder/AbsBuilder.java | 71 ++++++++ .../builder/BinaryOperatorBuilder.java | 156 ++++++++++++++++++ .../java/spoon/reflect/builder/Builder.java | 104 ++++++++++++ .../spoon/reflect/builder/CatchBuilder.java | 71 ++++++++ .../java/spoon/reflect/builder/IfBuilder.java | 89 ++++++++++ .../spoon/reflect/builder/LiteralBuilder.java | 27 +++ .../spoon/reflect/builder/MethodBuilder.java | 103 ++++++++++++ .../spoon/reflect/builder/TryBuilder.java | 84 ++++++++++ .../reflect/builder/UnaryOperatorBuilder.java | 37 +++++ .../java/spoon/reflect/factory/Factory.java | 3 + .../spoon/reflect/factory/FactoryImpl.java | 12 ++ .../reflect/builder/BinaryBuilderTest.java | 61 +++++++ .../reflect/builder/MethodBuilderTest.java | 47 ++++++ .../spoon/reflect/builder/TryBuilderTest.java | 54 ++++++ 14 files changed, 919 insertions(+) create mode 100644 src/main/java/spoon/reflect/builder/AbsBuilder.java create mode 100644 src/main/java/spoon/reflect/builder/BinaryOperatorBuilder.java create mode 100644 src/main/java/spoon/reflect/builder/Builder.java create mode 100644 src/main/java/spoon/reflect/builder/CatchBuilder.java create mode 100644 src/main/java/spoon/reflect/builder/IfBuilder.java create mode 100644 src/main/java/spoon/reflect/builder/LiteralBuilder.java create mode 100644 src/main/java/spoon/reflect/builder/MethodBuilder.java create mode 100644 src/main/java/spoon/reflect/builder/TryBuilder.java create mode 100644 src/main/java/spoon/reflect/builder/UnaryOperatorBuilder.java create mode 100644 src/test/java/spoon/reflect/builder/BinaryBuilderTest.java create mode 100644 src/test/java/spoon/reflect/builder/MethodBuilderTest.java create mode 100644 src/test/java/spoon/reflect/builder/TryBuilderTest.java diff --git a/src/main/java/spoon/reflect/builder/AbsBuilder.java b/src/main/java/spoon/reflect/builder/AbsBuilder.java new file mode 100644 index 00000000000..9d4bd81e005 --- /dev/null +++ b/src/main/java/spoon/reflect/builder/AbsBuilder.java @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.declaration.CtElement; +import spoon.reflect.factory.Factory; + +public abstract class AbsBuilder, P extends AbsBuilder> { + private final Factory factory; + private T element; + private P parent; + + protected AbsBuilder(Factory factory, T element) { + this.factory = factory; + this.element = element; + } + + protected T getElement() { + return element; + } + + protected void setElement(T element) { + this.element = element; + } + + protected Factory getFactory() { + return factory; + } + + protected P getParent() { + return parent; + } + + protected void setParent(P parent) { + this.parent = parent; + } + + public T build() { + return element; + } + + public P close() { + if (getParent() != null) { + getParent().end(this); + } + return getParent(); + } + + public void end(AbsBuilder child) { + + } + + @Override + public String toString() { + return build().toString(); + } +} diff --git a/src/main/java/spoon/reflect/builder/BinaryOperatorBuilder.java b/src/main/java/spoon/reflect/builder/BinaryOperatorBuilder.java new file mode 100644 index 00000000000..4bf944eeb9d --- /dev/null +++ b/src/main/java/spoon/reflect/builder/BinaryOperatorBuilder.java @@ -0,0 +1,156 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.BinaryOperatorKind; +import spoon.reflect.code.CtBinaryOperator; +import spoon.reflect.code.CtExpression; +import spoon.reflect.factory.Factory; + +public class BinaryOperatorBuilder

> extends + AbsBuilder, P> { + + public BinaryOperatorBuilder(Factory factory, CtExpression e) { + super(factory, factory.Core().createBinaryOperator()); + getElement().setLeftHandOperand(e); + } + + public BinaryOperatorBuilder greaterEquals(CtExpression e) { + addHand(e, BinaryOperatorKind.GE); + return this; + } + + public BinaryOperatorBuilder greaterEquals(AbsBuilder e) { + return greaterEquals(e.build()); + } + + public BinaryOperatorBuilder greater(CtExpression e) { + addHand(e, BinaryOperatorKind.GT); + return this; + } + + public BinaryOperatorBuilder greater(AbsBuilder e) { + return greater(e.build()); + } + + public BinaryOperatorBuilder lowerEquals(CtExpression e) { + addHand(e, BinaryOperatorKind.LE); + return this; + } + + public BinaryOperatorBuilder lowerEquals(AbsBuilder e) { + return lowerEquals(e.build()); + } + + public BinaryOperatorBuilder lower(CtExpression e) { + addHand(e, BinaryOperatorKind.LT); + return this; + } + + public BinaryOperatorBuilder lower(AbsBuilder e) { + return lower(e.build()); + } + + public BinaryOperatorBuilder division(CtExpression e) { + addHand(e, BinaryOperatorKind.DIV); + return this; + } + + public BinaryOperatorBuilder division(AbsBuilder e) { + return multiplication(e.build()); + } + + public BinaryOperatorBuilder multiplication(CtExpression e) { + addHand(e, BinaryOperatorKind.MUL); + return this; + } + + public BinaryOperatorBuilder multiplication(AbsBuilder e) { + return multiplication(e.build()); + } + + public BinaryOperatorBuilder different(CtExpression e) { + addHand(e, BinaryOperatorKind.NE); + return this; + } + + public BinaryOperatorBuilder different(AbsBuilder e) { + return different(e.build()); + } + + public BinaryOperatorBuilder equals(CtExpression e) { + addHand(e, BinaryOperatorKind.EQ); + return this; + } + + public BinaryOperatorBuilder equals(AbsBuilder e) { + return equals(e.build()); + } + + public BinaryOperatorBuilder minus(CtExpression e) { + addHand(e, BinaryOperatorKind.MINUS); + return this; + } + + public BinaryOperatorBuilder minus(AbsBuilder e) { + return minus(e.build()); + } + + public BinaryOperatorBuilder plus(CtExpression e) { + addHand(e, BinaryOperatorKind.PLUS); + return this; + } + + public BinaryOperatorBuilder plus(AbsBuilder e) { + return plus(e.build()); + } + + public BinaryOperatorBuilder and(CtExpression e) { + addHand(e, BinaryOperatorKind.AND); + return this; + } + + public BinaryOperatorBuilder and(AbsBuilder e) { + return and(e.build()); + } + + public BinaryOperatorBuilder or(CtExpression e) { + addHand(e, BinaryOperatorKind.AND); + return this; + } + + public BinaryOperatorBuilder or(AbsBuilder e) { + return or(e.build()); + } + + + private void addHand(CtExpression e, BinaryOperatorKind operator) { + if (getElement().getRightHandOperand() == null) { + getElement().setRightHandOperand(e); + } else { + CtBinaryOperator binaryOperator = getFactory().Core().createBinaryOperator(); + binaryOperator.setLeftHandOperand(getElement()); + binaryOperator.setRightHandOperand(e); + setElement(binaryOperator); + } + getElement().setKind(operator); + } + + public CtBinaryOperator build() { + return getElement(); + } +} diff --git a/src/main/java/spoon/reflect/builder/Builder.java b/src/main/java/spoon/reflect/builder/Builder.java new file mode 100644 index 00000000000..78af2756907 --- /dev/null +++ b/src/main/java/spoon/reflect/builder/Builder.java @@ -0,0 +1,104 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.CtExpression; +import spoon.reflect.code.UnaryOperatorKind; +import spoon.reflect.factory.Factory; + +public class Builder { + + private final Factory factory; + + public Builder(Factory factory) { + this.factory = factory; + } + + /*****************/ + /** If **/ + /*****************/ + public IfBuilder If(AbsBuilder e) { + return new IfBuilder<>(factory, e.build()); + } + + public IfBuilder If(CtExpression e) { + return new IfBuilder<>(factory, e); + } + + /*****************/ + /** Try **/ + /*****************/ + public TryBuilder Try() { + return new TryBuilder(factory); + } + + public CatchBuilder Catch() { + return new CatchBuilder(factory); + } + + /*****************/ + /** Method **/ + /*****************/ + public MethodBuilder Method(String name) { + return new MethodBuilder(factory, name); + } + + /*****************/ + /** Binary **/ + /*****************/ + public BinaryOperatorBuilder Binary(AbsBuilder e) { + return Binary(e.build()); + } + + public BinaryOperatorBuilder Binary(CtExpression e) { + return new BinaryOperatorBuilder(factory, e); + } + + /*****************/ + /** Unary **/ + /*****************/ + public UnaryOperatorBuilder Increment(CtExpression e) { + return new UnaryOperatorBuilder(factory, e, UnaryOperatorKind.POSTINC); + } + + public UnaryOperatorBuilder Increment(AbsBuilder e) { + return Increment(e.build()); + } + + public UnaryOperatorBuilder Decrement(CtExpression e) { + return new UnaryOperatorBuilder(factory, e, UnaryOperatorKind.POSTDEC); + } + + public UnaryOperatorBuilder Decrement(AbsBuilder e) { + return Decrement(e.build()); + } + + public UnaryOperatorBuilder Not(CtExpression e) { + return new UnaryOperatorBuilder(factory, e, UnaryOperatorKind.NOT); + } + + public UnaryOperatorBuilder Not(AbsBuilder e) { + return Not(e.build()); + } + + /*****************/ + /** Literal **/ + /*****************/ + public LiteralBuilder Literal(Object e) { + return new LiteralBuilder(factory, e); + } +} diff --git a/src/main/java/spoon/reflect/builder/CatchBuilder.java b/src/main/java/spoon/reflect/builder/CatchBuilder.java new file mode 100644 index 00000000000..43023deeff9 --- /dev/null +++ b/src/main/java/spoon/reflect/builder/CatchBuilder.java @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.CtCatch; +import spoon.reflect.code.CtStatement; +import spoon.reflect.declaration.CtElement; +import spoon.reflect.factory.Factory; +import spoon.reflect.reference.CtIntersectionTypeReference; +import spoon.reflect.reference.CtTypeReference; + +public class CatchBuilder

> extends + AbsBuilder, P> { + + public CatchBuilder(Factory factory) { + super(factory, factory.Core().createCatch()); + getElement().setBody(getFactory().Core().createBlock()); + } + + public CatchBuilder

parameter(String variableName, Class...clazz) { + CtTypeReference ref; + if (clazz.length == 1) { + ref = getFactory().Code().createCtTypeReference(clazz[0]); + } else if (clazz.length > 1) { + CtIntersectionTypeReference interRef = getFactory().Core().createIntersectionTypeReference(); + for (int i = 0; i < clazz.length; i++) { + Class aClass = clazz[i]; + interRef.addBound(getFactory().Code().createCtTypeReference(aClass)); + } + ref = interRef; + } else { + throw new IllegalArgumentException("No specified type"); + } + getElement().setParameter(getFactory().Code().createCatchVariable( + ref, + variableName)); + return this; + } + + public CatchBuilder

inBody(CtStatement... statements) { + if (statements.length == 1) { + getElement().getBody().addStatement(statements[0]); + return this; + } + for (int i = 0; i < statements.length; i++) { + inBody(statements[i]); + } + return this; + } + + public CatchBuilder

inBody(AbsBuilder... statements) { + for (int i = 0; i < statements.length; i++) { + inBody(statements[i].build()); + } + return this; + } +} diff --git a/src/main/java/spoon/reflect/builder/IfBuilder.java b/src/main/java/spoon/reflect/builder/IfBuilder.java new file mode 100644 index 00000000000..4c32c7ec7bd --- /dev/null +++ b/src/main/java/spoon/reflect/builder/IfBuilder.java @@ -0,0 +1,89 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.CtBlock; +import spoon.reflect.code.CtExpression; +import spoon.reflect.code.CtIf; +import spoon.reflect.code.CtStatement; +import spoon.reflect.factory.Factory; + +public class IfBuilder

> extends + AbsBuilder, P> { + + public IfBuilder(Factory factory, CtExpression e) { + super(factory, factory.Core().createIf()); + getElement().setCondition(e); + } + + public IfBuilder

inThen(CtStatement ... statements) { + for (int i = 0; i < statements.length; i++) { + CtStatement statement = statements[i]; + inThen(statement); + } + return this; + } + + public IfBuilder

inThen(AbsBuilder... statements) { + for (int i = 0; i < statements.length; i++) { + inThen(statements[i]); + } + return this; + } + + public IfBuilder

inThen(CtStatement s) { + if (getElement().getThenStatement() == null) { + getElement().setThenStatement(getFactory().Core().createBlock()); + } + ((CtBlock) getElement().getThenStatement()).addStatement(s); + return this; + } + + + public IfBuilder

inThen(AbsBuilder b) { + return inThen(b.build()); + } + + + public IfBuilder

inElse(CtStatement ... statements) { + for (int i = 0; i < statements.length; i++) { + CtStatement statement = statements[i]; + inElse(statement); + } + return this; + } + + public IfBuilder

inElse(AbsBuilder... statements) { + for (int i = 0; i < statements.length; i++) { + inElse(statements[i]); + } + return this; + } + + public IfBuilder

inElse(CtStatement s) { + if (getElement().getElseStatement() == null) { + getElement().setElseStatement(getFactory().Core().createBlock()); + } + ((CtBlock) getElement().getElseStatement()).addStatement(s); + return this; + } + + + public IfBuilder

inElse(AbsBuilder b) { + return inElse(b.build()); + } +} diff --git a/src/main/java/spoon/reflect/builder/LiteralBuilder.java b/src/main/java/spoon/reflect/builder/LiteralBuilder.java new file mode 100644 index 00000000000..d576fdb9f1d --- /dev/null +++ b/src/main/java/spoon/reflect/builder/LiteralBuilder.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.CtLiteral; +import spoon.reflect.factory.Factory; + +public class LiteralBuilder

> extends AbsBuilder, P> { + + public LiteralBuilder(Factory factory, Object value) { + super(factory, factory.Code().createLiteral(value)); + } +} diff --git a/src/main/java/spoon/reflect/builder/MethodBuilder.java b/src/main/java/spoon/reflect/builder/MethodBuilder.java new file mode 100644 index 00000000000..97bd899a2ca --- /dev/null +++ b/src/main/java/spoon/reflect/builder/MethodBuilder.java @@ -0,0 +1,103 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.CtStatement; +import spoon.reflect.declaration.CtMethod; +import spoon.reflect.declaration.CtParameter; +import spoon.reflect.declaration.ModifierKind; +import spoon.reflect.factory.Factory; +import spoon.reflect.reference.CtTypeReference; + +public class MethodBuilder

> extends + AbsBuilder, P> { + + public MethodBuilder(Factory factory, String name) { + super(factory, factory.Core().createMethod()); + getElement().setBody(factory.Core().createBlock()); + getElement().setSimpleName(name); + setPrivate(); + type(getFactory().Type().VOID_PRIMITIVE); + } + + public MethodBuilder

type(CtTypeReference ref) { + getElement().setType(ref); + return this; + } + + public MethodBuilder

type(Class clazz) { + getElement().setType(getFactory().Code().createCtTypeReference(clazz)); + return this; + } + + public MethodBuilder

setPublic() { + getElement().addModifier(ModifierKind.PUBLIC); + + getElement().removeModifier(ModifierKind.PRIVATE); + getElement().removeModifier(ModifierKind.PROTECTED); + return this; + } + + public MethodBuilder

setPrivate() { + getElement().addModifier(ModifierKind.PRIVATE); + + getElement().removeModifier(ModifierKind.PUBLIC); + getElement().removeModifier(ModifierKind.PROTECTED); + return this; + } + + public MethodBuilder

setProtected() { + getElement().addModifier(ModifierKind.PROTECTED); + + getElement().removeModifier(ModifierKind.PRIVATE); + getElement().removeModifier(ModifierKind.PUBLIC); + return this; + } + + public MethodBuilder

setAbstract() { + getElement().addModifier(ModifierKind.ABSTRACT); + getElement().setBody(null); + return this; + } + + public MethodBuilder

setStatic() { + getElement().addModifier(ModifierKind.STATIC); + return this; + } + + public MethodBuilder

setFinal() { + getElement().addModifier(ModifierKind.FINAL); + return this; + } + + public MethodBuilder

addParam(Class clazz, String name) { + CtParameter parameter = getFactory().Core().createParameter(); + parameter.setType(getFactory().Code().createCtTypeReference(clazz)); + parameter.setSimpleName(name); + getElement().addParameter(parameter); + return this; + } + + public MethodBuilder

inBody(AbsBuilder e) { + return inBody(e.build()); + } + + public MethodBuilder

inBody(CtStatement e) { + getElement().getBody().addStatement(e); + return this; + } +} diff --git a/src/main/java/spoon/reflect/builder/TryBuilder.java b/src/main/java/spoon/reflect/builder/TryBuilder.java new file mode 100644 index 00000000000..96742885362 --- /dev/null +++ b/src/main/java/spoon/reflect/builder/TryBuilder.java @@ -0,0 +1,84 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.CtCatch; +import spoon.reflect.code.CtStatement; +import spoon.reflect.code.CtTry; +import spoon.reflect.factory.Factory; + +public class TryBuilder

> extends + AbsBuilder, P> { + + public TryBuilder(Factory factory) { + super(factory, factory.Core().createTry()); + getElement().setBody(getFactory().Core().createBlock()); + } + + public TryBuilder

inBody(CtStatement... statements) { + if (statements.length == 1) { + getElement().getBody().addStatement(statements[0]); + return this; + } + for (int i = 0; i < statements.length; i++) { + inBody(statements[i]); + } + return this; + } + + public TryBuilder

inBody(AbsBuilder... statements) { + for (int i = 0; i < statements.length; i++) { + inBody(statements[i].build()); + } + return this; + } + + public TryBuilder

inFinally(CtStatement... statements) { + if (statements.length == 1) { + if (getElement().getFinalizer() == null) { + getElement().setFinalizer(getFactory().Core().createBlock()); + } + getElement().getFinalizer().addStatement(statements[0]); + return this; + } + for (int i = 0; i < statements.length; i++) { + inFinally(statements[i]); + } + return this; + } + + public TryBuilder

inFinally(AbsBuilder... statements) { + for (int i = 0; i < statements.length; i++) { + inFinally(statements[i].build()); + } + return this; + } + + public CatchBuilder> createCatch() { + CatchBuilder> aCatch = new CatchBuilder<>(getFactory()); + aCatch.setParent(this); + return aCatch; + } + + + @Override + public void end(AbsBuilder child) { + if (child instanceof CatchBuilder) { + getElement().addCatcher((CtCatch) child.build()); + } + } +} diff --git a/src/main/java/spoon/reflect/builder/UnaryOperatorBuilder.java b/src/main/java/spoon/reflect/builder/UnaryOperatorBuilder.java new file mode 100644 index 00000000000..ec4409bec8a --- /dev/null +++ b/src/main/java/spoon/reflect/builder/UnaryOperatorBuilder.java @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import spoon.reflect.code.CtExpression; +import spoon.reflect.code.CtUnaryOperator; +import spoon.reflect.code.UnaryOperatorKind; +import spoon.reflect.factory.Factory; + +public class UnaryOperatorBuilder

> extends + AbsBuilder, P> { + + public UnaryOperatorBuilder(Factory factory, CtExpression e, UnaryOperatorKind operator) { + super(factory, factory.Core().createUnaryOperator()); + getElement().setOperand(e); + getElement().setKind(operator); + } + + @Override + public CtUnaryOperator build() { + return super.build(); + } +} diff --git a/src/main/java/spoon/reflect/factory/Factory.java b/src/main/java/spoon/reflect/factory/Factory.java index 5cb9b764e43..90a19d53c93 100644 --- a/src/main/java/spoon/reflect/factory/Factory.java +++ b/src/main/java/spoon/reflect/factory/Factory.java @@ -18,6 +18,7 @@ import spoon.compiler.Environment; import spoon.reflect.CtModel; +import spoon.reflect.builder.Builder; /** * Provides the sub-factories required by Spoon. @@ -62,4 +63,6 @@ public interface Factory { ConstructorFactory Constructor(); // used 3 times InternalFactory Internal(); + + Builder Builder(); } diff --git a/src/main/java/spoon/reflect/factory/FactoryImpl.java b/src/main/java/spoon/reflect/factory/FactoryImpl.java index 34d91a8730a..103a8335c4b 100644 --- a/src/main/java/spoon/reflect/factory/FactoryImpl.java +++ b/src/main/java/spoon/reflect/factory/FactoryImpl.java @@ -19,6 +19,7 @@ import spoon.compiler.Environment; import spoon.reflect.CtModel; import spoon.reflect.CtModelImpl; +import spoon.reflect.builder.Builder; import spoon.reflect.cu.CompilationUnit; import spoon.reflect.declaration.CtAnnotationType; import spoon.reflect.declaration.CtClass; @@ -266,6 +267,16 @@ public InternalFactory Internal() { return internal; } + private transient Builder builder; + + @Override + public Builder Builder() { + if (internal == null) { + builder = new Builder(this); + } + return builder; + } + /** * A constructor that takes the parent factory */ @@ -325,6 +336,7 @@ public String dedup(String symbol) { private final CtModel model = new CtModelImpl(this); + @Override public CtModel getModel() { return model; diff --git a/src/test/java/spoon/reflect/builder/BinaryBuilderTest.java b/src/test/java/spoon/reflect/builder/BinaryBuilderTest.java new file mode 100644 index 00000000000..9cd015a88e9 --- /dev/null +++ b/src/test/java/spoon/reflect/builder/BinaryBuilderTest.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import org.junit.Assert; +import org.junit.Test; +import spoon.Launcher; +import spoon.reflect.code.CtBinaryOperator; +import spoon.reflect.code.CtUnaryOperator; +import spoon.reflect.factory.Factory; + +public class BinaryBuilderTest { + + @Test + public void multiBuilderTest() { + Factory factory = new Launcher().getFactory(); + Builder B = factory.Builder(); + CtUnaryOperator not = B.Not(B.Binary(B.Literal(2)).lower(B.Literal(1))).build(); + Assert.assertEquals("!(2 < 1)", not.toString()); + } + + @Test + public void simpleBinaryTest() { + Factory factory = new Launcher().getFactory(); + Builder B = factory.Builder(); + CtBinaryOperator binary = B.Binary( + B.Literal(2)) + .multiplication(B.Literal(1)) + .equals(B.Literal(2)) + .build(); + Assert.assertEquals("(2 * 1) == 2", binary.toString()); + } + + @Test + public void multiBinaryTest() { + Factory factory = new Launcher().getFactory(); + Builder B = factory.Builder(); + CtBinaryOperator binary = B.Binary( + B.Literal(2)) + .plus(B.Literal(1)) + .lower( + B.Binary(B.Literal(10)) + .minus(B.Literal(5)) + ).build(); + Assert.assertEquals("(2 + 1) < (10 - 5)", binary.toString()); + } +} \ No newline at end of file diff --git a/src/test/java/spoon/reflect/builder/MethodBuilderTest.java b/src/test/java/spoon/reflect/builder/MethodBuilderTest.java new file mode 100644 index 00000000000..99d8e809cd5 --- /dev/null +++ b/src/test/java/spoon/reflect/builder/MethodBuilderTest.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import org.junit.Assert; +import org.junit.Test; +import spoon.Launcher; +import spoon.reflect.code.CtReturn; +import spoon.reflect.declaration.CtMethod; +import spoon.reflect.factory.Factory; + +public class MethodBuilderTest { + + @Test + public void test() { + Factory factory = new Launcher().getFactory(); + Builder x = factory.Builder(); + + CtReturn aReturn = factory.Core().createReturn(); + aReturn.setReturnedExpression(x.Literal(1).build()); + CtMethod m = x.Method("m") + .type(int.class) + .setPrivate() + .setStatic() + .addParam(int.class, "x") + .inBody(aReturn).build(); + Assert.assertEquals("private static int m(int x) {\n" + + " return 1;\n" + + "}", m.toString()); + + } + +} \ No newline at end of file diff --git a/src/test/java/spoon/reflect/builder/TryBuilderTest.java b/src/test/java/spoon/reflect/builder/TryBuilderTest.java new file mode 100644 index 00000000000..96435a01c57 --- /dev/null +++ b/src/test/java/spoon/reflect/builder/TryBuilderTest.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * 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 CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package spoon.reflect.builder; + +import org.junit.Assert; +import org.junit.Test; +import spoon.Launcher; +import spoon.reflect.code.CtTry; +import spoon.reflect.factory.Factory; + +public class TryBuilderTest { + + @Test + public void test() { + Factory factory = new Launcher().getFactory(); + Builder x = factory.Builder(); + +CtTry aTry = x.Try() + .inBody(x.Increment(x.Literal(1))) + .createCatch() + .parameter("e", IllegalArgumentException.class) + .inBody(x.Increment(x.Literal(1))) + .close() + .createCatch() + .parameter("e", Exception.class) + .close() + .inFinally(x.Decrement(x.Literal(1))) +.build(); +Assert.assertEquals("try {\n" + + " 1++;\n" + + "} catch (java.lang.IllegalArgumentException e) {\n" + + " 1++;\n" + + "} catch (java.lang.Exception e) {\n" + + "} finally {\n" + + " 1--;\n" + + "}", aTry.toString()); + + } + +} \ No newline at end of file