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 net
.sf
.cglib
.asm
.ClassVisitor
;
21 import net
.sf
.cglib
.asm
.Label
;
22 import net
.sf
.cglib
.asm
.Type
;
23 import net
.sf
.cglib
.core
.*;
25 import java
.lang
.reflect
.Modifier
;
30 public class InstanceofCheckerGeneratorImpl
extends InstanceofCheckerGenerator
{
31 private final ConcurrentFactoryMap
<Class
, Condition
<Object
>> myCache
= new ConcurrentFactoryMap
<Class
, Condition
<Object
>>() {
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
) {
60 myCheckedClass
= checkedClass
;
64 protected ClassLoader
getDefaultClassLoader() {
65 return myCheckedClass
.getClassLoader();
68 public Condition
<Object
> createClass() {
69 return (Condition
<Object
>)super.create(myCheckedClass
);
73 protected Object
firstInstance(Class type
) throws Exception
{
74 return type
.newInstance();
78 protected Object
nextInstance(Object instance
) throws Exception
{
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('.', '$'), toInternalName(Object
.class), new String
[]{toInternalName(Condition
.class)}, Constants
.SOURCE_FILE
);
86 final Signature signature
= new Signature("<init>", "()V");
87 final CodeEmitter cons
= cv
.begin_method(Modifier
.PUBLIC
, signature
, new Type
[0], null);
90 cons
.super_invoke_constructor(signature
);
94 final CodeEmitter e
= cv
.begin_method(Modifier
.PUBLIC
, new Signature("value", "(L" + toInternalName(Object
.class) + ";)Z"), new Type
[0], null);
96 e
.instance_of(Type
.getType(myCheckedClass
));
98 Label fail
= e
.make_label();
99 e
.if_jump(CodeEmitter
.EQ
, fail
);