by-class generated instanceof checker
[fedora-idea.git] / platform-impl / src / com / intellij / util / InstanceofCheckerGeneratorImpl.java
blob90ecd58ad9d57b4f11c9d98f5825d072264ed455
1 /*
2 * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
3 * Use is subject to license terms.
4 */
5 package com.intellij.util;
7 import com.intellij.openapi.util.Condition;
8 import com.intellij.util.containers.ConcurrentFactoryMap;
9 import net.sf.cglib.asm.ClassVisitor;
10 import net.sf.cglib.asm.Label;
11 import net.sf.cglib.asm.Type;
12 import net.sf.cglib.core.*;
14 import java.lang.reflect.Modifier;
16 /**
17 * @author peter
19 public class InstanceofCheckerGeneratorImpl extends InstanceofCheckerGenerator {
20 private final ConcurrentFactoryMap<Class, Condition<Object>> myCache = new ConcurrentFactoryMap<Class, Condition<Object>>() {
21 @Override
22 protected Condition<Object> create(Class key) {
23 return new InstanceofClassGenerator(key).createClass();
27 public Condition<Object> getInstanceofChecker(final Class<?> someClass) {
28 return myCache.get(someClass);
31 private static String toInternalName(Class<?> someClass) {
32 return someClass.getName().replace('.', '/');
35 private static class InstanceofClassGenerator extends AbstractClassGenerator {
36 private static final Source SOURCE = new Source("IntellijInstanceof");
37 private final Class<?> myCheckedClass;
39 public InstanceofClassGenerator(Class<?> checkedClass) {
40 super(SOURCE);
41 myCheckedClass = checkedClass;
44 @Override
45 protected ClassLoader getDefaultClassLoader() {
46 return myCheckedClass.getClassLoader();
49 public Condition<Object> createClass() {
50 return (Condition<Object>)super.create(myCheckedClass);
53 @Override
54 protected Object firstInstance(Class type) throws Exception {
55 return type.newInstance();
58 @Override
59 protected Object nextInstance(Object instance) throws Exception {
60 return instance;
63 public void generateClass(ClassVisitor classVisitor) throws Exception {
64 ClassEmitter cv = new ClassEmitter(classVisitor);
66 cv.visit(Constants.V1_2, Modifier.PUBLIC, "com/intellij/util/InstanceofChecker$$$$$" + myCheckedClass.getName().replace('.', '$'), toInternalName(Object.class), new String[]{toInternalName(Condition.class)}, Constants.SOURCE_FILE);
67 final Signature signature = new Signature("<init>", "()V");
68 final CodeEmitter cons = cv.begin_method(Modifier.PUBLIC, signature, new Type[0], null);
69 cons.load_this();
70 cons.dup();
71 cons.super_invoke_constructor(signature);
72 cons.return_value();
73 cons.end_method();
75 final CodeEmitter e = cv.begin_method(Modifier.PUBLIC, new Signature("value", "(L" + toInternalName(Object.class) + ";)Z"), new Type[0], null);
76 e.load_arg(0);
77 e.instance_of(Type.getType(myCheckedClass));
79 Label fail = e.make_label();
80 e.if_jump(CodeEmitter.EQ, fail);
81 e.push(true);
82 e.return_value();
84 e.mark(fail);
85 e.push(false);
86 e.return_value();
87 e.end_method();
89 cv.visitEnd();