المتغيرات المحلية Java - كيف أحصل على اسم أو نوع متغير باستخدام الفهرس الخاص به

StackOverflow https://stackoverflow.com/questions/4324321

سؤال

أنا أستخدم مكتبة أجهزة ASM. باستخدام VisitVarinsn أحصل على فهرس متغير محلي. أرغب في استخدام هذا الفهرس واستلام المزيد من المعلومات المفيدة مثل اسم المتغير والنوع. هل لديك أي فكرة كيف؟ شكرًا.

هل كانت مفيدة؟

المحلول

استقله في LocalVariablorster.visitlocalvariable طريقة.

نصائح أخرى

أنا أستخدم الكود أدناه:

    private LocalVariableNode getLocalVariableNode(VarInsnNode varInsnNode, MethodNode methodNode) {
        int varIdx = varInsnNode.var;
        int instrIdx = getInstrIndex(varInsnNode);
        List<?> localVariables = methodNode.localVariables;
        for (int idx = 0; idx < localVariables.size(); idx++) {
            LocalVariableNode localVariableNode = (LocalVariableNode) localVariables.get(idx);
            if (localVariableNode.index == varIdx) {
                int scopeEndInstrIndex = getInstrIndex(localVariableNode.end);
                if (scopeEndInstrIndex >= instrIdx) {
                    // still valid for current line
                    return localVariableNode;
                }
            }
        }
        throw new RuntimeException("Variable with index " + varIdx + " and scope end >= " + instrIdx
                + " not found for method " + methodNode.name + "!");
    }

المشكلة العامة هي أنه يمكن إعادة استخدام فهرس المتغير المحلي. لذلك عليك التأكد من أنك تحصل على محلي محلي صحيح لمؤشر معين. للقيام بذلك ، تحتاج إلى التأكد من أن المتغير المعطى لا يزال صالحًا في موضع الكود حيث يتم استخدامه. المشكلة هي أنه لا يمكنك استخدام أرقام الأسطر ، لأن

  1. موضع البدء هو سطر الكود التالي بعد، بعدما تم تعريف المتغير. منذ تجاهل الخطوط الفارغة والتعليقات ، يمكن أن يكون ذلك أي سطر متابع. ولكن نظرًا لأن الكود يمكن أن يعيد استخدام متغير موجود ، فقد يكون هذا أيضًا أي سطر قبل السطر الحالي.

  2. يمكن أن يكون الموضع النهائي قبل خط البداية من حكمة (على سبيل المثال في حلقة).

  3. ربما تم تجميع الكود بدون معلومات الخط.

لذلك تحتاج إلى استخدام فهرس التعليمات ، وهو صحيح دائمًا. ولكن هي معلومات داخلية في AbstractInsNnode التي لا يمكن الوصول إليها من الخارج. للتحايل على هذه المشكلة ، أستخدم الكود التالي ، والذي من الواضح أنه يكسر التغليف ولا ينصح به لعدد من الأسباب. إذا توصلت إلى أي شيء أفضل ، اسمحوا لي أن أعرف! في غضون ذلك ، هذا يعمل:

    private int getInstrIndex(AbstractInsnNode insnNode) {
        try {
            Field indexField = AbstractInsnNode.class.getDeclaredField("index");
            indexField.setAccessible(true);
            Object indexValue = indexField.get(insnNode);
            return ((Integer) indexValue).intValue();
        } catch (Exception exc) {
            throw new RuntimeException(exc);
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top