|
| 1 | +# This code is not used yet |
| 2 | +# It was moved from the work-in-progress code in proxy.jl |
| 3 | + |
| 4 | +struct GenInfo |
| 5 | + code |
| 6 | + typeCode |
| 7 | + deps |
| 8 | + classList |
| 9 | + methodDicts |
| 10 | + fielddicts |
| 11 | +end |
| 12 | + |
| 13 | +struct GenArgInfo |
| 14 | + name::Symbol |
| 15 | + javaType::Type |
| 16 | + juliaType |
| 17 | + spec |
| 18 | +end |
| 19 | + |
| 20 | +const genned = Set() |
| 21 | + |
| 22 | +hasClass(name::AbstractString) = hasClass(Symbol(name)) |
| 23 | +hasClass(name::Symbol) = name in genned |
| 24 | +hasClass(gen, name::AbstractString) = hasClass(gen, Symbol(name)) |
| 25 | +hasClass(gen, name::Symbol) = name in genned || haskey(gen.methodDicts, string(name)) |
| 26 | + |
| 27 | +function genTypeDecl(name::AbstractString, supername::Symbol, gen) |
| 28 | + if string(name) != "String" && !haskey(types, Symbol(name)) && !haskey(gen.methodDicts, name) |
| 29 | + typeName = typeNameFor(name) |
| 30 | + push!(gen.typeCode, :(abstract type $typeName <: $supername end)) |
| 31 | + end |
| 32 | +end |
| 33 | + |
| 34 | +function registerclass(name::AbstractString, classType::Type) |
| 35 | + registerclass(Symbol(name), classType) |
| 36 | +end |
| 37 | +function registerclass(name::Symbol, classType::Type) |
| 38 | + if !(classType <: Union{Array, String}) && !haskey(types, name) |
| 39 | + types[name] = classType |
| 40 | + end |
| 41 | + infoFor(classforname(string(name))) |
| 42 | +end |
| 43 | + |
| 44 | +gen(name::Symbol; genmode=:none, print=false, eval=true) = _gen(classforname(string(name)), genmode, print, eval) |
| 45 | +gen(name::AbstractString; genmode=:none, print=false, eval=true) = _gen(classforname(name), genmode, print, eval) |
| 46 | +gen(pxy::JProxy{T, C}) where {T, C} = gen(C) |
| 47 | +gen(class::JClass; genmode=:none, print=false, eval=true) = _gen(class, genmode, eval) |
| 48 | +function _gen(class::JClass, genmode, print, evalResult) |
| 49 | + n = legalClassName(class) |
| 50 | + gen = GenInfo() |
| 51 | + genClass(class, gen) |
| 52 | + if genmode == :deep |
| 53 | + while !isempty(gen.deps) |
| 54 | + cls = pop!(gen.deps) |
| 55 | + !hasClass(gen, cls) && genClass(classforname(string(cls)), gen) |
| 56 | + end |
| 57 | + else |
| 58 | + while !isempty(gen.deps) |
| 59 | + cls = pop!(gen.deps) |
| 60 | + !hasClass(gen, cls) && genType(classforname(string(cls)), gen) |
| 61 | + end |
| 62 | + end |
| 63 | + expr = :(begin $(gen.typeCode...); $(gen.code...); $(genClasses(getname.(gen.classList))...); end) |
| 64 | + if print |
| 65 | + for e in expr.args |
| 66 | + println(e) |
| 67 | + end |
| 68 | + end |
| 69 | + evalResult && eval(expr) |
| 70 | +end |
| 71 | + |
| 72 | +function genType(class, gen::GenInfo) |
| 73 | + name = getname(class) |
| 74 | + sc = superclass(class) |
| 75 | + push!(genned, Symbol(legalClassName(class))) |
| 76 | + if !isNull(sc) |
| 77 | + if !(Symbol(legalClassName(sc)) in genned) |
| 78 | + genType(getcomponentclass(sc), gen) |
| 79 | + end |
| 80 | + supertype = typeNameFor(sc) |
| 81 | + cType = componentType(supertype) |
| 82 | + genTypeDecl(name, cType, gen) |
| 83 | + else |
| 84 | + genTypeDecl(name, :java_lang, gen) |
| 85 | + end |
| 86 | +end |
| 87 | + |
| 88 | +genClass(class::JClass, gen::GenInfo) = genClass(class, gen, infoFor(class)) |
| 89 | +function genClass(class::JClass, gen::GenInfo, info::JClassInfo) |
| 90 | + name = getname(class) |
| 91 | + if !(Symbol(name) in genned) |
| 92 | + gen.fielddicts[legalClassName(class)] = fielddict(class) |
| 93 | + push!(gen.classList, class) |
| 94 | + sc = superclass(class) |
| 95 | + #@verbose("SUPERCLASS OF $name is $(isNull(sc) ? "" : "not ")null") |
| 96 | + push!(genned, Symbol(legalClassName(class))) |
| 97 | + if !isNull(sc) |
| 98 | + supertype = typeNameFor(sc) |
| 99 | + cType = componentType(supertype) |
| 100 | + !hasClass(gen, cType) && genClass(sc, gen) |
| 101 | + genTypeDecl(name, cType, gen) |
| 102 | + else |
| 103 | + genTypeDecl(name, :java_lang, gen) |
| 104 | + end |
| 105 | + genMethods(class, gen, info) |
| 106 | + end |
| 107 | +end |
| 108 | + |
| 109 | +GenInfo() = GenInfo([], [], Set(), [], Dict(), Dict()) |
| 110 | + |
| 111 | +function GenArgInfo(index, info::JMethodInfo, gen::GenInfo) |
| 112 | + javaType = info.argTypes[index] |
| 113 | + GenArgInfo(Symbol("a" * string(index)), javaType, argType(javaType, gen), argSpec(javaType, gen)) |
| 114 | +end |
| 115 | + |
| 116 | +argType(t, gen) = t |
| 117 | +argType(::Type{JavaObject{Symbol("java.lang.String")}}, gen) = String |
| 118 | +argType(::Type{JavaObject{Symbol("java.lang.Object")}}, gen) = :JLegalArg |
| 119 | +argType(::Type{<: Number}, gen) = Number |
| 120 | +argType(typ::Type{JavaObject{T}}, gen) where T = :(JProxy{<:$(typeNameFor(T, gen)), T}) |
| 121 | + |
| 122 | +argSpec(t, gen) = t |
| 123 | +argSpec(::Type{JavaObject{Symbol("java.lang.String")}}, gen) = String |
| 124 | +argSpec(::Type{JavaObject{Symbol("java.lang.Object")}}, gen) = :JObject |
| 125 | +argSpec(::Type{<: Number}, gen) = Number |
| 126 | +argSpec(typ::Type{JavaObject{T}}, gen) where T = :(JProxy{<:$(typeNameFor(T, gen)), T}) |
| 127 | +argSpec(arg::GenArgInfo) = arg.spec |
| 128 | + |
| 129 | +typeNameFor(T::Symbol, gen::GenInfo) = typeNameFor(string(T), gen) |
| 130 | +function typeNameFor(T::AbstractString, gen::GenInfo) |
| 131 | + aType, dims = arrayinfo(T) |
| 132 | + c = dims != 0 ? aType : T |
| 133 | + csym = Symbol(c) |
| 134 | + if (dims == 0 || length(c) > 1) && !(csym in gen.deps) && !hasClass(gen, csym) && !get(typeInfo, c, genericFieldInfo).primitive |
| 135 | + push!(gen.deps, csym) |
| 136 | + end |
| 137 | + typeNameFor(T) |
| 138 | +end |
| 139 | + |
| 140 | +function argCode(arg::GenArgInfo) |
| 141 | + argname = arg.name |
| 142 | + if arg.juliaType == String |
| 143 | + argname |
| 144 | + elseif arg.juliaType == JLegalArg |
| 145 | + :(box($argname)) |
| 146 | + elseif arg.juliaType == Number |
| 147 | + :($(arg.javaType)($argname)) |
| 148 | + else |
| 149 | + argname |
| 150 | + end |
| 151 | +end |
| 152 | + |
| 153 | +function fieldEntry((name, fld)) |
| 154 | + fieldType = JavaObject{Symbol(legalClassName(fld.owner))} |
| 155 | + name => :(jfield($(fld.typeInfo.class), $(string(name)), $fieldType)) |
| 156 | +end |
| 157 | + |
| 158 | +function genMethods(class, gen, info) |
| 159 | + methodList = listmethods(class) |
| 160 | + classname = legalClassName(class) |
| 161 | + gen.methodDicts[classname] = methods = Dict() |
| 162 | + typeName = typeNameFor(classname, gen) |
| 163 | + classVar = Symbol("class_" * string(typeName)) |
| 164 | + fieldsVar = Symbol("fields_" * string(typeName)) |
| 165 | + methodsVar = Symbol("staticMethods_" * string(typeName)) |
| 166 | + push!(gen.code, :($classVar = classforname($classname))) |
| 167 | + push!(gen.code, :($fieldsVar = Dict([$([fieldEntry(f) for f in gen.fielddicts[classname]]...)]))) |
| 168 | + push!(gen.code, :($methodsVar = Set($([string(n) for (n, m) in info.methods if any(x->x.static, m)])))) |
| 169 | + push!(gen.code, :(function Base.getproperty(p::JProxy{T, C}, name::Symbol) where {T <: $typeName, C} |
| 170 | + if (f = get($fieldsVar, name, nothing)) != nothing |
| 171 | + getField(p, name, f) |
| 172 | + else |
| 173 | + JMethodProxy(name, $typeName, p, emptyset) |
| 174 | + end |
| 175 | + end)) |
| 176 | + for nameSym in sort(collect(keys(info.methods))) |
| 177 | + name = string(nameSym) |
| 178 | + multiple = length(info.methods[nameSym]) > 1 |
| 179 | + symId = 0 |
| 180 | + for minfo in info.methods[nameSym] |
| 181 | + owner = javaType(minfo.owner) |
| 182 | + if isSame(class.ptr, minfo.owner.ptr) |
| 183 | + symId += 1 |
| 184 | + args = (GenArgInfo(i, minfo, gen) for i in 1:length(minfo.argTypes)) |
| 185 | + argDecs = (:($(arg.name)::$(arg.juliaType)) for arg in args) |
| 186 | + methodIdName = Symbol("method_" * string(typeName) * "__" * name * (multiple ? string(symId) : "")) |
| 187 | + callinfo = jnicalls[minfo.typeInfo.classname] |
| 188 | + push!(gen.code, :($methodIdName = getmethodid($(minfo.static), $classVar, $name, $(legalClassName(minfo.returnClass)), $(legalClassName.(minfo.argClasses))))) |
| 189 | + push!(gen.code, :(function (pxy::JMethodProxy{Symbol($name), <: $typeName})($(argDecs...))::$(genReturnType(minfo, gen)) |
| 190 | + @verbose($("Generated method $name$(multiple ? "(" * string(symId) * ")" : "")")) |
| 191 | + $(genConvertResult(minfo.typeInfo.convertType, minfo, :(call(pxy.obj, $methodIdName, $(static ? callinfo.static : callinfo.instance), $(minfo.typeInfo.juliaType), ($(argSpec.(args)...),), $((argCode(arg) for arg in args)...))))) |
| 192 | + end)) |
| 193 | + end |
| 194 | + end |
| 195 | + end |
| 196 | + push!(gen.code, :(push!(genned, Symbol($(legalClassName(class)))))) |
| 197 | +end |
| 198 | + |
| 199 | +function genReturnType(methodInfo, gen) |
| 200 | + t = methodInfo.typeInfo.convertType |
| 201 | + if methodInfo.typeInfo.primitive || t <: String || t == Nothing |
| 202 | + t |
| 203 | + else |
| 204 | + :(JProxy{<:$(typeNameFor(methodInfo.returnType, gen))}) |
| 205 | + end |
| 206 | +end |
| 207 | + |
| 208 | +genConvertResult(toType::Type{Bool}, info, expr) = :($expr != 0) |
| 209 | +genConvertResult(toType::Type{String}, info, expr) = :(unsafe_string($expr)) |
| 210 | +genConvertResult(toType::Type{<:JBoxTypes}, info, expr) = :(unbox($(toType.parameters[1]), $expr)) |
| 211 | +function genConvertResult(toType, info, expr) |
| 212 | + if isVoid(info) || info.typeInfo.primitive |
| 213 | + expr |
| 214 | + else |
| 215 | + :(asJulia($toType, $expr)) |
| 216 | + end |
| 217 | +end |
| 218 | + |
| 219 | +genClasses(classNames) = (:(registerclass($name, $(Symbol(typeNameFor(name))))) for name in reverse(classNames)) |
| 220 | + |
0 commit comments