forked from M-Labs/artiq
compiler: make kernel_invariant an instance, not class, property.
Fixes #409.
This commit is contained in:
parent
79c7c2dd45
commit
f7d83e9bdf
@ -55,6 +55,7 @@ class ASTSynthesizer:
|
||||
self.object_map, self.type_map, self.value_map = object_map, type_map, value_map
|
||||
self.quote_function = quote_function
|
||||
self.expanded_from = expanded_from
|
||||
self.diagnostics = []
|
||||
|
||||
def finalize(self):
|
||||
self.source_buffer.source = self.source
|
||||
@ -124,6 +125,35 @@ class ASTSynthesizer:
|
||||
|
||||
if typ in self.type_map:
|
||||
instance_type, constructor_type = self.type_map[typ]
|
||||
|
||||
if hasattr(value, 'kernel_invariants') and \
|
||||
value.kernel_invariants != instance_type.constant_attributes:
|
||||
attr_diff = value.kernel_invariants.difference(
|
||||
instance_type.constant_attributes)
|
||||
if len(attr_diff) > 0:
|
||||
diag = diagnostic.Diagnostic("warning",
|
||||
"object {value} of type {typ} declares attribute(s) {attrs} as "
|
||||
"kernel invariant, but other objects of the same type do not; "
|
||||
"the invariant annotation on this object will be ignored",
|
||||
{"value": repr(value),
|
||||
"typ": types.TypePrinter().name(instance_type, max_depth=0),
|
||||
"attrs": ", ".join(["'{}'".format(attr) for attr in attr_diff])},
|
||||
loc)
|
||||
self.diagnostics.append(diag)
|
||||
attr_diff = instance_type.constant_attributes.difference(
|
||||
value.kernel_invariants)
|
||||
if len(attr_diff) > 0:
|
||||
diag = diagnostic.Diagnostic("warning",
|
||||
"object {value} of type {typ} does not declare attribute(s) {attrs} as "
|
||||
"kernel invariant, but other objects of the same type do; "
|
||||
"the invariant annotation on other objects will be ignored",
|
||||
{"value": repr(value),
|
||||
"typ": types.TypePrinter().name(instance_type, max_depth=0),
|
||||
"attrs": ", ".join(["'{}'".format(attr) for attr in attr_diff])},
|
||||
loc)
|
||||
self.diagnostics.append(diag)
|
||||
value.kernel_invariants = value.kernel_invariants.intersection(
|
||||
instance_type.constant_attributes)
|
||||
else:
|
||||
if issubclass(typ, BaseException):
|
||||
if hasattr(typ, 'artiq_builtin'):
|
||||
@ -138,16 +168,16 @@ class ASTSynthesizer:
|
||||
instance_type = types.TInstance("{}.{}".format(typ.__module__, typ.__qualname__),
|
||||
OrderedDict())
|
||||
instance_type.attributes['__objectid__'] = builtins.TInt32()
|
||||
if hasattr(typ, 'kernel_invariants'):
|
||||
assert isinstance(typ.kernel_invariants, set)
|
||||
instance_type.constant_attributes = typ.kernel_invariants
|
||||
|
||||
constructor_type = types.TConstructor(instance_type)
|
||||
constructor_type.attributes['__objectid__'] = builtins.TInt32()
|
||||
instance_type.constructor = constructor_type
|
||||
|
||||
self.type_map[typ] = instance_type, constructor_type
|
||||
|
||||
if hasattr(value, 'kernel_invariants'):
|
||||
assert isinstance(value.kernel_invariants, set)
|
||||
instance_type.constant_attributes = value.kernel_invariants
|
||||
|
||||
if isinstance(value, type):
|
||||
self.value_map[constructor_type].append((value, loc))
|
||||
return asttyped.QuoteT(value=value, type=constructor_type,
|
||||
@ -801,4 +831,7 @@ class Stitcher:
|
||||
synthesizer = self._synthesizer(loc)
|
||||
node = synthesizer.quote(value)
|
||||
synthesizer.finalize()
|
||||
if len(synthesizer.diagnostics) > 0:
|
||||
for warning in synthesizer.diagnostics:
|
||||
self.engine.process(warning)
|
||||
return node
|
||||
|
@ -3,8 +3,14 @@ import sys, os
|
||||
from artiq.master.databases import DeviceDB
|
||||
from artiq.master.worker_db import DeviceManager
|
||||
|
||||
import artiq.coredevice.core
|
||||
from artiq.coredevice.core import Core, CompileError
|
||||
|
||||
def _render_diagnostic(diagnostic, colored):
|
||||
return "\n".join(diagnostic.render(only_line=True))
|
||||
|
||||
artiq.coredevice.core._render_diagnostic = _render_diagnostic
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1 and sys.argv[1] == "+diag":
|
||||
del sys.argv[1]
|
||||
@ -35,7 +41,6 @@ def main():
|
||||
print(core.comm.get_log())
|
||||
core.comm.clear_log()
|
||||
except CompileError as error:
|
||||
print("\n".join(error.__cause__.diagnostic.render(only_line=True)))
|
||||
if not diag:
|
||||
exit(1)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
|
22
artiq/test/lit/embedding/warning_invariant_1.py
Normal file
22
artiq/test/lit/embedding/warning_invariant_1.py
Normal file
@ -0,0 +1,22 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
from artiq.language.types import *
|
||||
|
||||
class c:
|
||||
a = b = 0
|
||||
def __init__(self, invariants):
|
||||
self.kernel_invariants = invariants
|
||||
|
||||
def __repr__(self):
|
||||
return "<testbench.c object>"
|
||||
|
||||
i1 = c({'a'})
|
||||
i2 = c({'a', 'b'})
|
||||
|
||||
@kernel
|
||||
def entrypoint():
|
||||
# CHECK-L: <synthesized>:1: warning: object <testbench.c object> of type <instance testbench.c> declares attribute(s) 'b' as kernel invariant, but other objects of the same type do not; the invariant annotation on this object will be ignored
|
||||
# CHECK-L: ${LINE:+1}: note: expanded from here
|
||||
[i1, i2]
|
22
artiq/test/lit/embedding/warning_invariant_2.py
Normal file
22
artiq/test/lit/embedding/warning_invariant_2.py
Normal file
@ -0,0 +1,22 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.language.core import *
|
||||
from artiq.language.types import *
|
||||
|
||||
class c:
|
||||
a = b = 0
|
||||
def __init__(self, invariants):
|
||||
self.kernel_invariants = invariants
|
||||
|
||||
def __repr__(self):
|
||||
return "<testbench.c object>"
|
||||
|
||||
i1 = c({'a', 'b'})
|
||||
i2 = c({'a'})
|
||||
|
||||
@kernel
|
||||
def entrypoint():
|
||||
# CHECK-L: <synthesized>:1: warning: object <testbench.c object> of type <instance testbench.c> does not declare attribute(s) 'b' as kernel invariant, but other objects of the same type do; the invariant annotation on other objects will be ignored
|
||||
# CHECK-L: ${LINE:+1}: note: expanded from here
|
||||
[i1, i2]
|
@ -1,4 +1,4 @@
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s >%t
|
||||
# RUN: %python -m artiq.compiler.testbench.embedding +diag %s 2>%t
|
||||
# RUN: OutputCheck %s --file-to-check=%t
|
||||
|
||||
from artiq.experiment import *
|
||||
|
Loading…
Reference in New Issue
Block a user