4 Replies Latest reply on Feb 27, 2005 12:56 PM by sins ro

    How to replace this??

    sins ro Newbie

      I need to find and replace all instances of

      if(Display.getDisplay(this).getCurrent()==null)
      {
      ...
      }

      in a given class, with
      if (_getCurrent()==null)
      {
      ...
      }

      _getCurrent() is a local method in the same class.

      Sounds easy, but I have found no way to do this in Javassist so far. Is it possible at all?

      Please help!



        • 1. Re: How to replace this??
          Shigeru Chiba Expert

          I think you want to replace cascaded method calls
          with another expression.

          But I'm wondering whether or not such replacement
          is used frequently enough to be included in the Javassist
          API. Do you think the Javassist API includes a method
          for replacing two-cascaded method calls, three-cascaded,
          ...? I would like to know your thought.

          Thank you,

          • 2. Re: How to replace this??
            sins ro Newbie

             

            "chiba" wrote:
            I think you want to replace cascaded method calls
            with another expression.

            But I'm wondering whether or not such replacement
            is used frequently enough to be included in the Javassist
            API. Do you think the Javassist API includes a method
            for replacing two-cascaded method calls, three-cascaded,
            ...? I would like to know your thought.

            Thank you,


            I wrote a search/replace class myself that is quite useful in fact. It is a bit low-level, but still user friendly.

            It takes two arrays as input, one for search and one for replace.

            The array elements have two different meanings: Opcode, or reference. An opcode is simply a byte, the reference is a string which will be converted to the right two byte long index for comparison.

            
            //Replace all Display.getDisplay(this).getCurrent() with _getCurrent()
             SmartBytecode search=new SmartBytecode();
             search.addOpcode(Opcode.ALOAD_0);
             search.addOpcode(Opcode.INVOKESTATIC);
             search.addReference("getDisplay");
             search.addOpcode(Opcode.INVOKEVIRTUAL);
             search.addReference("getCurrent");
            
             SmartBytecode replace=new SmartBytecode();
             replace.addOpcode(Opcode.INVOKESTATIC);
             replace.addReference("_getCurrent,javax.microedition.lcdui.Displayable");
             replaceAll(cHost, search, replace,"_getCurrent");
            
            


            The search is mathced both on the value, but also on the location. If a byte is found which matches a opcode, it will still be rejected if it is not in a dedicated opcode position, same with reference values.

            Replacing is done by the replacing code, with correct indexes to the reference names, and NOPs are filled in where needed.

            Also, very importantly, I allow putting "holes" in the arrays, to allow for proper search and replace when some bytes might change value, like which local variable is used to hold a parameter value for example. The 'holes' will be ignored during comparison, and will not overwrite upon replacing. This allows for search and replace on complex patterns, with good flexibility.

            Not sure if this is everyones cup of tea, but it solved all my complex search and replace needs... :)


            • 3. Re: How to replace this??
              Shigeru Chiba Expert

              I see. Your approach is right. However, your approach
              might complicate a program if the search pattern is
              complex.

              For example, if you want to find both

              boolean b
              = Display.getDisplay(<some expression>).getCurrent()

              and

              Display d = Display.getDisplay(this);
              boolean b = d.getCurrent();

              Then the pattern given to SmartBytecode would be
              much more complicated.

              • 4. Re: How to replace this??
                sins ro Newbie

                Yes, there are many different ways to write code to do the same thing, and smartbytecode is not supposed to find all in one pass. Multiple passes is needed, and if planned carefully most cases can be found... Works fine for me at least.. :)


                "chiba" wrote:
                I see. Your approach is right. However, your approach
                might complicate a program if the search pattern is
                complex.

                For example, if you want to find both

                boolean b
                = Display.getDisplay(<some expression>).getCurrent()

                and

                Display d = Display.getDisplay(this);
                boolean b = d.getCurrent();

                Then the pattern given to SmartBytecode would be
                much more complicated.