
com.hazelcast.shaded.org.codehaus.janino.ClassFileIClass Maven / Gradle / Ivy
The newest version!
/*
* Janino - An embedded Java[TM] compiler
*
* Copyright (c) 2001-2010 Arno Unkrig. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
* following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.hazelcast.shaded.org.codehaus.janino;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;
import com.hazelcast.shaded.org.codehaus.commons.compiler.CompileException;
import com.hazelcast.shaded.org.codehaus.commons.compiler.InternalCompilerException;
import com.hazelcast.shaded.org.codehaus.commons.nullanalysis.Nullable;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.Annotation;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.ArrayElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.BooleanElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.ByteElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.CharElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.ClassElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.ConstantClassInfo;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.DoubleElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.EnumConstValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.FloatElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.IntElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.LongElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.ShortElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.SignatureAttribute;
import com.hazelcast.shaded.org.codehaus.janino.util.ClassFile.StringElementValue;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.ArrayTypeSignature;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.ClassSignature;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.ClassTypeSignature;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.FieldTypeSignature;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.FieldTypeSignatureVisitor;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.FormalTypeParameter;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.SignatureException;
import com.hazelcast.shaded.org.codehaus.janino.util.signature.SignatureParser.TypeVariableSignature;
/**
* A wrapper object that turns a {@link ClassFile} object into an {@link IClass}.
*/
public
class ClassFileIClass extends IClass {
private static final Logger LOGGER = Logger.getLogger(ClassFileIClass.class.getName());
private final ClassFile classFile;
private final IClassLoader iClassLoader;
private final short accessFlags;
@Nullable private final ClassSignature classSignature;
private final Map resolvedFields = new HashMap<>();
/**
* @param classFile Source of data
* @param iClassLoader {@link IClassLoader} through which to load other classes
*/
public
ClassFileIClass(ClassFile classFile, IClassLoader iClassLoader) {
this.classFile = classFile;
this.iClassLoader = iClassLoader;
// Determine class access flags.
this.accessFlags = classFile.accessFlags;
SignatureAttribute sa = classFile.getSignatureAttribute();
if (sa == null) {
this.classSignature = null;
} else {
try {
this.classSignature = new SignatureParser().decodeClassSignature(sa.getSignature(classFile));
} catch (SignatureException e) {
throw new InternalCompilerException("Decoding signature of \"" + this + "\"", e);
}
}
// Example 1:
// interface Map
// has signature
// Ljava/lang/Object;
// [this-class] extends Object
// Example 2:
// class HashMap extends AbstractMap implements Map, Cloneable, Serializable
// has signature
// \
// Ljava/util/AbstractMap;\
// Ljava/util/Map;\
// Ljava/lang/Cloneable;\
// Ljava/io/Serializable;
// [this-class] extends AbstractMap implements Map, Cloneable, java.io.Serializable
}
// Implement IClass.
@Override protected ITypeVariable[]
getITypeVariables2() throws CompileException {
ClassSignature cs = this.classSignature;
if (cs == null) return new ITypeVariable[0];
ITypeVariable[] result = new ITypeVariable[cs.formalTypeParameters.size()];
for (int i = 0; i < result.length; i++) {
final FormalTypeParameter ftp = (FormalTypeParameter) cs.formalTypeParameters.get(i);
final ITypeVariableOrIClass[] bounds = ClassFileIClass.this.getBounds(ftp);
result[i] = new ITypeVariable() {
@Override public String
getName() { return ftp.identifier; }
@Override public ITypeVariableOrIClass[]
getBounds() { return bounds; }
@Override public String
toString() {
ITypeVariableOrIClass[] bs = this.getBounds();
String s = this.getName() + " extends " + bs[0];
for (int i = 1; i < bs.length; i++) s += " & " + bs[i];
return s;
}
};
}
return result;
}
private ITypeVariableOrIClass[]
getBounds(SignatureParser.FormalTypeParameter ftp) throws CompileException {
List result = new ArrayList<>();
if (ftp.classBound != null) {
result.add(this.fieldTypeSignatureToITypeVariableOrIClass(ftp.classBound));
}
return (ITypeVariableOrIClass[]) result.toArray(new ITypeVariableOrIClass[result.size()]);
}
private ITypeVariableOrIClass
fieldTypeSignatureToITypeVariableOrIClass(FieldTypeSignature fts) throws CompileException {
return (ITypeVariableOrIClass) fts.accept(
new FieldTypeSignatureVisitor() {
@Override public ITypeVariableOrIClass
visitArrayTypeSignature(ArrayTypeSignature ats) { throw new AssertionError(ats); }
@Override public ITypeVariableOrIClass
visitClassTypeSignature(ClassTypeSignature cts) throws CompileException {
String fd = Descriptor.fromClassName(cts.packageSpecifier + cts.simpleClassName);
IClass result;
try {
result = ClassFileIClass.this.iClassLoader.loadIClass(fd);
} catch (ClassNotFoundException cnfe) {
throw new CompileException("Loading \"" + Descriptor.toClassName(fd) + "\"", null, cnfe);
}
if (result == null) {
throw new CompileException("Cannot load \"" + Descriptor.toClassName(fd) + "\"", null);
}
return result;
}
@Override public ITypeVariableOrIClass
visitTypeVariableSignature(final TypeVariableSignature tvs) {
return new ITypeVariable() {
@Override public String
getName() { return tvs.identifier; }
@Override public ITypeVariableOrIClass[]
getBounds() { throw new AssertionError(this); }
};
}
}
);
}
@Override protected IConstructor[]
getDeclaredIConstructors2() {
List iConstructors = new ArrayList<>();
for (ClassFile.MethodInfo mi : this.classFile.methodInfos) {
IInvocable ii;
try {
ii = this.resolveMethod(mi);
} catch (ClassNotFoundException ex) {
throw new InternalCompilerException(ex.getMessage(), ex);
}
if (ii instanceof IConstructor) iConstructors.add(ii);
}
return (IConstructor[]) iConstructors.toArray(new IConstructor[iConstructors.size()]);
}
@Override protected IMethod[]
getDeclaredIMethods2() {
List iMethods = new ArrayList<>();
for (ClassFile.MethodInfo mi : this.classFile.methodInfos) {
// Skip JDK 1.5 synthetic methods (e.g. those generated for
// covariant return values).
// if (Mod.isSynthetic(mi.getAccessFlags())) continue;
IInvocable ii;
try {
ii = this.resolveMethod(mi);
} catch (ClassNotFoundException ex) {
throw new InternalCompilerException(ex.getMessage(), ex);
}
if (ii instanceof IMethod) iMethods.add((IMethod) ii);
}
return (IMethod[]) iMethods.toArray(new IMethod[iMethods.size()]);
}
@Override protected IField[]
getDeclaredIFields2() {
IField[] ifs = new IClass.IField[this.classFile.fieldInfos.size()];
for (int i = 0; i < this.classFile.fieldInfos.size(); ++i) {
try {
ifs[i] = this.resolveField((ClassFile.FieldInfo) this.classFile.fieldInfos.get(i));
} catch (ClassNotFoundException ex) {
throw new InternalCompilerException(ex.getMessage(), ex);
}
}
return ifs;
}
@Override protected IClass[]
getDeclaredIClasses2() throws CompileException {
ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
if (ica == null) return new IClass[0];
List res = new ArrayList<>();
for (ClassFile.InnerClassesAttribute.Entry e : ica.getEntries()) {
if (e.outerClassInfoIndex == this.classFile.thisClass) {
try {
res.add(this.resolveClass(e.innerClassInfoIndex));
} catch (ClassNotFoundException ex) {
throw new CompileException(ex.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
}
return (IClass[]) res.toArray(new IClass[res.size()]);
}
@Override @Nullable protected IClass
getDeclaringIClass2() throws CompileException {
ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
if (ica == null) return null;
for (ClassFile.InnerClassesAttribute.Entry e : ica.getEntries()) {
if (e.innerClassInfoIndex == this.classFile.thisClass) {
// Is this an anonymous class?
if (e.outerClassInfoIndex == 0) return null;
try {
return this.resolveClass(e.outerClassInfoIndex);
} catch (ClassNotFoundException ex) {
throw new CompileException(ex.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
}
return null;
}
@Override @Nullable protected IClass
getOuterIClass2() throws CompileException {
ClassFile.InnerClassesAttribute ica = this.classFile.getInnerClassesAttribute();
if (ica == null) return null;
for (ClassFile.InnerClassesAttribute.Entry e : ica.getEntries()) {
if (e.innerClassInfoIndex == this.classFile.thisClass) {
if (e.outerClassInfoIndex == 0) {
// Anonymous class or local class.
// TODO: Determine enclosing instance of anonymous class or local class
return null;
} else {
// Member type.
if (Mod.isStatic(e.innerClassAccessFlags)) return null;
try {
return this.resolveClass(e.outerClassInfoIndex);
} catch (ClassNotFoundException ex) {
throw new CompileException(ex.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
}
}
return null;
}
@Override @Nullable protected IClass
getSuperclass2() throws CompileException {
if (this.classFile.superclass == 0 || (this.classFile.accessFlags & Mod.INTERFACE) != 0) return null;
try {
return this.resolveClass(this.classFile.superclass);
} catch (ClassNotFoundException e) {
throw new CompileException(e.getMessage(), null); // SUPPRESS CHECKSTYLE AvoidHidingCause
}
}
@Override public Access
getAccess() { return ClassFileIClass.accessFlags2Access(this.accessFlags); }
@Override public boolean
isFinal() { return Mod.isFinal(this.accessFlags); }
@Override protected IClass[]
getInterfaces2() throws CompileException { return this.resolveClasses(this.classFile.interfaces); }
@Override public boolean
isAbstract() { return Mod.isAbstract(this.accessFlags); }
@Override protected String
getDescriptor2() { return Descriptor.fromClassName(this.classFile.getThisClassName()); }
@Override public boolean
isEnum() { return Mod.isEnum(this.accessFlags); }
@Override public boolean
isInterface() { return Mod.isInterface(this.accessFlags); }
@Override public boolean
isArray() { return false; }
@Override public boolean
isPrimitive() { return false; }
@Override public boolean
isPrimitiveNumeric() { return false; }
@Override @Nullable protected IClass
getComponentType2() { return null; }
@Override protected IAnnotation[]
getIAnnotations2() throws CompileException { return this.toIAnnotations(this.classFile.getAnnotations(true)); }
private IAnnotation[]
toIAnnotations(ClassFile.Annotation[] annotations) throws CompileException {
int count = annotations.length;
if (count == 0) return new IAnnotation[0];
IAnnotation[] result = new IAnnotation[count];
for (int i = 0; i < count; i++) result[i] = this.toIAnnotation(annotations[i]);
return result;
}
private IAnnotation
toIAnnotation(final ClassFile.Annotation annotation) throws CompileException {
final Map evps2 = new HashMap<>();
for (Entry e : annotation.elementValuePairs.entrySet()) {
Short elementNameIndex = (Short) e.getKey();
ClassFile.ElementValue elementValue = (ClassFile.ElementValue) e.getValue();
Object ev = elementValue.accept(
new ClassFile.ElementValue.Visitor
© 2015 - 2025 Weber Informatics LLC | Privacy Policy