Make it build with cglib-2.2
[fedora-idea.git] / platform / platform-impl / src / com / intellij / util / InstanceofCheckerGeneratorImpl.java
blobca512ad8044205a9a48a4ccb9ac9b916be7ff50c
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.util;
18 import com.intellij.openapi.util.Condition;
19 import com.intellij.util.containers.ConcurrentFactoryMap;
20 import org.objectweb.asm.ClassVisitor;
21 import org.objectweb.asm.Label;
22 import org.objectweb.asm.Type;
23 import net.sf.cglib.core.*;
25 import java.lang.reflect.Modifier;
27 /**
28 * @author peter
30 public class InstanceofCheckerGeneratorImpl extends InstanceofCheckerGenerator {
31 private final ConcurrentFactoryMap<Class, Condition<Object>> myCache = new ConcurrentFactoryMap<Class, Condition<Object>>() {
32 @Override
33 protected Condition<Object> create(final Class key) {
34 if (key.isAnonymousClass() || Modifier.isPrivate(key.getModifiers())) {
35 return new Condition<Object>() {
36 public boolean value(Object o) {
37 return key.isInstance(o);
42 return new InstanceofClassGenerator(key).createClass();
46 public Condition<Object> getInstanceofChecker(final Class<?> someClass) {
47 return myCache.get(someClass);
50 private static String toInternalName(Class<?> someClass) {
51 return someClass.getName().replace('.', '/');
54 private static class InstanceofClassGenerator extends AbstractClassGenerator {
55 private static final Source SOURCE = new Source("IntellijInstanceof");
56 private final Class<?> myCheckedClass;
58 public InstanceofClassGenerator(Class<?> checkedClass) {
59 super(SOURCE);
60 myCheckedClass = checkedClass;
63 @Override
64 protected ClassLoader getDefaultClassLoader() {
65 return myCheckedClass.getClassLoader();
68 public Condition<Object> createClass() {
69 return (Condition<Object>)super.create(myCheckedClass);
72 @Override
73 protected Object firstInstance(Class type) throws Exception {
74 return type.newInstance();
77 @Override
78 protected Object nextInstance(Object instance) throws Exception {
79 return instance;
82 public void generateClass(ClassVisitor classVisitor) throws Exception {
83 ClassEmitter cv = new ClassEmitter(classVisitor);
85 cv.visit(Constants.V1_2, Modifier.PUBLIC, "com/intellij/util/InstanceofChecker$$$$$" + myCheckedClass.getName().replace('.', '$'), null, toInternalName(Object.class), new String[]{toInternalName(Condition.class)});
86 cv.visitSource(Constants.SOURCE_FILE, null);
87 final Signature signature = new Signature("<init>", "()V");
88 final CodeEmitter cons = cv.begin_method(Modifier.PUBLIC, signature, new Type[0]);
89 cons.load_this();
90 cons.dup();
91 cons.super_invoke_constructor(signature);
92 cons.return_value();
93 cons.end_method();
95 final CodeEmitter e = cv.begin_method(Modifier.PUBLIC, new Signature("value", "(L" + toInternalName(Object.class) + ";)Z"), new Type[0]);
96 e.load_arg(0);
97 e.instance_of(Type.getType(myCheckedClass));
99 Label fail = e.make_label();
100 e.if_jump(CodeEmitter.EQ, fail);
101 e.push(true);
102 e.return_value();
104 e.mark(fail);
105 e.push(false);
106 e.return_value();
107 e.end_method();
109 cv.visitEnd();