analysis: add the implementation of the reachable as initializer analysis
authorJean-Sebastien Gelinas <calestar@gmail.com>
Sat, 21 Nov 2009 20:40:50 +0000 (15:40 -0500)
committerJean Privat <jean@pryen.org>
Mon, 11 Jan 2010 21:52:28 +0000 (16:52 -0500)
Signed-off-by: Jean-Sebastien Gelinas <calestar@gmail.com>
Signed-off-by: Jean Privat <jean@pryen.org>

src/analysis/analysis.nit
src/analysis/reachable_as_init_impl.nit [new file with mode: 0644]

index 01e7104..b5f9c09 100644 (file)
@@ -35,6 +35,7 @@ import reachable_as_init
 # Global Analysis implementation
 import cha_analysis
 import rta_analysis
+import reachable_as_init_impl
 
 # Global Optimizations
 import dead_method_removal
@@ -63,6 +64,10 @@ redef class Program
                # Ensure we have all analysis created
                if rma == null then rma = new DefaultReachableMethodAnalysis
                if ita == null then ita = new DefaultInstantiatedTypeAnalysis
+
+               var rai_builder = new ReachableAsInitBuilder(self)
+               rai_builder.work
+               rai = rai_builder.context
        end
        # This method will optimize the program (in global compilation only)
        fun do_global_optimizations do
diff --git a/src/analysis/reachable_as_init_impl.nit b/src/analysis/reachable_as_init_impl.nit
new file mode 100644 (file)
index 0000000..a3b3677
--- /dev/null
@@ -0,0 +1,77 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2009 Jean-Sebastien Gelinas <calestar@gmail.com>
+#
+# 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.
+
+# This package introduces an analysis that flags all initializers called as new A.x
+package reachable_as_init_impl
+
+import reachable_method_analysis
+import reachable_as_init
+
+class ReachableAsInitBuilder
+       readable var _context: ReachableAsInitAnalysisImpl = new ReachableAsInitAnalysisImpl
+       readable var _program: Program
+
+       fun work do
+               program.with_each_iroutines !action(i, m)  do
+                       if program.rma.is_iroutine_reachable(i) then
+                               var v = new RAIVisitor(self)
+                               v.visit_iroutine(i)
+                       end
+               end
+       end
+
+       init(p: Program) do
+               _program = p
+       end
+end
+
+# Visitor will add only initializers in the _methods list.
+# If the checked method is in this list, it is reachable as init !
+class ReachableAsInitAnalysisImpl
+special ReachableAsInitAnalysis
+       var _methods: HashMap[MMLocalClass, List[MMMethod]] = new HashMap[MMLocalClass, List[MMMethod]]
+
+       redef fun is_method_reachable_as_init(method: MMMethod, c: MMLocalClass): Bool do
+               if _methods.has_key(c) then return _methods[c].has(method)
+               return false
+       end
+
+       init do end
+end
+
+class RAIVisitor
+special ICodeVisitor
+       readable var _builder: ReachableAsInitBuilder
+
+       redef fun visit_icode(ic)
+       do
+               if ic isa INew then
+                       # FIXME: take only the last property on the redef. hierarchie
+                       var t = ic.stype
+                       var cls = t.for_module(builder.program.module).local_class
+                       var m = cls[ic.property.global].as(MMMethod)
+                       assert m.global.is_init
+                       if not builder.context._methods.has_key(cls) then builder.context._methods[cls] = new List[MMMethod]
+                       if not builder.context._methods[cls].has(m) then builder.context._methods[cls].add(m)
+               end
+               super
+       end
+
+       init(b: ReachableAsInitBuilder)
+       do
+               _builder = b
+       end
+end