frontend: remove deprecated cached annotation and phase
authorJean Privat <jean@pryen.org>
Thu, 26 Feb 2015 04:50:42 +0000 (11:50 +0700)
committerJean Privat <jean@pryen.org>
Thu, 26 Feb 2015 04:50:42 +0000 (11:50 +0700)
Signed-off-by: Jean Privat <jean@pryen.org>

src/frontend/cached.nit [deleted file]
src/frontend/check_annotation.nit
src/frontend/frontend.nit
src/nitlight.nit

diff --git a/src/frontend/cached.nit b/src/frontend/cached.nit
deleted file mode 100644 (file)
index f331b1d..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Implementation of the method-related annotation `cached`
-#
-# The cached annotation is deprecated, use the `lazy` annotation instead.
-module cached
-
-import modelize
-private import parser_util
-import simple_misc_analysis
-private import annotation
-intrude import modelize::modelize_property
-
-redef class ToolContext
-       # Process the `cached` annotation on methods
-       var cached_phase: Phase = new CachedPhase(self, [modelize_property_phase])
-end
-
-private class CachedPhase
-       super Phase
-
-       init
-       do
-               # FIXME The phase has to be executed just after `modelize_property_phase`
-               # But there is no simple way to express this
-               # So, for the moment, I just looked at the linearization and see what phase is after `modelize_property_phase`
-               # And inserted before it
-               toolcontext.phases.add_edge(toolcontext.simple_misc_analysis_phase, self)
-       end
-
-       redef fun process_annotated_node(npropdef, nat)
-       do
-               # Skip if we are not interested
-               if nat.name != "cached" then return
-
-               # Do some validity checks and print errors if the annotation is used incorrectly
-               var modelbuilder = toolcontext.modelbuilder
-
-               if not npropdef isa AMethPropdef then
-                       modelbuilder.error(npropdef, "Syntax error: only a function can be cached.")
-                       return
-               end
-
-               var mpropdef = npropdef.mpropdef.as(not null)
-
-               var mtype = mpropdef.msignature.return_mtype
-               if mtype == null then
-                       modelbuilder.error(npropdef, "Syntax error: only a function can be cached.")
-                       return
-               end
-
-               if not npropdef.n_signature.n_params.is_empty then
-                       modelbuilder.error(npropdef, "Syntax error: only a function without arguments can be cached.")
-                       return
-               end
-
-               # OK, let we do some meta-programming...
-
-               var location = npropdef.location
-               var name = mpropdef.mproperty.name
-               var nclassdef = npropdef.parent.as(AClassdef)
-               var mclassdef = nclassdef.mclassdef.as(not null)
-
-               if not mclassdef.mclass.kind.need_init then
-                       modelbuilder.error(npropdef, "Error: only abstract and concrete classes can have cached functions.")
-                       return
-               end
-
-               # Create a new private attribute to store the cache
-               var cache_mpropdef = new MAttributeDef(mclassdef, new MAttribute(mclassdef, "@{name}<cache>", private_visibility), location)
-               cache_mpropdef.static_mtype = mtype.as_nullable
-
-               # Create another new private attribute to store the boolean «is the function cached?»
-               # The point is to manage the case where `null` is a genuine return value of the method
-               var is_cached_mpropdef = new MAttributeDef(mclassdef, new MAttribute(mclassdef, "@{name}<is_cached>", private_visibility), location)
-               is_cached_mpropdef.static_mtype = mclassdef.mmodule.get_primitive_class("Bool").mclass_type
-               # FIXME? Because there is a default value ("false") a real propdef is required
-               var is_cached_npropdef = toolcontext.parse_propdef("var is_cached = false").as(AAttrPropdef)
-               associate_propdef(is_cached_mpropdef, is_cached_npropdef)
-
-               # Create a new private method to do the real work
-               var real_mpropdef = new MMethodDef(mclassdef, new MMethod(mclassdef, "{name}<real>", private_visibility), location)
-               real_mpropdef.msignature = mpropdef.msignature
-               # FIXME: Again, if the engine require a real propdef even if it is empty
-               var real_npropdef = toolcontext.parse_propdef("fun real do end").as(AMethPropdef)
-               associate_propdef(real_mpropdef, real_npropdef)
-               # Note: the body is set at the last line of this function
-
-               # Save the original body
-               var real_body = npropdef.n_block.as(not null)
-
-               # Replace the original body with a new body that do the proxy'n'cache work
-               var proxy_body = toolcontext.parse_stmts("if self._is_cached then return self._cache.as(not null)\nvar res = call_real\nself._cache_write = res\nself._is_cached_write = true\nreturn res")
-               real_body.replace_with(proxy_body)
-
-               # Do some transformation on the identifiers used on the proxy body so that correct entities are designated
-               # FIXME: we just trick the following phases into associating by name some tokens with some model-entities
-               # But this is bad at at least two levels
-               # - we already know the real model-entities, so why doing latter the association and not now?
-               # - associating by names may cause a useless fragility (name-conflicts, etc.)
-               proxy_body.collect_tokens_by_text("_is_cached").first.text = is_cached_mpropdef.mproperty.name
-               proxy_body.collect_tokens_by_text("_is_cached_write").first.text = is_cached_mpropdef.mproperty.name
-               proxy_body.collect_tokens_by_text("_cache").first.text = cache_mpropdef.mproperty.name
-               proxy_body.collect_tokens_by_text("_cache_write").first.text = cache_mpropdef.mproperty.name
-               proxy_body.collect_tokens_by_text("call_real").first.text = real_mpropdef.mproperty.name
-
-               # FIXME a last transformation cannot be done yet. So, the call to `super` (`ASuperExpr`) is broken in cached methods.
-
-               # Give the original body to the private real methoddef
-               real_npropdef.n_block.replace_with(real_body)
-       end
-
-       # Detach `n` from its original AST and attach it to `m` (and its related AST)
-       # `n` must not be already attached to an existing model entity
-       # `m` must not be already attached to an existing AST node
-       fun associate_propdef(m: MPropDef, n: APropdef)
-       do
-               # FIXME: the model-AST relations **must** be rationalized:
-               # * 1- fragility: the risk of inconsistencies is too hight
-               # * 2- complexity: there is too much paths to access the same things
-
-               # Easy attach
-               assert n.mpropdef == null
-               n.mpropdef = m
-
-               # Required to so that look-for implementation works
-               assert not toolcontext.modelbuilder.mpropdef2npropdef.has_key(m)
-               toolcontext.modelbuilder.mpropdef2npropdef[m] = n
-
-               var mclassdef = m.mclassdef
-               var nclassdef = toolcontext.modelbuilder.mclassdef2nclassdef[mclassdef]
-               # Sanity checks
-               assert nclassdef.mclassdef == mclassdef
-
-               if n isa AAttrPropdef then
-                       n.has_value = n.n_expr != null or n.n_block != null
-               end
-
-               # Required so that propdef are visited in visitors
-               if not nclassdef.n_propdefs.has(n) then nclassdef.n_propdefs.add(n)
-       end
-end
index 9408e95..419c5ae 100644 (file)
@@ -84,7 +84,6 @@ readonly
 writable
 autoinit
 noautoinit
-cached
 nosuper
 old_style_init
 abstract
index 5b04e01..8c5079f 100644 (file)
@@ -21,7 +21,6 @@ import literal
 import modelize
 import semantize
 import div_by_zero
-import cached
 import serialization_phase
 import check_annotation
 import glsl_validation
index 5b64e3d..9a7b050 100644 (file)
@@ -19,9 +19,6 @@ import highlight
 
 var toolcontext = new ToolContext
 
-# Disable `cached` because it causes issues when printing transformed AST. FIXME
-toolcontext.cached_phase.disabled = true
-
 # Try to colorize, even if programs are non valid
 toolcontext.keep_going = true