Implement checking of range, span, and filter types in macros.
Show the type signatures in ythe wmlscope error messages for the mismatches.
This commit is contained in:
parent
8a2db11ceb
commit
7eb3510fca
3 changed files with 43 additions and 27 deletions
|
@ -47,12 +47,12 @@
|
|||
villages_per_scout=0
|
||||
#enddef
|
||||
|
||||
#define RANDOM RANGE
|
||||
#define RANDOM THING
|
||||
# Macro to quickly pick a random value (in the $random variable, to avoid
|
||||
# cluttering up savegames with such temporary variables).
|
||||
[set_variable]
|
||||
name=random
|
||||
rand={RANGE}
|
||||
rand={THING}
|
||||
[/set_variable]
|
||||
#enddef
|
||||
|
||||
|
|
|
@ -60,37 +60,53 @@ def isresource(filename):
|
|||
(root, ext) = os.path.splitext(filename)
|
||||
return ext and ext[1:] in resource_extensions
|
||||
|
||||
def formaltype(f):
|
||||
# Deduce the expected type of the formal
|
||||
if f in ("SIDE",):
|
||||
ftype = "numeric"
|
||||
elif f in ("X", "Y", "SPAN"):
|
||||
ftype = "span"
|
||||
elif f in ("RANGE",):
|
||||
ftype = "range"
|
||||
elif f in ("TYPE", "DESCRIPTION", "USER_DESCRIPTION", "TERRAIN"):
|
||||
ftype = "string"
|
||||
elif f.endswith("IMAGE"):
|
||||
ftype = "image"
|
||||
elif f in ("FILTER",):
|
||||
ftype = "filter"
|
||||
else:
|
||||
ftype = None
|
||||
return ftype
|
||||
|
||||
def actualtype(a):
|
||||
# Deduce the type of the actual
|
||||
if a.isdigit() or a.startswith("-") and a[1:].isdigit():
|
||||
atype = "numeric"
|
||||
elif re.match(r"([0-9]+\-[0-9]+,?|[0-9]+,?)+\Z", a):
|
||||
atype = "span"
|
||||
elif a in ("melee", "ranged"):
|
||||
atype = "range"
|
||||
elif a.startswith("{") and a.endswith("}") or a.startswith("$"):
|
||||
atype = None # Can't tell -- it's a macro expansion
|
||||
elif a.endswith(".png") or a.endswith(".jpg"):
|
||||
atype = "image"
|
||||
elif "=" in a:
|
||||
atype = "filter"
|
||||
else:
|
||||
atype = "string"
|
||||
return atype
|
||||
|
||||
def argmatch(formals, actuals):
|
||||
if len(formals) != len(actuals):
|
||||
return False
|
||||
for (f, a) in zip(formals, actuals):
|
||||
# Deduce the expected type of the formal
|
||||
if f in ("SIDE",):
|
||||
ftype = "numeric"
|
||||
elif f in ("X", "Y"):
|
||||
ftype = "range"
|
||||
elif f in ("TYPE", "DESCRIPTION", "USER_DESCRIPTION", "TERRAIN"):
|
||||
ftype = "string"
|
||||
elif f.endswith("IMAGE"):
|
||||
ftype = "image"
|
||||
else:
|
||||
ftype = None
|
||||
# Deduce the type of the actual
|
||||
if a.isdigit() or a.startswith("-") and a[1:].isdigit():
|
||||
atype = "numeric"
|
||||
elif re.search(r"[0-9]+\-[0-9]+", a):
|
||||
atype = "range"
|
||||
elif a.startswith("{") and a.endswith("}") or a.startswith("$"):
|
||||
atype = None # Can't tell -- it's a macro expansion
|
||||
elif a.endswith(".png") or a.endswith(".jpg"):
|
||||
atype = "image"
|
||||
else:
|
||||
atype = "string"
|
||||
ftype = formaltype(f)
|
||||
atype = actualtype(a)
|
||||
# Here's the compatibility logic. First, we catch the situations
|
||||
# in which a more restricted actual type matches a more general
|
||||
# formal one. Then we have a fallback rule checking for type
|
||||
# equality or wildcarding.
|
||||
if atype == "numeric" and ftype == "range":
|
||||
if atype == "numeric" and ftype == "span":
|
||||
pass
|
||||
elif atype == "image" and ftype == "string":
|
||||
pass
|
||||
|
|
|
@ -139,10 +139,10 @@ class CrossRefLister(CrossRef):
|
|||
if mismatched:
|
||||
print "# Mismatched references:"
|
||||
for (n, m) in mismatched:
|
||||
print "%s: macro %s(%s) has signature mismatches:" % (m, n, ", ".join(m.args))
|
||||
print "%s: macro %s(%s) has signature (%s) mismatches:" % (m, n, ", ".join(m.args), ", ".join(map(lambda x: str(formaltype(x)), m.args)))
|
||||
for (file, refs) in m.references.items():
|
||||
for (ln, args) in refs:
|
||||
print '"%s", line %d: %s(%s)' % (file, ln, n, ", ".join(args))
|
||||
print '"%s", line %d: %s(%s) with signature (%s)' % (file, ln, n, ", ".join(args), ", ".join(map(lambda x: str(actualtype(x)), args)))
|
||||
def deflist(self, pred=None):
|
||||
"List all resource definitions."
|
||||
sorted = self.xref.keys()
|
||||
|
|
Loading…
Add table
Reference in a new issue