mm: adds basic explicit imports to metamodel and typing
authorAlexis Laferrière <alexis.laf@xymus.net>
Tue, 9 Aug 2011 15:37:45 +0000 (11:37 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Thu, 9 Feb 2012 21:00:46 +0000 (16:00 -0500)
Also adds support for future new explicit import formats.

Alows the user to specify a precise type to be used in the
native signature instead of it being the class where the
property was introduced.

Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

src/metamodel/abstractmetamodel.nit
src/metamodel/static_type.nit
src/syntax/syntax_base.nit
src/syntax/typing.nit

index 5a20652..6baec20 100644 (file)
@@ -655,6 +655,11 @@ class MMAttribute
        super MMLocalProperty
 end
 
+class MMExplicitImport
+       var local_class : MMLocalClass
+       var method : MMMethod
+end
+
 # Method local properties
 class MMMethod
        super MMLocalProperty
@@ -666,6 +671,9 @@ class MMMethod
 
        # Is the method extern, if yes what is the extern_name
        fun extern_name: nullable String is abstract
+
+       # properties explicitly exported to native code
+       fun explicit_imports : Set[ MMExplicitImport ] is abstract
 end
 
 # Concrete local classes
index e3abaf0..65e70b9 100644 (file)
@@ -246,6 +246,17 @@ class MMSignature
        end
 end
 
+
+redef class MMExplicitImport
+       var signature : MMSignature
+
+       redef init( local_class : MMLocalClass, meth : MMMethod )
+       do
+               super
+               signature = meth.signature.adaptation_to( local_class.get_type )
+       end
+end
+
 # A closure in a signature
 class MMClosure
        # The name of the closure (without the !)
index ab3020e..8d052ca 100644 (file)
@@ -187,6 +187,7 @@ class MMMethSrcMethod
        redef readable var _is_intern: Bool
        redef readable var _is_abstract: Bool
        redef readable writable var _extern_name: nullable String # Will be computed during MMBuilder
+       redef readable var _explicit_imports : Set[MMExplicitImport] = new HashSet[MMExplicitImport]
        redef fun node: nullable AMethPropdef do return mmmodule.nodes(self).as(nullable AMethPropdef)
        init(name: Symbol, cla: MMLocalClass, n: nullable AMethPropdef)
        do
index 800d1ea..e9abbc5 100644 (file)
@@ -1159,6 +1159,81 @@ redef class ASuperExpr
        end
 end
 
+redef class AExternCall
+       fun target_class_name : nullable Symbol do return null
+       fun target_method_name : Symbol is abstract
+
+       redef fun after_typing(v)
+       do
+               var target_class_name = self.target_class_name
+               var target_method_name = self.target_method_name
+
+               var target_class : MMLocalClass
+               var target_method : MMMethod
+
+               # find class
+               # self.target_class_name can be redef'd by sub-classes
+               if target_class_name == null then
+                       target_class = v.local_property.local_class
+               else
+                       if v.local_property.mmmodule.has_global_class_named( target_class_name ) then
+                               var global_class = v.local_property.mmmodule.global_class_named( target_class_name )
+                               target_class = v.local_property.mmmodule[ global_class ]
+                       else
+                               v.error( self, "Error: class {target_class_name.to_s}, not found." )
+                               return
+                       end
+               end
+
+               if target_class.has_global_property_by_name( target_method_name ) then
+                       var global_property = target_class.get_property_by_name( target_method_name )
+
+                       var target_property = target_class[global_property]
+
+                       if target_property isa MMMethod then
+                               target_method = target_property
+                       else
+                               v.error( self, "Error: property {target_method_name.to_s} is not a method." )
+                               return
+                       end
+               else
+                       v.error( self, "Error: property {target_method_name.to_s} not found in target class." )
+                       return
+               end
+
+               var explicit_import = new MMExplicitImport( target_class, target_method )
+               v.local_property.as(MMSrcMethod).explicit_imports.add( explicit_import )
+       end
+end
+
+redef class ALocalPropExternCall
+       redef fun target_class_name do return null
+       redef fun target_method_name do return n_methid.name.as(not null)
+end
+
+redef class ASuperExternCall
+       redef fun after_typing(v)
+       do
+               var precs: Array[MMLocalProperty] = v.local_property.prhe.direct_greaters
+               if not precs.is_empty then
+                       v.local_property.need_super = true
+               else
+                       v.error(self, "Error: No super method to call for {v.local_property}.")
+                       return
+               end
+       end
+end
+
+redef class AFullPropExternCall
+       redef fun target_class_name do return n_classid.to_symbol
+       redef fun target_method_name do return n_methid.name.as(not null)
+end
+
+redef class AInitPropExternCall
+       redef fun target_class_name do return n_classid.to_symbol
+       redef fun target_method_name do return "init".to_symbol
+end
+
 redef class AAttrFormExpr
        redef fun prop do return _prop.as(not null)
        var _prop: nullable MMAttribute