e6dfca20d153bf42080079adcc6778f85c5f6e83
[nit.git] / src / ffi / extra_java_files.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Intro the annotation `extra_java_files` to compile extra java files
18 #
19 # It is mainly used to declare public Java classes.
20 module extra_java_files
21
22 import literal
23 import java
24 private import annotation
25
26 redef class ToolContext
27 var extra_java_files_phase: Phase = new JavaExtraFilesPhase(self, [literal_phase])
28 end
29
30 redef class MModule
31 # Extra Java files to compile with the module
32 private var extra_java_files: nullable Array[JavaFile] = null
33 end
34
35 private class JavaExtraFilesPhase
36 super Phase
37
38 redef fun process_annotated_node(nmoduledecl, nat)
39 do
40 # Skip if we are not interested
41 var annot_name = "extra_java_files"
42 if nat.name != annot_name then return
43
44 # Do some validity checks and print errors if the annotation is used incorrectly
45 var modelbuilder = toolcontext.modelbuilder
46
47 if not nmoduledecl isa AModuledecl then
48 modelbuilder.error(nat, "Syntax Error: only the declaration of modules may use `{annot_name}`.")
49 return
50 end
51
52 var args = nat.n_args
53 if args.is_empty then
54 modelbuilder.error(nat, "Syntax Error: `{annot_name}` expects at least one argument.")
55 return
56 end
57
58 # retrieve module
59 var nmodule = nmoduledecl.parent.as(AModule)
60 var mmodule = nmodule.mmodule.as(not null)
61 var java_files = mmodule.extra_java_files
62 if java_files == null then
63 java_files = new Array[JavaFile]
64 mmodule.extra_java_files = java_files
65 end
66
67 var format_error = "Syntax Error: `{annot_name}` expects its arguments to be paths to java files."
68 for arg in args do
69 var path = arg.as_string
70 if path == null then
71 modelbuilder.error(arg, format_error)
72 return
73 end
74
75 # Append specified path to directory of the Nit source file
76 var source_file = nat.location.file
77 if source_file != null then path = "{source_file.filename.dirname}/{path}"
78
79 if not path.file_exists then
80 modelbuilder.error(nat, "FFI with Java Error: file `{path}` not found.")
81 continue
82 end
83
84 var file = new JavaFile(path)
85 mmodule.ffi_files.add file
86 java_files.add file
87 end
88 end
89 end
90
91 redef class JavaLanguage
92 redef fun compile_to_files(mmodule, compdir)
93 do
94 super
95
96 # also copy over the java files
97 var extra_java_files = mmodule.extra_java_files
98 if extra_java_files != null then for file in extra_java_files do
99 var path = file.filename
100 path.file_copy_to("{compdir}/{path.basename}")
101 end
102 end
103 end