Skip to content

Commit

Permalink
Merge branch 'master' into issue/12
Browse files Browse the repository at this point in the history
  • Loading branch information
skapral authored Aug 26, 2017
2 parents aa6b6bf + 358a30d commit 3f19421
Show file tree
Hide file tree
Showing 26 changed files with 455 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@
*/
package oo.atom.codegen.bytebuddy.bt;

import oo.atom.codegen.validator.ValAtomAlias;

/**
*
* @author Kapralov Sergey
*/
public class BtApplyAtomAliasPatch extends BtSequence {
public class BtApplyAtomAliasPatch extends BtValidated {
public BtApplyAtomAliasPatch() {
super(
new ValAtomAlias(),
new BtAnnotate()
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,21 @@
*/
package oo.atom.codegen.bytebuddy.bt;

import oo.atom.codegen.validator.ValAtom;

/**
*
* @author Kapralov Sergey
*/
public class BtApplyAtomPatch extends BtSequence {
public class BtApplyAtomPatch extends BtValidated {
public BtApplyAtomPatch() {
super(
new BtAnnotate(),
new BtGenerateEquals(),
new BtGenerateHashCode()
new ValAtom(),
new BtSequence(
new BtAnnotate(),
new BtGenerateEquals(),
new BtGenerateHashCode()
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package oo.atom.codegen.bytebuddy.matchers;
package oo.atom.codegen.bytebuddy.bt;

import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
Expand All @@ -30,11 +30,12 @@
*
* @author Kapralov Sergey
*/
public class IsAtomAlias extends ConjunctionMatcher<TypeDescription> implements ElementMatcher<TypeDescription> {
public IsAtomAlias() {
public class BtApplyIfMatches extends BtConditional implements BuilderTransition {
public BtApplyIfMatches(ElementMatcher<TypeDescription> matcher, BuilderTransition bt) {
super(
new IsInheritedFromAtom(),
new FollowsAtomAliasSpecification()
matcher,
bt,
new BtNop()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,36 +24,31 @@
package oo.atom.codegen.bytebuddy.bt;

import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType.Builder;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.matcher.ElementMatcher;
import oo.atom.codegen.bytebuddy.matchers.IsAtom;
import oo.atom.r.RFailure;
import oo.atom.r.Result;
import oo.atom.r.ResultTransition;

/**
*
* @author Kapralov Sergey
*/
public class BtDoIfClassIsAtom implements ResultTransition<Builder<?>, Builder<?>> {
private static final ElementMatcher<TypeDescription> IS_ATOM = new IsAtom();

private final TypeDescription type;
private final ResultTransition<Builder<?>, Builder<?>> task;
public class BtConditional implements BuilderTransition {
private final ElementMatcher<TypeDescription> matcher;
private final BuilderTransition matchBranch;
private final BuilderTransition mismatchBranch;

public BtDoIfClassIsAtom(TypeDescription type, ResultTransition<Builder<?>, Builder<?>> task) {
this.type = type;
this.task = task;
public BtConditional(ElementMatcher<TypeDescription> matcher, BuilderTransition matchBranch, BuilderTransition mismatchBranch) {
this.matcher = matcher;
this.matchBranch = matchBranch;
this.mismatchBranch = mismatchBranch;
}

@Override
public final Result<Builder<?>> transitionResult(Builder<?> source) {
if(IS_ATOM.matches(type)) {
return task.transitionResult(source);
public final Result<DynamicType.Builder<?>> transitionResult(DynamicType.Builder<?> source, TypeDescription typeDescription) {
if(matcher.matches(typeDescription)) {
return matchBranch.transitionResult(source, typeDescription);
} else {
return new RFailure(
String.format("%s is not atom", type.getName())
);
return mismatchBranch.transitionResult(source, typeDescription);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package oo.atom.codegen.bytebuddy.matchers;
package oo.atom.codegen.bytebuddy.bt;

import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.dynamic.DynamicType;
import oo.atom.r.RSuccess;
import oo.atom.r.Result;

/**
*
* @author Kapralov Sergey
*/
public class IsInheritedFromAtom implements ElementMatcher<TypeDescription> {
private static final ElementMatcher<TypeDescription> IS_ATOM = new IsAtom();

public class BtNop implements BuilderTransition {
@Override
public final boolean matches(TypeDescription t) {
TypeDescription superClass = t.getSuperClass().asErasure();
return IS_ATOM.matches(superClass);
public final Result<DynamicType.Builder<?>> transitionResult(DynamicType.Builder<?> source, TypeDescription typeDescription) {
return new RSuccess<>(source);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public BtSequence(BuilderTransition... transitions) {
}

@Override
public Result<Builder<?>> transitionResult(Builder<?> source, TypeDescription typeDescription) {
public final Result<Builder<?>> transitionResult(Builder<?> source, TypeDescription typeDescription) {
return transitions.<Result<Builder<?>>>foldLeft(
new RSuccess<>(source),
(state, transition) -> new RBind<>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,34 @@
*/
package oo.atom.codegen.bytebuddy.bt;

import io.vavr.collection.List;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType.Builder;
import net.bytebuddy.matcher.ElementMatcher;
import oo.atom.codegen.bytebuddy.matchers.IsAtom;
import oo.atom.codegen.bytebuddy.matchers.IsAtomAlias;
import net.bytebuddy.dynamic.DynamicType;
import oo.atom.codegen.validator.Validator;
import oo.atom.r.RFailure;
import oo.atom.r.Result;

/**
*
* @author Kapralov Sergey
*/
public class BtApplyPatch implements BuilderTransition {
private final static ElementMatcher<TypeDescription> IS_ATOM = new IsAtom();
private final static ElementMatcher<TypeDescription> IS_ATOM_ALIAS = new IsAtomAlias();
public class BtValidated implements BuilderTransition {
private final Validator validator;
private final BuilderTransition delegate;

public BtValidated(Validator validator, BuilderTransition delegate) {
this.validator = validator;
this.delegate = delegate;
}

@Override
public Result<Builder<?>> transitionResult(Builder<?> source, TypeDescription type) {
if (IS_ATOM_ALIAS.matches(type)) {
return new BtApplyAtomAliasPatch().transitionResult(source, type);
} else if (IS_ATOM.matches(type)) {
return new BtApplyAtomPatch().transitionResult(source, type);
public final Result<DynamicType.Builder<?>> transitionResult(DynamicType.Builder<?> source, TypeDescription typeDescription) {
final Result<TypeDescription> validateResult = validator.transitionResult(typeDescription);
final List<String> issues = validateResult.issues();
if(issues.isEmpty()) {
return delegate.transitionResult(source, typeDescription);
} else {
return new BtFail(
// @todo #1 put more information the logs, about the cause of
// the patch failure
String.format("%s is not atom", type.getName())
).transitionResult(source, type);
return new RFailure<>(issues);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*
* @author Kapralov Sergey
*/
public class AnnotatedWithNotAtom implements ElementMatcher<TypeDescription> {
public class AnnotatedNonAtom implements ElementMatcher<TypeDescription> {
@Override
public final boolean matches(TypeDescription target) {
return hasAnnotation(annotationType(NotAtom.class)).matches(target);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,28 @@
*/
package oo.atom.codegen.bytebuddy.matchers;

import io.vavr.control.Option;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import static net.bytebuddy.matcher.ElementMatchers.*;

/**
*
* @author Kapralov Sergey
*/
public class ShouldBeInstrumented implements ElementMatcher<TypeDescription> {
private static final ElementMatcher<TypeDescription> IS_CLASS = not(isInterface().or(isAnnotation()));
private static final ElementMatcher<TypeDescription> IS_NOT_EXPLICIT_NONATOM = not(new IsNotAtom());

public class Extending implements ElementMatcher<TypeDescription> {
private final ElementMatcher<TypeDescription> superClassMatcher;

public Extending(ElementMatcher<TypeDescription> superClassMatcher) {
this.superClassMatcher = superClassMatcher;
}

@Override
public final boolean matches(TypeDescription target) {
return IS_CLASS.matches(target) && IS_NOT_EXPLICIT_NONATOM.matches(target);
Option<TypeDescription> optSuperClass = Option
.of(target.getSuperClass())
.map(TypeDescription.Generic::asErasure);
return optSuperClass
.map(sc -> superClassMatcher.matches(sc))
.getOrElse(Boolean.FALSE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,16 @@
*/
package oo.atom.codegen.bytebuddy.matchers;

import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import net.bytebuddy.matcher.ElementMatchers;

/**
*
* @author Kapralov Sergey
*/
public class IsAtom extends WrappedMatcher<TypeDescription> implements ElementMatcher<TypeDescription> {
public IsAtom() {
public class ExtendingAnythingButObject extends Extending {
public ExtendingAnythingButObject() {
super(
new DisjunctionMatcher<>(
new NaturalJavaAtom(),
new AnnotatedAtom(),
new FollowsAtomSpecification()
)
ElementMatchers.noneOf(Object.class)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@

import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
import static net.bytebuddy.matcher.ElementMatchers.not;
import static net.bytebuddy.matcher.ElementMatchers.*;

/**
*
Expand All @@ -37,6 +36,7 @@ public class NoMethods implements ElementMatcher<TypeDescription> {
public final boolean matches(TypeDescription target) {
return target.getDeclaredMethods()
.filter(not(isConstructor()))
.filter(not(isSynthetic()))
.isEmpty();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@
package oo.atom.codegen.bytebuddy.plugin;

import net.bytebuddy.build.Plugin;
import oo.atom.codegen.bytebuddy.matchers.ShouldBeInstrumented;
import oo.atom.codegen.bytebuddy.bt.BtApplyPatch;
import net.bytebuddy.description.type.TypeDescription;
import static net.bytebuddy.matcher.ElementMatchers.*;
import oo.atom.codegen.bytebuddy.bt.BtApplyAtomAliasPatch;
import oo.atom.codegen.bytebuddy.bt.BtApplyAtomPatch;
import oo.atom.codegen.bytebuddy.bt.BtApplyIfMatches;
import oo.atom.codegen.bytebuddy.bt.BtConditional;
import oo.atom.codegen.bytebuddy.matchers.AnnotatedNonAtom;
import oo.atom.codegen.bytebuddy.matchers.ConjunctionMatcher;
import oo.atom.codegen.bytebuddy.matchers.ExtendingAnythingButObject;


/**
Expand All @@ -35,8 +42,17 @@
public class AtomPlugin extends TaskPlugin implements Plugin {
public AtomPlugin() {
super(
new ShouldBeInstrumented(),
new BtApplyPatch()
new BtApplyIfMatches(
new ConjunctionMatcher<TypeDescription>(
not(new AnnotatedNonAtom()),
not(isInterface())
),
new BtConditional(
new ExtendingAnythingButObject(),
new BtApplyAtomAliasPatch(),
new BtApplyAtomPatch()
)
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import net.bytebuddy.build.Plugin;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType.Builder;
import net.bytebuddy.matcher.ElementMatcher;
import oo.atom.codegen.bytebuddy.bt.BuilderTransition;
import oo.atom.r.Result;

Expand All @@ -36,16 +35,15 @@
* @author Kapralov Sergey
*/
public class TaskPlugin implements Plugin {
private final ElementMatcher<TypeDescription> matcher;
private final BuilderTransition bt;

public TaskPlugin(ElementMatcher<TypeDescription> matcher, BuilderTransition bt) {
this.matcher = matcher;
public TaskPlugin(BuilderTransition bt) {
this.bt = bt;
}

@Override
public final Builder<?> apply(Builder<?> builder, TypeDescription typeDescription) {
System.out.println("Transforming type: " + typeDescription.getName());
Result<Builder<?>> result = bt
.transitionResult(builder, typeDescription);
List<String> issues = result.issues();
Expand All @@ -59,6 +57,6 @@ public final Builder<?> apply(Builder<?> builder, TypeDescription typeDescriptio

@Override
public final boolean matches(TypeDescription target) {
return matcher.matches(target);
return true;
}
}
Loading

0 comments on commit 3f19421

Please sign in to comment.