Perl-Critic / PPI

53 stars 44 forks source link

Allow statements as well as structures and tokens to be inserted adjacent to a token #151

Open karenetheridge opened 9 years ago

karenetheridge commented 9 years ago

Otherwise, this would be impossible:

my $doc = PPI::Document->new(\ "1;\n");
my $token = $doc->last_element;

my $new_document = PPI::Document->new(\ '$foo = 1;');
$token->insert_after($_) foreach reverse $new_document->schildren;
adamkennedy commented 9 years ago

I'm not sure it can be this simple.

You need tests for this, because I'm fairly certain this will allow breaking the structural integrity rules. You end up with statement/statement children, and possibly structure/structure children as well.

The token you insert after has to be insignificant and not be a direct child of the same type of thing you are inserting.

But that said, I'm really excited to see someone padding document manipulation functionality forward. Thank you so much.

karenetheridge commented 9 years ago

Hmm ok, I guess I picked the wrong solution to the problem.

Let me back up and restate the problem:

"I have a parsed PPI::Document. I have a snippet of code, in a string, that I wish to insert at a specific point (let's say the end, for simplicity) in the document. How can I do that?" The code example in the top post was my best guess at a solution, but it only works if the new code snippet parses to specific types of nodes (e.g. tokens), and not other types (a statement).

adamkennedy commented 9 years ago

I had always intended PPI::Document::Fragment to represent arbitrary chunks of code that may not be serialisable out to as a full document (so they have a tree but no line numbers etc) , and would hold the complex logic needed to automate insertion into documents properly.

Adam On Dec 19, 2014 5:46 AM, "Karen Etheridge" notifications@github.com wrote:

Hmm ok, I guess I picked the wrong solution to the problem.

Let me back up and restate the problem:

"I have a parsed PPI::Document. I have a snippet of code, in a string, that I wish to insert at a specific point in the document. How can I do that?" The code example in the top post was my best guess at a solution, but it only works if the new code snippet parses to specific types of nodes (e.g. tokens), and not other types (a statement).

— Reply to this email directly or view it on GitHub https://github.com/adamkennedy/PPI/pull/151#issuecomment-67534157.

adamkennedy commented 9 years ago

By the way, that idea of serialisable or not is why you can't save arbitrary statements to files. Without identifying something as a full blown document, things like heredocs won't unroll correctly.

Fragments would not be expected to serialize in this way, freeing them up to be moved and manipulated much more freely and becoming the main vessel for cut/copy/paste operations and the like.

Adam On Dec 19, 2014 5:46 AM, "Karen Etheridge" notifications@github.com wrote:

Hmm ok, I guess I picked the wrong solution to the problem.

Let me back up and restate the problem:

"I have a parsed PPI::Document. I have a snippet of code, in a string, that I wish to insert at a specific point in the document. How can I do that?" The code example in the top post was my best guess at a solution, but it only works if the new code snippet parses to specific types of nodes (e.g. tokens), and not other types (a statement).

— Reply to this email directly or view it on GitHub https://github.com/adamkennedy/PPI/pull/151#issuecomment-67534157.

wchristian commented 2 years ago

This does need tests and also particularly tests of the type of "what happens if the document you're inserting to is a partial perl document and the last element is an unclosed string in the middle of a function call in the middle of a subrouting? how does this interact with serializing?"