MCPcopy Create free account
hub / github.com/AutoHotkey/AutoHotkey / PreparseCommands

Method PreparseCommands

source/script.cpp:7478–7671  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

7476
7477
7478Line *Script::PreparseCommands(Line *aStartingLine)
7479// Preparse any commands which might rely on blocks having been fully preparsed,
7480// such as any command which has a jump target (label).
7481// Also perform some late-stage optimizations and validation.
7482{
7483 for (Line *line = aStartingLine; line; line = line->mNextLine)
7484 {
7485 LPTSTR line_raw_arg1 = LINE_RAW_ARG1; // Resolve only once to help reduce code size.
7486 LPTSTR line_raw_arg2 = LINE_RAW_ARG2; //
7487
7488 switch (line->mActionType)
7489 {
7490 case ACT_BLOCK_BEGIN:
7491 if (line->mAttribute) // This is the opening brace of a function definition.
7492 g->CurrentFunc = (UserFunc *)line->mAttribute; // Must be set only for the above condition because functions can of course contain types of blocks other than the function's own block.
7493 break;
7494 case ACT_BLOCK_END:
7495 if (line->mAttribute) // This is the closing brace of a function definition.
7496 {
7497 auto &func = *(UserFunc *)line->mAttribute;
7498
7499 g->CurrentFunc = func.mOuterFunc;
7500
7501 Line *block_begin = line->mParentLine;
7502 Line *parent = block_begin->mParentLine;
7503
7504 if (func.mIsFuncExpression // =>
7505 && block_begin->mParentLine
7506 && block_begin->mParentLine->mActionType != ACT_BLOCK_BEGIN)
7507 {
7508 if (line->mNextLine->mActionType == ACT_BLOCK_BEGIN) // It could only be a fat arrow block-begin under these conditions.
7509 // There's another =>function after this one (defined within the same
7510 // expression), so just continue until the last =>function is found.
7511 continue;
7512 // This fat arrow function's parent line is a statement with a single-line
7513 // action, but that action is currently separated from its parent by one or
7514 // more fat arrow functions. It won't work that way because If/Else/Loop/etc.
7515 // all skip an initial ACT_BLOCK_BEGIN (to avoid an extra ExecUntil call),
7516 // which would result in executing the function's body instead of skipping it.
7517 Line *body = line->mNextLine;
7518 #ifdef KEEP_FAT_ARROW_FUNCTIONS_IN_LINE_LIST // Currently unused.
7519 block_begin = parent->mNextLine; // In case there are multiple fat arrow functions on one line.
7520 Line *after_body = parent->mRelatedLine;
7521 Line *body_end = after_body->mPrevLine; // In case body is multiple lines (such as a nested IF or LOOP).
7522 // Swap the statement body and fat arrow functions around to make it work:
7523 parent ->mNextLine = body , body ->mPrevLine = parent;
7524 body_end ->mNextLine = block_begin, block_begin->mPrevLine = body_end;
7525 line ->mNextLine = after_body , after_body ->mPrevLine = line;
7526 #else
7527 // Remove the fat arrow functions to allow the correct body to execute.
7528 // This relies on there being no need for the fat arrow functions to
7529 // remain in the Line list after this point (so for instance, there's
7530 // no possibility of setting a breakpoint in one of these functions).
7531 parent->mNextLine = body, body->mPrevLine = parent;
7532 #endif
7533 }
7534 else if (parent && parent->mActionType != ACT_BLOCK_BEGIN)
7535 {

Callers

nothing calls this directly

Calls 5

IsNumericFunction · 0.85
sntprintfFunction · 0.85
PreparseErrorMethod · 0.80
GetJumpTargetMethod · 0.80
FinalizeExpressionMethod · 0.80

Tested by

no test coverage detected