Commit 6fd55fdd authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #910 from kmod/decorator

Support the "decorator" library
parents e18f82ad a0dccca2
...@@ -34,3 +34,6 @@ ...@@ -34,3 +34,6 @@
[submodule "test/lib/numpy"] [submodule "test/lib/numpy"]
path = test/lib/numpy path = test/lib/numpy
url = https://github.com/numpy/numpy url = https://github.com/numpy/numpy
[submodule "test/lib/decorator"]
path = test/lib/decorator
url = https://github.com/micheles/decorator
Subproject commit 1f62a285c57da50c00249a704deac00dae3c247b Subproject commit 728c4bc8c99d09da224ff3a2be82c98a1b026e82
...@@ -370,12 +370,12 @@ static CLFunction* compileForEvalOrExec(AST* source, std::vector<AST_stmt*> body ...@@ -370,12 +370,12 @@ static CLFunction* compileForEvalOrExec(AST* source, std::vector<AST_stmt*> body
return cl_f; return cl_f;
} }
static AST_Module* parseExec(llvm::StringRef source, bool interactive = false) { static AST_Module* parseExec(llvm::StringRef source, FutureFlags future_flags, bool interactive = false) {
// TODO error message if parse fails or if it isn't an expr // TODO error message if parse fails or if it isn't an expr
// TODO should have a cleaner interface that can parse the Expression directly // TODO should have a cleaner interface that can parse the Expression directly
// TODO this memory leaks // TODO this memory leaks
const char* code = source.data(); const char* code = source.data();
AST_Module* parsedModule = parse_string(code); AST_Module* parsedModule = parse_string(code, future_flags);
if (interactive) { if (interactive) {
for (int i = 0; i < parsedModule->body.size(); ++i) { for (int i = 0; i < parsedModule->body.size(); ++i) {
...@@ -397,7 +397,7 @@ static CLFunction* compileExec(AST_Module* parsedModule, BoxedString* fn, PyComp ...@@ -397,7 +397,7 @@ static CLFunction* compileExec(AST_Module* parsedModule, BoxedString* fn, PyComp
return compileForEvalOrExec(parsedModule, parsedModule->body, fn, flags); return compileForEvalOrExec(parsedModule, parsedModule->body, fn, flags);
} }
static AST_Expression* parseEval(llvm::StringRef source) { static AST_Expression* parseEval(llvm::StringRef source, FutureFlags future_flags) {
const char* code = source.data(); const char* code = source.data();
// TODO error message if parse fails or if it isn't an expr // TODO error message if parse fails or if it isn't an expr
...@@ -409,7 +409,7 @@ static AST_Expression* parseEval(llvm::StringRef source) { ...@@ -409,7 +409,7 @@ static AST_Expression* parseEval(llvm::StringRef source) {
while (*code == ' ' || *code == '\t' || *code == '\n' || *code == '\r') while (*code == ' ' || *code == '\t' || *code == '\n' || *code == '\r')
code++; code++;
AST_Module* parsedModule = parse_string(code); AST_Module* parsedModule = parse_string(code, future_flags);
if (parsedModule->body.size() == 0) if (parsedModule->body.size() == 0)
raiseSyntaxError("unexpected EOF while parsing", 0, 0, "<string>", ""); raiseSyntaxError("unexpected EOF while parsing", 0, 0, "<string>", "");
...@@ -496,11 +496,11 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) { ...@@ -496,11 +496,11 @@ Box* compile(Box* source, Box* fn, Box* type, Box** _args) {
llvm::StringRef source_str = static_cast<BoxedString*>(source)->s(); llvm::StringRef source_str = static_cast<BoxedString*>(source)->s();
if (type_str->s() == "exec") { if (type_str->s() == "exec") {
parsed = parseExec(source_str); parsed = parseExec(source_str, future_flags);
} else if (type_str->s() == "eval") { } else if (type_str->s() == "eval") {
parsed = parseEval(source_str); parsed = parseEval(source_str, future_flags);
} else if (type_str->s() == "single") { } else if (type_str->s() == "single") {
parsed = parseExec(source_str, true); parsed = parseExec(source_str, future_flags, true);
} else { } else {
raiseExcHelper(ValueError, "compile() arg 3 must be 'exec', 'eval' or 'single'"); raiseExcHelper(ValueError, "compile() arg 3 must be 'exec', 'eval' or 'single'");
} }
...@@ -578,7 +578,11 @@ static Box* evalMain(Box* boxedCode, Box* globals, Box* locals, PyCompilerFlags* ...@@ -578,7 +578,11 @@ static Box* evalMain(Box* boxedCode, Box* globals, Box* locals, PyCompilerFlags*
CLFunction* cl; CLFunction* cl;
if (boxedCode->cls == str_cls) { if (boxedCode->cls == str_cls) {
AST_Expression* parsed = parseEval(static_cast<BoxedString*>(boxedCode)->s()); CLFunction* caller_cl = getTopPythonFunction();
assert(caller_cl != NULL);
assert(caller_cl->source != NULL);
AST_Expression* parsed = parseEval(static_cast<BoxedString*>(boxedCode)->s(), caller_cl->source->future_flags);
static BoxedString* string_string = internStringImmortal("<string>"); static BoxedString* string_string = internStringImmortal("<string>");
cl = compileEval(parsed, string_string, flags); cl = compileEval(parsed, string_string, flags);
} else if (boxedCode->cls == code_cls) { } else if (boxedCode->cls == code_cls) {
...@@ -627,7 +631,7 @@ Box* execfile(Box* _fn, Box* globals, Box* locals) { ...@@ -627,7 +631,7 @@ Box* execfile(Box* _fn, Box* globals, Box* locals) {
if (!exists) if (!exists)
raiseExcHelper(IOError, "No such file or directory: '%s'", fn->s().data()); raiseExcHelper(IOError, "No such file or directory: '%s'", fn->s().data());
AST_Module* parsed = caching_parse_file(fn->s().data()); AST_Module* parsed = caching_parse_file(fn->s().data(), /* future_flags = */ 0);
assert(parsed); assert(parsed);
CLFunction* caller_cl = getTopPythonFunction(); CLFunction* caller_cl = getTopPythonFunction();
...@@ -667,7 +671,11 @@ Box* execMain(Box* boxedCode, Box* globals, Box* locals, PyCompilerFlags* flags) ...@@ -667,7 +671,11 @@ Box* execMain(Box* boxedCode, Box* globals, Box* locals, PyCompilerFlags* flags)
CLFunction* cl; CLFunction* cl;
if (boxedCode->cls == str_cls) { if (boxedCode->cls == str_cls) {
auto parsed = parseExec(static_cast<BoxedString*>(boxedCode)->s()); CLFunction* caller_cl = getTopPythonFunction();
assert(caller_cl != NULL);
assert(caller_cl->source != NULL);
auto parsed = parseExec(static_cast<BoxedString*>(boxedCode)->s(), caller_cl->source->future_flags);
static BoxedString* string_string = internStringImmortal("<string>"); static BoxedString* string_string = internStringImmortal("<string>");
cl = compileExec(parsed, string_string, flags); cl = compileExec(parsed, string_string, flags);
} else if (boxedCode->cls == code_cls) { } else if (boxedCode->cls == code_cls) {
......
...@@ -1012,13 +1012,17 @@ static std::string getParserCommandLine(const char* fn) { ...@@ -1012,13 +1012,17 @@ static std::string getParserCommandLine(const char* fn) {
return std::string("/usr/bin/python -S ") + parse_ast_fn.str().str() + " " + fn; return std::string("/usr/bin/python -S ") + parse_ast_fn.str().str() + " " + fn;
} }
AST_Module* parse_string(const char* code) { AST_Module* parse_string(const char* code, FutureFlags inherited_flags) {
if (ENABLE_PYPA_PARSER) { inherited_flags &= ~(CO_NESTED | CO_FUTURE_DIVISION);
AST_Module* rtn = pypa_parse_string(code);
if (ENABLE_PYPA_PARSER || inherited_flags) {
AST_Module* rtn = pypa_parse_string(code, inherited_flags);
RELEASE_ASSERT(rtn, "unknown parse error (possibly: '%s'?)", strerror(errno)); RELEASE_ASSERT(rtn, "unknown parse error (possibly: '%s'?)", strerror(errno));
return rtn; return rtn;
} }
ASSERT(!inherited_flags, "the old cpython parser doesn't support specifying initial future flags");
int size = strlen(code); int size = strlen(code);
char buf[] = "pystontmp_XXXXXX"; char buf[] = "pystontmp_XXXXXX";
char* tmpdir = mkdtemp(buf); char* tmpdir = mkdtemp(buf);
...@@ -1033,17 +1037,17 @@ AST_Module* parse_string(const char* code) { ...@@ -1033,17 +1037,17 @@ AST_Module* parse_string(const char* code) {
fputc('\n', f); fputc('\n', f);
fclose(f); fclose(f);
AST_Module* m = parse_file(tmp.c_str()); AST_Module* m = parse_file(tmp.c_str(), inherited_flags);
removeDirectoryIfExists(tmpdir); removeDirectoryIfExists(tmpdir);
return m; return m;
} }
AST_Module* parse_file(const char* fn) { AST_Module* parse_file(const char* fn, FutureFlags inherited_flags) {
Timer _t("parsing"); Timer _t("parsing");
if (ENABLE_PYPA_PARSER) { if (ENABLE_PYPA_PARSER) {
AST_Module* rtn = pypa_parse(fn); AST_Module* rtn = pypa_parse(fn, inherited_flags);
RELEASE_ASSERT(rtn, "unknown parse error (possibly: '%s'?)", strerror(errno)); RELEASE_ASSERT(rtn, "unknown parse error (possibly: '%s'?)", strerror(errno));
return rtn; return rtn;
} }
...@@ -1070,9 +1074,9 @@ AST_Module* parse_file(const char* fn) { ...@@ -1070,9 +1074,9 @@ AST_Module* parse_file(const char* fn) {
const char* getMagic() { const char* getMagic() {
if (ENABLE_PYPA_PARSER) if (ENABLE_PYPA_PARSER)
return "a\ncM"; return "a\ncN";
else else
return "a\ncm"; return "a\ncn";
} }
#define MAGIC_STRING_LENGTH 4 #define MAGIC_STRING_LENGTH 4
...@@ -1080,7 +1084,9 @@ const char* getMagic() { ...@@ -1080,7 +1084,9 @@ const char* getMagic() {
#define CHECKSUM_LENGTH 1 #define CHECKSUM_LENGTH 1
// Does at least one of: returns a valid file_data vector, or fills in 'module' // Does at least one of: returns a valid file_data vector, or fills in 'module'
static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, AST_Module*& module) { static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, AST_Module*& module,
FutureFlags inherited_flags) {
inherited_flags &= ~(CO_NESTED | CO_FUTURE_DIVISION);
FILE* cache_fp = fopen(cache_fn.c_str(), "w"); FILE* cache_fp = fopen(cache_fn.c_str(), "w");
if (DEBUG_PARSING) { if (DEBUG_PARSING) {
...@@ -1110,8 +1116,8 @@ static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, A ...@@ -1110,8 +1116,8 @@ static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, A
file_data.insert(file_data.end(), (char*)&checksum, (char*)&checksum + CHECKSUM_LENGTH); file_data.insert(file_data.end(), (char*)&checksum, (char*)&checksum + CHECKSUM_LENGTH);
checksum = 0; checksum = 0;
if (ENABLE_PYPA_PARSER) { if (ENABLE_PYPA_PARSER || inherited_flags) {
module = pypa_parse(fn); module = pypa_parse(fn, inherited_flags);
RELEASE_ASSERT(module, "unknown parse error"); RELEASE_ASSERT(module, "unknown parse error");
if (!cache_fp) if (!cache_fp)
...@@ -1121,6 +1127,7 @@ static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, A ...@@ -1121,6 +1127,7 @@ static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, A
checksum = p.second; checksum = p.second;
bytes_written += p.first; bytes_written += p.first;
} else { } else {
ASSERT(!inherited_flags, "the old cpython parser doesn't support specifying initial future flags");
FILE* parser = popen(getParserCommandLine(fn).c_str(), "r"); FILE* parser = popen(getParserCommandLine(fn).c_str(), "r");
char buf[80]; char buf[80];
while (true) { while (true) {
...@@ -1157,7 +1164,7 @@ static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, A ...@@ -1157,7 +1164,7 @@ static std::vector<char> _reparse(const char* fn, const std::string& cache_fn, A
// Parsing the file is somewhat expensive since we have to shell out to cpython; // Parsing the file is somewhat expensive since we have to shell out to cpython;
// it's not a huge deal right now, but this caching version can significantly cut down // it's not a huge deal right now, but this caching version can significantly cut down
// on the startup time (40ms -> 10ms). // on the startup time (40ms -> 10ms).
AST_Module* caching_parse_file(const char* fn) { AST_Module* caching_parse_file(const char* fn, FutureFlags inherited_flags) {
std::ostringstream oss; std::ostringstream oss;
if (DEBUG_PARSING) { if (DEBUG_PARSING) {
oss << "caching_parse_file() on " << fn << '\n'; oss << "caching_parse_file() on " << fn << '\n';
...@@ -1192,7 +1199,7 @@ AST_Module* caching_parse_file(const char* fn) { ...@@ -1192,7 +1199,7 @@ AST_Module* caching_parse_file(const char* fn) {
if (ferror(cache_fp)) { if (ferror(cache_fp)) {
oss << "encountered io error reading from the file\n"; oss << "encountered io error reading from the file\n";
AST_Module* mod = 0; AST_Module* mod = 0;
file_data = _reparse(fn, cache_fn, mod); file_data = _reparse(fn, cache_fn, mod, inherited_flags);
if (mod) if (mod)
return mod; return mod;
assert(file_data.size()); assert(file_data.size());
...@@ -1295,7 +1302,7 @@ AST_Module* caching_parse_file(const char* fn) { ...@@ -1295,7 +1302,7 @@ AST_Module* caching_parse_file(const char* fn) {
file_data.clear(); file_data.clear();
AST_Module* mod = 0; AST_Module* mod = 0;
file_data = _reparse(fn, cache_fn, mod); file_data = _reparse(fn, cache_fn, mod, inherited_flags);
if (mod) if (mod)
return mod; return mod;
assert(file_data.size()); assert(file_data.size());
......
...@@ -15,14 +15,15 @@ ...@@ -15,14 +15,15 @@
#ifndef PYSTON_CODEGEN_PARSER_H #ifndef PYSTON_CODEGEN_PARSER_H
#define PYSTON_CODEGEN_PARSER_H #define PYSTON_CODEGEN_PARSER_H
#include "core/types.h"
namespace pyston { namespace pyston {
class AST_Module; class AST_Module;
AST_Module* parse_string(const char* code); AST_Module* parse_string(const char* code, FutureFlags inherited_flags);
AST_Module* parse_file(const char* fn, FutureFlags inherited_flags);
AST_Module* parse_file(const char* fn); AST_Module* caching_parse_file(const char* fn, FutureFlags inherited_flags);
AST_Module* caching_parse_file(const char* fn);
} }
#endif #endif
...@@ -1163,7 +1163,7 @@ private: ...@@ -1163,7 +1163,7 @@ private:
int position; int position;
}; };
static AST_Module* parse_with_reader(std::unique_ptr<pypa::Reader> reader) { static AST_Module* parse_with_reader(std::unique_ptr<pypa::Reader> reader, FutureFlags future_flags) {
pypa::Lexer lexer(std::move(reader)); pypa::Lexer lexer(std::move(reader));
pypa::SymbolTablePtr symbols; pypa::SymbolTablePtr symbols;
pypa::AstModulePtr module; pypa::AstModulePtr module;
...@@ -1176,6 +1176,35 @@ static AST_Module* parse_with_reader(std::unique_ptr<pypa::Reader> reader) { ...@@ -1176,6 +1176,35 @@ static AST_Module* parse_with_reader(std::unique_ptr<pypa::Reader> reader) {
options.error_handler = pypaErrorHandler; options.error_handler = pypaErrorHandler;
options.escape_handler = pypaEscapeDecoder; options.escape_handler = pypaEscapeDecoder;
if (future_flags & CO_FUTURE_PRINT_FUNCTION) {
future_flags &= ~CO_FUTURE_PRINT_FUNCTION;
options.initial_future_features.print_function = true;
}
if (future_flags & CO_FUTURE_DIVISION) {
future_flags &= ~CO_FUTURE_DIVISION;
options.initial_future_features.division = true;
}
if (future_flags & CO_FUTURE_ABSOLUTE_IMPORT) {
future_flags &= ~CO_FUTURE_ABSOLUTE_IMPORT;
options.initial_future_features.absolute_imports = true;
}
if (future_flags & CO_FUTURE_WITH_STATEMENT) {
future_flags &= ~CO_FUTURE_WITH_STATEMENT;
options.initial_future_features.with_statement = true;
}
if (future_flags & CO_FUTURE_UNICODE_LITERALS) {
future_flags &= ~CO_FUTURE_UNICODE_LITERALS;
options.initial_future_features.unicode_literals = true;
}
// Strip out some flags:
future_flags &= ~(CO_NESTED);
RELEASE_ASSERT(!future_flags, "0x%x", future_flags);
if (pypa::parse(lexer, module, symbols, options) && module) { if (pypa::parse(lexer, module, symbols, options) && module) {
return readModule(*module); return readModule(*module);
} }
...@@ -1199,17 +1228,17 @@ PyObject* PystonStringReader::open_python_file() noexcept { ...@@ -1199,17 +1228,17 @@ PyObject* PystonStringReader::open_python_file() noexcept {
return PycStringIO->NewInput(s); return PycStringIO->NewInput(s);
} }
AST_Module* pypa_parse(char const* file_path) { AST_Module* pypa_parse(char const* file_path, FutureFlags future_flags) {
auto reader = PystonFileReader::create(file_path); auto reader = PystonFileReader::create(file_path);
if (!reader) if (!reader)
return nullptr; return nullptr;
return parse_with_reader(std::move(reader)); return parse_with_reader(std::move(reader), future_flags);
} }
AST_Module* pypa_parse_string(char const* str) { AST_Module* pypa_parse_string(char const* str, FutureFlags future_flags) {
auto reader = llvm::make_unique<PystonStringReader>(str); auto reader = llvm::make_unique<PystonStringReader>(str);
return parse_with_reader(std::move(reader)); return parse_with_reader(std::move(reader), future_flags);
} }
} }
...@@ -17,10 +17,12 @@ ...@@ -17,10 +17,12 @@
#include <cstdio> #include <cstdio>
#include "core/types.h"
namespace pyston { namespace pyston {
class AST_Module; class AST_Module;
AST_Module* pypa_parse(char const* file_path); AST_Module* pypa_parse(char const* file_path, FutureFlags future_flags);
AST_Module* pypa_parse_string(char const* str); AST_Module* pypa_parse_string(char const* str, FutureFlags future_flags);
} }
#endif // PYSTON_CODEGEN_PYPAPARSER_H #endif // PYSTON_CODEGEN_PYPAPARSER_H
...@@ -418,7 +418,7 @@ static int main(int argc, char** argv) { ...@@ -418,7 +418,7 @@ static int main(int argc, char** argv) {
if (command != NULL) { if (command != NULL) {
try { try {
main_module = createModule(boxString("__main__"), "<string>"); main_module = createModule(boxString("__main__"), "<string>");
AST_Module* m = parse_string(command); AST_Module* m = parse_string(command, /* future_flags = */ 0);
compileAndRunModule(m, main_module); compileAndRunModule(m, main_module);
rtncode = 0; rtncode = 0;
} catch (ExcInfo e) { } catch (ExcInfo e) {
...@@ -457,7 +457,7 @@ static int main(int argc, char** argv) { ...@@ -457,7 +457,7 @@ static int main(int argc, char** argv) {
main_module = createModule(boxString("__main__"), fn); main_module = createModule(boxString("__main__"), fn);
try { try {
AST_Module* ast = caching_parse_file(fn); AST_Module* ast = caching_parse_file(fn, /* future_flags = */ 0);
compileAndRunModule(ast, main_module); compileAndRunModule(ast, main_module);
} catch (ExcInfo e) { } catch (ExcInfo e) {
setCAPIException(e); setCAPIException(e);
...@@ -487,7 +487,7 @@ static int main(int argc, char** argv) { ...@@ -487,7 +487,7 @@ static int main(int argc, char** argv) {
add_history(line); add_history(line);
try { try {
AST_Module* m = parse_string(line); AST_Module* m = parse_string(line, /* future_flags = */ 0);
Timer _t("repl"); Timer _t("repl");
......
...@@ -43,7 +43,7 @@ static void removeModule(BoxedString* name) { ...@@ -43,7 +43,7 @@ static void removeModule(BoxedString* name) {
Box* createAndRunModule(BoxedString* name, const std::string& fn) { Box* createAndRunModule(BoxedString* name, const std::string& fn) {
BoxedModule* module = createModule(name, fn.c_str()); BoxedModule* module = createModule(name, fn.c_str());
AST_Module* ast = caching_parse_file(fn.c_str()); AST_Module* ast = caching_parse_file(fn.c_str(), /* future_flags = */ 0);
assert(ast); assert(ast);
try { try {
compileAndRunModule(ast, module); compileAndRunModule(ast, module);
...@@ -69,7 +69,7 @@ static Box* createAndRunModule(BoxedString* name, const std::string& fn, const s ...@@ -69,7 +69,7 @@ static Box* createAndRunModule(BoxedString* name, const std::string& fn, const s
static BoxedString* path_str = internStringImmortal("__path__"); static BoxedString* path_str = internStringImmortal("__path__");
module->setattr(path_str, path_list, NULL); module->setattr(path_str, path_list, NULL);
AST_Module* ast = caching_parse_file(fn.c_str()); AST_Module* ast = caching_parse_file(fn.c_str(), /* future_flags = */ 0);
assert(ast); assert(ast);
try { try {
compileAndRunModule(ast, module); compileAndRunModule(ast, module);
...@@ -646,7 +646,7 @@ extern "C" PyObject* PyImport_ExecCodeModuleEx(char* name, PyObject* co, char* p ...@@ -646,7 +646,7 @@ extern "C" PyObject* PyImport_ExecCodeModuleEx(char* name, PyObject* co, char* p
static BoxedString* file_str = internStringImmortal("__file__"); static BoxedString* file_str = internStringImmortal("__file__");
module->setattr(file_str, boxString(pathname), NULL); module->setattr(file_str, boxString(pathname), NULL);
AST_Module* ast = parse_string(code->data()); AST_Module* ast = parse_string(code->data(), /* future_flags = */ 0);
compileAndRunModule(ast, module); compileAndRunModule(ast, module);
return module; return module;
} catch (ExcInfo e) { } catch (ExcInfo e) {
......
import os, sys
sys.path.append(os.path.dirname(__file__) + "/../lib")
EXTRA_PATH = os.path.dirname(os.path.abspath(__file__)) + "/../lib/decorator/src"
sys.path.insert(0, EXTRA_PATH)
EXTRA_PATH = os.path.dirname(os.path.abspath(__file__)) + "/../lib/decorator"
sys.path.insert(0, EXTRA_PATH)
import decorator
import tests.test
import unittest
unittest.main(tests.test)
Subproject commit e13cf0704b7c28f1de1e71cb7c59b47a84daa9ca
...@@ -52,3 +52,9 @@ except TypeError: ...@@ -52,3 +52,9 @@ except TypeError:
for i in xrange(10): for i in xrange(10):
print() print()
# These two should output "1 2"
exec """print(1, 2)"""
eval("print(1, 2)")
# This one should output "(1, 2)"
exec compile("print(1, 2)", "<string>", "exec", dont_inherit=True)
...@@ -26,7 +26,7 @@ protected: ...@@ -26,7 +26,7 @@ protected:
TEST_F(AnalysisTest, augassign) { TEST_F(AnalysisTest, augassign) {
const std::string fn("test/unittests/analysis_listcomp.py"); const std::string fn("test/unittests/analysis_listcomp.py");
AST_Module* module = caching_parse_file(fn.c_str()); AST_Module* module = caching_parse_file(fn.c_str(), 0);
assert(module); assert(module);
ScopingAnalysis *scoping = new ScopingAnalysis(module, true); ScopingAnalysis *scoping = new ScopingAnalysis(module, true);
...@@ -59,7 +59,7 @@ TEST_F(AnalysisTest, augassign) { ...@@ -59,7 +59,7 @@ TEST_F(AnalysisTest, augassign) {
void doOsrTest(bool is_osr, bool i_maybe_undefined) { void doOsrTest(bool is_osr, bool i_maybe_undefined) {
const std::string fn("test/unittests/analysis_osr.py"); const std::string fn("test/unittests/analysis_osr.py");
AST_Module* module = caching_parse_file(fn.c_str()); AST_Module* module = caching_parse_file(fn.c_str(), 0);
assert(module); assert(module);
ScopingAnalysis *scoping = new ScopingAnalysis(module, true); ScopingAnalysis *scoping = new ScopingAnalysis(module, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment