Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local signature = dofile "/home/lukas/Dokumente/Projects/Lua/Cronos/core/classic/signature.lua"
- local annotation, parseFunc = dofile "/home/lukas/Dokumente/Projects/Lua/Cronos/core/classic/annotation.lua"
- local stack = dofile "/home/lukas/Dokumente/Projects/Lua/Cronos/core/classic/stack.lua"
- local classic = {
- compiler = {
- loading;
- compileclass;
- class;
- extends;
- interface;
- implements;
- clone;
- classpath = {
- default = {};
- packages = {};
- anonymous = {};
- };
- classProxy = {
- default = {};
- packages = {};
- };
- classloader = {
- loadclass;
- readfile;
- parsename;
- getclass;
- addclass;
- };
- isMAnnotation;
- isFAnnotation;
- isPrimitive;
- isInstance;
- isSTable;
- };
- class = { -- most functions not implemented yet
- superOf;
- subclassOf;
- getConstructor;
- getDeclaredFields;
- getDeclaredField;
- getDeclaredMethods;
- getDeclaredMethod;
- getSuperclass;
- getInterfaces;
- getName;
- getRessource;
- getAnnotationsFrom;
- isPrimitive;
- newInstance;
- toString;
- };
- runtime = {
- opstack = stack();
- framestack = stack();
- invokevirtual;
- invokestatic;
- invokespecial;
- setfield;
- getfield;
- getstatic;
- setstatic;
- };
- util = {
- deepcopy;
- debugprint;
- wrapper;
- }
- }
- do
- _G.public = annotation("public")
- _G.private = annotation("private")
- _G.final = annotation("final")
- _G.static = annotation("static")
- _G.number = annotation("number")
- _G.Table = annotation("Table")
- _G.String = annotation("String")
- _G.thread = annotation("thread")
- _G.boolean = annotation("boolean")
- _G.void = annotation("void")
- _G.property = annotation("property")
- _G.async = annotation("async")
- end
- classic.compiler.classResolver = function(t, name)
- if classic.compiler.classProxy.default[name] then
- return classic.compiler.classProxy.default[name]
- else
- return classic.compiler.classProxy.packages[name]
- end
- end
- classic.compiler.class = function(name,isSealed,isStatic)
- local classname, package = classic.compiler.classloader.parseName(name)
- local klass = {}
- klass.name = classname
- klass.package = package or "null"
- klass.super = nil
- klass.vtable = {}
- klass.methods = {}
- klass.fields = {}
- klass.interfaces = {}
- klass.isGeneric = false
- klass.genericTypeName = ""
- klass.anonCount = 1
- klass.__type = "class"
- klass.isStatic = (isStatic and true) or false
- klass.isSealed = (isSealed and true) or false
- classic.compiler.loading = klass
- return setmetatable({},{
- __call = function(_,classtable)
- classic.compiler.compileClass(klass,classtable)
- end;
- __index = function(_,k) -- k represents generic variable type for this class
- _G[k] = annotation("generic")
- klass.isGeneric, klass.genericTypeName = true, k
- return function(_,classtable)
- classic.compiler.compileClass(klass,classtable)
- end
- end
- })
- end
- classic.compiler.extends = function(name)
- local klass, super = classic.compiler.loading, classic.compiler.classloader.getClass(name)
- if super and klass then
- if super.isSealed then
- error(klass.name.." can't inherit from sealed class "..super.name)
- end
- klass.super = super
- else
- error("Can't find class "..name.." - must be either imported or declared")
- end
- return setmetatable({},{
- __call = function(_,classtable)
- classic.compiler.compileClass(klass,classtable)
- end;
- __index = function(_,k) -- k represents generic variable type for this class
- _G[k] = annotation("generic")
- klass.isGeneric, klass.genericTypeName = true, k
- return function(_,classtable)
- classic.compiler.compileClass(klass,classtable)
- end
- end
- })
- end
- classic.compiler.compileClass = function(klass,ctable)
- local klass, ctable = klass, ctable
- for iname, reference in pairs(ctable) do
- if classic.compiler.isMethodSignature(reference) then
- klass.methods[iname] = classic.compiler.compileMethod(klass,reference,iname)
- klass.vtable[iname] = klass.methods[iname]
- elseif classic.compiler.isAttributeSignature(reference) then
- klass.fields[klass.name.."/"..iname] = classic.compiler.compileAttribute(klass,reference,iname)
- classic.util.checkType(klass.fields[klass.name.."/"..iname],classic.util.getType(klass.fields[klass.name.."/"..iname].value))
- elseif classic.compiler.isRawClassEntry(reference) then
- local type, signature = classic.compiler.compileRawEntry(klass, reference,iname)
- if type == "method" then
- klass.methods[iname] = signature
- klass.vtable[iname] = signature
- elseif type == "attribute" then
- klass.fields[klass.name.."/"..iname] = signature
- end
- end
- end
- klass.super = (klass.super or (klass.name ~= "CObject" and classic.compiler.classpath.packages.classic.internal.CObject)) or nil
- klass.vtable = classic.util.mergeClasses(klass,klass.vtable,klass.super,(klass.super and klass.super.vtable) or {})
- classic.compiler.classloader.addClass(klass)
- end
- classic.util.mergeClasses = function(klass1,vtable1,klass2,vtable2)
- local merged = {}
- for mname, sig in pairs(vtable1) do
- merged[klass1.name..sig.toPath()..mname] = sig
- end
- for mname, sig in pairs(vtable2) do
- if sig.public() and (not sig.static()) and (not sig.final()) and merged[klass1.name.."/public/"..sig.name] then
- merged[mname] = merged[klass1.name.."/public/"..sig.name]
- else
- merged[mname] = sig
- end
- end
- return merged
- end
- classic.compiler.isMethodSignature = function(reference)
- if not type(reference) == "table" then return false end
- if type(reference) == "table" and reference.__type and reference.__type == "annotation" then
- return reference.type == "method"
- end
- return false
- end
- classic.compiler.isAttributeSignature = function(reference)
- if not type(reference) == "table" then return false end
- if type(reference) == "table" and reference.__type and reference.__type == "annotation" then
- return reference.type == "attribute"
- end
- return false
- end
- classic.compiler.isRawClassEntry = function(reference)
- if type(reference) ~= "table" then return true end
- if reference.__type and (reference.type == "method" or reference.type == "attribute") then
- return false
- end
- return true
- end
- classic.compiler.compileMethod = function(klass,annotation,name)
- local klass, annotation = klass, annotation
- return signature(klass,name,annotation.descriptors,annotation.value,"method")
- end
- classic.compiler.compileAttribute = function(klass, annotation,name)
- local klass, annotation, compiled = klass, annotation
- return signature(klass,name,annotation.descriptors,annotation.value,"attribute",annotation.objType)
- end
- classic.compiler.compileRawEntry = function(klass,rawEntry,name)
- local klass, raw, compiled = klass, rawEntry
- local compiled = signature(klass,name,{},rawEntry,nil)
- compiled.type = (type(rawEntry) == "function" and "method") or "attribute"
- return compiled.type, compiled
- end
- classic.class.newInstance = function(_type, klass, genericType, ...)
- local klass, proxy, obj, _type, args, tempType = klass, {}, {}, (_type or klass ), {...}, nil
- local handleIndexResolved = function(valueExists, itype, name, fullPath, destclass, isInternal)
- if valueExists then
- if itype == "method" then
- if isStatic then return classic.runtime.invokeStatic(fullPath,tempType or _type)
- else
- classic.runtime.opstack.push(obj)
- return classic.runtime.invokeVirtual(fullPath)
- end
- elseif itype == "attribute" then
- if isStatic then return classic.runtime.getStatic(fullPath, destclass)
- else
- classic.runtime.opstack.push(obj)
- return classic.runtime.getField(fullPath,destclass)
- end
- end
- else
- 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)
- end
- end
- local handleNewIndexResolved = function(valueExists, itype, name, value, fullPath, destclass, isInternal)
- if valueExists then
- if itype == "method" then
- error("Attempt to set "..name.." with value "..tostring(value).." - "..name.." is a method")
- elseif isStatic then
- classic.runtime.setStatic(fullPath, value, destclass)
- else
- classic.runtime.opstack.push(obj)
- classic.runtime.setField(fullPath, value, destclass)
- end
- else
- error(" Attempt to set undefined "..name.." with value: "..tostring(value))
- end
- end
- proxy = setmetatable({},{
- __clone = obj;
- __setClassType = function(t)
- _type = t
- end;
- __index = function(_,name)
- local valueExists, fullPath, itype, isStatic, destclass
- if name == "super" then return setmetatable({},{
- __index = function(_,name)
- classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
- oldType = _type
- _type = _type.super
- local res = proxy[name]
- _type = oldType
- classic.runtime.framestack.pop()
- return res
- end,
- __newindex = function(_,name, value)
- classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
- oldType = _type
- _type = _type.super
- proxy[name] = value
- _type = oldType
- classic.runtime.framestack.pop()
- end
- })
- end
- valueExists, fullPath, itype, isStatc, destclass = classic.class.resolve(name, _type, false)
- return handleIndexResolved(valueExists, itype, name, fullPath, destclass, false)
- end;
- __newindex = function(_,name,value)
- local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,_type, false)
- handleNewIndexResolved(valueExists, itype, name, value, fullPath, destclass, false)
- end;
- __call = function(_,classtable) -- create an anonymous class that extends the class of this object
- 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)
- klass.anonCount = klass.anonCount + 1
- return classic.class.newInstance(klass,classic.compiler.classpath.packages.anonymous[klass.name.."$"..klass.anonCount-1],nil,nil)
- end
- })
- this = setmetatable({}, {
- __clone = obj;
- __setClassType = function(t)
- _type = t
- end;
- __index = function(_,name)
- local valueExists, fullPath, itype, isStatic, destclass
- if name == "super" then return setmetatable({},{
- __index = function(_,name)
- classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
- oldType = _type
- _type = _type.super
- local res = proxy[name]
- _type = oldType
- classic.runtime.framestack.pop()
- return res
- end,
- __newindex = function(_,name, value)
- classic.runtime.framestack.push({ class = _type.super; methodname = "__super__"; objID = getmetatable(proxy).__proxyID })
- oldType = _type
- _type = _type.super
- proxy[name] = value
- _type = oldType
- classic.runtime.framestack.pop()
- end
- })
- end
- local currentFrame = classic.runtime.framestack.peek()
- local currentClass = (currentFrame and currentFrame.class) or _type
- valueExists, fullPath, itype, isStatc, destclass = classic.class.resolve(name, currentClass,true)
- return handleIndexResolved(valueExists, itype, name, fullPath, destclass, true)
- end;
- __newindex = function(_,name,value)
- local currentFrame = classic.runtime.framestack.peek()
- local currentClass = (currentFrame and currentFrame.class) or _type
- local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,currentClass, true)
- handleNewIndexResolved(valueExists, itype, name, value, fullPath, destclass, true)
- end;
- })
- if genericType and rawget(genericType,"__type") == "annotation" then
- obj.__typeParameter = genericType.descriptors[1]
- elseif genericType and getmetatable(genericType) and getmetatable(genericType).__type == "class" then
- obj.__typeParameter = getmetatable(genericType).__class
- else
- obj.__typeParameter = classic.compiler.classpath.packages.classic.internal.CObject
- end
- obj.__type = "instance"
- obj.__proxy = proxy
- obj.__this = this
- obj.class = klass
- obj.fields = classic.util.collectAttributes(klass,{})
- local calledAllConstructors, init, current, constructors = false, nil, klass, {}
- while current ~= nil do
- table.insert(constructors, current)
- current = current.super or nil
- end
- for i=#constructors, 1, -1 do
- local curr = constructors[i]
- classic.runtime.opstack.push(obj)
- init = classic.runtime.invokeSpecial(curr, curr.name, true)
- if init and ( curr == klass ) then
- init(unpack(args))
- elseif init then
- init()
- end
- end
- return proxy
- end
- classic.class.resolve = function(name,klass, isInternal)
- if type(name) ~= "string" then error("Index must be a string, got "..type(name),3) end
- local currentFrame= classic.runtime.framestack.peek()
- local currentClass, cName, inSuper = klass, klass.name, false
- if (currentFrame and currentFrame.methodname == "__super__") then
- inSuper = true
- end
- local foundMethod, foundAttribute = false, false
- local oClass = currentClass
- while currentClass do
- if currentClass.methods[name] then
- local cMethod = currentClass.methods[name]
- if cMethod.public() then
- if cMethod.static() then
- return true, currentClass.name..cMethod.toPath()..name, "method", true, cMethod.class
- else
- return true, currentClass.name..cMethod.toPath()..name,"method", false, cMethod.class
- end
- elseif cMethod.private() then
- if (currentClass == oClass) and (not inSuper) and isInternal then
- if cMethod.static() then
- return true, currentClass.name..cMethod.toPath()..name, "method",true, cMethod.class
- else
- return true, currentClass.name..cMethod.toPath()..name, "method",false, cMethod.class
- end
- end
- end
- elseif currentClass.fields[currentClass.name.."/"..name] then
- local cField = currentClass.fields[currentClass.name.."/"..name]
- if cField.public() then
- if cField.static() then
- return true, currentClass.name.."/"..name, "attribute", true, cField.class
- else
- return true, currentClass.name.."/"..name, "attribute", false, cField.class
- end
- elseif cField.private() then
- if (currentClass == oClass) and (not inSuper) and isInternal then
- if cField.static() then
- return true, currentClass.name.."/"..name, "attribute", true, cField.class
- else
- return true, currentClass.name.."/"..name, "attribute", false, cField.class
- end
- end
- end
- end
- currentClass = currentClass.super or nil
- end
- return false, nil, false
- end
- classic.runtime.invokeSpecial = function(klass, methodname, checkVisible) -- this function feels a little useless, as it only really calls the
- local objectref = classic.runtime.opstack.pop() -- constructor of a class. meh
- if klass.methods[methodname] and (not klass.methods[methodname].private()) then
- return classic.runtime.methodWrapper(objectref,klass.methods[methodname])
- end
- end
- classic.runtime.getField = function(sigName, destClass)
- local objectref = classic.runtime.opstack.pop()
- local propReturn, isProperty, getter = nil, false, nil
- if destClass.fields[sigName].property() and (not destClass.fields[sigName].gettable) then
- local c = destClass.fields[sigName]
- isProperty = true
- classic.runtime.opstack.push(objectref)
- c.settable, c.gettable = true, true
- getter = classic.runtime.invokeSpecial(destClass,"get"..string.upper(string.sub(c.name,1,1))..string.sub(c.name,2,#c.name))
- propReturn = (getter and getter()) or "null"
- c.settable, c.gettable = false, false
- end
- if ((not isProperty) or propReturn == "null") then
- return objectref.fields[sigName]
- else
- return propReturn
- end
- end
- classic.runtime.setField = function(sigName,value, destClass)
- local objectref = classic.runtime.opstack.pop()
- local genericType = objectref.__typeParameter
- local propReturn, isProperty, setter = nil, false, nil
- if destClass.fields[sigName].final() then
- error("Attempt to set final attribute "..sigName.." with value "..tostring(value))
- end
- if destClass.fields[sigName].property() and (not destClass.fields[sigName].settable) then
- local c = destClass.fields[sigName]
- isProperty = true
- classic.runtime.opstack.push(objectref)
- c.settable, c.gettable = true, true
- setter = classic.runtime.invokeSpecial(destClass,"set"..string.upper(string.sub(c.name,1,1))..string.sub(c.name,2,#c.name))
- if setter then setter(value) end
- c.settable, c.gettable = false, false
- end
- classic.util.hasType(value,destClass.fields[sigName], genericType)
- if (not isProperty) or (not setter) then
- objectref.fields[sigName] = value
- end
- end
- classic.runtime.setStatic = function(sigName,value,klass)
- if klass.fields[sigName].final() then
- error("Attempt to set final attribute "..sigName.." with value "..tostring(value))
- end
- if klass.fields[sigName] then
- classic.util.hasType(klass.fields[sigName],classic.util.getType(value))
- klass.fields[sigName].value = value
- end
- end
- classic.runtime.getStatic = function(sigName,klass)
- if klass.fields[sigName] then
- return klass.fields[sigName].value
- end
- end
- classic.runtime.invokeStatic = function(sigName,klass)
- return function(...)
- return klass.vtable[sigName].value(...)
- end
- end
- classic.runtime.invokeVirtual = function(sigName)
- local objectref = classic.runtime.opstack.pop()
- return classic.runtime.methodWrapper(objectref, objectref.class.vtable[sigName])
- end
- classic.runtime.methodWrapper = function(objref,vtblentry)
- return function(self,...)
- classic.runtime.framestack.push({
- class = vtblentry.class;
- methodName = vtblentry.name;
- isAsync = vtblentry.async();
- objID = getmetatable(objref.__proxy).__proxyID
- })
- local method, isAsync, methodResult, args, err = vtblentry.value, vtblentry.async(),nil,{...}, ""
- if (( self == objref.__proxy) or (self == objref.__this)) then
- methodResult =method(objref.__this, unpack(args))
- classic.runtime.framestack.pop()
- return unpack(methodResult)
- else
- methodResult = method(objref.__this,self,unpack(args))
- classic.runtime.framestack.pop()
- return unpack(methodResult)
- end
- end
- end
- classic.util.collectAttributes = function(klass,t)
- local cname, collected = klass.name, t
- for fname, sig in pairs(klass.fields) do
- if type(sig.value) ~= "table" then
- collected[fname] = sig.value
- elseif getmetatable(sig.value) and getmetatable(sig.value).__clone then
- collected[fname] = classic.util.clone(sig.value, sig.objType)
- else
- collected[fname] = classic.util.deepcopy(sig.value)
- end
- end
- if klass.super then
- collected = classic.util.collectAttributes(klass.super,collected)
- end
- return collected
- end
- classic.util.errorHandled = function(errString)
- if string.find(errString,"%[Classic Error%]") then
- return true
- end
- return false
- end
- classic.util.clone = function(object, objType)
- local clonable = getmetatable(object).__clone
- local cloned = classic.class.newInstance(nil,clonable.class)
- classic.class.cast(cloned, objType)
- for k,v in pairs(clonable.fields) do
- getmetatable(cloned).__clone.fields[k] = v
- end
- return cloned
- end
- classic.util.deepcopy = function(tbl)
- local orig_type, copy = type(tbl), nil
- if orig_type == 'table' then
- copy = {}
- for orig_key, orig_value in next, tbl, nil do
- copy[classic.util.deepcopy(orig_key)] = classic.util.deepcopy(orig_value)
- end
- setmetatable(copy, classic.util.deepcopy(getmetatable(tbl)))
- else
- copy = tbl
- end
- return copy
- end
- classic.util.checkType = function(sig, acType, forbidNil)
- if acType == nil then return true end
- if sig.value == nil and (forbidNil == nil or forbidNil == false) then return true end
- if acType == "object" then
- local allowed, dest = classic.util.canApplyClassType(
- getmetatable(sig.value).__clone.class,
- sig.objType)
- if not allowed then
- error(" Can't cast class "..dest.name.." to "..sig.objType)
- else
- classic.class.cast(sig.value, sig.objType)
- end
- elseif string.lower(acType) == type(sig.value) then
- return true
- else
- error(sig.type.." "..sig.name.." must be of type "..acType.." got "..type(sig.value).." instead")
- end
- end
- classic.util.hasType = function(nVal, cField, genType)
- if nVal == nil then return true end
- local typeOfVal, generic = classic.util.getType(nVal), false
- if cField.getType() == nil then return true end
- if cField.getType() == "generic" then generic = true end
- if typeOfVal == "object" then
- local allowed, dest = classic.util.canApplyClassType(getmetatable(nVal).__clone.class,(generic and genType.name) or cField.objType)
- if not allowed then
- error(" Can't cast class "..dest.name.." to type "..(cField.objType or (cField.getType()=="generic" and genType.name) or genType))
- else
- classic.class.cast(nVal, cField.objType)
- end
- elseif string.lower( ((generic and (genType.name or genType)) or cField.getType())) == typeOfVal then
- return true
- else
- error(cField.type.." "..cField.name.." must be of type "..((generic and (genType.name or genType)) or cField.getType()).." got "..typeOfVal.." instead")
- end
- end
- classic.util.getType = function(val)
- if type(val) ~= "table" then
- return type(val)
- else
- if getmetatable(val) == nil then
- return "table"
- elseif getmetatable(val).__clone then
- return "object"
- end
- end
- return type(val)
- end
- local tp = {
- number = true;
- Table = true;
- String = true;
- thread = true;
- boolean = true;
- }
- classic.util.isTypeOrClass = function(c)
- local t = type(c)
- if t ~= "table" then
- return false
- elseif getmetatable(c) and getmetatable(c).__type == "class" then
- return true
- elseif c.__type and c.__type == "annotation" and c.descriptors[1]~= nil and tp[c.descriptors[1]] then
- return true
- end
- return false
- end
- classic.util.canApplyClassType = function(klass, cname)
- local current = klass
- while current do
- if current.name == cname then
- return true, current
- elseif current.super then
- current = current.super
- else
- current = nil
- end
- end
- return false, klass
- end
- classic.class.cast = function(obj, destClass)
- if destClass == nil then return end
- local bClass, current, canApply = getmetatable(obj).__clone.class, getmetatable(obj).__clone.class, false
- -- first check if we can apply the given class to the object
- while current and (not canApply) do
- if current.name == destClass then
- canApply = true
- elseif current.super then
- current = current.super
- else
- current = nil
- end
- end
- if not canApply then
- error(" Can't cast "..bClass.name.." to class "..tostring(destClass))
- else
- getmetatable(obj).__setClassType(current)
- end
- end
- classic.compiler.classloader.parseName = function(name)
- local name, package = name, nil
- local current, indexes = classic.compiler.classpath.packages, {}
- if string.find(name,"%.") ~= nil then package = {} end
- if package == nil then return name end
- string.gsub(name, "(%a+%$*%d*)%.*", function(c) table.insert(indexes,c) end)
- for i=1,#indexes-1 do
- if current[indexes[i]] and not(current[indexes[i]].__type) then
- current = current[indexes[i]]
- elseif not current[indexes[i]] then
- current[indexes[i]] = {}
- current = current[indexes[i]]
- else
- error("Package "..indexes[i].." overwrites an already existing class")
- end
- end
- name = indexes[#indexes]
- table.remove(indexes,#indexes)
- package = indexes
- return name, ((#package ~= 0 and package) or nil)
- end
- classic.compiler.classloader.addClass = function(klass,defaultOnly)
- local name, package = klass.name, klass.package
- local current = classic.compiler.classpath.packages
- if package == "null" or defaultOnly then
- classic.compiler.classpath.default[name] = klass
- else
- classic.compiler.classpath.default[name] = klass
- for i=1,#package do
- if current[package[i]] then
- current = current[package[i]]
- end
- end
- current[name] = klass
- end
- classic.compiler.addProxy(klass,defaultOnly)
- end
- classic.compiler.addProxy = function(klass,defaultOnly)
- local name, package = klass.name, klass.package
- local current = classic.compiler.classProxy.packages
- local cProxy = {}
- setmetatable(cProxy,{
- __index = function(_,name)
- if type(name) == "table" then
- if classic.util.isTypeOrClass(name) and klass.isGeneric then
- return setmetatable({},{
- __call = function(_,...)
- if klass.isStatic then
- error(klass.name.." is a static class and can't be instanciated")
- end
- return classic.class.newInstance(nil, klass, name, ...)
- end;
- __type = "class";
- __class = klass;
- __sub = parseFunc;
- __gen = name;
- })
- elseif (not klass.isGeneric) then
- error("Class "..klass.name.." does not take type parameters")
- else
- error("Attempt to instanciate "..klass.name.." with invalid type parameters (generic parameter "..klass.genericTypeName..")")
- end
- end
- local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,klass, false)
- if valueExists then
- if not isStatic then
- error("Can't access non static field "..fullPath)
- end
- if itype == "method" then
- return classic.runtime.invokeStatic(fullPath, destclass)
- elseif itype == "attribute" then
- return classic.runtime.getStatic(fullPath, destclass)
- end
- else
- error("Can't access "..name.." in class "..klass.name.." or one of its superclasses. Field is either private or undefined.",2)
- end
- end;
- __newindex = function(_, name, value)
- local valueExists, fullPath, itype, isStatic, destclass = classic.class.resolve(name,klass, false)
- if valueExists then
- if (not isStatic) and itype == "field" then
- error("Can't set non static field or method "..fullPath)
- end
- if itype == "field" then
- classic.runtime.setStatic(fullPath, destclass)
- else
- classic.class.override(fullPath,name,klass, destclass, value)
- end
- else
- if type(value) ~= "function" then
- error("Attribute can't be defined outside of class declaration",2)
- end
- klass.methods[name] = signature(klass,name, {[1] = "public"},value,"method")
- klass.vtable[klass.name.."/public/"..name] = klass.methods[name]
- end
- end;
- __call = function(_,...)
- if klass.isStatic then error(klass.name.." is a static class and can't be instanciated")
- end
- if klass.isGeneric then
- error("Must specify type parameters for class "..klass.name.." (generic parameter "..klass.genericTypeName..")")
- end
- return classic.class.newInstance(nil, klass,nil, ...)
- end;
- __sub = parseFunc;
- __type = "class";
- __class = klass;
- })
- if package == "null" or defaultOnly then
- classic.compiler.classProxy.default[name] = cProxy
- else
- classic.compiler.classProxy.default[name] = cProxy
- for i=1,#package do
- if current[package[i]] then
- current = current[package[i]]
- else
- current[package[i]] = {}
- current = current[package[i]]
- end
- end
- current[name] = cProxy
- end
- end
- classic.class.override = function(fullPath,simpleName, current, destclass, newMethod)
- local m = destclass.methods[simpleName]
- if m.public() and (not m.static()) and (not m.final()) then
- current.methods[simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
- current.vtable[current.name.."/public/"..simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
- current.vtable[destclass.name.."/public/"..simpleName] = current.vtable[current.name.."/public/"..simpleName]
- else
- current.methods[simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
- current.vtable[current.name.."/public/"..simpleName] = signature(current,simpleName, {[1] = "public"}, newMethod, "method")
- end
- end
- classic.compiler.classloader.getClass = function(name)
- local name, package = classic.compiler.classloader.parseName(name)
- local current = classic.compiler.classpath.packages
- if package == nil then
- return classic.compiler.classpath.default[name]
- else
- for i=1, #package do
- if current[package[i]] then
- current = current[package[i]]
- end
- end
- return current[name]
- end
- end
- classic.compiler.using = function(name)
- local klass = classic.compiler.classloader.getClass(name)
- if klass then
- classic.compiler.classloader.addClass(klass,true)
- else
- return {
- from = function(_, location)
- local okay, err = pcall(function() dofile(location) end)
- if not okay then
- error("An error occurred while loading "..name.." from "..location.."\n"..err)
- end
- local k = classic.compiler.classloader.getClass(name)
- if k then
- classic.compiler.classloader.addClass(k,true)
- else
- error("Could not import class "..name.." into default namespace. Does "..location.." contain the correct class?")
- end
- end
- }
- end
- end
- setmetatable(_G, {__index = classic.compiler.classResolver})
- class = setmetatable({},{
- __call = function(_,name) return classic.compiler.class(name) end;
- __index = function(_,mod)
- if mod == "sealed" then
- return function(_,name)
- return classic.compiler.class(name,true,false)
- end
- elseif mod == "static" then
- return function(_,name)
- return classic.compiler.class(name,true,true)
- end
- else
- error("Unknown class modifier : "..mod)
- end
- end;
- })
- extends = classic.compiler.extends
- using = classic.compiler.using
- await = classic.compiler.await
- classic.compiler.class "classic.internal.CObject" {
- hashValue = public - function(self)
- local obj = getmetatable(self).__clone
- if obj then
- return string.sub(tostring(obj),8)
- else
- return "null"
- end
- end;
- getClass = public - final - function(self)
- local obj = getmetatable(self).__clone
- return classic.compiler.classProxy.packages.classic.internal.Class(obj.class)
- end;
- instanceof = function(self, className)
- local obj = getmetatable(self).__clone
- local name, package, current, isA = obj.class.name, obj.class.package, obj.class, false
- if className == name then
- return true
- end
- while current and (not isA) do
- if package == "null" then
- isA = name == className
- else
- isA = className == table.concat(package,".").."."..name
- end
- if current.super then
- current = current.super
- name, package = current.name, current.package
- else
- current = nil
- end
- end
- return isA
- end
- }
- class "classic.internal.Class" {
- classref = private - nil;
- Class = function(self,klass)
- self.classref = klass
- end;
- getConstructor = public - final - function(self)
- local klass = self.classref
- if klass.methods[klass.name] then
- return classic.runtime.invokeSpecial(klass, klass.name)
- else
- return false
- end
- end;
- getDeclaredField = function(self,name)
- local klass = self.classref
- if klass.fields[klass.name.."/"..name] then
- return klass.fields[klass.name.."/"..name].value
- else
- return false
- end
- end;
- getDeclaredFields = function(self)
- local klass, fields = self.classref, {}
- for k,v in pairs(klass.fields) do
- fields[v.name] = v.value or "nil"
- end
- return fields
- end;
- getDeclaredMethod = function(self,name)
- local klass = self.classref
- if name == klass.name then
- return false
- end
- if klass.methods[name] then
- return {
- name = klass.methods[name].name;
- public = klass.methods[name].public();
- private = klass.methods[name].private();
- static = klass.methods[name].static();
- final = klass.methods[name].final();
- }
- else
- return false
- end
- end;
- getDeclaredMethods = function(self)
- local klass, methods = self.classref, {}
- for k,v in pairs(klass.methods) do
- if v.name ~= klass.name then
- methods[k] = {
- name = v.name;
- public = v.public();
- private = v.private();
- static = v.static();
- final = v.final();
- }
- end
- end
- return methods
- end;
- getName = function(self)
- local klass = self.classref
- return klass.name
- end;
- getPackage = function(self)
- local klass = self.classref
- return klass.package~= "null" and table.concat(klass.package,".") or false
- end;
- getSuperclass = function(self)
- local klass = self.classref
- if klass.super then
- return classic.compiler.classProxy.packages.classic.internal.Class(klass.super)
- end
- end;
- toString = function(self)
- return "Class@"..string.sub(tostring(self.classref),8)
- end;
- getClass = function(self)
- return classic.compiler.classProxy.packages.classic.internal.Class(getmetatable(self).__clone.class)
- end;
- hasTypeParameters = function(self)
- return self.classref.isGeneric
- end
- }
Advertisement
Add Comment
Please, Sign In to add comment