Permalink
Browse files

Fixes #727 Use ByteBuddy to instrument classes instead Javassist: imp…

…lement suppress constructor

Fix code style issues
  • Loading branch information...
thekingnothing committed May 12, 2017
1 parent cc619f8 commit d6ccb0ff7a65b7ab8596ac9ca06f6fd7d3a1304b
Showing with 2,192 additions and 418 deletions.
  1. +1 −1 config/checkstyle/checkstyle.xml
  2. +1 −0 gradle/java-module.gradle
  3. +1 −0 gradle/release/fullJars.gradle
  4. +4 −0 powermock-core/src/main/java/org/powermock/core/MockGateway.java
  5. +78 −0 powermock-core/src/main/java/org/powermock/core/bytebuddy/ConditionalStateStackManipulation.java
  6. +143 −0 powermock-core/src/main/java/org/powermock/core/bytebuddy/Frame.java
  7. +76 −0 powermock-core/src/main/java/org/powermock/core/bytebuddy/MaxLocalsExtractor.java
  8. +44 −0 powermock-core/src/main/java/org/powermock/core/bytebuddy/MethodMaxLocals.java
  9. +146 −0 powermock-core/src/main/java/org/powermock/core/bytebuddy/MockGetawayCall.java
  10. +99 −0 powermock-core/src/main/java/org/powermock/core/bytebuddy/PrimitiveBoxing.java
  11. +60 −0 powermock-core/src/main/java/org/powermock/core/bytebuddy/Variable.java
  12. +26 −37 powermock-core/src/main/java/org/powermock/core/classloader/DeferSupportingClassLoader.java
  13. +5 −3 powermock-core/src/main/java/org/powermock/core/classloader/MockClassLoader.java
  14. +19 −0 powermock-core/src/main/java/org/powermock/core/classloader/MockClassLoaderConfiguration.java
  15. +17 −7 powermock-core/src/main/java/org/powermock/core/classloader/bytebuddy/ByteBuddyMockClassLoader.java
  16. +5 −7 powermock-core/src/main/java/org/powermock/core/classloader/javassist/JavassistMockClassLoader.java
  17. +34 −0 powermock-core/src/main/java/org/powermock/core/transformers/ForTestClass.java
  18. +128 −0 powermock-core/src/main/java/org/powermock/core/transformers/TestClassTransformer.java
  19. +39 −3 powermock-core/src/main/java/org/powermock/core/transformers/TransformStrategy.java
  20. +65 −0 ...src/main/java/org/powermock/core/transformers/bytebuddy/ByteBuddyMockTransformerChainFactory.java
  21. +50 −0 ...re/src/main/java/org/powermock/core/transformers/bytebuddy/ClassFinalModifierMockTransformer.java
  22. +187 −0 ...-core/src/main/java/org/powermock/core/transformers/bytebuddy/ConstructorCallMockTransformer.java
  23. +4 −52 .../src/main/java/org/powermock/core/transformers/bytebuddy/ConstructorModifiersMockTransformer.java
  24. +0 −122 ...k-core/src/main/java/org/powermock/core/transformers/bytebuddy/FinalModifiersMockTransformer.java
  25. +44 −0 ...ore/src/main/java/org/powermock/core/transformers/bytebuddy/StaticFinalFieldsMockTransformer.java
  26. +0 −2 ...ore/src/main/java/org/powermock/core/transformers/bytebuddy/StaticInitializerMockTransformer.java
  27. +257 −0 ...va/org/powermock/core/transformers/bytebuddy/constructor/ConstructorCallMethodVisitorWrapper.java
  28. +1 −2 powermock-core/src/main/java/org/powermock/core/transformers/bytebuddy/support/ByteBuddyClass.java
  29. +6 −4 ...re/src/main/java/org/powermock/core/transformers/javassist/AbstractJavaAssistMockTransformer.java
  30. +7 −4 ...rmock-core/src/main/java/org/powermock/core/transformers/javassist/InstrumentMockTransformer.java
  31. +15 −101 ...ock/core/transformers/javassist/{TestClassTransformer.java → JavaAssistTestClassTransformer.java}
  32. +0 −3 ...c/main/java/org/powermock/core/transformers/javassist/StaticFinalNativeMethodMockTransformer.java
  33. +5 −3 ...re/src/main/java/org/powermock/core/transformers/javassist/support/PowerMockExpressionEditor.java
  34. +4 −4 powermock-core/src/main/java/org/powermock/tests/utils/impl/AbstractCommonTestSuiteChunkerImpl.java
  35. +1 −1 powermock-core/src/main/java/org/powermock/tests/utils/impl/MockClassLoaderFactory.java
  36. +2 −1 powermock-core/src/test/java/org/powermock/core/classloader/MockClassLoaderTest.java
  37. +27 −2 powermock-core/src/test/java/org/powermock/core/test/ClassLoaderTestHelper.java
  38. +5 −0 powermock-core/src/test/java/org/powermock/core/test/MockClassLoaderFactory.java
  39. +7 −1 powermock-core/src/test/java/org/powermock/core/transformers/AbstractBaseMockTransformerTest.java
  40. +3 −4 ...ock-core/src/test/java/org/powermock/core/transformers/ClassFinalModifierMockTransformerTest.java
  41. +327 −0 powermock-core/src/test/java/org/powermock/core/transformers/ConstructorCallMockTransformerTest.java
  42. +2 −4 powermock-core/src/test/java/org/powermock/core/transformers/ConstructorsMockTransformerTest.java
  43. +1 −22 powermock-core/src/test/java/org/powermock/core/transformers/InstrumentMockTransformerTest.java
  44. +27 −7 powermock-core/src/test/java/org/powermock/core/transformers/MockTransformerTestHelper.java
  45. +116 −0 ...mock-core/src/test/java/org/powermock/core/transformers/StaticFinalFieldsMockTransformerTest.java
  46. +0 −4 ...ore/src/test/java/org/powermock/core/transformers/StaticFinalNativeMethodMockTransformerTest.java
  47. +1 −2 ...e/src/test/java/org/powermock/core/transformers/SuppressStaticInitializerMockTransformerTest.java
  48. +2 −1 .../transformers/javassist/{TestClassTransformerTest.java → TestClassTransformerJavaAssistTest.java}
  49. +100 −14 powermock-core/src/test/java/powermock/test/support/MainMockTransformerTestSupport.java
@@ -102,7 +102,7 @@
<property name="max" value="8"/>
</module>
<module name="AbbreviationAsWordInName">
<property name="allowedAbbreviationLength" value="5"/>
<property name="allowedAbbreviationLength" value="8"/>
</module>
<module name="PackageDeclaration">
<property name="matchDirectoryStructure" value="false"/>
@@ -1,4 +1,5 @@
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
@@ -12,6 +12,7 @@ configure(fullJars){ project ->
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
}
@@ -113,6 +113,10 @@ public static Object constructorCall(Class<?> type, Object[] args, Class<?>[] si
}
return PROCEED;
}
public static boolean suppressConstructorCall(Class<?> type, Object[] args, Class<?>[] sig) throws Throwable {
return constructorCall(type, args, sig) != PROCEED;
}
/**
* Tells PowerMock whether or not to mock
@@ -0,0 +1,78 @@
/*
*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.powermock.core.bytebuddy;
import net.bytebuddy.implementation.Implementation.Context;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.jar.asm.Label;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;
public class ConditionalStateStackManipulation implements StackManipulation {
private final StackManipulation condition;
private final StackManipulation action;
private final StackManipulation otherwise;
private final Frame frame;
public ConditionalStateStackManipulation(final StackManipulation condition,
final StackManipulation action,
final StackManipulation otherwise,
final Frame frame) {
this.condition = condition;
this.action = action;
this.otherwise = otherwise;
this.frame = frame;
}
@Override
public boolean isValid() {
return true;
}
@Override
public Size apply(final MethodVisitor mv, final Context implementationContext) {
Size size = new Size(0, 0);
Label proceed = new Label();
Label exit = new Label();
size = size.aggregate(condition.apply(mv, implementationContext));
mv.visitJumpInsn(Opcodes.IFEQ, proceed);
size = size.aggregate(action.apply(mv, implementationContext));
mv.visitJumpInsn(Opcodes.GOTO, exit);
mv.visitLabel(proceed);
mv.visitFrame(Opcodes.F_FULL, frame.localSize(), frame.locals(), 0, null);
size = size.aggregate(otherwise.apply(mv, implementationContext));
mv.visitLabel(exit);
mv.visitFrame(Opcodes.F_FULL, 0, null, 0, null);
return size;
}
}
@@ -0,0 +1,143 @@
/*
*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.powermock.core.bytebuddy;
import net.bytebuddy.description.method.ParameterDescription;
import net.bytebuddy.description.method.ParameterDescription.InDefinedShape;
import net.bytebuddy.description.method.ParameterList;
import net.bytebuddy.description.type.TypeDescription.Generic;
import net.bytebuddy.implementation.bytecode.StackSize;
import net.bytebuddy.jar.asm.Opcodes;
import net.bytebuddy.utility.CompoundList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
public class Frame {
public static Frame beforeConstructorCall(final Iterable<? extends ParameterDescription> constructorParameters) {
List<LocalVariable> locals = new ArrayList<LocalVariable>();
locals.add(LocalVariable.UNINITIALIZED_THIS);
int maxLocals = 1;
for (ParameterDescription sourceParameter : constructorParameters) {
Generic type = sourceParameter.getType();
locals.add(LocalVariable.from(type));
maxLocals += type.getStackSize().getSize();
}
return new Frame(locals);
}
private Deque<Object> stack;
private List<LocalVariable> locals;
public Frame(final List<LocalVariable> locals) {
this.locals = Collections.unmodifiableList(locals);
this.stack = new LinkedList<Object>();
}
public Frame addTopToLocals(final int count) {
List<LocalVariable> locals = new ArrayList<LocalVariable>();
for (int i = 0; i < count; i++) {
locals.add(LocalVariable.TOP);
}
return new Frame(
CompoundList.of(this.locals, locals)
);
}
public Frame addLocalVariable(final LocalVariable localVariable) {
return new Frame(
CompoundList.of(this.locals, localVariable)
);
}
public Frame addLocalVariables(final ParameterList<InDefinedShape> types) {
List<LocalVariable> frameLocals = new ArrayList<LocalVariable>();
for (ParameterDescription parameter : types) {
Generic type = parameter.getType();
frameLocals.add(LocalVariable.from(type));
}
return new Frame(CompoundList.of(this.locals, frameLocals));
}
public Object[] locals() {
Object[] frameLocals = new Object[this.locals.size()];
for (int i = 0; i < this.locals.size(); i++) {
frameLocals[i] = this.locals.get(i).getType();
}
return frameLocals;
}
public int localSize() {
return locals.size();
}
public int maxLocalVariableIndex() {
int localStackSize = 0;
for (LocalVariable localVariable : locals) {
localStackSize += localVariable.getStackSize().getSize();
}
return localStackSize;
}
public static class LocalVariable {
public static LocalVariable from(final Generic type) {
if (type.represents(double.class)) {
return DOUBLE;
} else {
return new LocalVariable(
type.getTypeName().replace('.', '/'),
type.getStackSize()
);
}
}
public static final LocalVariable UNINITIALIZED_THIS = new LocalVariable(Opcodes.UNINITIALIZED_THIS, StackSize.SINGLE);
public static final LocalVariable TOP = new LocalVariable(Opcodes.TOP, StackSize.SINGLE);
public static final LocalVariable DOUBLE = new LocalVariable(Opcodes.DOUBLE, StackSize.DOUBLE);
private final Object type;
private final StackSize stackSize;
private LocalVariable(final Object type, StackSize size) {
this.type = type;
this.stackSize = size;
}
public Object getType() {
return type;
}
public StackSize getStackSize() {
return stackSize;
}
}
}
@@ -0,0 +1,76 @@
/*
*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.powermock.core.bytebuddy;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.jar.asm.ClassVisitor;
import net.bytebuddy.jar.asm.MethodVisitor;
import net.bytebuddy.jar.asm.Opcodes;
public class MaxLocalsExtractor extends ClassVisitor {
private MethodMaxLocals methodMaxLocals;
public MaxLocalsExtractor() {
super(Opcodes.ASM5);
}
@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature,
final String[] exceptions) {
if (MethodDescription.CONSTRUCTOR_INTERNAL_NAME.equals(name)) {
methodMaxLocals = new MethodMaxLocals();
return new MaxLocalsMethodVisitor(name, desc, methodMaxLocals);
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
public MethodMaxLocals getMethods() {
return methodMaxLocals;
}
private static class MaxLocalsMethodVisitor extends MethodVisitor {
private final String name;
private final String signature;
private final MethodMaxLocals methodMaxLocals;
private int maxLocals;
private MaxLocalsMethodVisitor(final String name, final String signature,
final MethodMaxLocals methodMaxLocals) {
super(Opcodes.ASM5);
this.name = name;
this.signature = signature;
this.methodMaxLocals = methodMaxLocals;
}
@Override
public void visitMaxs(final int maxStack, final int maxLocals) {
this.maxLocals = maxLocals;
super.visitMaxs(maxStack, maxLocals);
}
@Override
public void visitEnd() {
methodMaxLocals.add(name, signature, maxLocals);
super.visitEnd();
}
}
}
@@ -0,0 +1,44 @@
/*
*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.powermock.core.bytebuddy;
import net.bytebuddy.description.method.MethodDescription;
import java.util.HashMap;
import java.util.Map;
public class MethodMaxLocals {
private final Map<String, Integer> methodMaxLocals;
MethodMaxLocals() {
methodMaxLocals = new HashMap<String, Integer>();
}
public void add(String name, String signature, int maxLocals) {
methodMaxLocals.put(name + signature, maxLocals);
}
public int getMethodMaxLocal(final MethodDescription instrumentedMethod) {
final String key = instrumentedMethod.getInternalName() + instrumentedMethod.getDescriptor();
final Integer maxLocals = methodMaxLocals.get(key);
return maxLocals == null ? 0 : maxLocals;
}
}
Oops, something went wrong.

0 comments on commit d6ccb0f

Please sign in to comment.