From fe57c7605aed46ed717a0f70671fe304b9f75925 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric=20Vachon?= Date: Sun, 13 Jul 2014 17:10:22 -0400 Subject: [PATCH] contrib/jwrapper: Added AST visitor for data extraction MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Frédéric Vachon --- contrib/jwrapper/src/javap_visitor.nit | 492 ++++++++++++++++++++++++++++++++ contrib/jwrapper/src/types.nit | 191 +++++++++++++ 2 files changed, 683 insertions(+) create mode 100644 contrib/jwrapper/src/javap_visitor.nit create mode 100644 contrib/jwrapper/src/types.nit diff --git a/contrib/jwrapper/src/javap_visitor.nit b/contrib/jwrapper/src/javap_visitor.nit new file mode 100644 index 0000000..69d0954 --- /dev/null +++ b/contrib/jwrapper/src/javap_visitor.nit @@ -0,0 +1,492 @@ +# This file is part of NIT (http://www.nitlanguage.org). +# +# Copyright 2014 Frédéric Vachon +# +# 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. + +# Uses a visitor to extract data from the javap output AST +# It sends the data to `code_generator` module +module javap_visitor + +import javap_test_parser +import code_generator +intrude import types + +class JavaVisitor + super Visitor + + fun generator: CodeGenerator do return once new CodeGenerator("bundle2.nit") + var declaration_type: nullable String = null + var declaration_element: nullable String = null + var full_class_name = new Array[String] + + var variable_id = "" + var variable_type = new JavaType + + var is_generic_param = false + var gen_params_index = 0 + + var is_primitive_array = false + + var method_id = "" + var method_return_type = new JavaType + var method_params = new Array[JavaType] + var param_index = 0 + + redef fun visit(n) do n.accept_visitor(self) +end + +redef class Node + fun accept_visitor(v: JavaVisitor) do visit_children(v) +end + +redef class Nidentifier + redef fun accept_visitor(v) + do + if v.declaration_type == "class_header" then + + if v.declaration_element == "id" then + v.full_class_name.add(self.text) + end + + else if v.declaration_type == "variable" then + + if v.declaration_element == "id" then + v.variable_id += self.text + else if v.declaration_element == "type" then + if v.is_generic_param then + v.variable_type.generic_params[v.gen_params_index].identifier.add(self.text) + else + v.variable_type.identifier.add(self.text) + end + end + + else if v.declaration_type == "method" then + + if v.declaration_element == "id" then + v.method_id = self.text + else if v.declaration_element == "return_type" then + if self.text == "void" then + v.method_return_type.is_void = true + else if v.is_generic_param then + v.method_return_type.generic_params[v.gen_params_index].identifier.add(self.text) + else + v.method_return_type.identifier.add(self.text) + end + else if v.declaration_element == "parameter_list" then + if v.is_generic_param then + v.method_params[v.param_index].generic_params[v.gen_params_index].identifier.add(self.text) + else + v.method_params[v.param_index].identifier.add(self.text) + end + end + + end + + super + end +end + +# Primitive array node +redef class N_39d_91d_93d_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + if v.is_generic_param then + v.variable_type.generic_params[v.gen_params_index].array_dimension += 1 + else + v.variable_type.array_dimension += 1 + end + end + + else if v.declaration_type == "method" then + + if v.declaration_element == "return_type" then + if v.is_generic_param then + v.method_return_type.generic_params[v.gen_params_index].array_dimension += 1 + else + v.method_return_type.array_dimension += 1 + end + else if v.declaration_element == "parameter_list" then + if v.is_generic_param then + v.method_params[v.param_index].generic_params[v.gen_params_index].array_dimension += 1 + else + v.method_params[v.param_index].array_dimension += 1 + end + end + + end + + super + end +end + +redef class N_39dchar_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +redef class N_39dboolean_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +redef class N_39dfloat_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +redef class N_39ddouble_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +redef class N_39dbyte_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +redef class N_39dshort_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +redef class N_39dint_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +redef class N_39dlong_39d + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.variable_type.identifier.add(self.text) + end + else if v.declaration_type == "method" then + if v.declaration_element == "return_type" then + v.method_return_type.identifier.add(self.text) + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].identifier.add(self.text) + end + end + end +end + +# # +# C L A S S H E A D E R # +# # +redef class Nclass_header + redef fun accept_visitor(v) + do + v.declaration_type = "class_header" + v.declaration_element = "id" + super + + # Exit class declaration + v.declaration_type = null + v.declaration_element = null + + v.generator.gen_class_header(v.full_class_name) + end +end + +# Extends declaration in the class header +redef class Nextends_declaration + redef fun accept_visitor(v) + do + v.declaration_element = "extends" + super + v.declaration_element = null + end +end + +# Implements declaration in the class header +redef class Nimplements_declaration + redef fun accept_visitor(v) + do + v.declaration_element = "implements" + super + v.declaration_element = null + end +end + +# # +# F I E L D D E C L A R A T I O N S # +# # + +# Method declaration in the field declarations +redef class Nmethod_declaration + redef fun accept_visitor(v) + do + v.declaration_type = "method" + super + v.declaration_type = null + + v.generator.gen_method(v.method_params, v.method_return_type, v.method_id) + + v.method_params.clear + v.method_id = "" + v.method_return_type = new JavaType + end +end + +# Constructor declaration in the field declarations +redef class Nconstructor_declaration + redef fun accept_visitor(v) + do + v.declaration_type = "constructor" + super + v.declaration_type = null + end +end + +# Variable declaration in the field declarations +redef class Nvariable_declaration + redef fun accept_visitor(v) + do + v.declaration_type = "variable" + super + v.declaration_type = null + + v.generator.gen_variable(v.variable_id, v.variable_type) + + v.variable_id = "" + v.variable_type = new JavaType + end +end + +# Static declaration in the field declarations +redef class Nstatic_declaration + redef fun accept_visitor(v) + do + v.declaration_type = "static" + super + v.declaration_type = null + end +end + +# Identifier of the field +redef class Nvariable_id + redef fun accept_visitor(v) + do + v.declaration_element = "id" + super + v.declaration_element = null + end +end + +# Identifier of the method +redef class Nmethod_id + redef fun accept_visitor(v) + do + v.declaration_element = "id" + super + v.declaration_element = null + end +end + +redef class Ntype + redef fun accept_visitor(v) + do + if v.declaration_type == "variable" and v.declaration_element != "id" then + v.declaration_element = "type" + end + + if v.declaration_type == "method" and v.declaration_element == null then + v.declaration_element = "return_type" + end + + super + + if v.declaration_element == "variable" then + v.declaration_element = null + end + end +end + +redef class Ngeneric_param + redef fun accept_visitor(v) + do + # Ignore the weird generic return type declaration + if v.declaration_type == "method" then + if v.declaration_element == null then + v.declaration_element = "ignore" + else + v.is_generic_param = true + v.gen_params_index = 0 + + if v.declaration_element == "return_type" then + v.method_return_type.generic_params = new Array[JavaType] + else if v.declaration_element == "parameter_list" then + v.method_params[v.param_index].generic_params = new Array[JavaType] + end + end + else if v.declaration_type == "variable" then + if v.declaration_element == "type" then + v.is_generic_param = true + v.gen_params_index = 0 + v.variable_type.generic_params = new Array[JavaType] + end + end + + super + + v.declaration_element = null + v.is_generic_param = false + end +end + +redef class Nparameter_list + redef fun accept_visitor(v) + do + v.declaration_element = "parameter_list" + v.param_index = 0 + super + v.declaration_element = null + v.param_index = 0 + end +end + +redef class Nparameter + redef fun accept_visitor(v) + do + if v.declaration_type == "method" then + if v.declaration_element == "parameter_list" then + if v.is_generic_param then + v.method_params[v.param_index].generic_params.add(new JavaType) + + super + + v.gen_params_index += 1 + else + v.method_params.add(new JavaType) + + super + + v.param_index += 1 + end + else if v.declaration_element == "return_type" and v.is_generic_param then + + v.method_return_type.generic_params.add(new JavaType) + + super + + v.gen_params_index += 1 + end + else if v.declaration_type == "variable" then + if v.declaration_element == "type" and v.is_generic_param then + v.variable_type.generic_params.add(new JavaType) + + super + + v.gen_params_index += 1 + end + else + super + end + end +end + +var p = new TestParser_javap +var tree = p.main + +var visitor = new JavaVisitor +visitor.enter_visit(tree) + +print "end" diff --git a/contrib/jwrapper/src/types.nit b/contrib/jwrapper/src/types.nit new file mode 100644 index 0000000..068a330 --- /dev/null +++ b/contrib/jwrapper/src/types.nit @@ -0,0 +1,191 @@ +# This file is part of NIT (http://www.nitlanguage.org). +# +# Copyright 2014 Frédéric Vachon +# +# 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. + +# Contains the java and nit type representation used to convert java to nit code +module types + +import jtype_converter + +class JavaType + private var converter = new JavaTypeConverter + var identifier: Array[String] = new Array[String] + var generic_params: nullable Array[JavaType] = null + var is_void = false + var array_dimension = 0 + + fun collections_list: Array[String] is cached do return ["List", "ArrayList", "LinkedList", "Vector", "Set", "SortedSet", "HashSet", "TreeSet", "LinkedHashSet", "Map", "SortedMap", "HashMap", "TreeMap", "Hashtable", "LinkedHashMap"] + fun iterable: Array[String] is cached do return ["ArrayList", "Set", "HashSet", "LinkedHashSet", "LinkedList", "Stack", "TreeSet", "Vector"] + fun maps: Array[String] is cached do return ["Map", "SortedMap", "HashMap", "TreeMap", "Hashtable", "LinkedHashMap"] + fun has_generic_params: Bool do return not generic_params == null + fun is_primitive_array: Bool do return array_dimension > 0 + fun full_id: String do return identifier.join(".") + fun id: String do return identifier.last + + fun return_cast: String + do + if self.has_generic_params then + return converter.cast_as_return(self.generic_params[0].id) + end + + return converter.cast_as_return(self.id) + end + + fun param_cast: String + do + if self.has_generic_params then + return converter.cast_as_param(self.generic_params[0].id) + end + + return converter.cast_as_param(self.id) + end + + fun to_nit_type: NitType + do + var nit_type: NitType + + if self.is_primitive_array then + return self.convert_primitive_array + end + + var type_id = converter.to_nit_type(self.id) + + if type_id == null then + nit_type = new NitType(self.full_id) + nit_type.is_complete = false + else + nit_type = new NitType(type_id) + end + + if not self.has_generic_params then return nit_type + + nit_type.generic_params = new Array[NitType] + + for param in generic_params do + var nit_param = param.to_nit_type + + nit_type.generic_params.add(nit_param) + + if not nit_param.is_complete then nit_type.is_complete = false + end + + return nit_type + end + + fun convert_primitive_array: NitType + do + var nit_type = new NitType("Array") + + var last_nit_type = nit_type + + for i in [1..array_dimension] do + var temp: NitType + last_nit_type.generic_params = new Array[NitType] + + if i == array_dimension then + var temp_type = converter.to_nit_type(self.id) + + if temp_type == null then + temp_type = self.full_id + nit_type.is_complete = false + end + + temp = new NitType(temp_type) + else + temp = new NitType("Array") + end + + last_nit_type.generic_params.add(temp) + + last_nit_type = temp + end + + return nit_type + end + + fun is_iterable: Bool do return iterable.has(self.id) + + fun is_collection: Bool do return is_primitive_array or collections_list.has(self.id) + + fun is_map: Bool do return maps.has(self.id) + + redef fun to_s: String + do + var id = self.full_id + + if self.is_primitive_array then + for i in [0..array_dimension[ do + id += "[]" + end + else if self.has_generic_params then + var gen_list = new Array[String] + + for param in generic_params do + gen_list.add(param.to_s) + end + + id += "<{gen_list.join(", ")}>" + end + + return id + end + + fun to_cast(jtype: String, is_param: Bool): String + do + if is_param then + return converter.cast_as_param(jtype) + end + + return converter.cast_as_return(jtype) + end +end + +class NitType + var identifier: String + var arg_id: String + var generic_params: nullable Array[NitType] = null + + # Returns `true` if all types have been successfully converted to Nit type + var is_complete: Bool = true + + fun has_generic_params: Bool do return not generic_params == null + fun maps: Array[String] is cached do return ["HashMap", "RBTreeMap"] + + fun id: String do return identifier + + init (id: String) + do + self.identifier = id + end + + fun is_map: Bool do return maps.has(self.identifier) + + redef fun to_s: String + do + var id = self.identifier + + if self.has_generic_params then + var gen_list = new Array[String] + + for param in generic_params do + gen_list.add(param.to_s) + end + + id += "[{gen_list.join(", ")}]" + end + + return id + end +end -- 1.7.9.5