Merge: Do not display test suite modules in Nitdoc
[nit.git] / src / platform.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Platform system, used to customize the behavior of the compiler.
16 #
17 # Customisation is done accordingly to the target platform.
18 # Also detects conflicts between targeted platforms.
19 module platform
20
21 import modelize
22 private import parser_util
23 private import annotation
24
25 redef class ToolContext
26 var platform_phase: Phase = new PlatformPhase(self, [modelize_property_phase])
27
28 protected fun platform_from_name(name: String): nullable Platform
29 do
30 return null
31 end
32 end
33
34 private class PlatformPhase
35 super Phase
36
37 redef fun process_annotated_node(nmoduledecl, nat)
38 do
39 var annotation_name = "platform"
40
41 # Skip if we are not interested
42 if nat.name != annotation_name then return
43
44 # Do some validity checks and print errors if the annotation is used incorrectly
45 var modelbuilder = toolcontext.modelbuilder
46 if not nmoduledecl isa AModuledecl then
47 modelbuilder.error(nat, "Syntax error: only the declaration of modules may use \"{annotation_name}\".")
48 return
49 end
50
51 var args = nat.n_args
52 var platform_name
53 if args.length > 1 then
54 modelbuilder.error(nat, "Syntax error: \"{annotation_name}\" expects at most a single argument.")
55 return
56 else if args.is_empty then
57 platform_name = nmoduledecl.n_name.collect_text
58 else
59 platform_name = args.first.as_string
60 if platform_name == null then
61 var format_error = "Syntax error: \"{annotation_name}\" expects its argument to be the name of the target platform as a String literal."
62 modelbuilder.error(nat, format_error)
63 return
64 end
65 end
66
67 var nmodule = nmoduledecl.parent.as(AModule)
68 var mmodule = nmodule.mmodule
69
70 var platform = toolcontext.platform_from_name(platform_name)
71 if platform == null then
72 toolcontext.error(nat.location, "Error: target platform \"{platform_name}\" unknown")
73 return
74 end
75
76 var previous_target_platform = mmodule.target_platform
77 if previous_target_platform != null and previous_target_platform != platform then
78 modelbuilder.error(nat, "Syntax error: a target platform has already been defined as \"{previous_target_platform}\".")
79 end
80
81 mmodule.local_target_platform = platform
82 end
83 end
84
85 redef class MModule
86 private var local_target_platform: nullable Platform = null
87
88 # Recursively get the platform targeted by this module or imported modules
89 fun target_platform: nullable Platform
90 do
91 var ltp = local_target_platform
92 if ltp != null then return ltp
93
94 for mmodule in in_importation.greaters do
95 ltp = mmodule.local_target_platform
96 if ltp != null then return ltp
97 end
98
99 return null
100 end
101 end
102
103 # Sub-classes of `Platform` represent the target platform of a compilation
104 #
105 # Services will be added to this class in other modules.
106 class Platform
107 # Does the platform provide and support the library `unwind`?
108 fun supports_libunwind: Bool do return true
109
110 # Does the platform provide and supports the Boehm's GC library?
111 fun supports_libgc: Bool do return true
112
113 # Does this platform declare its own main function? If so, we won't generate one in Nit.
114 fun no_main: Bool do return false
115
116 # Does the platform accepts linker scripts?
117 fun supports_linker_script: Bool do return true
118 end