static void findClojureTags (void) { vString *name = vStringNew (); const char *p; int scope_index = CORK_NIL; while ((p = (char *)readLineFromInputFile ()) != NULL) { vStringClear (name); while (isspace (*p)) p++; if (*p == '(') { if (isNamespace (p)) { skipToSymbol (&p); scope_index = makeNamespaceTag (name, p); } else if (isFunction (p)) { skipToSymbol (&p); makeFunctionTag (name, p, scope_index); } } } vStringDelete (name); }
static void findClojureTags (void) { vString *name = vStringNew (); const unsigned char *p; CurrentNamespace = vStringNew (); while ((p = fileReadLine ()) != NULL) { vStringClear (name); while (isspace (*p)) p++; if (*p == '(') { if (isNamespace (p)) { skipToSymbol (&p); makeNamespaceTag (name, p); } else if (isFunction (p)) { skipToSymbol (&p); makeFunctionTag (name, p); } } } vStringDelete (name); vStringDelete (CurrentNamespace); }
static void parseFunction (tokenInfo *const token) { tokenInfo *const name = newToken (); vString *const signature = vStringNew (); boolean is_class = FALSE; /* * This deals with these formats * function validFunctionTwo(a,b) {} */ readToken (name); if (!isType (name, TOKEN_IDENTIFIER)) goto cleanUp; /* Add scope in case this is an INNER function */ addToScope(name, token->scope); readToken (token); while (isType (token, TOKEN_PERIOD)) { readToken (token); if ( isKeyword(token, KEYWORD_NONE) ) { addContext (name, token); readToken (token); } } if ( isType (token, TOKEN_OPEN_PAREN) ) skipArgumentList(token, FALSE, signature); if ( isType (token, TOKEN_OPEN_CURLY) ) { is_class = parseBlock (token, name); if ( is_class ) makeClassTag (name, signature); else makeFunctionTag (name, signature); } findCmdTerm (token, FALSE, FALSE); cleanUp: vStringDelete (signature); deleteToken (name); }
/* parse a function * * if @name is NULL, parses a normal function * function myfunc($foo, $bar) {} * function &myfunc($foo, $bar) {} * function myfunc($foo, $bar) : type {} * * if @name is not NULL, parses an anonymous function with name @name * $foo = function($foo, $bar) {} * $foo = function&($foo, $bar) {} * $foo = function($foo, $bar) use ($x, &$y) {} * $foo = function($foo, $bar) use ($x, &$y) : type {} */ static boolean parseFunction (tokenInfo *const token, const tokenInfo *name) { boolean readNext = TRUE; accessType access = CurrentStatement.access; implType impl = CurrentStatement.impl; tokenInfo *nameFree = NULL; readToken (token); /* skip a possible leading ampersand (return by reference) */ if (token->type == TOKEN_AMPERSAND) readToken (token); if (! name) { if (token->type != TOKEN_IDENTIFIER && token->type != TOKEN_KEYWORD) return FALSE; name = nameFree = newToken (); copyToken (nameFree, token, TRUE); readToken (token); } if (token->type == TOKEN_OPEN_PAREN) { vString *arglist = vStringNew (); int depth = 1; vStringPut (arglist, '('); do { readToken (token); switch (token->type) { case TOKEN_OPEN_PAREN: depth++; break; case TOKEN_CLOSE_PAREN: depth--; break; default: break; } /* display part */ switch (token->type) { case TOKEN_AMPERSAND: vStringPut (arglist, '&'); break; case TOKEN_CLOSE_CURLY: vStringPut (arglist, '}'); break; case TOKEN_CLOSE_PAREN: vStringPut (arglist, ')'); break; case TOKEN_CLOSE_SQUARE: vStringPut (arglist, ']'); break; case TOKEN_COLON: vStringPut (arglist, ':'); break; case TOKEN_COMMA: vStringCatS (arglist, ", "); break; case TOKEN_EQUAL_SIGN: vStringCatS (arglist, " = "); break; case TOKEN_OPEN_CURLY: vStringPut (arglist, '{'); break; case TOKEN_OPEN_PAREN: vStringPut (arglist, '('); break; case TOKEN_OPEN_SQUARE: vStringPut (arglist, '['); break; case TOKEN_PERIOD: vStringPut (arglist, '.'); break; case TOKEN_SEMICOLON: vStringPut (arglist, ';'); break; case TOKEN_BACKSLASH: vStringPut (arglist, '\\'); break; case TOKEN_STRING: { vStringCatS (arglist, "'"); vStringCat (arglist, token->string); vStringCatS (arglist, "'"); break; } case TOKEN_IDENTIFIER: case TOKEN_KEYWORD: case TOKEN_VARIABLE: { switch (vStringLast (arglist)) { case 0: case ' ': case '{': case '(': case '[': case '.': case '\\': /* no need for a space between those and the identifier */ break; default: vStringPut (arglist, ' '); break; } if (token->type == TOKEN_VARIABLE) vStringPut (arglist, '$'); vStringCat (arglist, token->string); break; } default: break; } } while (token->type != TOKEN_EOF && depth > 0); vStringTerminate (arglist); makeFunctionTag (name, arglist, access, impl); vStringDelete (arglist); readToken (token); /* normally it's an open brace or "use" keyword */ } /* skip use(...) */ if (token->type == TOKEN_KEYWORD && token->keyword == KEYWORD_use) { readToken (token); skipOverParens (token); } /* PHP7 return type declaration or if parsing Zephir, skip function return * type hint */ if ((getInputLanguage () == Lang_php && token->type == TOKEN_COLON) || (getInputLanguage () == Lang_zephir && token->type == TOKEN_OPERATOR)) { do readToken (token); while (token->type == TOKEN_IDENTIFIER || token->type == TOKEN_BACKSLASH); } if (token->type == TOKEN_OPEN_CURLY) enterScope (token, name->string, K_FUNCTION); else readNext = FALSE; if (nameFree) deleteToken (nameFree); return readNext; }
/* parse a function * * function myfunc($foo, $bar) {} */ static bool parseFunction (tokenInfo *const token) { bool readNext = true; tokenInfo *nameFree = NULL; const char *access; readToken (token); if (token->type != TOKEN_IDENTIFIER) return false; access = parsePowerShellScope (token); nameFree = newToken (); copyToken (nameFree, token, true); readToken (token); if (token->type == TOKEN_OPEN_PAREN) { vString *arglist = vStringNew (); int depth = 1; vStringPut (arglist, '('); do { readToken (token); switch (token->type) { case TOKEN_OPEN_PAREN: depth++; break; case TOKEN_CLOSE_PAREN: depth--; break; default: break; } /* display part */ switch (token->type) { case TOKEN_CLOSE_CURLY: vStringPut (arglist, '}'); break; case TOKEN_CLOSE_PAREN: vStringPut (arglist, ')'); break; case TOKEN_CLOSE_SQUARE: vStringPut (arglist, ']'); break; case TOKEN_COLON: vStringPut (arglist, ':'); break; case TOKEN_COMMA: vStringCatS (arglist, ", "); break; case TOKEN_EQUAL_SIGN: vStringCatS (arglist, " = "); break; case TOKEN_OPEN_CURLY: vStringPut (arglist, '{'); break; case TOKEN_OPEN_PAREN: vStringPut (arglist, '('); break; case TOKEN_OPEN_SQUARE: vStringPut (arglist, '['); break; case TOKEN_PERIOD: vStringPut (arglist, '.'); break; case TOKEN_SEMICOLON: vStringPut (arglist, ';'); break; case TOKEN_STRING: vStringCatS (arglist, "'...'"); break; case TOKEN_IDENTIFIER: case TOKEN_KEYWORD: case TOKEN_VARIABLE: { switch (vStringLast (arglist)) { case 0: case ' ': case '{': case '(': case '[': case '.': /* no need for a space between those and the identifier */ break; default: vStringPut (arglist, ' '); break; } if (token->type == TOKEN_VARIABLE) vStringPut (arglist, '$'); vStringCat (arglist, token->string); break; } default: break; } } while (token->type != TOKEN_EOF && depth > 0); makeFunctionTag (nameFree, arglist, access); vStringDelete (arglist); readToken (token); } else if (token->type == TOKEN_OPEN_CURLY) { /* filters doesn't need to have an arglist */ makeFunctionTag (nameFree, NULL, access); } if (token->type == TOKEN_OPEN_CURLY) enterScope (token, nameFree->string, K_FUNCTION); else readNext = false; if (nameFree) deleteToken (nameFree); return readNext; }