/*
* Copyright 2009-2010 MBTE Sweden AB.
*
* 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.mbte.groovypp.compiler;
import org.codehaus.groovy.ast.*;
import org.codehaus.groovy.classgen.Verifier;
import org.codehaus.groovy.classgen.BytecodeSequence;
import org.codehaus.groovy.classgen.BytecodeExpression;
import org.codehaus.groovy.classgen.BytecodeHelper;
import org.codehaus.groovy.reflection.CachedField;
import org.codehaus.groovy.reflection.ReflectionCache;
import org.objectweb.asm.MethodVisitor;
import java.lang.reflect.Modifier;
import java.util.List;
class OpenVerifier extends Verifier {
@Override
public void visitClass(ClassNode classNode) {
addMetaClassFieldIfNeeded(classNode);
super.visitClass(classNode);
for (FieldNode fieldNode : classNode.getFields()) {
fieldNode.setInitialValueExpression(null);
}
}
@Override
protected void addGroovyObjectInterfaceAndMethods(ClassNode node, String classInternalName) {
final List<AnnotationNode> list = node.getAnnotations(TypeUtil.TYPED);
if (list == null || list.size() == 0 || list.get(0).getMember("value") != null)
super.addGroovyObjectInterfaceAndMethods(node, classInternalName);
}
protected void addPropertyMethod(MethodNode method) {
super.addPropertyMethod(method);
ClassNodeCache.clearCache(method.getDeclaringClass());
}
public void visitProperty(PropertyNode node) {
super.visitProperty(node);
node.setGetterBlock(null);
node.setSetterBlock(null);
}
protected void addInitialization(ClassNode node) {
super.addInitialization(node);
}
protected void addInitialization(ClassNode node, ConstructorNode constructorNode) {
if (constructorNode.getCode() instanceof BytecodeSequence)
return;
super.addInitialization(node, constructorNode);
}
private void addMetaClassFieldIfNeeded(ClassNode node) {
if (node.isInterface() || (node.getModifiers() & ACC_ABSTRACT) != 0)
return;
FieldNode ret = node.getDeclaredField("metaClass");
if (ret != null) {
// very dirty hack
// stub generator for joint compiler calls Verifier, which adds properties/methods
// we remove it initialization of metaClass here
if (ret.getInitialExpression() != null && ret.getInitialExpression().getClass().getName().startsWith("org.codehaus.groovy.classgen.Verifier$")) {
ret.setInitialValueExpression(null);
}
return;
}
ClassNode current = node;
while (current != ClassHelper.OBJECT_TYPE) {
current = current.getSuperClass();
if (current == null) break;
ret = current.getDeclaredField("metaClass");
if (ret == null) continue;
if (Modifier.isPrivate(ret.getModifiers())) continue;
return;
}
node.addField("metaClass", ACC_PRIVATE | ACC_TRANSIENT | ACC_SYNTHETIC, ClassHelper.METACLASS_TYPE, null).setSynthetic(true);
}
protected void addTimeStamp(ClassNode node) {
}
}