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

Method PreparseVarRefs

source/script.cpp:13540–13608  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

13538
13539
13540ResultType Script::PreparseVarRefs()
13541{
13542 // AddLine() and ExpressionToPostfix() currently leave validation of output variables
13543 // and lvalues to this function, to reduce code size. Search for "VarIsReadOnlyError".
13544 for (Line *line = mFirstLine; line; line = line->mNextLine)
13545 {
13546 switch (line->mActionType)
13547 { // Establish context for FindOrAddVar:
13548 case ACT_BLOCK_BEGIN: if (line->mAttribute) g->CurrentFunc = (UserFunc *)line->mAttribute; break;
13549 case ACT_BLOCK_END: if (line->mAttribute) g->CurrentFunc = g->CurrentFunc->mOuterFunc; break;
13550 }
13551
13552 for (int a = 0; a < line->mArgc; ++a)
13553 {
13554 ArgStruct &arg = line->mArg[a];
13555 if (!arg.is_expression)
13556 continue;
13557 for (ExprTokenType *token = arg.postfix; token->symbol != SYM_INVALID; ++token)
13558 {
13559 if (token->symbol != SYM_VAR // Not a var.
13560 || VARREF_IS_WRITE(token->var_usage)) // Already resolved by ExpressionToPostfix.
13561 continue;
13562 if ( !(token->var = FindOrAddVar(token->var_deref->marker, token->var_deref->length, FINDVAR_FOR_READ)) )
13563 return FAIL;
13564 if (token->var->IsAlias()) // Upvar.
13565 continue;
13566 switch (token->var->Type())
13567 {
13568 case VAR_CONSTANT:
13569 // Resolve constants to their values, except in cases like IsSet(SomeClass), or when
13570 // the constant is a closure (which may change each time the outer function is called).
13571 if (!token->var->IsLocal() && token->var_usage == VARREF_READ && !token->var->IsUninitialized())
13572 token->var->ToToken(*token);
13573 continue;
13574 case VAR_VIRTUAL:
13575 if (token->var_usage == VARREF_READ)
13576 ++arg.max_alloc; // Reserve a to_free[] slot for it in ExpandExpression().
13577 break;
13578 default:
13579 // Suppress any VarUnset warnings for IsSet(var) so that it can be used to determine if an
13580 // optionally-set global variable has been set, such as a class in an optional #Include.
13581 // MarkAssignedSomewhere() isn't used for this because PreprocessLocalVars() hasn't been
13582 // called yet, and it relies on the attribute being accurate.
13583 if (token->var_usage == VARREF_ISSET)
13584 token->var->MarkAlreadyWarned();
13585 // It's too early to show VarUnset warnings, since not all VARREF_ISSET references have been marked.
13586 // The effect of IsSet(v) for suppressing the warning shouldn't be positional since it's feasible for
13587 // a check in one function to guard evaluation of a VARREF_READ in some other function.
13588 }
13589 }
13590 if (arg.type == ARG_TYPE_INPUT_VAR)
13591 {
13592 if (arg.postfix->symbol != SYM_VAR || arg.postfix->var->Type() != VAR_NORMAL)
13593 {
13594 // Can't be ARG_TYPE_INPUT_VAR after all, as VAR_VIRTUAL and VAR_CONSTANT require ExpandExpression
13595 // (unless it's a constant which was converted to SYM_OBJECT above).
13596 arg.type = ARG_TYPE_NORMAL;
13597 }

Callers

nothing calls this directly

Calls 6

IsAliasMethod · 0.80
IsLocalMethod · 0.80
IsUninitializedMethod · 0.80
MarkAlreadyWarnedMethod · 0.80
TypeMethod · 0.45
ToTokenMethod · 0.45

Tested by

no test coverage detected