Kouksi44

classic metatabless

Mar 11th, 2017
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 34.75 KB | None | 0 0
  1. local signature  = dofile "/home/lukas/Dokumente/Projects/Lua/Cronos/core/classic/signature.lua"
  2. local annotation, parseFunc = dofile "/home/lukas/Dokumente/Projects/Lua/Cronos/core/classic/annotation.lua"
  3. local stack      = dofile "/home/lukas/Dokumente/Projects/Lua/Cronos/core/classic/stack.lua"
  4.  
  5.  
  6. local classic = {
  7.   compiler = {
  8.     loading;
  9.     compileclass;
  10.     class;
  11.     extends;
  12.     interface;
  13.     implements;
  14.     clone;
  15.     classpath = {
  16.       default = {};
  17.       packages = {};
  18.       anonymous = {};
  19.     };
  20.     classProxy = {
  21.       default = {};
  22.       packages = {};
  23.     };
  24.     classloader = {
  25.       loadclass;
  26.       readfile;
  27.       parsename;
  28.       getclass;
  29.       addclass;
  30.     };
  31.     isMAnnotation;
  32.     isFAnnotation;
  33.     isPrimitive;
  34.     isInstance;
  35.     isSTable;
  36.   };
  37.   class = { -- most functions not implemented yet
  38.     superOf;
  39.     subclassOf;
  40.     getConstructor;
  41.     getDeclaredFields;
  42.     getDeclaredField;
  43.     getDeclaredMethods;
  44.     getDeclaredMethod;
  45.     getSuperclass;
  46.     getInterfaces;
  47.     getName;
  48.     getRessource;
  49.     getAnnotationsFrom;
  50.     isPrimitive;
  51.     newInstance;
  52.     toString;
  53.   };
  54.   runtime = {
  55.     opstack    = stack();
  56.     framestack = stack();
  57.     invokevirtual;
  58.     invokestatic;
  59.     invokespecial;
  60.     setfield;
  61.     getfield;
  62.     getstatic;
  63.     setstatic;
  64.   };
  65.   util = {
  66.     deepcopy;
  67.     debugprint;
  68.     wrapper;
  69.   }
  70. }
  71.  
  72. do
  73.   _G.public   = annotation("public")
  74.   _G.private  = annotation("private")
  75.   _G.final    = annotation("final")
  76.   _G.static   = annotation("static")
  77.   _G.number   = annotation("number")
  78.   _G.Table    = annotation("Table")
  79.   _G.String   = annotation("String")
  80.   _G.thread   = annotation("thread")
  81.   _G.boolean  = annotation("boolean")
  82.   _G.void     = annotation("void")
  83.   _G.property = annotation("property")
  84.   _G.async    = annotation("async")
  85. end
  86.  
  87. classic.compiler.classResolver = function(t, name)
  88.   if classic.compiler.classProxy.default[name] then
  89.     return classic.compiler.classProxy.default[name]
  90.   else
  91.     return classic.compiler.classProxy.packages[name]
  92.   end
  93. end
  94.  
  95.  
  96. classic.compiler.class = function(name,isSealed,isStatic)
  97.   local classname, package = classic.compiler.classloader.parseName(name)
  98.   local klass              = {}
  99.         klass.name         = classname
  100.         klass.package      = package or "null"
  101.         klass.super        = nil
  102.         klass.vtable       = {}
  103.         klass.methods      = {}
  104.         klass.fields       = {}
  105.         klass.interfaces   = {}
  106.         klass.isGeneric    = false
  107.         klass.genericTypeName = ""
  108.         klass.anonCount    = 1
  109.         klass.__type       = "class"
  110.         klass.isStatic     = (isStatic and true) or false
  111.         klass.isSealed     = (isSealed and true) or false
  112.   classic.compiler.loading = klass
  113.  
  114.   return setmetatable({},{
  115.     __call = function(_,classtable)
  116.       classic.compiler.compileClass(klass,classtable)
  117.     end;
  118.     __index = function(_,k) -- k represents generic variable type for this class
  119.       _G[k] = annotation("generic")
  120.       klass.isGeneric, klass.genericTypeName = true, k
  121.       return function(_,classtable)
  122.         classic.compiler.compileClass(klass,classtable)
  123.       end
  124.     end
  125.   })
  126. end
  127.  
  128. classic.compiler.extends = function(name)
  129.   local klass, super = classic.compiler.loading, classic.compiler.classloader.getClass(name)
  130.  
  131.   if super and klass then
  132.     if super.isSealed then
  133.       error(klass.name.." can't inherit from sealed class "..super.name)
  134.     end
  135.     klass.super = super
  136.   else
  137.     error("Can't find class "..name.." - must be either imported or declared")
  138.   end
  139.   return setmetatable({},{
  140.     __call = function(_,classtable)
  141.       classic.compiler.compileClass(klass,classtable)
  142.     end;
  143.     __index = function(_,k) -- k represents generic variable type for this class
  144.       _G[k] = annotation("generic")
  145.       klass.isGeneric, klass.genericTypeName = true, k
  146.       return function(_,classtable)
  147.         classic.compiler.compileClass(klass,classtable)
  148.       end
  149.     end
  150.   })
  151. end
  152.  
  153. classic.compiler.compileClass = function(klass,ctable)
  154.   local klass, ctable = klass, ctable
  155.  
  156.   for iname, reference in pairs(ctable) do
  157.     if classic.compiler.isMethodSignature(reference) then
  158.       klass.methods[iname] = classic.compiler.compileMethod(klass,reference,iname)
  159.       klass.vtable[iname]  = klass.methods[iname]
  160.     elseif classic.compiler.isAttributeSignature(reference) then
  161.       klass.fields[klass.name.."/"..iname] = classic.compiler.compileAttribute(klass,reference,iname)
  162.       classic.util.checkType(klass.fields[klass.name.."/"..iname],classic.util.getType(klass.fields[klass.name.."/"..iname].value))
  163.     elseif classic.compiler.isRawClassEntry(reference) then
  164.       local type, signature = classic.compiler.compileRawEntry(klass, reference,iname)
  165.       if type == "method" then
  166.         klass.methods[iname] = signature
  167.         klass.vtable[iname]  = signature
  168.       elseif type == "attribute" then
  169.         klass.fields[klass.name.."/"..iname] = signature
  170.       end
  171.     end
  172.   end
  173.  
  174.   klass.super = (klass.super or (klass.name ~= "CObject" and classic.compiler.classpath.packages.classic.internal.CObject)) or nil
  175.   klass.vtable = classic.util.mergeClasses(klass,klass.vtable,klass.super,(klass.super and klass.super.vtable) or {})
  176.   classic.compiler.classloader.addClass(klass)
  177. end
  178.  
  179. classic.util.mergeClasses = function(klass1,vtable1,klass2,vtable2)
  180.   local merged = {}
  181.   for mname, sig in pairs(vtable1) do
  182.     merged[klass1.name..sig.toPath()..mname] = sig
  183.   end
  184.   for mname, sig in pairs(vtable2) do
  185.     if sig.public() and (not sig.static()) and (not sig.final()) and merged[klass1.name.."/public/"..sig.name] then
  186.       merged[mname] = merged[klass1.name.."/public/"..sig.name]
  187.     else
  188.       merged[mname] = sig
  189.     end
  190.   end
  191.   return merged
  192. end
  193.  
  194.  
  195. classic.compiler.isMethodSignature = function(reference)
  196.   if not type(reference) == "table" then return false end
  197.   if type(reference) == "table" and reference.__type and reference.__type == "annotation" then
  198.     return reference.type == "method"
  199.   end
  200.   return false
  201. end
  202.  
  203. classic.compiler.isAttributeSignature = function(reference)
  204.   if not type(reference) == "table" then return false end
  205.   if type(reference) == "table" and reference.__type and reference.__type == "annotation" then
  206.     return reference.type == "attribute"
  207.   end
  208.   return false
  209. end
  210.  
  211. classic.compiler.isRawClassEntry = function(reference)
  212.   if type(reference) ~= "table" then return true end
  213.   if reference.__type and (reference.type == "method" or reference.type == "attribute") then
  214.     return false
  215.   end
  216.   return true
  217. end
  218.  
  219. classic.compiler.compileMethod = function(klass,annotation,name)
  220.   local klass, annotation = klass, annotation
  221.   return signature(klass,name,annotation.descriptors,annotation.value,"method")
  222. end
  223.  
  224. classic.compiler.compileAttribute = function(klass, annotation,name)
  225.   local klass, annotation, compiled = klass, annotation
  226.   return signature(klass,name,annotation.descriptors,annotation.value,"attribute",annotation.objType)
  227. end
  228.  
  229. classic.compiler.compileRawEntry = function(klass,rawEntry,name)
  230.   local klass, raw, compiled = klass, rawEntry
  231.   local compiled = signature(klass,name,{},rawEntry,nil)
  232.  
  233.   compiled.type  = (type(rawEntry) == "function" and "method") or "attribute"
  234.   return compiled.type, compiled
  235. end
  236.  
  237. classic.class.newInstance = function(_type, klass, genericType, ...)
  238.   local klass, proxy, obj, _type, args, tempType = klass, {}, {}, (_type or klass ), {...}, nil
  239.   local handleIndexResolved = function(valueExists, itype, name, fullPath, destclass, isInternal)
  240.     if valueExists then
  241.       if itype == "method" then
  242.         if isStatic then return classic.runtime.invokeStatic(fullPath,tempType or _type)
  243.         else
  244.           classic.runtime.opstack.push(obj)
  245.           return classic.runtime.invokeVirtual(fullPath)
  246.         end
  247.       elseif itype == "attribute" then
  248.         if isStatic then return classic.runtime.getStatic(fullPath, destclass)
  249.         else
  250.           classic.runtime.opstack.push(obj)
  251.           return classic.runtime.getField(fullPath,destclass)
  252.         end
  253.       end
  254.     else
  255.       error("Can't access "..name.." in class "..((isInternal and (classic.runtime.framestack.peek() and classic.runtime.framestack.peek().class.name)) or _type.name).." or one of its superclasses. Field is either private or undefined.",2)
  256.     end
  257.   end
  258.  
  259.   local handleNewIndexResolved = function(valueExists, itype, name, value, fullPath, destclass, isInternal)
  260.     if valueExists then
  261.       if itype == "method" then
  262.         error("Attempt to set "..name.." with value "..tostring(value).." - "..name.." is a method")
  263.       elseif isStatic then
  264.         classic.runtime.setStatic(fullPath, value, destclass)
  265.       else
  266.         classic.runtime.opstack.push(obj)
  267.         classic.runtime.setField(fullPath, value, destclass)
  268.       end
  269.     else
  270.       error(" Attempt to set undefined "..name.." with value: "..tostring(value))
  271.     end
  272.   end
  273.  
  274.   proxy = setmetatable({},{
  275.     __clone = obj;
  276.     __setClassType = function(t)
  277.       _type = t
  278.     end;
  279.     __index = function(_,name)
  280.       local valueExists, fullPath, itype, isStatic, destclass
  281.       if name == "super" then return setmetatable({},{
  282.           __index = function(_,name)
  283.             classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
  284.             oldType = _type
  285.             _type = _type.super
  286.             local res = proxy[name]
  287.             _type = oldType
  288.             classic.runtime.framestack.pop()
  289.             return res
  290.           end,
  291.           __newindex = function(_,name, value)
  292.             classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
  293.             oldType = _type
  294.             _type = _type.super
  295.             proxy[name] = value
  296.             _type = oldType
  297.             classic.runtime.framestack.pop()
  298.           end
  299.         })
  300.       end
  301.       valueExists, fullPath, itype, isStatc, destclass = classic.class.resolve(name, _type, false)
  302.       return handleIndexResolved(valueExists, itype, name, fullPath, destclass, false)
  303.     end;
  304.  
  305.     __newindex = function(_,name,value)
  306.       local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,_type, false)
  307.       handleNewIndexResolved(valueExists, itype, name, value, fullPath, destclass, false)
  308.     end;
  309.     __call = function(_,classtable) -- create an anonymous class that extends the class of this object
  310.       classic.compiler.class("anonymous."..klass.name.."$"..klass.anonCount) classic.compiler.extends((klass.package ~= "null" and table.concat(klass.package,".").."."..klass.name) or klass.name) (classtable)
  311.       klass.anonCount = klass.anonCount + 1
  312.       return classic.class.newInstance(klass,classic.compiler.classpath.packages.anonymous[klass.name.."$"..klass.anonCount-1],nil,nil)
  313.     end
  314.  
  315.   })
  316.  
  317.   this = setmetatable({}, {
  318.     __clone = obj;
  319.     __setClassType = function(t)
  320.       _type = t
  321.     end;
  322.     __index = function(_,name)
  323.       local valueExists, fullPath, itype, isStatic, destclass
  324.  
  325.       if name == "super" then return setmetatable({},{
  326.           __index = function(_,name)
  327.             classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
  328.             oldType = _type
  329.             _type = _type.super
  330.             local res = proxy[name]
  331.             _type = oldType
  332.             classic.runtime.framestack.pop()
  333.             return res
  334.           end,
  335.           __newindex = function(_,name, value)
  336.             classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
  337.             oldType = _type
  338.             _type = _type.super
  339.             proxy[name] = value
  340.             _type = oldType
  341.             classic.runtime.framestack.pop()
  342.           end
  343.         })
  344.       end
  345.       local currentFrame = classic.runtime.framestack.peek()
  346.       local currentClass = (currentFrame and currentFrame.class) or _type
  347.       valueExists, fullPath, itype, isStatc, destclass = classic.class.resolve(name, currentClass,true)
  348.       return handleIndexResolved(valueExists, itype, name, fullPath, destclass, true)
  349.     end;
  350.  
  351.  
  352.     __newindex = function(_,name,value)
  353.       local currentFrame = classic.runtime.framestack.peek()
  354.       local currentClass = (currentFrame and currentFrame.class) or _type
  355.       local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,currentClass, true)
  356.       handleNewIndexResolved(valueExists, itype, name, value, fullPath, destclass, true)
  357.     end;
  358.  
  359.   })
  360.  
  361.   if genericType and rawget(genericType,"__type") == "annotation" then
  362.     obj.__typeParameter = genericType.descriptors[1]
  363.   elseif genericType and getmetatable(genericType) and getmetatable(genericType).__type == "class" then
  364.     obj.__typeParameter = getmetatable(genericType).__class
  365.   else
  366.     obj.__typeParameter = classic.compiler.classpath.packages.classic.internal.CObject
  367.   end
  368.  
  369.   obj.__type  = "instance"
  370.   obj.__proxy = proxy
  371.   obj.__this  = this
  372.   obj.class   = klass
  373.   obj.fields  = classic.util.collectAttributes(klass,{})
  374.  
  375.   local calledAllConstructors, init, current, constructors = false, nil, klass, {}
  376.   while current ~= nil do
  377.     table.insert(constructors, current)
  378.     current = current.super or nil
  379.   end
  380.  
  381.   for i=#constructors, 1, -1 do
  382.     local curr = constructors[i]
  383.     classic.runtime.opstack.push(obj)
  384.     init = classic.runtime.invokeSpecial(curr, curr.name, true)
  385.     if init and ( curr == klass ) then
  386.       init(unpack(args))
  387.     elseif init then
  388.       init()
  389.     end
  390.   end
  391.  
  392.   return proxy
  393. end
  394.  
  395. classic.class.resolve = function(name,klass, isInternal)
  396.   if type(name) ~= "string" then error("Index must be a string, got "..type(name),3) end
  397.   local currentFrame= classic.runtime.framestack.peek()
  398.   local currentClass, cName, inSuper = klass, klass.name, false
  399.  
  400.   if (currentFrame and currentFrame.methodname == "__super__") then
  401.     inSuper = true
  402.   end
  403.  
  404.   local foundMethod, foundAttribute = false, false
  405.   local oClass = currentClass
  406.  
  407.   while currentClass do
  408.     if currentClass.methods[name] then
  409.       local cMethod = currentClass.methods[name]
  410.       if cMethod.public() then
  411.         if cMethod.static() then
  412.           return true, currentClass.name..cMethod.toPath()..name, "method", true, cMethod.class
  413.         else
  414.           return true, currentClass.name..cMethod.toPath()..name,"method", false, cMethod.class
  415.         end
  416.       elseif cMethod.private() then
  417.         if (currentClass == oClass) and (not inSuper) and isInternal then
  418.           if cMethod.static() then
  419.             return true, currentClass.name..cMethod.toPath()..name, "method",true, cMethod.class
  420.           else
  421.             return true, currentClass.name..cMethod.toPath()..name, "method",false, cMethod.class
  422.           end
  423.         end
  424.       end
  425.     elseif currentClass.fields[currentClass.name.."/"..name] then
  426.       local cField = currentClass.fields[currentClass.name.."/"..name]
  427.       if cField.public() then
  428.         if cField.static() then
  429.           return true, currentClass.name.."/"..name, "attribute", true, cField.class
  430.         else
  431.           return true, currentClass.name.."/"..name, "attribute", false, cField.class
  432.         end
  433.       elseif cField.private() then
  434.         if (currentClass == oClass) and (not inSuper) and isInternal then
  435.           if cField.static() then
  436.             return true, currentClass.name.."/"..name, "attribute", true, cField.class
  437.           else
  438.             return true, currentClass.name.."/"..name, "attribute", false, cField.class
  439.           end
  440.         end
  441.       end
  442.     end
  443.     currentClass = currentClass.super or nil
  444.   end
  445.   return false, nil, false
  446. end
  447.  
  448. classic.runtime.invokeSpecial = function(klass, methodname, checkVisible) -- this function feels a little useless, as it only really calls the
  449.   local objectref = classic.runtime.opstack.pop()           -- constructor of a class. meh
  450.   if klass.methods[methodname] and (not klass.methods[methodname].private()) then
  451.     return classic.runtime.methodWrapper(objectref,klass.methods[methodname])
  452.   end
  453. end
  454.  
  455. classic.runtime.getField = function(sigName, destClass)
  456.   local objectref = classic.runtime.opstack.pop()
  457.   local propReturn, isProperty, getter = nil, false, nil
  458.   if destClass.fields[sigName].property() and (not destClass.fields[sigName].gettable) then
  459.     local c = destClass.fields[sigName]
  460.     isProperty = true
  461.     classic.runtime.opstack.push(objectref)
  462.     c.settable, c.gettable = true, true
  463.     getter = classic.runtime.invokeSpecial(destClass,"get"..string.upper(string.sub(c.name,1,1))..string.sub(c.name,2,#c.name))
  464.     propReturn = (getter and getter()) or "null"
  465.     c.settable, c.gettable = false, false
  466.   end
  467.   if ((not isProperty) or propReturn == "null") then
  468.     return objectref.fields[sigName]
  469.   else
  470.     return propReturn
  471.   end
  472. end
  473.  
  474. classic.runtime.setField = function(sigName,value, destClass)
  475.   local objectref = classic.runtime.opstack.pop()
  476.   local genericType = objectref.__typeParameter
  477.   local propReturn, isProperty, setter = nil, false, nil
  478.   if destClass.fields[sigName].final() then
  479.     error("Attempt to set final attribute "..sigName.." with value "..tostring(value))
  480.   end
  481.  
  482.   if destClass.fields[sigName].property() and (not destClass.fields[sigName].settable) then
  483.     local c = destClass.fields[sigName]
  484.     isProperty = true
  485.     classic.runtime.opstack.push(objectref)
  486.     c.settable, c.gettable = true, true
  487.     setter = classic.runtime.invokeSpecial(destClass,"set"..string.upper(string.sub(c.name,1,1))..string.sub(c.name,2,#c.name))
  488.     if setter then setter(value) end
  489.     c.settable, c.gettable = false, false
  490.   end
  491.  
  492.  
  493.   classic.util.hasType(value,destClass.fields[sigName], genericType)
  494.   if (not isProperty) or (not setter) then
  495.     objectref.fields[sigName] = value
  496.   end
  497. end
  498.  
  499. classic.runtime.setStatic = function(sigName,value,klass)
  500.   if klass.fields[sigName].final() then
  501.     error("Attempt to set final attribute "..sigName.." with value "..tostring(value))
  502.   end
  503.   if klass.fields[sigName] then
  504.     classic.util.hasType(klass.fields[sigName],classic.util.getType(value))
  505.     klass.fields[sigName].value = value
  506.   end
  507. end
  508.  
  509. classic.runtime.getStatic = function(sigName,klass)
  510.   if klass.fields[sigName] then
  511.     return klass.fields[sigName].value
  512.   end
  513. end
  514.  
  515. classic.runtime.invokeStatic = function(sigName,klass)
  516.   return function(...)
  517.     return klass.vtable[sigName].value(...)
  518.   end
  519. end
  520.  
  521.  
  522. classic.runtime.invokeVirtual = function(sigName)
  523.   local objectref = classic.runtime.opstack.pop()
  524.   return classic.runtime.methodWrapper(objectref, objectref.class.vtable[sigName])
  525. end
  526.  
  527. classic.runtime.methodWrapper = function(objref,vtblentry)
  528.   return function(self,...)
  529.     classic.runtime.framestack.push({
  530.       class = vtblentry.class;
  531.       methodName = vtblentry.name;
  532.       isAsync = vtblentry.async();
  533.       objID = getmetatable(objref.__proxy).__proxyID
  534.     })
  535.     local method, isAsync, methodResult, args, err = vtblentry.value, vtblentry.async(),nil,{...}, ""
  536.     if (( self == objref.__proxy) or (self == objref.__this)) then
  537.       methodResult =method(objref.__this, unpack(args))
  538.       classic.runtime.framestack.pop()
  539.       return unpack(methodResult)
  540.     else
  541.       methodResult = method(objref.__this,self,unpack(args))
  542.       classic.runtime.framestack.pop()
  543.       return unpack(methodResult)
  544.     end
  545.   end
  546. end
  547.  
  548. classic.util.collectAttributes = function(klass,t)
  549.   local cname, collected = klass.name, t
  550.  
  551.   for fname, sig in pairs(klass.fields) do
  552.     if type(sig.value) ~= "table" then
  553.       collected[fname] = sig.value
  554.     elseif getmetatable(sig.value) and getmetatable(sig.value).__clone then
  555.       collected[fname] = classic.util.clone(sig.value, sig.objType)
  556.     else
  557.       collected[fname] = classic.util.deepcopy(sig.value)
  558.     end
  559.   end
  560.  
  561.   if klass.super then
  562.     collected = classic.util.collectAttributes(klass.super,collected)
  563.   end
  564.   return collected
  565. end
  566.  
  567. classic.util.errorHandled = function(errString)
  568.   if string.find(errString,"%[Classic Error%]") then
  569.     return true
  570.   end
  571.   return false
  572. end
  573.  
  574. classic.util.clone = function(object, objType)
  575.   local clonable = getmetatable(object).__clone
  576.   local cloned   = classic.class.newInstance(nil,clonable.class)
  577.   classic.class.cast(cloned, objType)
  578.   for k,v in pairs(clonable.fields) do
  579.     getmetatable(cloned).__clone.fields[k] = v
  580.   end
  581.   return cloned
  582. end
  583.  
  584. classic.util.deepcopy = function(tbl)
  585.   local orig_type, copy = type(tbl), nil
  586.   if orig_type == 'table' then
  587.     copy = {}
  588.     for orig_key, orig_value in next, tbl, nil do
  589.       copy[classic.util.deepcopy(orig_key)] = classic.util.deepcopy(orig_value)
  590.     end
  591.       setmetatable(copy, classic.util.deepcopy(getmetatable(tbl)))
  592.   else
  593.     copy = tbl
  594.   end
  595.   return copy
  596. end
  597.  
  598. classic.util.checkType = function(sig, acType, forbidNil)
  599.   if acType == nil then return true end
  600.   if sig.value == nil and (forbidNil == nil or forbidNil == false) then return true end
  601.   if acType == "object" then
  602.     local allowed, dest = classic.util.canApplyClassType(
  603.     getmetatable(sig.value).__clone.class,
  604.     sig.objType)
  605.     if not allowed then
  606.       error(" Can't cast class "..dest.name.." to "..sig.objType)
  607.     else
  608.       classic.class.cast(sig.value, sig.objType)
  609.     end
  610.   elseif string.lower(acType) == type(sig.value) then
  611.     return true
  612.   else
  613.     error(sig.type.." "..sig.name.." must be of type "..acType.." got "..type(sig.value).." instead")
  614.   end
  615. end
  616.  
  617. classic.util.hasType = function(nVal, cField, genType)
  618.   if nVal == nil then return true end
  619.   local typeOfVal, generic = classic.util.getType(nVal), false
  620.   if cField.getType() == nil then return true end
  621.   if cField.getType() == "generic" then generic = true end
  622.   if typeOfVal == "object" then
  623.     local allowed, dest = classic.util.canApplyClassType(getmetatable(nVal).__clone.class,(generic and genType.name) or cField.objType)
  624.     if not allowed then
  625.       error(" Can't cast class "..dest.name.." to type "..(cField.objType or (cField.getType()=="generic" and genType.name) or genType))
  626.     else
  627.       classic.class.cast(nVal, cField.objType)
  628.     end
  629.   elseif string.lower( ((generic and (genType.name or genType)) or cField.getType())) == typeOfVal then
  630.     return true
  631.   else
  632.     error(cField.type.." "..cField.name.." must be of type "..((generic and (genType.name or genType)) or cField.getType()).." got "..typeOfVal.." instead")
  633.   end
  634. end
  635.  
  636.  
  637. classic.util.getType = function(val)
  638.   if type(val) ~= "table" then
  639.     return type(val)
  640.   else
  641.     if getmetatable(val) == nil then
  642.       return "table"
  643.     elseif getmetatable(val).__clone then
  644.       return "object"
  645.     end
  646.   end
  647.   return type(val)
  648. end
  649.  
  650. local tp = {
  651.   number = true;
  652.   Table  = true;
  653.   String = true;
  654.   thread = true;
  655.   boolean = true;
  656. }
  657.  
  658. classic.util.isTypeOrClass = function(c)
  659.   local t = type(c)
  660.   if t ~= "table" then
  661.     return false
  662.   elseif getmetatable(c) and getmetatable(c).__type == "class" then
  663.     return true
  664.   elseif c.__type and c.__type == "annotation" and c.descriptors[1]~= nil and tp[c.descriptors[1]] then
  665.     return true
  666.   end
  667.   return false
  668. end
  669.  
  670.  
  671. classic.util.canApplyClassType = function(klass, cname)
  672.   local current = klass
  673.   while current do
  674.     if current.name == cname then
  675.       return true, current
  676.     elseif current.super then
  677.       current = current.super
  678.     else
  679.       current = nil
  680.     end
  681.   end
  682.   return false, klass
  683. end
  684.  
  685. classic.class.cast = function(obj, destClass)
  686.   if destClass == nil then return end
  687.   local bClass, current, canApply = getmetatable(obj).__clone.class, getmetatable(obj).__clone.class, false
  688.   -- first check if we can apply the given class to the object
  689.   while current and (not canApply) do
  690.     if current.name == destClass then
  691.       canApply = true
  692.     elseif current.super then
  693.       current = current.super
  694.     else
  695.       current = nil
  696.     end
  697.   end
  698.   if not canApply then
  699.     error(" Can't cast "..bClass.name.." to class "..tostring(destClass))
  700.   else
  701.     getmetatable(obj).__setClassType(current)
  702.   end
  703. end
  704.  
  705.  
  706. classic.compiler.classloader.parseName = function(name)
  707.   local name, package = name, nil
  708.   local current, indexes = classic.compiler.classpath.packages, {}
  709.   if string.find(name,"%.") ~= nil then package = {} end
  710.   if package == nil then return name end
  711.  
  712.   string.gsub(name, "(%a+%$*%d*)%.*", function(c) table.insert(indexes,c) end)
  713.   for i=1,#indexes-1 do
  714.     if current[indexes[i]] and not(current[indexes[i]].__type) then
  715.       current = current[indexes[i]]
  716.     elseif not current[indexes[i]] then
  717.       current[indexes[i]] = {}
  718.       current = current[indexes[i]]
  719.     else
  720.       error("Package "..indexes[i].." overwrites an already existing class")
  721.     end
  722.   end
  723.   name = indexes[#indexes]
  724.   table.remove(indexes,#indexes)
  725.   package = indexes
  726.  
  727.   return name, ((#package ~= 0 and package) or nil)
  728. end
  729.  
  730. classic.compiler.classloader.addClass = function(klass,defaultOnly)
  731.   local name, package = klass.name, klass.package
  732.   local current = classic.compiler.classpath.packages
  733.  
  734.   if package == "null" or defaultOnly then
  735.     classic.compiler.classpath.default[name] = klass
  736.   else
  737.     classic.compiler.classpath.default[name] = klass
  738.     for i=1,#package do
  739.       if current[package[i]] then
  740.         current = current[package[i]]
  741.       end
  742.     end
  743.     current[name] = klass
  744.   end
  745.   classic.compiler.addProxy(klass,defaultOnly)
  746. end
  747.  
  748. classic.compiler.addProxy = function(klass,defaultOnly)
  749.   local name, package = klass.name, klass.package
  750.   local current = classic.compiler.classProxy.packages
  751.   local cProxy = {}
  752.   setmetatable(cProxy,{
  753.  
  754.     __index = function(_,name)
  755.  
  756.       if type(name) == "table" then
  757.         if classic.util.isTypeOrClass(name) and klass.isGeneric then
  758.           return setmetatable({},{
  759.             __call = function(_,...)
  760.               if klass.isStatic then
  761.                 error(klass.name.." is a static class and can't be instanciated")
  762.               end
  763.               return classic.class.newInstance(nil, klass, name, ...)
  764.             end;
  765.             __type  = "class";
  766.             __class = klass;
  767.             __sub   = parseFunc;
  768.             __gen   = name;
  769.           })
  770.         elseif (not klass.isGeneric) then
  771.           error("Class "..klass.name.." does not take type parameters")
  772.         else
  773.           error("Attempt to instanciate "..klass.name.." with invalid type parameters (generic parameter "..klass.genericTypeName..")")
  774.         end
  775.       end
  776.  
  777.       local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,klass, false)
  778.  
  779.       if valueExists then
  780.         if not isStatic then
  781.           error("Can't access non static field "..fullPath)
  782.         end
  783.         if itype == "method" then
  784.           return classic.runtime.invokeStatic(fullPath, destclass)
  785.         elseif itype == "attribute" then
  786.           return classic.runtime.getStatic(fullPath, destclass)
  787.         end
  788.       else
  789.         error("Can't access "..name.." in class "..klass.name.." or one of its superclasses. Field is either private or undefined.",2)
  790.       end
  791.     end;
  792.  
  793.   __newindex = function(_, name, value)
  794.     local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,klass, false)
  795.  
  796.     if valueExists then
  797.       if (not isStatic) and itype == "field" then
  798.         error("Can't set non static field or method "..fullPath)
  799.       end
  800.       if itype == "field" then
  801.         classic.runtime.setStatic(fullPath, destclass)
  802.       else
  803.         classic.class.override(fullPath,name,klass, destclass, value)
  804.       end
  805.     else
  806.       if type(value) ~= "function" then
  807.         error("Attribute can't be defined outside of class declaration",2)
  808.       end
  809.       klass.methods[name] = signature(klass,name, {[1] = "public"},value,"method")
  810.       klass.vtable[klass.name.."/public/"..name] = klass.methods[name]
  811.     end
  812.   end;
  813.  
  814.   __call = function(_,...)
  815.     if klass.isStatic then error(klass.name.." is a static class and can't be instanciated")
  816.     end
  817.     if klass.isGeneric then
  818.       error("Must specify type parameters for class "..klass.name.." (generic parameter "..klass.genericTypeName..")")
  819.     end
  820.     return classic.class.newInstance(nil, klass,nil, ...)
  821.   end;
  822.   __sub = parseFunc;
  823.   __type = "class";
  824.   __class = klass;
  825.   })
  826.  
  827.   if package == "null" or defaultOnly then
  828.     classic.compiler.classProxy.default[name] = cProxy
  829.   else
  830.     classic.compiler.classProxy.default[name] = cProxy
  831.     for i=1,#package do
  832.       if current[package[i]] then
  833.         current = current[package[i]]
  834.       else
  835.         current[package[i]] = {}
  836.         current = current[package[i]]
  837.       end
  838.     end
  839.     current[name] = cProxy
  840.   end
  841. end
  842.  
  843. classic.class.override = function(fullPath,simpleName, current, destclass, newMethod)
  844.   local m = destclass.methods[simpleName]
  845.   if m.public() and (not m.static()) and (not m.final()) then
  846.     current.methods[simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
  847.     current.vtable[current.name.."/public/"..simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
  848.     current.vtable[destclass.name.."/public/"..simpleName] = current.vtable[current.name.."/public/"..simpleName]
  849.   else
  850.     current.methods[simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
  851.     current.vtable[current.name.."/public/"..simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
  852.   end
  853. end
  854.  
  855. classic.compiler.classloader.getClass = function(name)
  856.   local name, package = classic.compiler.classloader.parseName(name)
  857.   local current = classic.compiler.classpath.packages
  858.   if package == nil then
  859.     return classic.compiler.classpath.default[name]
  860.   else
  861.     for i=1, #package do
  862.       if current[package[i]] then
  863.         current = current[package[i]]
  864.       end
  865.     end
  866.     return current[name]
  867.   end
  868. end
  869.  
  870. classic.compiler.using = function(name)
  871.   local klass = classic.compiler.classloader.getClass(name)
  872.   if klass then
  873.     classic.compiler.classloader.addClass(klass,true)
  874.   else
  875.     return {
  876.       from = function(_, location)
  877.         local okay, err = pcall(function() dofile(location) end)
  878.         if not okay then
  879.           error("An error occurred while loading "..name.." from "..location.."\n"..err)
  880.         end
  881.         local k = classic.compiler.classloader.getClass(name)
  882.         if k then
  883.           classic.compiler.classloader.addClass(k,true)
  884.         else
  885.           error("Could not import class "..name.." into default namespace. Does "..location.." contain the correct class?")
  886.         end
  887.       end
  888.     }
  889.   end
  890. end
  891.  
  892.  
  893.  
  894. setmetatable(_G, {__index = classic.compiler.classResolver})
  895.  
  896. class = setmetatable({},{
  897.   __call = function(_,name) return classic.compiler.class(name) end;
  898.   __index = function(_,mod)
  899.     if mod == "sealed" then
  900.       return function(_,name)
  901.         return classic.compiler.class(name,true,false)
  902.       end
  903.     elseif mod == "static" then
  904.       return function(_,name)
  905.         return classic.compiler.class(name,true,true)
  906.       end
  907.     else
  908.       error("Unknown class modifier : "..mod)
  909.     end
  910.    end;
  911. })
  912.  
  913. extends = classic.compiler.extends
  914. using   = classic.compiler.using
  915. await   = classic.compiler.await
  916.  
  917. classic.compiler.class "classic.internal.CObject" {
  918.  
  919.   hashValue = public - function(self)
  920.     local obj = getmetatable(self).__clone
  921.     if obj then
  922.       return string.sub(tostring(obj),8)
  923.     else
  924.       return "null"
  925.     end
  926.   end;
  927.  
  928.   getClass = public - final - function(self)
  929.     local obj = getmetatable(self).__clone
  930.     return classic.compiler.classProxy.packages.classic.internal.Class(obj.class)
  931.   end;
  932.  
  933.   instanceof = function(self, className)
  934.     local obj = getmetatable(self).__clone
  935.     local name, package, current, isA = obj.class.name, obj.class.package, obj.class, false
  936.     if className == name then
  937.       return true
  938.     end
  939.     while current and (not isA) do
  940.       if package == "null" then
  941.         isA = name == className
  942.       else
  943.         isA = className == table.concat(package,".").."."..name
  944.       end
  945.       if current.super then
  946.         current = current.super
  947.         name, package = current.name, current.package
  948.       else
  949.         current = nil
  950.       end
  951.     end
  952.     return isA
  953.   end
  954. }
  955.  
  956. class "classic.internal.Class" {
  957.  
  958.   classref = private - nil;
  959.  
  960.   Class = function(self,klass)
  961.     self.classref = klass
  962.   end;
  963.  
  964.   getConstructor = public - final - function(self)
  965.     local klass = self.classref
  966.     if klass.methods[klass.name] then
  967.       return classic.runtime.invokeSpecial(klass, klass.name)
  968.     else
  969.       return false
  970.     end
  971.   end;
  972.  
  973.   getDeclaredField = function(self,name)
  974.     local klass = self.classref
  975.     if klass.fields[klass.name.."/"..name] then
  976.       return klass.fields[klass.name.."/"..name].value
  977.     else
  978.       return false
  979.     end
  980.   end;
  981.   getDeclaredFields = function(self)
  982.     local klass, fields = self.classref, {}
  983.     for k,v in pairs(klass.fields) do
  984.       fields[v.name] = v.value or "nil"
  985.     end
  986.     return fields
  987.   end;
  988.  
  989.   getDeclaredMethod = function(self,name)
  990.     local klass = self.classref
  991.     if name == klass.name then
  992.       return false
  993.     end
  994.     if klass.methods[name] then
  995.       return {
  996.         name    = klass.methods[name].name;
  997.         public  = klass.methods[name].public();
  998.         private = klass.methods[name].private();
  999.         static  = klass.methods[name].static();
  1000.         final   = klass.methods[name].final();
  1001.       }
  1002.     else
  1003.       return false
  1004.     end
  1005.   end;
  1006.  
  1007.   getDeclaredMethods = function(self)
  1008.     local klass, methods = self.classref, {}
  1009.     for k,v in pairs(klass.methods) do
  1010.       if v.name ~= klass.name then
  1011.         methods[k] = {
  1012.           name    = v.name;
  1013.           public  = v.public();
  1014.           private = v.private();
  1015.           static  = v.static();
  1016.           final   = v.final();
  1017.         }
  1018.       end
  1019.     end
  1020.     return methods
  1021.   end;
  1022.   getName = function(self)
  1023.     local klass = self.classref
  1024.     return klass.name
  1025.   end;
  1026.   getPackage = function(self)
  1027.     local klass = self.classref
  1028.     return klass.package~= "null" and table.concat(klass.package,".") or false
  1029.   end;
  1030.   getSuperclass = function(self)
  1031.     local klass = self.classref
  1032.     if klass.super then
  1033.       return classic.compiler.classProxy.packages.classic.internal.Class(klass.super)
  1034.     end
  1035.   end;
  1036.   toString = function(self)
  1037.     return "Class@"..string.sub(tostring(self.classref),8)
  1038.   end;
  1039.  
  1040.   getClass = function(self)
  1041.     return classic.compiler.classProxy.packages.classic.internal.Class(getmetatable(self).__clone.class)
  1042.   end;
  1043.  
  1044.   hasTypeParameters = function(self)
  1045.     return self.classref.isGeneric
  1046.   end
  1047.  
  1048. }
Advertisement
Add Comment
Please, Sign In to add comment