/*
* Copyright (c) 2006-2013 Rogério Liesenfeld
* This file is subject to the terms of the MIT license (see LICENSE.txt).
*/
package mockit.internal.expectations.mocking;
import java.lang.reflect.*;
import static java.lang.reflect.Modifier.*;
import static mockit.external.asm4.Opcodes.*;
import mockit.internal.state.*;
public abstract class FieldTypeRedefinitions extends TypeRedefinitions
{
private static final int FIELD_ACCESS_MASK = ACC_SYNTHETIC + ACC_STATIC;
protected Field field;
protected boolean finalField;
protected FieldTypeRedefinitions(Object objectWithMockFields)
{
super(objectWithMockFields);
}
protected final void redefineFieldTypes(Class<?> classWithMockFields, boolean isTestClass)
{
Class<?> superClass = classWithMockFields.getSuperclass();
//noinspection UnnecessaryFullyQualifiedName
if (
superClass != null && superClass != Object.class &&
superClass != mockit.Expectations.class && superClass != mockit.NonStrictExpectations.class
) {
redefineFieldTypes(superClass, isTestClass);
}
Field[] fields = classWithMockFields.getDeclaredFields();
for (Field candidateField : fields) {
int fieldModifiers = candidateField.getModifiers();
if ((fieldModifiers & FIELD_ACCESS_MASK) == 0) {
field = candidateField;
redefineFieldType(isTestClass, fieldModifiers);
field = null;
}
}
}
private void redefineFieldType(boolean fromTestClass, int modifiers)
{
typeMetadata = new MockedType(field, fromTestClass);
if (typeMetadata.isMockField()) {
finalField = isFinal(modifiers);
redefineTypeForMockField();
typesRedefined++;
registerCaptureOfNewInstances();
}
typeMetadata = null;
}
protected abstract void redefineTypeForMockField();
protected final void registerMockedClassIfNonStrict()
{
if (typeMetadata.nonStrict) {
TestRun.getExecutingTest().addNonStrictMock(typeMetadata.getClassType());
}
}
@Override
public final CaptureOfNewInstancesForFields getCaptureOfNewInstances()
{
return (CaptureOfNewInstancesForFields) captureOfNewInstances;
}
private void registerCaptureOfNewInstances()
{
if (typeMetadata.getMaxInstancesToCapture() <= 0) {
return;
}
if (captureOfNewInstances == null) {
captureOfNewInstances = new CaptureOfNewInstancesForFields();
}
getCaptureOfNewInstances().registerCaptureOfNewInstances(typeMetadata, null);
}
/**
* Returns true iff the mock instance concrete class is not mocked in some test, ie it's a class
* which only appears in the code under test.
*/
public abstract boolean captureNewInstanceForApplicableMockField(Object mock);
}