Skip to content

Commit

Permalink
feature(model): add interface CtBodyHolder (#943)
Browse files Browse the repository at this point in the history
  • Loading branch information
pvojtechovsky authored and monperrus committed Nov 16, 2016
1 parent df8b0ca commit b4fbe3e
Show file tree
Hide file tree
Showing 19 changed files with 318 additions and 61 deletions.
36 changes: 36 additions & 0 deletions src/main/java/spoon/reflect/code/CtBodyHolder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (C) 2006-2016 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.code;

import spoon.reflect.declaration.CtElement;

/**
* This abstract code element defines an element, which contains a body
*/
public interface CtBodyHolder extends CtElement {

/**
* Gets the body of this element
*/
CtStatement getBody();

/**
* Sets the body of this element.
* If body is not a block, it is wrapped in a CtBlock which is semantically equivalent and eases transformation afterwards if required.
*/
<T extends CtBodyHolder> T setBody(CtStatement body);
}
8 changes: 2 additions & 6 deletions src/main/java/spoon/reflect/code/CtCatch.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*
* @see spoon.reflect.code.CtTry
*/
public interface CtCatch extends CtCodeElement {
public interface CtCatch extends CtCodeElement, CtBodyHolder {

/**
* Gets the catch's parameter (a throwable).
Expand All @@ -36,13 +36,9 @@ public interface CtCatch extends CtCodeElement {
/**
* Gets the catch's body.
*/
@Override
CtBlock<?> getBody();

/**
* Sets the catch's body.
*/
<T extends CtCatch> T setBody(CtBlock<?> body);

@Override
CtCatch clone();
}
8 changes: 2 additions & 6 deletions src/main/java/spoon/reflect/code/CtLoop.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,14 @@
/**
* This abstract code element defines a loop.
*/
public interface CtLoop extends CtStatement, TemplateParameter<Void> {
public interface CtLoop extends CtStatement, TemplateParameter<Void>, CtBodyHolder {

/**
* Gets the body of this loop.
*/
@Override
CtStatement getBody();

/**
* Sets the body of this loop.
*/
<T extends CtLoop> T setBody(CtStatement body);

@Override
CtLoop clone();
}
10 changes: 3 additions & 7 deletions src/main/java/spoon/reflect/code/CtTry.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* } catch (Exception ignore) {}
* </pre>
*/
public interface CtTry extends CtStatement, TemplateParameter<Void> {
public interface CtTry extends CtStatement, TemplateParameter<Void>, CtBodyHolder {

/**
* Gets the <i>catchers</i> of this <code>try</code>.
Expand All @@ -53,15 +53,11 @@ public interface CtTry extends CtStatement, TemplateParameter<Void> {
boolean removeCatcher(CtCatch catcher);

/**
* Sets the tried body.
* Gets the try body.
*/
@Override
CtBlock<?> getBody();

/**
* Sets the tried body.
*/
<T extends CtTry> T setBody(CtBlock<?> body);

/**
* Gets the <i>finalizer</i> block of this <code>try</code> (
* <code>finally</code> part).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
*/
package spoon.reflect.declaration;

import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtStatement;
import spoon.reflect.reference.CtTypeReference;
import spoon.support.UnsettableProperty;

Expand All @@ -43,7 +44,7 @@ public interface CtAnnotationMethod<T> extends CtMethod<T> {

@Override
@UnsettableProperty
<B extends T, T1 extends CtExecutable<T>> T1 setBody(CtBlock<B> body);
<T1 extends CtBodyHolder> T1 setBody(CtStatement body);

@Override
@UnsettableProperty
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/spoon/reflect/declaration/CtExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package spoon.reflect.declaration;

import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.support.DerivedProperty;
Expand All @@ -28,7 +29,7 @@
* This element represents an executable element such as a method, a
* constructor, or an anonymous block.
*/
public interface CtExecutable<R> extends CtNamedElement, CtTypedElement<R> {
public interface CtExecutable<R> extends CtNamedElement, CtTypedElement<R>, CtBodyHolder {

/**
* The separator for a string representation of an executable.
Expand All @@ -46,12 +47,8 @@ public interface CtExecutable<R> extends CtNamedElement, CtTypedElement<R> {
/**
* Gets the body expression.
*/
<B extends R> CtBlock<B> getBody();

/**
* Sets the body expression.
*/
<B extends R, T extends CtExecutable<R>> T setBody(CtBlock<B> body);
@Override
CtBlock<R> getBody();

/**
* Gets the parameters list.
Expand Down
19 changes: 19 additions & 0 deletions src/main/java/spoon/reflect/factory/CodeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,25 @@ public <T extends CtStatement> CtBlock<?> createCtBlock(T element) {
return factory.Core().createBlock().addStatement(element);
}

/**
* Accepts instance of CtStatement or CtBlock.
* If element is CtStatement, then it creates wrapping CtBlock, which contains the element
* If element is CtBlock, then it directly returns that element
* If element is null, then it returns null.
* note: It must not create empty CtBlock - as expected in CtCatch, CtExecutable, CtLoop and CtTry setBody implementations
* @param element
* @return CtBlock instance
*/
public <T extends CtStatement> CtBlock<?> getOrCreateCtBlock(T element) {
if (element == null) {
return null;
}
if (element instanceof CtBlock<?>) {
return (CtBlock<?>) element;
}
return this.createCtBlock(element);
}

/**
* Creates a throw.
*
Expand Down
15 changes: 3 additions & 12 deletions src/main/java/spoon/support/compiler/jdt/JDTCommentBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,21 @@
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
import spoon.reflect.code.CtBinaryOperator;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.code.CtCase;
import spoon.reflect.code.CtCatch;
import spoon.reflect.code.CtComment;
import spoon.reflect.code.CtConditional;
import spoon.reflect.code.CtIf;
import spoon.reflect.code.CtLoop;
import spoon.reflect.code.CtNewArray;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtStatementList;
import spoon.reflect.code.CtSwitch;
import spoon.reflect.code.CtTry;
import spoon.reflect.cu.CompilationUnit;
import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.CtAnonymousExecutable;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtConstructor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.CtMethod;
Expand Down Expand Up @@ -436,14 +433,8 @@ public void scan(CtElement element) {
* @return body of element or null if this element has no body
*/
static CtElement getBody(CtElement e) {
if (e instanceof CtLoop) {
return ((CtLoop) e).getBody();
} else if (e instanceof CtExecutable) {
return ((CtExecutable<?>) e).getBody();
} else if (e instanceof CtTry) {
return ((CtTry) e).getBody();
} else if (e instanceof CtCatch) {
return ((CtCatch) e).getBody();
if (e instanceof CtBodyHolder) {
return ((CtBodyHolder) e).getBody();
}
return null;
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/spoon/support/reflect/code/CtCatchImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package spoon.support.reflect.code;

import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.code.CtCatch;
import spoon.reflect.code.CtCatchVariable;
import spoon.reflect.code.CtStatement;
import spoon.reflect.visitor.CtVisitor;

public class CtCatchImpl extends CtCodeElementImpl implements CtCatch {
Expand All @@ -44,7 +46,8 @@ public CtCatchVariable<? extends Throwable> getParameter() {
}

@Override
public <T extends CtCatch> T setBody(CtBlock<?> body) {
public <T extends CtBodyHolder> T setBody(CtStatement statement) {
CtBlock<?> body = getFactory().Code().getOrCreateCtBlock(statement);
if (body != null) {
body.setParent(this);
}
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/spoon/support/reflect/code/CtLambdaImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@

import spoon.SpoonException;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtLambda;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtNamedElement;
import spoon.reflect.declaration.CtParameter;
Expand Down Expand Up @@ -60,12 +62,13 @@ public <C extends CtNamedElement> C setSimpleName(String simpleName) {

@Override
@SuppressWarnings("unchecked")
public <B extends T> CtBlock<B> getBody() {
return (CtBlock<B>) body;
public CtBlock<T> getBody() {
return (CtBlock<T>) body;
}

@Override
public <B extends T, C extends CtExecutable<T>> C setBody(CtBlock<B> body) {
public <C extends CtBodyHolder> C setBody(CtStatement statement) {
CtBlock<?> body = getFactory().Code().getOrCreateCtBlock(statement);
if (expression != null && body != null) {
throw new SpoonException("A lambda can't have two bodys.");
}
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/spoon/support/reflect/code/CtLoopImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package spoon.support.reflect.code;

import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.code.CtCodeElement;
import spoon.reflect.code.CtLoop;
import spoon.reflect.code.CtStatement;
Expand All @@ -31,8 +33,10 @@ public CtStatement getBody() {
return body;
}

@SuppressWarnings("unchecked")
@Override
public <T extends CtLoop> T setBody(CtStatement body) {
public <T extends CtBodyHolder> T setBody(CtStatement statement) {
CtBlock<?> body = getFactory().Code().getOrCreateCtBlock(statement);
if (body != null) {
body.setParent(this);
}
Expand Down
5 changes: 4 additions & 1 deletion src/main/java/spoon/support/reflect/code/CtTryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package spoon.support.reflect.code;

import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.code.CtCatch;
import spoon.reflect.code.CtCodeElement;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtTry;
import spoon.reflect.declaration.CtType;
import spoon.reflect.visitor.CtVisitor;
Expand Down Expand Up @@ -99,7 +101,8 @@ public CtBlock<?> getBody() {
}

@Override
public <T extends CtTry> T setBody(CtBlock<?> body) {
public <T extends CtBodyHolder> T setBody(CtStatement statement) {
CtBlock<?> body = getFactory().Code().getOrCreateCtBlock(statement);
if (body != null) {
body.setParent(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.Set;

import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBodyHolder;
import spoon.reflect.code.CtStatement;
import spoon.reflect.declaration.CtExecutable;
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.reference.CtExecutableReference;
Expand Down Expand Up @@ -50,12 +52,13 @@ public CtExecutableImpl() {

@Override
@SuppressWarnings("unchecked")
public <B extends R> CtBlock<B> getBody() {
return (CtBlock<B>) body;
public CtBlock<R> getBody() {
return (CtBlock<R>) body;
}

@Override
public <B extends R, T extends CtExecutable<R>> T setBody(CtBlock<B> body) {
public <T extends CtBodyHolder> T setBody(CtStatement statement) {
CtBlock<?> body = getFactory().Code().getOrCreateCtBlock(statement);
if (body != null) {
body.setParent(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,9 @@ public <A extends java.lang.annotation.Annotation> void visitCtAnnotationType(fi

// auto-generated, see spoon.generating.ReplacementVisitorGenerator
class CtExecutableBodyReplaceListener implements spoon.generating.replace.ReplaceListener<spoon.reflect.code.CtBlock> {
private final spoon.reflect.declaration.CtExecutable element;
private final spoon.reflect.code.CtBodyHolder element;

CtExecutableBodyReplaceListener(spoon.reflect.declaration.CtExecutable element) {
CtExecutableBodyReplaceListener(spoon.reflect.code.CtBodyHolder element) {
this.element = element;
}

Expand Down Expand Up @@ -535,9 +535,9 @@ public void set(spoon.reflect.code.CtCatchVariable replace) {

// auto-generated, see spoon.generating.ReplacementVisitorGenerator
class CtCatchBodyReplaceListener implements spoon.generating.replace.ReplaceListener<spoon.reflect.code.CtBlock> {
private final spoon.reflect.code.CtCatch element;
private final spoon.reflect.code.CtBodyHolder element;

CtCatchBodyReplaceListener(spoon.reflect.code.CtCatch element) {
CtCatchBodyReplaceListener(spoon.reflect.code.CtBodyHolder element) {
this.element = element;
}

Expand Down Expand Up @@ -747,9 +747,9 @@ public void set(spoon.reflect.code.CtExpression replace) {

// auto-generated, see spoon.generating.ReplacementVisitorGenerator
class CtLoopBodyReplaceListener implements spoon.generating.replace.ReplaceListener<spoon.reflect.code.CtStatement> {
private final spoon.reflect.code.CtLoop element;
private final spoon.reflect.code.CtBodyHolder element;

CtLoopBodyReplaceListener(spoon.reflect.code.CtLoop element) {
CtLoopBodyReplaceListener(spoon.reflect.code.CtBodyHolder element) {
this.element = element;
}

Expand Down Expand Up @@ -1571,9 +1571,9 @@ public void visitCtThrow(final spoon.reflect.code.CtThrow throwStatement) {

// auto-generated, see spoon.generating.ReplacementVisitorGenerator
class CtTryBodyReplaceListener implements spoon.generating.replace.ReplaceListener<spoon.reflect.code.CtBlock> {
private final spoon.reflect.code.CtTry element;
private final spoon.reflect.code.CtBodyHolder element;

CtTryBodyReplaceListener(spoon.reflect.code.CtTry element) {
CtTryBodyReplaceListener(spoon.reflect.code.CtBodyHolder element) {
this.element = element;
}

Expand Down
Loading

0 comments on commit b4fbe3e

Please sign in to comment.