dynamicclassreferenceinitializer.java

来自「proguard 一个java的混淆器」· Java 代码 · 共 441 行 · 第 1/2 页

JAVA
441
字号
                                            WarningPrinter notePrinter,                                            StringMatcher  noteExceptionMatcher)    {        this.programClassPool     = programClassPool;        this.libraryClassPool     = libraryClassPool;        this.notePrinter          = notePrinter;        this.noteExceptionMatcher = noteExceptionMatcher;    }    // Implementations for InstructionVisitor.    public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)    {        // Try to match the Class.forName("SomeClass") construct.        instruction.accept(clazz, method, codeAttribute, offset,                           constantClassForNameMatcher);        // Did we find a match?        if (constantClassForNameMatcher.isMatching())        {            // Fill out the matched string constant.            clazz.constantPoolEntryAccept(constantClassForNameMatcher.matchedConstantIndex(X), this);            // Don't look for the dynamic construct.            classForNameCastMatcher.reset();        }        // Try to match the (SomeClass)Class.forName(someName).newInstance()        // construct.        instruction.accept(clazz, method, codeAttribute, offset,                           classForNameCastMatcher);        // Did we find a match?        if (classForNameCastMatcher.isMatching())        {            // Print out a note about the construct.            clazz.constantPoolEntryAccept(classForNameCastMatcher.matchedConstantIndex(X), this);        }        // Try to match the javac .class construct.        instruction.accept(clazz, method, codeAttribute, offset,                           dotClassJavacMatcher);        // Did we find a match?        if (dotClassJavacMatcher.isMatching() &&            isDotClassMethodref(clazz, dotClassJavacMatcher.matchedConstantIndex(0)))        {            // Fill out the matched string constant.            clazz.constantPoolEntryAccept(dotClassJavacMatcher.matchedConstantIndex(X), this);        }        // Try to match the jikes .class construct.        instruction.accept(clazz, method, codeAttribute, offset,                           dotClassJikesMatcher);        // Did we find a match?        if (dotClassJikesMatcher.isMatching() &&            isDotClassMethodref(clazz, dotClassJikesMatcher.matchedConstantIndex(0)))        {            // Fill out the matched string constant.            clazz.constantPoolEntryAccept(dotClassJikesMatcher.matchedConstantIndex(X), this);        }    }    // Implementations for ConstantVisitor.    /**     * Fills out the link to the referenced class.     */    public void visitStringConstant(Clazz clazz, StringConstant stringConstant)    {        // Save a reference to the corresponding class.        String externalClassName = stringConstant.getString(clazz);        String internalClassName = ClassUtil.internalClassName(externalClassName);        stringConstant.referencedClass = findClass(internalClassName);    }    /**     * Prints out a note about the class cast to this class, if applicable.     */    public void visitClassConstant(Clazz clazz, ClassConstant classConstant)    {        // Print out a note about the class cast.        if (notePrinter != null &&            (noteExceptionMatcher == null ||             !noteExceptionMatcher.matches(classConstant.getName(clazz))))        {            notePrinter.print("Note: " +                              ClassUtil.externalClassName(clazz.getName()) +                              " calls '(" +                              ClassUtil.externalClassName(classConstant.getName(clazz)) +                              ")Class.forName(variable).newInstance()'");        }    }    /**     * Checks whether the referenced method is a .class method.     */    public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)    {        String methodType = methodrefConstant.getType(clazz);        // Do the method's class and type match?        if (methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JAVAC) ||            methodType.equals(ClassConstants.INTERNAL_METHOD_TYPE_DOT_CLASS_JIKES))        {            String methodName = methodrefConstant.getName(clazz);            // Does the method's name match one of the special names?            isClassForNameInvocation =                methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JAVAC) ||                methodName.equals(ClassConstants.INTERNAL_METHOD_NAME_DOT_CLASS_JIKES);            if (isClassForNameInvocation)            {                return;            }            String className  = methodrefConstant.getClassName(clazz);            // Note that we look for the class by name, since the referenced            // class has not been initialized yet.            Clazz referencedClass = programClassPool.getClass(className);            if (referencedClass != null)            {                // Check if the code of the referenced method is .class code.                // Note that we look for the method by name and type, since the                // referenced method has not been initialized yet.                referencedClass.methodAccept(methodName,                                             methodType,                                             new AllAttributeVisitor(this));            }        }    }    // Implementations for AttributeVisitor.    public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)    {        // Check whether this is class$(String), as generated by javac, or        // class(String, boolean), as generated by jikes, or an optimized        // version.        isClassForNameInvocation =            isDotClassMethodCode(clazz, method, codeAttribute,                                 dotClassJavacImplementationMatcher, 5)  ||            isDotClassMethodCode(clazz, method, codeAttribute,                                 dotClassJikesImplementationMatcher, 12) ||            isDotClassMethodCode(clazz, method, codeAttribute,                                 dotClassJikesImplementationMatcher2, 8);    }    // Small utility methods.    /**     * Returns whether the given method reference corresponds to a .class     * method, as generated by javac or by jikes.     */    private boolean isDotClassMethodref(Clazz clazz, int methodrefConstantIndex)    {        isClassForNameInvocation = false;        // Check if the code of the referenced method is .class code.        clazz.constantPoolEntryAccept(methodrefConstantIndex, this);        return isClassForNameInvocation;    }    /**     * Returns whether the first whether the first instructions of the     * given code attribute match with the given instruction matcher.     */    private boolean isDotClassMethodCode(Clazz                      clazz,                                         Method                     method,                                         CodeAttribute              codeAttribute,                                         InstructionSequenceMatcher codeMatcher,                                         int                        codeLength)    {        // Check the minimum code length.        if (codeAttribute.u4codeLength < codeLength)        {            return false;        }        // Check the actual instructions.        codeMatcher.reset();        codeAttribute.instructionsAccept(clazz, method, 0, codeLength, codeMatcher);        return codeMatcher.isMatching();    }    /**     * Returns the class with the given name, either for the program class pool     * or from the library class pool, or <code>null</code> if it can't be found.     */    private Clazz findClass(String name)    {        // First look for the class in the program class pool.        Clazz clazz = programClassPool.getClass(name);        // Otherwise look for the class in the library class pool.        if (clazz == null)        {            clazz = libraryClassPool.getClass(name);        }        return clazz;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?