File: JavaScriptFunctionsLocator.cpp

package info (click to toggle)
codelite 12.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 95,112 kB
  • sloc: cpp: 424,040; ansic: 18,284; php: 9,569; lex: 4,186; yacc: 2,820; python: 2,294; sh: 312; makefile: 51; xml: 13
file content (123 lines) | stat: -rw-r--r-- 4,094 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "JavaScriptFunctionsLocator.h"
#include <algorithm>
#include <wx/tokenzr.h>
#include "CxxScannerTokens.h"
#include "JSLexerTokens.h"
#include "fileutils.h"

JavaScriptFunctionsLocator::JavaScriptFunctionsLocator(const wxFileName& filename, const wxString& content)
    : m_state(kNormal)
{
    const wxString jsKeywords = "abstract	arguments	boolean	break	byte "
                                "case	catch	char	class*	const "
                                "continue	debugger	default	delete	do "
                                "double	else	enum*	eval	export* "
                                "extends*	false	final	finally	float "
                                "for	function	goto	if	implements "
                                "import*	in	instanceof	int	interface "
                                "let	long	native	new	null "
                                "package	private	protected	public	return "
                                "short	static	super*	switch	synchronized "
                                "this	throw	throws	transient	true "
                                "try	typeof	var	void	volatile "
                                "while	with	yield prototype undefined StringtoString NaN";
    wxArrayString keywords = ::wxStringTokenize(jsKeywords, "\t ", wxTOKEN_STRTOK);
    for(size_t i = 0; i < keywords.size(); ++i) {
        m_keywords.insert(keywords.Item(i));
    }

    wxString fileContent = content;
    if(!fileContent.IsEmpty() || FileUtils::ReadFileContent(filename, fileContent)) {
        m_scanner = ::jsLexerNew(fileContent);
    }
}

JavaScriptFunctionsLocator::~JavaScriptFunctionsLocator()
{
    if(m_scanner) {
        ::jsLexerDestroy(&m_scanner);
    }
}

void JavaScriptFunctionsLocator::OnToken(JSLexerToken& token)
{
    // We collect every word which is followed by "(" (except for keywords)

    switch(m_state) {
    //---------------------------------------------------------
    // Normal parsing state, nothing special here
    //---------------------------------------------------------
    case kNormal: {
        switch(token.type) {
        case kJS_IDENTIFIER: {
            if(m_keywords.count(token.text) == 0) {
                // keep it
                m_lastIdentifier = token.text;
            } else {
                // a keyword, skip it
                m_lastIdentifier.clear();
            }
            break;
        }
        case kJS_DOT:
            if(!m_lastIdentifier.IsEmpty()) {
                // a property
                m_properties.insert(m_lastIdentifier);
            }
            m_lastIdentifier.Clear();
            m_state = kScopeOperator;
            break;
        case '(':
            if(!m_lastIdentifier.IsEmpty()) {
                m_functions.insert(m_lastIdentifier);
            }
            m_lastIdentifier.Clear();
            break;
        default:
            m_lastIdentifier.Clear();
            break;
        }
        break;
    }
    //---------------------------------------------------------
    // Previous match was "."
    //---------------------------------------------------------
    case kScopeOperator: {
        if(token.type == kJS_IDENTIFIER) {
            wxString word = token.text;
            if(m_keywords.count(word) == 0) {
                m_functions.insert(word);
            }
            m_lastIdentifier.clear();
        }

        // Back to normal state
        m_lastIdentifier.Clear();
        m_state = kNormal;
        break;
    }
    }
}

wxString JavaScriptFunctionsLocator::GetFunctionsString() const
{
    wxString str;
    std::for_each(m_functions.begin(), m_functions.end(), [&](const wxString& func) { str << func << " "; });
    return str;
}

wxString JavaScriptFunctionsLocator::GetPropertiesString() const
{
    wxString str;
    std::for_each(m_properties.begin(), m_properties.end(), [&](const wxString& prop) { str << prop << " "; });
    return str;
}

void JavaScriptFunctionsLocator::Parse()
{
    if(!m_scanner) return;
    JSLexerToken token;
    while(::jsLexerNext(m_scanner, token)) {
        OnToken(token);
    }
}