2 * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
3 * Use is subject to license terms.
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
;
19 public class InstanceofCheckerGeneratorImpl
extends InstanceofCheckerGenerator
{
20 private final ConcurrentFactoryMap
<Class
, Condition
<Object
>> myCache
= new ConcurrentFactoryMap
<Class
, Condition
<Object
>>() {
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
) {
41 myCheckedClass
= checkedClass
;
45 protected ClassLoader
getDefaultClassLoader() {
46 return myCheckedClass
.getClassLoader();
49 public Condition
<Object
> createClass() {
50 return (Condition
<Object
>)super.create(myCheckedClass
);
54 protected Object
firstInstance(Class type
) throws Exception
{
55 return type
.newInstance();
59 protected Object
nextInstance(Object instance
) throws Exception
{
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);
71 cons
.super_invoke_constructor(signature
);
75 final CodeEmitter e
= cv
.begin_method(Modifier
.PUBLIC
, new Signature("value", "(L" + toInternalName(Object
.class) + ";)Z"), new Type
[0], null);
77 e
.instance_of(Type
.getType(myCheckedClass
));
79 Label fail
= e
.make_label();
80 e
.if_jump(CodeEmitter
.EQ
, fail
);