build(python): simplify rpycdec vendor layout
This commit was merged in pull request #17.
This commit is contained in:
1
third_party/python/rpycdec/src/renpy/__init__.py
vendored
Normal file
1
third_party/python/rpycdec/src/renpy/__init__.py
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Ren'Py AST and support modules for rpycdec
|
||||
1350
third_party/python/rpycdec/src/renpy/ast.py
vendored
Normal file
1350
third_party/python/rpycdec/src/renpy/ast.py
vendored
Normal file
File diff suppressed because it is too large
Load Diff
32
third_party/python/rpycdec/src/renpy/astsupport.py
vendored
Normal file
32
third_party/python/rpycdec/src/renpy/astsupport.py
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
class PyExpr(str):
|
||||
|
||||
expr: str
|
||||
filename: str
|
||||
linenumber: int
|
||||
py: int
|
||||
hashcode: str
|
||||
column: int
|
||||
|
||||
def __new__(
|
||||
cls,
|
||||
expr: str,
|
||||
filename: str = '',
|
||||
linenumber: int = 0,
|
||||
py: int = 3,
|
||||
hashcode: str = '',
|
||||
column: int = 0,
|
||||
):
|
||||
self = super().__new__(cls, expr)
|
||||
self.expr = expr
|
||||
self.filename = filename
|
||||
self.linenumber = linenumber
|
||||
self.py = py
|
||||
self.hashcode = hashcode
|
||||
self.column = column
|
||||
return self
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
return self.expr
|
||||
|
||||
def __str__(self):
|
||||
return self.expr
|
||||
319
third_party/python/rpycdec/src/renpy/atl.py
vendored
Normal file
319
third_party/python/rpycdec/src/renpy/atl.py
vendored
Normal file
@@ -0,0 +1,319 @@
|
||||
from . import util, ast, astsupport
|
||||
from .object import Object
|
||||
|
||||
|
||||
class Context(object):
|
||||
pass
|
||||
|
||||
|
||||
class ATLTransformBase(Object):
|
||||
pass
|
||||
|
||||
|
||||
class RawStatement(object):
|
||||
pass
|
||||
|
||||
|
||||
class Statement(Object):
|
||||
pass
|
||||
|
||||
|
||||
class RawBlock(RawStatement):
|
||||
statements = None
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#block-statement
|
||||
|
||||
atl_block_stmt ::= "block" ":"
|
||||
atl_block
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
if (
|
||||
not self.animation
|
||||
and len(self.statements) == 1
|
||||
and isinstance(self.statements[0], RawBlock)
|
||||
):
|
||||
return util.get_code(self.statements[0], **kwargs)
|
||||
|
||||
rv = []
|
||||
if self.animation:
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#animation-statement
|
||||
|
||||
atl_animation ::= "animation"
|
||||
|
||||
image eileen vhappy moving:
|
||||
animation
|
||||
"eileen vhappy"
|
||||
xalign 0.0
|
||||
linear 5.0 xalign 1.0
|
||||
repeat
|
||||
"""
|
||||
rv.append("animation")
|
||||
|
||||
statements = self.statements
|
||||
if statements:
|
||||
for statement in statements:
|
||||
if statement is None:
|
||||
rv.append("pass")
|
||||
else:
|
||||
rv.append(util.get_code(statement, **kwargs))
|
||||
else:
|
||||
rv.append("pass")
|
||||
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class Block(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawMultipurpose(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#interpolation-statement
|
||||
|
||||
atl_interp ::= ((warper simple_expression) | ("warp" simple_expression simple_expression)) (atl_interp_target+ | (":"
|
||||
atl_interp_target+ ))
|
||||
atl_interp_target ::= (atl_property+ ("knot" simple_expression)* )
|
||||
| atl_transform_expression
|
||||
| "clockwise"
|
||||
| "counterclockwise"
|
||||
| ("circles" simple_expression)
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
start = ""
|
||||
warp_fun, duration, wrap = self.warp_function, self.duration, self.warper
|
||||
if warp_fun and wrap is None:
|
||||
# warp {warp_function:expr} {duration:expr}
|
||||
start = f"warp {util.get_code(warp_fun, **kwargs)} {util.get_code(duration, **kwargs)}"
|
||||
elif not warp_fun and wrap:
|
||||
# {wrap} {duration:expr}
|
||||
start = f"{wrap} {util.get_code(duration, **kwargs)}"
|
||||
elif not warp_fun and not wrap and duration == "0":
|
||||
pass
|
||||
|
||||
rv = []
|
||||
|
||||
revolution = self.revolution
|
||||
if revolution:
|
||||
rv.append(revolution)
|
||||
|
||||
circles = self.circles
|
||||
if circles and circles != "0":
|
||||
# circles {expression}
|
||||
rv.append(f"circles {util.get_code(circles, **kwargs)}")
|
||||
|
||||
for prop, expr in self.properties:
|
||||
rv.append(f"{prop} {util.get_code(expr, **kwargs)}")
|
||||
|
||||
for prop, exprs in self.splines:
|
||||
last, exprs = exprs[-1], exprs[:-1]
|
||||
knots = " ".join(f"knot {util.get_code(expr, **kwargs)}" for expr in exprs)
|
||||
rv.append(f"{prop} {util.get_code(last, **kwargs)} {knots}")
|
||||
|
||||
for expr, with_expr in self.expressions:
|
||||
if with_expr is None:
|
||||
rv.append(str(expr))
|
||||
continue
|
||||
if isinstance(with_expr, ast.PyExpr):
|
||||
valstr = f"with {with_expr}"
|
||||
elif isinstance(with_expr, astsupport.PyExpr):
|
||||
valstr = f"with {with_expr}"
|
||||
else:
|
||||
valstr = str(with_expr)
|
||||
rv.append(f"{expr} {valstr}")
|
||||
|
||||
if not start:
|
||||
return " ".join(rv)
|
||||
if not rv:
|
||||
# if no properties, return just the warp
|
||||
return start
|
||||
if len(rv) < 3:
|
||||
# if only few properties, return them in one line
|
||||
return start + " " + " ".join(rv)
|
||||
return start + ":\n" + util.indent(" ".join(rv))
|
||||
|
||||
|
||||
class RawContainsExpr(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#inline-contains-statement
|
||||
|
||||
atl_contains ::= "contains" simple_expression
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
"""
|
||||
Returns the code for a contains expression.
|
||||
"""
|
||||
expression = util.attr(self, "expression")
|
||||
if expression:
|
||||
return f"contains {util.get_code(expression, **kwargs)}"
|
||||
return "contains"
|
||||
|
||||
|
||||
# This allows us to have multiple ATL transforms as children.
|
||||
class RawChild(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#contains-block-statement
|
||||
|
||||
atl_counts ::= "contains" ":"
|
||||
atl_block
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
children = util.attr(self, "children")
|
||||
if not children:
|
||||
return "contains:\n pass"
|
||||
rv = ["contains:"]
|
||||
rv.append(util.indent(util.get_code(children, **kwargs)))
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
# This changes the child of this statement, optionally with a transition.
|
||||
class Child(Statement):
|
||||
pass
|
||||
|
||||
|
||||
# This causes interpolation to occur.
|
||||
class Interpolation(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawRepeat(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#repeat-statement
|
||||
|
||||
atl_repeat ::= "repeat" (simple_expression)?
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
if self.repeats:
|
||||
return f"repeat {util.get_code(self.repeats, **kwargs)}"
|
||||
return "repeat"
|
||||
|
||||
|
||||
class Repeat(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawParallel(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#parallel-statement
|
||||
|
||||
atl_parallel ::= ("parallel" ":"
|
||||
atl_block)+
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = ["parallel:"]
|
||||
blocks = util.attr(self, "blocks")
|
||||
if not blocks:
|
||||
rv.append(util.indent("pass"))
|
||||
else:
|
||||
rv.append(util.indent(util.get_code(blocks, **kwargs)))
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class Parallel(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawChoice(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#choice-statement
|
||||
|
||||
atl_choice ::= ("choice" (simple_expression)? ":"
|
||||
atl_block)+
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = []
|
||||
for text, stmt in self.choices:
|
||||
rv.append(f"choice {text}:")
|
||||
rv.append(util.indent(util.get_code(stmt, **kwargs)))
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class Choice(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawTime(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/atl.html#time-statement
|
||||
|
||||
atl_time ::= "time" (simple_expression)?
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
time = util.attr(self, "time")
|
||||
if time:
|
||||
return f"time {util.get_code(time, **kwargs)}"
|
||||
return "time"
|
||||
|
||||
|
||||
class Time(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawOn(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#on-statement
|
||||
|
||||
atl_on ::= "on" name [ "," name ] * ":"
|
||||
atl_block
|
||||
|
||||
on show:
|
||||
alpha 0.0
|
||||
linear .5 alpha 1.0
|
||||
on hide:
|
||||
linear .5 alpha 0.0
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = []
|
||||
for text, stmt in self.handlers.items():
|
||||
rv.append(f"on {text}:")
|
||||
rv.append(util.indent(util.get_code(stmt, **kwargs)))
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class On(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawEvent(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#event-statement
|
||||
|
||||
atl_event ::= "event" name
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
name = util.attr(self, "name")
|
||||
if name:
|
||||
return f"event {name}"
|
||||
return "event"
|
||||
|
||||
|
||||
class Event(Statement):
|
||||
pass
|
||||
|
||||
|
||||
class RawFunction(RawStatement):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/transforms.html#function-statement
|
||||
|
||||
atl_function ::= "function" simple_expression
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
if self.expr:
|
||||
return "function " + str(self.expr)
|
||||
else:
|
||||
return "function"
|
||||
|
||||
|
||||
class Function(Statement):
|
||||
pass
|
||||
15
third_party/python/rpycdec/src/renpy/config.py
vendored
Normal file
15
third_party/python/rpycdec/src/renpy/config.py
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
from typing import Optional
|
||||
|
||||
# Do we use old text substitutions?
|
||||
old_substitutions = True
|
||||
|
||||
# An alternate path to use when uneliding. (Mostly used by the launcher to enable
|
||||
# the style inspector.)
|
||||
alternate_unelide_path = None
|
||||
|
||||
# Various directories.
|
||||
gamedir = ""
|
||||
basedir = ""
|
||||
renpy_base = ""
|
||||
commondir = None # type: Optional[str]
|
||||
logdir = None # type: Optional[str] # Where log and error files go.
|
||||
71
third_party/python/rpycdec/src/renpy/display/behavior.py
vendored
Normal file
71
third_party/python/rpycdec/src/renpy/display/behavior.py
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
from . import layout, core
|
||||
from ..text import text
|
||||
from .. import object as renpyobject, python
|
||||
|
||||
|
||||
class Keymap(layout.Null):
|
||||
pass
|
||||
|
||||
|
||||
class RollForward(layout.Null):
|
||||
pass
|
||||
|
||||
|
||||
class PauseBehavior(layout.Null):
|
||||
pass
|
||||
|
||||
|
||||
class DismissBehavior(layout.Null):
|
||||
pass
|
||||
|
||||
|
||||
class SoundStopBehavior(layout.Null):
|
||||
pass
|
||||
|
||||
|
||||
class SayBehavior(layout.Null):
|
||||
pass
|
||||
|
||||
|
||||
class Button(layout.Window):
|
||||
pass
|
||||
|
||||
|
||||
class ImageButton(Button):
|
||||
pass
|
||||
|
||||
|
||||
class HoveredProxy(object):
|
||||
pass
|
||||
|
||||
|
||||
class Input(text.Text): # @UndefinedVariable
|
||||
pass
|
||||
|
||||
|
||||
class Adjustment(renpyobject.Object):
|
||||
pass
|
||||
|
||||
|
||||
class Bar(core.Displayable):
|
||||
pass
|
||||
|
||||
|
||||
class Conditional(layout.Container):
|
||||
pass
|
||||
|
||||
|
||||
class TimerState(python.RevertableObject):
|
||||
pass
|
||||
|
||||
|
||||
class Timer(layout.Null):
|
||||
pass
|
||||
|
||||
|
||||
class MouseArea(core.Displayable):
|
||||
pass
|
||||
|
||||
|
||||
class OnEvent(core.Displayable):
|
||||
pass
|
||||
33
third_party/python/rpycdec/src/renpy/display/core.py
vendored
Normal file
33
third_party/python/rpycdec/src/renpy/display/core.py
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
from .. import object as renpyobject
|
||||
|
||||
|
||||
class IgnoreEvent(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class EndInteraction(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class absolute(float):
|
||||
pass
|
||||
|
||||
|
||||
class DisplayableArguments(renpyobject.Object):
|
||||
pass
|
||||
|
||||
|
||||
class Displayable(renpyobject.Object):
|
||||
pass
|
||||
|
||||
|
||||
class SceneLists(renpyobject.Object):
|
||||
pass
|
||||
|
||||
|
||||
class MouseMove(object):
|
||||
pass
|
||||
|
||||
|
||||
class Interface(object):
|
||||
pass
|
||||
10
third_party/python/rpycdec/src/renpy/display/dragdrop.py
vendored
Normal file
10
third_party/python/rpycdec/src/renpy/display/dragdrop.py
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
from . import core, layout
|
||||
from .. import python
|
||||
|
||||
|
||||
class Drag(core.Displayable, python.RevertableObject):
|
||||
pass
|
||||
|
||||
|
||||
class DragGroup(layout.MultiBox):
|
||||
pass
|
||||
84
third_party/python/rpycdec/src/renpy/display/layout.py
vendored
Normal file
84
third_party/python/rpycdec/src/renpy/display/layout.py
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
from ..display import core, layout
|
||||
from .. import object as renpyobject
|
||||
|
||||
|
||||
class Null(core.Displayable):
|
||||
pass
|
||||
|
||||
|
||||
class Container(core.Displayable):
|
||||
pass
|
||||
|
||||
|
||||
class Position(layout.Container):
|
||||
pass
|
||||
|
||||
|
||||
class Grid(Container):
|
||||
pass
|
||||
|
||||
|
||||
class IgnoreLayers(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class MultiBox(layout.Container):
|
||||
pass
|
||||
|
||||
|
||||
class SizeGroup(renpyobject.Object):
|
||||
pass
|
||||
|
||||
|
||||
class Window(Container):
|
||||
pass
|
||||
|
||||
|
||||
class DynamicDisplayable(core.Displayable):
|
||||
pass
|
||||
|
||||
|
||||
def ConditionSwitch(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class IgnoresEvents(Container):
|
||||
pass
|
||||
|
||||
|
||||
def Crop(rect, child, **properties):
|
||||
pass
|
||||
|
||||
|
||||
LiveCrop = Crop
|
||||
|
||||
|
||||
class Side(Container):
|
||||
pass
|
||||
|
||||
|
||||
class Alpha(core.Displayable):
|
||||
pass
|
||||
|
||||
|
||||
class AdjustTimes(Container):
|
||||
pass
|
||||
|
||||
|
||||
class Tile(Container):
|
||||
pass
|
||||
|
||||
|
||||
LiveTile = Tile
|
||||
|
||||
|
||||
class Flatten(Container):
|
||||
pass
|
||||
|
||||
|
||||
class AlphaMask(Container):
|
||||
pass
|
||||
|
||||
|
||||
class NearRect(Container):
|
||||
pass
|
||||
2
third_party/python/rpycdec/src/renpy/display/transform.py
vendored
Normal file
2
third_party/python/rpycdec/src/renpy/display/transform.py
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
class Transform:
|
||||
pass
|
||||
50
third_party/python/rpycdec/src/renpy/lexer.py
vendored
Normal file
50
third_party/python/rpycdec/src/renpy/lexer.py
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import os
|
||||
from typing import NamedTuple
|
||||
|
||||
import renpy
|
||||
|
||||
|
||||
class SubParse(object):
|
||||
"""
|
||||
This represents the information about a subparse that can be provided to
|
||||
a creator-defined statement.
|
||||
"""
|
||||
|
||||
def __init__(self, block):
|
||||
self.block = block
|
||||
|
||||
def __repr__(self):
|
||||
if not self.block:
|
||||
return "<SubParse empty>"
|
||||
else:
|
||||
return "<SubParse {}:{}>".format(
|
||||
self.block[0].filename, self.block[0].linenumber
|
||||
)
|
||||
|
||||
|
||||
def unelide_filename(fn: str) -> str:
|
||||
fn = os.path.normpath(fn)
|
||||
|
||||
if renpy.config.alternate_unelide_path is not None:
|
||||
fn0 = os.path.join(renpy.config.alternate_unelide_path, fn)
|
||||
if os.path.exists(fn0):
|
||||
return fn0
|
||||
|
||||
fn1 = os.path.join(renpy.config.basedir, fn)
|
||||
if os.path.exists(fn1):
|
||||
return fn1
|
||||
|
||||
fn2 = os.path.join(renpy.config.renpy_base, fn)
|
||||
if os.path.exists(fn2):
|
||||
return fn2
|
||||
|
||||
return fn
|
||||
|
||||
|
||||
class GroupedLine(NamedTuple):
|
||||
# The filename the line is from.
|
||||
filename: str
|
||||
number: int
|
||||
indent: int
|
||||
text: str
|
||||
block: list["GroupedLine"]
|
||||
33
third_party/python/rpycdec/src/renpy/object.py
vendored
Normal file
33
third_party/python/rpycdec/src/renpy/object.py
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
class Object(object):
|
||||
__version__ = 0
|
||||
|
||||
nosave = []
|
||||
|
||||
def __getstate__(self):
|
||||
rv = vars(self).copy()
|
||||
|
||||
for f in self.nosave:
|
||||
if f in rv:
|
||||
del rv[f]
|
||||
|
||||
rv["__version__"] = self.__version__
|
||||
|
||||
return rv
|
||||
|
||||
# None, to prevent this from being called when unnecessary.
|
||||
after_setstate = None
|
||||
|
||||
def __setstate__(self, new_dict):
|
||||
version = new_dict.pop("__version__", 0)
|
||||
|
||||
self.__dict__.update(new_dict)
|
||||
|
||||
if version != self.__version__:
|
||||
self.after_upgrade(version) # E1101
|
||||
|
||||
if self.after_setstate:
|
||||
self.after_setstate() # E1102
|
||||
|
||||
|
||||
class Sentinel(object):
|
||||
pass
|
||||
63
third_party/python/rpycdec/src/renpy/parameter.py
vendored
Normal file
63
third_party/python/rpycdec/src/renpy/parameter.py
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
from .. import util
|
||||
|
||||
|
||||
class Signature:
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = []
|
||||
parameters = util.attr(self, "parameters")
|
||||
if isinstance(parameters, dict):
|
||||
for name, value in parameters.items():
|
||||
rv.append(util.get_code(value, **kwargs))
|
||||
else:
|
||||
for value in parameters:
|
||||
rv.append(str(value))
|
||||
if not rv:
|
||||
return ""
|
||||
return f"({', '.join(rv)})"
|
||||
|
||||
|
||||
class Parameter:
|
||||
|
||||
(
|
||||
POSITIONAL_ONLY,
|
||||
POSITIONAL_OR_KEYWORD,
|
||||
VAR_POSITIONAL,
|
||||
KEYWORD_ONLY,
|
||||
VAR_KEYWORD,
|
||||
) = range(5)
|
||||
|
||||
def _variable_or_default(self, name, default):
|
||||
return f"{name}={default}" if default is not None else f"{name}"
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
name = util.attr(self, "name")
|
||||
kind = util.attr(self, "kind")
|
||||
default = util.attr(self, "default")
|
||||
if kind == self.POSITIONAL_ONLY:
|
||||
return self._variable_or_default(name, default)
|
||||
elif kind == self.POSITIONAL_OR_KEYWORD:
|
||||
return self._variable_or_default(name, default)
|
||||
elif kind == self.VAR_POSITIONAL:
|
||||
return f"*{name}"
|
||||
elif kind == self.KEYWORD_ONLY:
|
||||
return self._variable_or_default(name, default)
|
||||
elif kind == self.VAR_KEYWORD:
|
||||
return f"**{name}"
|
||||
else:
|
||||
raise ValueError(f"Unknown parameter kind: {kind}")
|
||||
|
||||
|
||||
class ArgumentInfo:
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = []
|
||||
for i, (keyword, expression) in enumerate(self.arguments):
|
||||
if i in self.starred_indexes:
|
||||
rv.append("*" + expression)
|
||||
elif i in self.doublestarred_indexes:
|
||||
rv.append("**" + expression)
|
||||
elif keyword is not None:
|
||||
rv.append("{}={}".format(keyword, expression))
|
||||
else:
|
||||
rv.append(str(expression))
|
||||
return "(" + ", ".join(rv) + ")"
|
||||
25
third_party/python/rpycdec/src/renpy/pyanalysis.py
vendored
Normal file
25
third_party/python/rpycdec/src/renpy/pyanalysis.py
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import ast
|
||||
|
||||
# Three levels of constness.
|
||||
GLOBAL_CONST = 2 # Expressions that are const everywhere.
|
||||
LOCAL_CONST = 1 # Expressions that are const with regard to a screen + parameters.
|
||||
NOT_CONST = 0 # Expressions that are not const.
|
||||
|
||||
|
||||
class Control(object):
|
||||
pass
|
||||
|
||||
|
||||
class Analysis(object):
|
||||
pass
|
||||
|
||||
|
||||
class PyAnalysis(ast.NodeVisitor):
|
||||
pass
|
||||
|
||||
|
||||
class CompilerCache(object):
|
||||
pass
|
||||
|
||||
|
||||
ccache = CompilerCache()
|
||||
82
third_party/python/rpycdec/src/renpy/python.py
vendored
Normal file
82
third_party/python/rpycdec/src/renpy/python.py
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
import ast
|
||||
import random
|
||||
from .object import Object
|
||||
|
||||
|
||||
class StoreDeleted(object):
|
||||
pass
|
||||
|
||||
|
||||
class StoreModule(object):
|
||||
pass
|
||||
|
||||
|
||||
class StoreDict(dict):
|
||||
pass
|
||||
|
||||
|
||||
class StoreBackup:
|
||||
pass
|
||||
|
||||
|
||||
class NoRollback(object):
|
||||
pass
|
||||
|
||||
|
||||
class WrapNode(ast.NodeTransformer):
|
||||
pass
|
||||
|
||||
|
||||
class CompressedList(object):
|
||||
pass
|
||||
|
||||
|
||||
class RevertableList(list):
|
||||
pass
|
||||
|
||||
|
||||
class RevertableDict(dict):
|
||||
pass
|
||||
|
||||
|
||||
class RevertableSet(set):
|
||||
def __setstate__(self, state):
|
||||
if isinstance(state, tuple):
|
||||
self.update(state[0].keys())
|
||||
else:
|
||||
self.update(state)
|
||||
|
||||
__reduce__ = object.__reduce__
|
||||
__reduce_ex__ = object.__reduce_ex__
|
||||
|
||||
|
||||
class RevertableObject(object):
|
||||
pass
|
||||
|
||||
|
||||
class RollbackRandom(random.Random):
|
||||
pass
|
||||
|
||||
|
||||
class DetRandom(random.Random):
|
||||
pass
|
||||
|
||||
|
||||
class Rollback(Object):
|
||||
pass
|
||||
|
||||
|
||||
class RollbackLog(Object):
|
||||
pass
|
||||
|
||||
|
||||
class StoreProxy(object):
|
||||
pass
|
||||
|
||||
|
||||
def py_compile(source, mode, filename="<none>", lineno=1, ast_node=False, cache=True):
|
||||
pass
|
||||
|
||||
|
||||
def py_eval_bytecode(bytecode, globals=None, locals=None): # @ReservedAssignment
|
||||
pass
|
||||
83
third_party/python/rpycdec/src/renpy/revertable.py
vendored
Normal file
83
third_party/python/rpycdec/src/renpy/revertable.py
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
import ast
|
||||
import random
|
||||
from .object import Object
|
||||
|
||||
|
||||
class StoreDeleted(object):
|
||||
pass
|
||||
|
||||
|
||||
class StoreModule(object):
|
||||
pass
|
||||
|
||||
|
||||
class StoreDict(dict):
|
||||
pass
|
||||
|
||||
|
||||
class StoreBackup:
|
||||
pass
|
||||
|
||||
|
||||
class NoRollback(object):
|
||||
pass
|
||||
|
||||
|
||||
class WrapNode(ast.NodeTransformer):
|
||||
pass
|
||||
|
||||
|
||||
class CompressedList(object):
|
||||
pass
|
||||
|
||||
|
||||
class RevertableList(list):
|
||||
pass
|
||||
|
||||
|
||||
class RevertableDict(dict):
|
||||
pass
|
||||
|
||||
|
||||
class RevertableSet(set):
|
||||
def __setstate__(self, state):
|
||||
if isinstance(state, tuple):
|
||||
self.update(state[0].keys())
|
||||
else:
|
||||
self.update(state)
|
||||
|
||||
# Required to ensure that getstate and setstate are called.
|
||||
__reduce__ = object.__reduce__
|
||||
__reduce_ex__ = object.__reduce_ex__
|
||||
|
||||
|
||||
class RevertableObject(object):
|
||||
pass
|
||||
|
||||
|
||||
class RollbackRandom(random.Random):
|
||||
pass
|
||||
|
||||
|
||||
class DetRandom(random.Random):
|
||||
pass
|
||||
|
||||
|
||||
class Rollback(Object):
|
||||
pass
|
||||
|
||||
|
||||
class RollbackLog(Object):
|
||||
pass
|
||||
|
||||
|
||||
class StoreProxy(object):
|
||||
pass
|
||||
|
||||
|
||||
def py_compile(source, mode, filename="<none>", lineno=1, ast_node=False, cache=True):
|
||||
pass
|
||||
|
||||
|
||||
def py_eval_bytecode(bytecode, globals=None, locals=None): # @ReservedAssignment
|
||||
pass
|
||||
12
third_party/python/rpycdec/src/renpy/script.py
vendored
Normal file
12
third_party/python/rpycdec/src/renpy/script.py
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
def collapse_stmts(stmts):
|
||||
"""
|
||||
Returns a flat list containing every statement in the tree
|
||||
stmts.
|
||||
"""
|
||||
|
||||
rv = []
|
||||
|
||||
for i in stmts:
|
||||
i.get_children(rv.append)
|
||||
|
||||
return rv
|
||||
323
third_party/python/rpycdec/src/renpy/sl2/slast.py
vendored
Normal file
323
third_party/python/rpycdec/src/renpy/sl2/slast.py
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
import logging
|
||||
from .. import ast, astsupport, ui, util
|
||||
|
||||
|
||||
class SLContext(ui.Addable):
|
||||
pass
|
||||
|
||||
|
||||
class SLNode(object):
|
||||
pass
|
||||
|
||||
|
||||
class SLBlock(SLNode):
|
||||
"""
|
||||
foo bar
|
||||
baz 1
|
||||
|
||||
expression
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = []
|
||||
if self.keyword:
|
||||
rv.append(util.get_code_properties(self.keyword, newline=True))
|
||||
if self.children:
|
||||
rv.append(util.get_code(self.children, **kwargs))
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class SLCache(object):
|
||||
pass
|
||||
|
||||
|
||||
class SLDisplayable(SLBlock):
|
||||
"""
|
||||
`displayable`
|
||||
A function that, when called with the positional and keyword
|
||||
arguments, causes the displayable to be displayed.
|
||||
|
||||
`scope`
|
||||
If true, the scope is supplied as an argument to the displayable.
|
||||
|
||||
`child_or_fixed`
|
||||
If true and the number of children of this displayable is not one,
|
||||
the children are added to a Fixed, and the Fixed is added to the
|
||||
displayable.
|
||||
|
||||
`style`
|
||||
The base name of the main style.
|
||||
|
||||
`pass_context`
|
||||
If given, the context is passed in as the first positonal argument
|
||||
of the displayable.
|
||||
|
||||
`imagemap`
|
||||
True if this is an imagemap, and should be handled as one.
|
||||
|
||||
`hotspot`
|
||||
True if this is a hotspot that depends on the imagemap it was
|
||||
first displayed with.
|
||||
|
||||
`replaces`
|
||||
True if the object this displayable replaces should be
|
||||
passed to it.
|
||||
|
||||
`default_keywords`
|
||||
The default keyword arguments to supply to the displayable.
|
||||
|
||||
`variable`
|
||||
A variable that the main displayable is assigned to.
|
||||
|
||||
https://www.renpy.org/doc/html/screens.html#add-statement
|
||||
https://www.renpy.org/doc/html/screens.html#use
|
||||
https://www.renpy.org/doc/html/screens.html#has
|
||||
https://www.renpy.org/doc/html/screens.html#imagebutton
|
||||
"""
|
||||
|
||||
def get_name(self) -> str:
|
||||
# higher version use style instead of name
|
||||
name = getattr(self, "name", None)
|
||||
displayable = getattr(self, "displayable", None)
|
||||
style = getattr(self, "style", None)
|
||||
start = ""
|
||||
if name:
|
||||
start = name
|
||||
elif displayable:
|
||||
# displayable function named sl2xxx like sl2vbar , sl2viewport
|
||||
displable_name = displayable.__name__.lower()
|
||||
if displable_name.startswith("sl2"):
|
||||
start = displable_name.replace("sl2", "")
|
||||
elif displable_name == "onevent":
|
||||
start = "on"
|
||||
else:
|
||||
start = displable_name.replace("_", "")
|
||||
if style:
|
||||
match start:
|
||||
case "multibox":
|
||||
start = style
|
||||
case "window":
|
||||
start = style
|
||||
if not start:
|
||||
logging.warning(
|
||||
"warning: displayable not found, use textbutton instead, you may need fix it manually"
|
||||
)
|
||||
start = "textbutton"
|
||||
return start
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
# higher version use style instead of name
|
||||
start = self.get_name()
|
||||
if not start:
|
||||
raise Exception("displayable not found")
|
||||
|
||||
variable = util.attr(self, "variable")
|
||||
if variable:
|
||||
start += f" as {variable}"
|
||||
|
||||
tag = util.attr(self, "tag")
|
||||
if tag:
|
||||
start += f" tag {tag}"
|
||||
|
||||
positional = util.attr(self, "positional")
|
||||
if positional:
|
||||
if isinstance(positional, list):
|
||||
start += " " + " ".join(util.get_code(p, **kwargs) for p in positional)
|
||||
else:
|
||||
start += " " + util.get_code(positional, **kwargs)
|
||||
# keywords
|
||||
keyword = util.attr(self, "keyword")
|
||||
children = util.attr(self, "children")
|
||||
if not children:
|
||||
if keyword:
|
||||
start += f" {util.get_code_properties(keyword)}"
|
||||
return start
|
||||
# children
|
||||
rv = [start + ":"]
|
||||
if keyword:
|
||||
rv.append(util.indent(util.get_code_properties(keyword, newline=True)))
|
||||
rv.append(util.indent(util.get_code(children, **kwargs)))
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class SLIf(SLNode):
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = []
|
||||
for index, (cond, body) in enumerate(self.entries):
|
||||
body_code = util.get_code(body, **kwargs)
|
||||
if not body_code:
|
||||
body_code = "pass"
|
||||
body_code = util.indent(body_code)
|
||||
if index == 0:
|
||||
rv.append(f"if {cond}:\n{body_code}")
|
||||
continue
|
||||
if cond and cond != "True":
|
||||
rv.append(f"elif {cond}:\n{body_code}")
|
||||
else:
|
||||
rv.append(f"else:\n{body_code}")
|
||||
break
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class SLShowIf(SLNode):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/screens.html#showif-statement
|
||||
|
||||
showif n == 3:
|
||||
text "Three" size 100 at cd_transform
|
||||
elif n == 2:
|
||||
text "Two" size 100 at cd_transform
|
||||
elif n == 1:
|
||||
text "One" size 100 at cd_transform
|
||||
else:
|
||||
text "Liftoff!" size 100 at cd_transform
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = []
|
||||
for index, (cond, body) in enumerate(self.entries):
|
||||
body_code = util.get_code(body, **kwargs)
|
||||
if not body_code:
|
||||
body_code = "pass"
|
||||
body_code = util.indent(body_code)
|
||||
if index == 0:
|
||||
rv.append(f"showif {cond}:\n{body_code}")
|
||||
continue
|
||||
if cond and cond != "True":
|
||||
rv.append(f"elif {cond}:\n{body_code}")
|
||||
else:
|
||||
rv.append(f"else:\n{body_code}")
|
||||
break
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class SLFor(SLBlock):
|
||||
pass
|
||||
|
||||
"""
|
||||
screen five_buttons():
|
||||
vbox:
|
||||
for i, numeral index numeral in enumerate(numerals):
|
||||
textbutton numeral action Return(i + 1)
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
rv = [f"for {self.variable} in {self.expression}:"]
|
||||
children = util.attr(self, "children")
|
||||
if not children:
|
||||
rv.append(util.indent("pass"))
|
||||
else:
|
||||
rv.append(util.indent(util.get_code(children, **kwargs)))
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class SLPython(SLNode):
|
||||
def get_code(self, **kwargs) -> str:
|
||||
inner_code = util.get_code(self.code, **kwargs)
|
||||
if not inner_code:
|
||||
return ""
|
||||
if len(inner_code.splitlines()) == 1:
|
||||
return f"$ {inner_code}"
|
||||
return f"python:\n{util.indent(inner_code)}"
|
||||
|
||||
|
||||
class SLPass(SLNode):
|
||||
pass
|
||||
|
||||
|
||||
class SLDefault(SLNode):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/python.html#default-statement
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
return f"default {self.variable} = {self.expression}"
|
||||
|
||||
|
||||
class SLUse(SLNode):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/screens.html#use
|
||||
|
||||
use [expression EXPR pass|WORD] ARGUMENTS [id EXPR][:]
|
||||
BLOCK
|
||||
"""
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
start = "use"
|
||||
target = util.attr(self, "target")
|
||||
if target:
|
||||
if isinstance(target, ast.PyExpr):
|
||||
start += f" expression {util.get_code(target, **kwargs)} pass "
|
||||
elif isinstance(target, astsupport.PyExpr):
|
||||
start += f" expression {util.get_code(target, **kwargs)} pass "
|
||||
else:
|
||||
start += f" {target}"
|
||||
if self.args:
|
||||
start += f"{util.get_code(self.args, **kwargs)}"
|
||||
if self.block:
|
||||
return util.label_code(start, self.block, **kwargs)
|
||||
if self.ast:
|
||||
return util.label_code(start, self.ast, **kwargs)
|
||||
return start
|
||||
|
||||
|
||||
# https://www.renpy.org/doc/html/screens.html#use-and-transclude
|
||||
"""
|
||||
screen movable_frame(pos):
|
||||
drag:
|
||||
pos pos
|
||||
|
||||
frame:
|
||||
background Frame("movable_frame.png", 10, 10)
|
||||
top_padding 20
|
||||
|
||||
transclude
|
||||
"""
|
||||
|
||||
|
||||
class SLTransclude(SLNode):
|
||||
def get_code(self, **kwargs) -> str:
|
||||
return "transclude"
|
||||
|
||||
|
||||
class SLScreen(SLBlock):
|
||||
"""
|
||||
https://www.renpy.org/doc/html/screens.html#screen-statement
|
||||
"""
|
||||
|
||||
parameters: ast.ParameterInfo
|
||||
keyword: list
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
start = "screen"
|
||||
if self.name:
|
||||
start += f" {self.name}"
|
||||
if self.parameters:
|
||||
start += f"{util.get_code(self.parameters, **kwargs)}"
|
||||
|
||||
properties = self.keyword.copy()
|
||||
tag = util.attr(self, "tag")
|
||||
if tag:
|
||||
properties.append(("tag", tag))
|
||||
|
||||
rv = [start + ":"]
|
||||
# keyword
|
||||
if properties:
|
||||
rv.append(util.indent(util.get_code_properties(properties, newline=True)))
|
||||
rv.append("") # add a newline after keyword
|
||||
# children
|
||||
children = util.attr(self, "children")
|
||||
if children:
|
||||
rv.append(util.indent(util.get_code(children, **kwargs)))
|
||||
if len(rv) == 1:
|
||||
rv.append("pass")
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
class ScreenCache(object):
|
||||
pass
|
||||
|
||||
|
||||
class SLContinue(SLNode):
|
||||
def get_code(self, **kwargs) -> str:
|
||||
return "continue"
|
||||
25
third_party/python/rpycdec/src/renpy/sl2/sldisplayables.py
vendored
Normal file
25
third_party/python/rpycdec/src/renpy/sl2/sldisplayables.py
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
from ..display import layout
|
||||
|
||||
|
||||
class ShowIf(layout.Container):
|
||||
pass
|
||||
|
||||
|
||||
def sl2vbar(context=None, **properties):
|
||||
pass
|
||||
|
||||
|
||||
def sl2viewport(context=None, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def sl2vpgrid(context=None, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def sl2add(d, replaces=None, scope=None, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def sl2bar(context=None, **properties):
|
||||
pass
|
||||
0
third_party/python/rpycdec/src/renpy/test/__init__.py
vendored
Normal file
0
third_party/python/rpycdec/src/renpy/test/__init__.py
vendored
Normal file
2
third_party/python/rpycdec/src/renpy/text/extras.py
vendored
Normal file
2
third_party/python/rpycdec/src/renpy/text/extras.py
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
class ParameterizedText(object):
|
||||
pass
|
||||
26
third_party/python/rpycdec/src/renpy/text/font.py
vendored
Normal file
26
third_party/python/rpycdec/src/renpy/text/font.py
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
class ImageFont(object):
|
||||
pass
|
||||
|
||||
|
||||
class FontGroup(object):
|
||||
pass
|
||||
|
||||
|
||||
class ScaledImageFont(ImageFont):
|
||||
pass
|
||||
|
||||
|
||||
class BMFont(ImageFont):
|
||||
pass
|
||||
|
||||
|
||||
class MudgeFont(ImageFont):
|
||||
pass
|
||||
|
||||
|
||||
class SFont(ImageFont):
|
||||
pass
|
||||
|
||||
|
||||
class ImageFont(object):
|
||||
pass
|
||||
33
third_party/python/rpycdec/src/renpy/text/text.py
vendored
Normal file
33
third_party/python/rpycdec/src/renpy/text/text.py
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
from ..display import core
|
||||
|
||||
|
||||
class Blit(object):
|
||||
pass
|
||||
|
||||
|
||||
class DrawInfo(object):
|
||||
pass
|
||||
|
||||
|
||||
class TextSegment(object):
|
||||
pass
|
||||
|
||||
|
||||
class SpaceSegment(object):
|
||||
pass
|
||||
|
||||
|
||||
class DisplayableSegment(object):
|
||||
pass
|
||||
|
||||
|
||||
class FlagSegment(object):
|
||||
pass
|
||||
|
||||
|
||||
class Layout(object):
|
||||
pass
|
||||
|
||||
|
||||
class Text(core.Displayable):
|
||||
pass
|
||||
28
third_party/python/rpycdec/src/renpy/translation/__init__.py
vendored
Normal file
28
third_party/python/rpycdec/src/renpy/translation/__init__.py
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import re
|
||||
|
||||
|
||||
def encode_say_string(s):
|
||||
"""
|
||||
Encodes a string in the format used by Ren'Py say statements.
|
||||
"""
|
||||
|
||||
s = s.replace("\\", "\\\\")
|
||||
s = s.replace("\n", "\\n")
|
||||
s = s.replace('"', '\\"')
|
||||
s = re.sub(r"(?<= ) ", "\\ ", s)
|
||||
|
||||
return '"' + s + '"'
|
||||
|
||||
|
||||
def quote_unicode(s):
|
||||
s = s.replace("\\", "\\\\")
|
||||
s = s.replace('"', '\\"')
|
||||
s = s.replace("\a", "\\a")
|
||||
s = s.replace("\b", "\\b")
|
||||
s = s.replace("\f", "\\f")
|
||||
s = s.replace("\n", "\\n")
|
||||
s = s.replace("\r", "\\r")
|
||||
s = s.replace("\t", "\\t")
|
||||
s = s.replace("\v", "\\v")
|
||||
|
||||
return s
|
||||
27
third_party/python/rpycdec/src/renpy/translation/generation.py
vendored
Normal file
27
third_party/python/rpycdec/src/renpy/translation/generation.py
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import os
|
||||
|
||||
import renpy
|
||||
|
||||
|
||||
def shorten_filename(filename):
|
||||
"""
|
||||
Shortens a file name. Returns the shortened filename, and a flag that says
|
||||
if the filename is in the common directory.
|
||||
"""
|
||||
|
||||
commondir = os.path.normpath(renpy.config.commondir) # type: ignore
|
||||
gamedir = os.path.normpath(renpy.config.gamedir)
|
||||
|
||||
if filename.startswith(commondir):
|
||||
fn = os.path.relpath(filename, commondir)
|
||||
common = True
|
||||
|
||||
elif filename.startswith(gamedir):
|
||||
fn = os.path.relpath(filename, gamedir)
|
||||
common = False
|
||||
|
||||
else:
|
||||
fn = os.path.basename(filename)
|
||||
common = False
|
||||
|
||||
return fn, common
|
||||
9
third_party/python/rpycdec/src/renpy/translation/scanstrings.py
vendored
Normal file
9
third_party/python/rpycdec/src/renpy/translation/scanstrings.py
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
STRING_RE = r"""(?x)
|
||||
\b(?:_|__|___|_p)
|
||||
\s*(\((?:[\s\\\n]*[uU]?(?:
|
||||
\"\"\"(?:\\.|\\\n|\"{1,2}|[^\\"])*?\"\"\"
|
||||
|'''(?:\\.|\\\n|\'{1,2}|[^\\'])*?'''
|
||||
|"(?:\\.|\\\n|[^\\"])*"
|
||||
|'(?:\\.|\\\n|[^\\'])*'
|
||||
))+\s*\))
|
||||
"""
|
||||
96
third_party/python/rpycdec/src/renpy/ui.py
vendored
Normal file
96
third_party/python/rpycdec/src/renpy/ui.py
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
from .object import Object
|
||||
|
||||
|
||||
class Action(Object):
|
||||
pass
|
||||
|
||||
|
||||
class BarValue(Object):
|
||||
pass
|
||||
|
||||
|
||||
class Addable(object):
|
||||
pass
|
||||
|
||||
|
||||
class Layer(Addable):
|
||||
pass
|
||||
|
||||
|
||||
class Many(Addable):
|
||||
pass
|
||||
|
||||
|
||||
class One(Addable):
|
||||
pass
|
||||
|
||||
|
||||
class Detached(Addable):
|
||||
pass
|
||||
|
||||
|
||||
class ChildOrFixed(Addable):
|
||||
pass
|
||||
|
||||
def get_code(self, **kwargs) -> str:
|
||||
pass
|
||||
|
||||
|
||||
def _hotspot(spot, style="hotspot", **properties):
|
||||
pass
|
||||
|
||||
|
||||
def _imagebutton(
|
||||
idle_image=None,
|
||||
hover_image=None,
|
||||
insensitive_image=None,
|
||||
activate_image=None,
|
||||
selected_idle_image=None,
|
||||
selected_hover_image=None,
|
||||
selected_insensitive_image=None,
|
||||
selected_activate_image=None,
|
||||
idle=None,
|
||||
hover=None,
|
||||
insensitive=None,
|
||||
selected_idle=None,
|
||||
selected_hover=None,
|
||||
selected_insensitive=None,
|
||||
image_style=None,
|
||||
auto=None,
|
||||
**properties,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
def _imagemap(
|
||||
ground,
|
||||
selected,
|
||||
hotspots,
|
||||
unselected=None,
|
||||
overlays=False,
|
||||
style="imagemap",
|
||||
mouse="imagemap",
|
||||
with_none=None,
|
||||
**properties,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
def _textbutton(
|
||||
label,
|
||||
clicked=None,
|
||||
style=None,
|
||||
text_style=None,
|
||||
substitute=True,
|
||||
scope=None,
|
||||
**kwargs,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
def _key(key, action=None, activate_sound=None):
|
||||
pass
|
||||
|
||||
|
||||
def _label(label, style=None, text_style=None, substitute=True, scope=None, **kwargs):
|
||||
pass
|
||||
250
third_party/python/rpycdec/src/renpy/util.py
vendored
Normal file
250
third_party/python/rpycdec/src/renpy/util.py
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
from . import ast
|
||||
from collections import deque
|
||||
|
||||
IDENT_CHAR = " "
|
||||
|
||||
|
||||
def indent(code: str, level: int = 1) -> str:
|
||||
"""
|
||||
Indent each line of code by a specified level.
|
||||
|
||||
Args:
|
||||
code: The string to indent
|
||||
level: Number of indentation levels to apply (default: 1)
|
||||
|
||||
Returns:
|
||||
The indented string
|
||||
"""
|
||||
if not code:
|
||||
return ""
|
||||
indent_str = IDENT_CHAR * level
|
||||
# add indentation to each non-empty line
|
||||
# keep empty lines as they are
|
||||
rv = [indent_str + line if line.strip() else line for line in code.split("\n")]
|
||||
return "\n".join(rv)
|
||||
|
||||
|
||||
def get_code_properties(props: tuple | dict, newline: bool = False, **kwargs) -> str:
|
||||
"""
|
||||
:param keyword: tuple | dict
|
||||
:param newline: bool
|
||||
:return: str
|
||||
|
||||
>>> get_code_properties((("a", 1), ("b", 2)))
|
||||
a 1 b 2
|
||||
>>> get_code_properties((("a", 1), (None, b)), newline=True)
|
||||
a 1
|
||||
b
|
||||
>>> get_code_properties({"a": 1, "b": None})
|
||||
a 1
|
||||
b None
|
||||
"""
|
||||
list = []
|
||||
if isinstance(props, dict):
|
||||
props = props.items()
|
||||
for prop in props:
|
||||
if isinstance(prop, tuple) and len(prop) == 2:
|
||||
key, value = prop[0], prop[1]
|
||||
valstr = get_code(value, **kwargs)
|
||||
if not valstr:
|
||||
list.append(f"{key}")
|
||||
else:
|
||||
list.append(f"{key} {valstr}")
|
||||
continue
|
||||
else:
|
||||
prop_str = " ".join([str(x) for x in prop])
|
||||
if not prop_str:
|
||||
continue
|
||||
list.append(prop_str)
|
||||
return ("\n" if newline else " ").join(list)
|
||||
|
||||
|
||||
def get_code(node, **kwargs) -> str:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
node : ast.Node
|
||||
kwargs : dict
|
||||
indent : int
|
||||
space indent level
|
||||
modifier : Callable[[ast.Node], ast.Node]
|
||||
modify node before get code
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
generated code
|
||||
|
||||
Raises
|
||||
------
|
||||
NotImplementedError
|
||||
if node type is not implemented or some attributes unable to handle.
|
||||
|
||||
"""
|
||||
|
||||
if isinstance(node, str):
|
||||
return node
|
||||
if isinstance(node, list):
|
||||
rv = []
|
||||
items = deque(node)
|
||||
while items:
|
||||
item = items.popleft()
|
||||
|
||||
# [Say|UserStatement?, Menu]
|
||||
if isinstance(item, ast.Say) or isinstance(item, ast.UserStatement):
|
||||
next = items[0] if items else None
|
||||
if isinstance(next, ast.Menu) and attr(next, "statement_start") == item:
|
||||
menu = items.popleft()
|
||||
call_kwargs = kwargs.copy()
|
||||
call_kwargs["menu_say"] = item
|
||||
rv.append(get_code(menu, **call_kwargs))
|
||||
continue
|
||||
|
||||
# [Label, Say|UserStatement?, Menu]
|
||||
if isinstance(item, ast.Label):
|
||||
next = items[0] if items else None
|
||||
# [Label, Say|UserStatement, Menu]
|
||||
if isinstance(next, ast.Say) or isinstance(next, ast.UserStatement):
|
||||
next_next = items[1] if len(items) > 1 else None
|
||||
if (
|
||||
isinstance(next_next, ast.Menu)
|
||||
and attr(next_next, "statement_start") == item
|
||||
):
|
||||
say = items.popleft()
|
||||
menu = items.popleft()
|
||||
call_kwargs = kwargs.copy()
|
||||
call_kwargs["menu_label"] = item
|
||||
call_kwargs["menu_say"] = say
|
||||
rv.append(get_code(menu, **call_kwargs))
|
||||
continue
|
||||
# [Label, Menu]
|
||||
if isinstance(next, ast.Menu) and attr(next, "statement_start") == item:
|
||||
menu = items.popleft()
|
||||
call_kwargs = kwargs.copy()
|
||||
call_kwargs["menu_label"] = item
|
||||
rv.append(get_code(menu, **call_kwargs))
|
||||
continue
|
||||
|
||||
if isinstance(item, ast.With):
|
||||
# some node quoted by two ast.With if has with suffix expr, the sdk snippet:
|
||||
#
|
||||
# renpy.parser.parse_with(node):
|
||||
# if not "with":
|
||||
# return node
|
||||
# expr = simple_expression
|
||||
# return [ast.With(loc, "None", paired=expr), node, ast.With(loc, expr)]
|
||||
#
|
||||
# - ast.Scene
|
||||
# - ast.Show
|
||||
# - ast.Hide
|
||||
expr, paired = attr(item, "expr"), attr(item, "paired")
|
||||
if (not expr or expr == "None") and paired:
|
||||
next_next = items[1] if len(items) > 1 else None
|
||||
if (
|
||||
isinstance(next_next, ast.With)
|
||||
and attr(next_next, "expr") == paired
|
||||
):
|
||||
node = items.popleft()
|
||||
close_with = items.popleft()
|
||||
call_kwargs = kwargs.copy()
|
||||
call_kwargs.update({"with_expr": attr(close_with, "expr")})
|
||||
rv.append(get_code(node, **call_kwargs))
|
||||
continue
|
||||
|
||||
if isinstance(item, ast.Call):
|
||||
# call = [Call, Label?, Pass]
|
||||
from_label = None
|
||||
# try to pop next Label|Pass
|
||||
next = items.popleft() if items else None
|
||||
if isinstance(next, ast.Label):
|
||||
from_label = next
|
||||
# pop Pass
|
||||
items.popleft() if items else None
|
||||
|
||||
if from_label is not None:
|
||||
call_kwargs = kwargs.copy()
|
||||
call_kwargs["from_label"] = from_label
|
||||
rv.append(get_code(item, **call_kwargs))
|
||||
continue
|
||||
|
||||
if isinstance(item, ast.Return):
|
||||
if (
|
||||
# it cant tell out an anto appended Return or an empty one
|
||||
# currently we must not ignore
|
||||
False
|
||||
and len(node) > 1
|
||||
and not items
|
||||
and not attr(item, "expression")
|
||||
# omit the return after While may cause unexpected behavior
|
||||
and not any(isinstance(n, ast.While) for n in node)
|
||||
):
|
||||
# ignore the return
|
||||
continue
|
||||
|
||||
# if all left items are returns
|
||||
if all(
|
||||
isinstance(n, ast.Return) and not attr(n, "expression")
|
||||
for n in items
|
||||
):
|
||||
# ignore all returns
|
||||
rv.append(get_code(item, **kwargs))
|
||||
break
|
||||
|
||||
# if isinstance(item, ast.Init):
|
||||
# if item.priority == 500:
|
||||
# if len(item.block) == 1 and isinstance(item.block[0], ast.Image):
|
||||
# rv.append(get_code(item.block[0]))
|
||||
# continue
|
||||
|
||||
rv.append(get_code(item, **kwargs))
|
||||
return "\n".join(rv)
|
||||
|
||||
# modify node before get code
|
||||
modifier = kwargs.get("modifier")
|
||||
if modifier:
|
||||
modifier(node, **kwargs)
|
||||
return node.get_code(**kwargs)
|
||||
|
||||
|
||||
def get_block_code(node, **kwargs) -> str:
|
||||
"""
|
||||
https://www.renpy.org/doc/html/layeredimage.html#layeredimage
|
||||
"""
|
||||
if isinstance(node, list):
|
||||
return "\n".join(map(lambda x: get_block_code(x, **kwargs), node))
|
||||
lines = []
|
||||
if isinstance(node, tuple):
|
||||
if len(node) == 5:
|
||||
_, _, _, code, block = node
|
||||
elif len(node) == 4:
|
||||
_, _, code, block = node
|
||||
else:
|
||||
raise NotImplementedError
|
||||
lines.append(code)
|
||||
lines.append(indent(get_block_code(block, **kwargs)))
|
||||
else:
|
||||
raise NotImplementedError
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def attr(item, key: str) -> str:
|
||||
if isinstance(item, dict):
|
||||
return item.get(key, None)
|
||||
if hasattr(item, key):
|
||||
return getattr(item, key)
|
||||
return None
|
||||
|
||||
|
||||
def label_code(label: str, child, **kwargs) -> str:
|
||||
"""
|
||||
return a code block with a label
|
||||
example:
|
||||
>>> label_getcode("label foo", None)
|
||||
"label foo"
|
||||
>>> label_getcode("label foo", Expression("bar"))
|
||||
"label foo:
|
||||
bar"
|
||||
"""
|
||||
if not child:
|
||||
return label
|
||||
return f"{label}:\n{indent(get_code(child, **kwargs))}"
|
||||
Reference in New Issue
Block a user