I can haz source files added to targets.

pull/1103/head
Jussi Pakkanen 8 years ago
parent c41805f012
commit 8734013690
  1. 2
      mesonast.py
  2. 41
      mesonbuild/astinterpreter.py
  3. 38
      mesonbuild/mparser.py

@ -35,7 +35,7 @@ if __name__ == '__main__':
source_root = sys.argv[1]
ast = mesonbuild.astinterpreter.AstInterpreter(source_root, '')
try:
ast.dump()
ast.add_source('trivialprog', 'newfile.c')
except Exception as e:
if isinstance(e, MesonException):
if hasattr(e, 'file') and hasattr(e, 'lineno') and hasattr(e, 'colno'):

@ -20,7 +20,7 @@ from . import environment
from .interpreterbase import InterpreterException
import os
import os, sys
class DontCareObject(interpreterbase.InterpreterObject):
pass
@ -40,6 +40,8 @@ class MockCustomTarget(interpreterbase.InterpreterObject):
class MockRunTarget(interpreterbase.InterpreterObject):
pass
ADD_SOURCE = 0
class AstInterpreter(interpreterbase.InterpreterBase):
def __init__(self, source_root, subdir):
super().__init__(source_root, subdir)
@ -86,28 +88,33 @@ class AstInterpreter(interpreterbase.InterpreterBase):
'is_variable' : self.func_is_variable,
})
def func_do_nothing(self, *args, **kwargs):
def func_do_nothing(self, node, args, kwargs):
return True
def method_call(self, node):
return True
def func_executable(self, *args, **kwargs):
def func_executable(self, node, args, kwargs):
if args[0] == self.targetname:
if self.operation == ADD_SOURCE:
self.add_source_to_target(node, args, kwargs)
else:
raise NotImplementedError('Bleep bloop')
return MockExecutable()
def func_static_lib(self, *args, **kwargs):
def func_static_lib(self, node, args, kwargs):
return MockStaticLibrary()
def func_shared_lib(self, *args, **kwargs):
def func_shared_lib(self, node, args, kwargs):
return MockSharedLibrary()
def func_library(self, *args, **kwargs):
return self.func_shared_lib(*args, **kwargs)
def func_library(self, node, args, kwargs):
return self.func_shared_lib(node, args, kwargs)
def func_custom_target(self, *args, **kwargs):
def func_custom_target(self, node, args, kwargs):
return MockCustomTarget()
def func_run_target(self, *args, **kwargs):
def func_run_target(self, node, args, kwargs):
return MockRunTarget()
def func_subdir(self, node, args, kwargs):
@ -144,12 +151,26 @@ class AstInterpreter(interpreterbase.InterpreterBase):
def evaluate_indexing(self, node):
return 0
def dump(self):
def transform(self):
self.load_root_meson_file()
self.sanity_check_ast()
self.parse_project()
self.run()
print('AST here')
def add_source(self, targetname, filename):
self.operation = ADD_SOURCE
self.targetname = targetname
self.filename = filename
self.transform()
def unknown_function_called(self, func_name):
mlog.warning('Unknown function called: ' + func_name)
def add_source_to_target(self, node, args, kwargs):
namespan = node.args.arguments[0].bytespan
buildfilename = os.path.join(self.source_root, self.subdir, environment.build_filename)
raw_data = open(buildfilename, 'r').read()
updated = raw_data[0:namespan[1]] + (", '%s'" % self.filename) + raw_data[namespan[1]:]
open(buildfilename, 'w').write(updated)
sys.exit(0)

@ -22,10 +22,11 @@ class ParseException(MesonException):
self.colno = colno
class Token:
def __init__(self, tid, lineno, colno, value):
def __init__(self, tid, lineno, colno, bytespan, value):
self.tid = tid
self.lineno = lineno
self.colno = colno
self.bytespan = bytespan
self.value = value
def __eq__(self, other):
@ -87,7 +88,10 @@ class Lexer:
curline = lineno
col = mo.start()-line_start
matched = True
span_start = loc
loc = mo.end()
span_end = loc
bytespan = (span_start, span_end)
match_text = mo.group()
if tid == 'ignore' or tid == 'comment':
break
@ -123,40 +127,40 @@ class Lexer:
tid = match_text
else:
value = match_text
yield Token(tid, curline, col, value)
yield Token(tid, curline, col, bytespan, value)
break
if not matched:
raise ParseException('lexer', lineno, col)
class BooleanNode:
def __init__(self, token, value):
class ElementaryNode:
def __init__(self, token):
self.lineno = token.lineno
self.colno = token.colno
self.value = token.value
self.bytespan = token.bytespan
class BooleanNode(ElementaryNode):
def __init__(self, token, value):
super().__init__(token)
self.value = value
assert(isinstance(self.value, bool))
class IdNode:
class IdNode(ElementaryNode):
def __init__(self, token):
self.lineno = token.lineno
self.colno = token.colno
self.value = token.value
super().__init__(token)
assert(isinstance(self.value, str))
def __str__(self):
return "Id node: '%s' (%d, %d)." % (self.value, self.lineno, self.colno)
class NumberNode:
class NumberNode(ElementaryNode):
def __init__(self, token):
self.lineno = token.lineno
self.colno = token.colno
self.value = token.value
super().__init__(token)
assert(isinstance(self.value, int))
class StringNode:
class StringNode(ElementaryNode):
def __init__(self, token):
self.lineno = token.lineno
self.colno = token.colno
self.value = token.value
super().__init__(token)
assert(isinstance(self.value, str))
def __str__(self):
@ -360,7 +364,7 @@ class Parser:
try:
self.current = next(self.stream)
except StopIteration:
self.current = Token('eof', 0, 0, None)
self.current = Token('eof', 0, 0, (0, 0), None)
def accept(self, s):
if self.current.tid == s:

Loading…
Cancel
Save