Excluding code from IDE

Every so often I run into a block of JavaScript code that messes with the IDE. Everything compiles and runs fine, but If I try to double-click on an event in the object inspector or autogenerate a new function implementation, it fails with errors like "Cannot find Imlementation Method" or "cannot complete a class with incomplete implementation methods". This is due to the IDE seemingly not able to parse that a method has ended when it encounters this code. Sometimes, even commenting out the code doesn't work - even though it is valid code.

Is there a way to more fully block the IDE from trying to parse the JavaScript code? Here's an example:

procedure TForm1.WebButton1Click(Sender: TObject);
begin

  {$IFNDEF WIN32} asm {
    var i = {elements: 0, unicorns: 3};
    while ((i.elements < i.unicorns) && (i.unicorns < 10)) {
      console.log('elements: '+i.elements)
      i.elements++;
    }
  } end; {$ENDIF}

end;

procedure TForm1.WebFormCreate(Sender: TObject);
begin
  //
end;

Looks innocent enough, right? Well, when you look at the code in the IDE, you can see the little "expand" square beside the WebFormCreate function isn't there.

In this example commenting out the code brings it back and things work ok again IDE-wise.

Sometimes the code can't be rearranged all that easily to get the IDE to cooperate as it isn't clear (at least to me!) what it is getting tripped up by. This is just one example, but there are others. So is there another way to wrap the JavaScript code that will get everyone to play together nicely?

Hm. Adding an extra space in the {$IFNDEF WIN32 } line between the WIN32 and the closing brace seems to help?! But not for everything. For example, JavaScript's try/catch seems to also cause the IDE to parse incorrectly.

Is there a way to preprocess the code before it is sent to PAS2JS? LIke If I coded up the try/catch as attempt/catch instead, but somehow swap out the attempt for try before it is sent along to be compiled? It doesn't come up all that often so moving a method that has that in it to the bottom of the implementation seems to be workable at the moment.

Is it possible that you have a mix of CR and CR/LF linebreaks in the code.
In the past, when I ran into similar issues, I reformatted the code (Ctrl-D) and issues were gone.

1 Like

Good idea. I've run across that as well, particularly when copying & pasting code from online sources. Didn't help here though. I just came up with the extra space idea today so that's been a big help. Here it is in action.

space

Note that most of the time, this works well without giving it a second thought. There are just some bits of JavaScript that trip it up. For example, remove the && condition from the while loop and it is fine.

The extra space seems to have solved them all except for the try/catch situation. I think it assumes that the try block is Delphi and can't find the rest of it so things don't work quite as well. Code still compiles fine though.

I'm mostly using this:

image

and doesn't cause a problem with try/catch.

I have no problems compiling and running the code, even with try/catch. Just with the IDE not being able to correctly parse the end of the method. Visually this is when the next method gets its little code expand/collapse UI element (shown here with the WebFormCreate method), but if the IDE doesn't get that sorted, then other IDE stuff doesn't quite work right, like method completion and that sort of thing. I tried with the PAS2JS variation, doesn't seem to be any better.

IDE2

Oh, and if I comment out the while loop as well, the PAS2JS variant does parse correctly, as it does with the WIN32 variant.

So to recap:

Without compiler directive (just asm by itself)

  • While loop doesn't have issue
  • try/catch does have issue

{$IFNDEF WIN32}

  • While loop does have issue
  • try/catch doesn't have issue

{$IFNDEF WIN32 } (with extra space after WIN32)

  • While loop doesn't have issue
  • try/catch does have issue

{$IFDEF PAS2JS}

  • While loop does have issue
  • try/catch doesn't have issue

Just odd.

I see that while loop indeed has the issue.
Why the LSP is still going into the code-block disabled with {$IFDEF PAS2JS} is a mystery to me. Looks like a bug in the LSP.

Trick with which I could workaround it:

  {$IFDEF PAS2JS}
  asm  
   var i = {lions: 0, unicorns: 3};
   {
     while ((i.lions < i.unicorns) && (i.unicorns < 10))  {
     console.log('lions:'+i.lions);
     i.lions++;
     }
   }
  end;  
  {$ENDIF}

Well, the good thing is that they all compile and work, ultimately. But a bit of a nuisance as sometimes you don't notice when this happens until something else doesn't work, like double-clicking on an event and it starts complaining.

Why the LSP cares is I suppose a mystery. If it is suppose to ignore the code...

Another workaround is to just put that JS code elsewhere in its own unit so all the offenders can hangout together.