mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 01:29:29 +02:00
pas2js: changed TGuid to record
git-svn-id: trunk@38792 -
This commit is contained in:
parent
f64115913d
commit
2945f4a3c9
116
utils/pas2js/dist/rtl.js
vendored
116
utils/pas2js/dist/rtl.js
vendored
@ -99,12 +99,12 @@ var rtl = {
|
||||
$intfcode: intfcode,
|
||||
$implcode: implcode,
|
||||
$impl: null,
|
||||
$rtti: Object.create(rtl.tSectionRTTI),
|
||||
$rtti: Object.create(rtl.tSectionRTTI)
|
||||
};
|
||||
module.$rtti.$module = module;
|
||||
if (implcode) module.$impl = {
|
||||
$module: module,
|
||||
$rtti: module.$rtti,
|
||||
$rtti: module.$rtti
|
||||
};
|
||||
},
|
||||
|
||||
@ -405,6 +405,7 @@ var rtl = {
|
||||
i.$name = name;
|
||||
i.$fullname = module.$name+'.'+name;
|
||||
i.$guid = guid;
|
||||
i.$guidr = null;
|
||||
i.$names = fnnames?fnnames:[];
|
||||
if (rtl.isFunction(initfn)){
|
||||
// rtti
|
||||
@ -418,8 +419,65 @@ var rtl = {
|
||||
return i;
|
||||
},
|
||||
|
||||
strToGUIDR: function(s,g){
|
||||
var p = 0;
|
||||
function n(l){
|
||||
var h = s.substr(p,l);
|
||||
p+=l;
|
||||
return parseInt(h,16);
|
||||
}
|
||||
p+=1; // skip {
|
||||
g.D1 = n(8);
|
||||
p+=1; // skip -
|
||||
g.D2 = n(4);
|
||||
p+=1; // skip -
|
||||
g.D3 = n(4);
|
||||
p+=1; // skip -
|
||||
if (!g.D4) g.D4=[];
|
||||
g.D4[0] = n(2);
|
||||
g.D4[1] = n(2);
|
||||
p+=1; // skip -
|
||||
for(var i=2; i<8; i++) g.D4[i] = n(2);
|
||||
return g;
|
||||
},
|
||||
|
||||
guidrToStr: function(g){
|
||||
if (g.$intf) return g.$intf.$guid;
|
||||
function h(n,digits){
|
||||
return ("0000000"+n.toString(16).toUpperCase()).slice(-digits);
|
||||
}
|
||||
var s='{'+h(g.D1,8)+'-'+h(g.D2,4)+'-'+h(g.D3,4)+'-'+h(g.D4[0],2)+h(g.D4[1],2)+'-';
|
||||
for (var i=2; i<8; i++) s+=h(g.D4[i],2);
|
||||
s+='}';
|
||||
return s;
|
||||
},
|
||||
|
||||
createTGUID: function(guid){
|
||||
var TGuid = (pas.System)?pas.System.TGuid:pas.system.tguid;
|
||||
var g = rtl.strToGUIDR(guid,new TGuid());
|
||||
return g;
|
||||
},
|
||||
|
||||
getIntfGUIDR: function(intfTypeOrVar){
|
||||
if (!intfTypeOrVar) return null;
|
||||
if (!intfTypeOrVar.$guidr){
|
||||
var g = rtl.createTGUID(intfTypeOrVar.$guid);
|
||||
if (!intfTypeOrVar.hasOwnProperty('$guid')) intfTypeOrVar = Object.getPrototypeOf(intfTypeOrVar);
|
||||
g.$intf = intfTypeOrVar;
|
||||
intfTypeOrVar.$guidr = g;
|
||||
}
|
||||
return intfTypeOrVar.$guidr;
|
||||
},
|
||||
|
||||
addIntf: function (aclass, intf, map){
|
||||
'use strict';
|
||||
function jmp(fn){
|
||||
if (typeof(fn)==="function"){
|
||||
return function(){ return fn.apply(this.$o,arguments); };
|
||||
} else {
|
||||
return function(){ rtl.raiseE('EAbstractError'); };
|
||||
}
|
||||
}
|
||||
if(!map) map = {};
|
||||
var t = intf;
|
||||
var item = Object.create(t);
|
||||
@ -431,13 +489,8 @@ var rtl = {
|
||||
var intfname = names[i];
|
||||
var fnname = map[intfname];
|
||||
if (!fnname) fnname = intfname;
|
||||
let fn = aclass[fnname];
|
||||
//console.log('addIntf: intftype='+t.$name+' index='+i+' intfname="'+intfname+'" fnname="'+fnname+'" proc='+typeof(fn));
|
||||
if (typeof(fn)==="function"){
|
||||
item[intfname] = function(){ return fn.apply(this.$o,arguments); };
|
||||
} else {
|
||||
item[intfname] = function(){ rtl.raiseE('EAbstractError'); };
|
||||
}
|
||||
item[intfname] = jmp(aclass[fnname]);
|
||||
}
|
||||
t = Object.getPrototypeOf(t);
|
||||
}while(t!=null);
|
||||
@ -453,30 +506,31 @@ var rtl = {
|
||||
if (!item) return null;
|
||||
// check delegation
|
||||
//console.log('getIntfG: obj='+obj.$classname+' guid='+guid+' query='+query+' item='+typeof(item));
|
||||
if (typeof item === 'function') return item.call(obj);
|
||||
if (typeof item === 'function') return item.call(obj); // COM: contains _AddRef
|
||||
// check cache
|
||||
var intf = null;
|
||||
if (obj.$interfaces){
|
||||
intf = obj.$interfaces[guid];
|
||||
// intf can be undefined!
|
||||
//console.log('getIntfG: obj='+obj.$classname+' guid='+guid+' cache='+typeof(intf));
|
||||
}
|
||||
if (!intf){
|
||||
if (!intf){ // intf can be undefined!
|
||||
intf = Object.create(item);
|
||||
intf.$o = obj;
|
||||
if (!obj.$interfaces) obj.$interfaces = {};
|
||||
obj.$interfaces[guid] = intf;
|
||||
}
|
||||
if (query===1){
|
||||
if (typeof(query)==='object'){
|
||||
// called by queryIntfT
|
||||
var o = null;
|
||||
if (intf.QueryInterface(guid,
|
||||
if (intf.QueryInterface(rtl.getIntfGUIDR(query),
|
||||
{get:function(){ return o; }, set:function(v){ o=v; }}) === 0){
|
||||
return o;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if(query===2){
|
||||
intf._AddRef();
|
||||
// called by TObject.GetInterfaceByStr
|
||||
if (intf.$kind === 'com') intf._AddRef();
|
||||
}
|
||||
return intf;
|
||||
},
|
||||
@ -485,23 +539,19 @@ var rtl = {
|
||||
return rtl.getIntfG(obj,intftype.$guid);
|
||||
},
|
||||
|
||||
queryIntfG: function(obj,guid){
|
||||
return rtl.getIntfG(obj,guid,1);
|
||||
},
|
||||
|
||||
queryIntfT: function(obj,intftype){
|
||||
return rtl.queryIntfG(obj,intftype.$guid);
|
||||
return rtl.getIntfG(obj,intftype.$guid,intftype);
|
||||
},
|
||||
|
||||
queryIntfIsT: function(obj,intftype){
|
||||
var i = rtl.queryIntfG(obj,intftype.$guid);
|
||||
if (!i) return false;
|
||||
if (i._Release) i._Release();
|
||||
if (i.$kind === 'com') i._Release();
|
||||
return true;
|
||||
},
|
||||
|
||||
asIntfT: function (obj,intftype){
|
||||
var i = getIntfG(obj,intftype.$guid);
|
||||
var i = rtl.getIntfG(obj,intftype.$guid);
|
||||
if (i!==null) return i;
|
||||
rtl.raiseEInvalidCast();
|
||||
},
|
||||
@ -536,10 +586,10 @@ var rtl = {
|
||||
},
|
||||
free: function(){
|
||||
//console.log('rtl.intfRefs.free...');
|
||||
for (id in this){
|
||||
for (var id in this){
|
||||
if (this.hasOwnProperty(id)) this[id]._Release;
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
createIntfRefs: function(){
|
||||
@ -570,6 +620,10 @@ var rtl = {
|
||||
if (old!==null){
|
||||
old._Release(); // Release after AddRef, to avoid double Release if Release creates an exception
|
||||
}
|
||||
} else if (skipAddRef){
|
||||
if (old!==null){
|
||||
old._Release(); // value has an AddRef
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
@ -633,6 +687,14 @@ var rtl = {
|
||||
return setLength(arr,2);
|
||||
},
|
||||
|
||||
arrayEq: function(a,b){
|
||||
if (a===null) return b===null;
|
||||
if (b===null) return false;
|
||||
if (a.length!==b.length) return false;
|
||||
for (var i=0; i<a.length; i++) if (a[i]!==b[i]) return false;
|
||||
return true;
|
||||
},
|
||||
|
||||
arrayClone: function(type,src,srcpos,end,dst,dstpos){
|
||||
// type: 0 for references, "refset" for calling refSet(), a function for new type()
|
||||
// src must not be null
|
||||
@ -640,7 +702,7 @@ var rtl = {
|
||||
if (rtl.isFunction(type)){
|
||||
for (; srcpos<end; srcpos++) dst[dstpos++] = new type(src[srcpos]); // clone record
|
||||
} else if((typeof(type)==="string") && (type === 'refSet')) {
|
||||
for (; srcpos<end; srcpos++) dst[dstpos++] = refSet(src[srcpos]); // ref set
|
||||
for (; srcpos<end; srcpos++) dst[dstpos++] = rtl.refSet(src[srcpos]); // ref set
|
||||
} else {
|
||||
for (; srcpos<end; srcpos++) dst[dstpos++] = src[srcpos]; // reference
|
||||
};
|
||||
@ -669,7 +731,7 @@ var rtl = {
|
||||
if (index < 0) index = 0;
|
||||
if (count === undefined) count=srcarray.length;
|
||||
var end = index+count;
|
||||
if (end>scrarray.length) end = scrarray.length;
|
||||
if (end>scrarray.length) end = srcarray.length;
|
||||
if (index>=end) return [];
|
||||
if (type===0){
|
||||
return srcarray.slice(index,end);
|
||||
@ -1014,7 +1076,7 @@ var rtl = {
|
||||
$Class: function(name,o){ return this.$Scope(name,rtl.tTypeInfoClass,o); },
|
||||
$ClassRef: function(name,o){ return this.$inherited(name,rtl.tTypeInfoClassRef,o); },
|
||||
$Pointer: function(name,o){ return this.$inherited(name,rtl.tTypeInfoPointer,o); },
|
||||
$Interface: function(name,o){ return this.$Scope(name,rtl.tTypeInfoInterface,o); },
|
||||
$Interface: function(name,o){ return this.$Scope(name,rtl.tTypeInfoInterface,o); }
|
||||
},
|
||||
|
||||
newTIParam: function(param){
|
||||
@ -1022,7 +1084,7 @@ var rtl = {
|
||||
var t = {
|
||||
name: param[0],
|
||||
typeinfo: param[1],
|
||||
flags: (rtl.isNumber(param[2]) ? param[2] : 0),
|
||||
flags: (rtl.isNumber(param[2]) ? param[2] : 0)
|
||||
};
|
||||
return t;
|
||||
},
|
||||
|
@ -632,6 +632,8 @@ function(){
|
||||
<li>Supported: Assign, pass as argument, equal, not equal, array of record</li>
|
||||
<li>Not yet implemented: Constants, pointer of record, advanced records, operators.</li>
|
||||
<li>When assigning a record it is cloned. This is compatible with Delphi and FPC.</li>
|
||||
<li>Since record types are JS objects it is possible to typecast a record type
|
||||
to the JS Object, e.g. TJSObject(TPoint)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -1629,7 +1631,8 @@ function(){
|
||||
}
|
||||
</pre>
|
||||
When an interface is created for an object (here: a Pascal class instance),
|
||||
for example by using the <i>as</i>-operator "<i>ObjVar as IUnknown</i>", a JS object is created, which
|
||||
for example by using the <i>as</i>-operator "<i>ObjVar as IUnknown</i>",
|
||||
a JS object is created, which
|
||||
is an instance of the map object with its <i>$o</i> set to the <i>ObjVar</i>.<br>
|
||||
<br>
|
||||
Supported:
|
||||
@ -1644,8 +1647,9 @@ function(){
|
||||
</ul>
|
||||
</li>
|
||||
<li>inheriting</li>
|
||||
<li>Contrary to Delphi/FPC the GUIDs are simple string literals, TGUID = string.</li>
|
||||
<li>An interface without a GUID gets one autogenerated from its name and method names.</li>
|
||||
<li>Contrary to Delphi/FPC you can assign an interface type or var to
|
||||
the type TGuidString.</li>
|
||||
<li>a class implementing an interface must not be external</li>
|
||||
<li>a ClassType "supports" an interface, if it itself or one of its
|
||||
ancestors implements the interface.
|
||||
@ -1663,17 +1667,15 @@ function(){
|
||||
<li>IntfVar as IntfType - types must be releated</li>
|
||||
<li>IntfVar as ClassType - types can be unrelated, nil returns nil,
|
||||
invalid raises EInvalidCast</li>
|
||||
<li>ObjVar as IntfType - mode delphi: types must be related,
|
||||
objfpc: can be unrelated, nil if not found, COM: uses _AddRef</li>
|
||||
<li>ObjVar as IntfType - can be unrelated, nil if not found, COM: uses _AddRef</li>
|
||||
</ul>
|
||||
<li>typecast:</li>
|
||||
<ul>
|
||||
<li>IntfType(IntfVar) - must be related</li>
|
||||
<li>ClassType(IntfVar) - can be unrelated, nil if invalid</li>
|
||||
<li>IntfType(ObjVar) - mode delphi: must be related,
|
||||
objfpc: can be unrelated, nil if not found,
|
||||
<li>IntfType(ObjVar) - nil if not found,
|
||||
COM: if ObjVar has delegate uses _AddRef</li>
|
||||
<li>TJSObject(intfvar)</li>
|
||||
<li>TJSObject(IntfTypeOrVar)</li>
|
||||
<li>jsvalue(intfvar)</li>
|
||||
</ul>
|
||||
<li>Assign operator:</li>
|
||||
@ -1682,9 +1684,25 @@ function(){
|
||||
<li>IntfVar:=IntfVar2; - IntfVar2 must be same type or a descendant</li>
|
||||
<li>IntfVar:=ObjVar; - nil if unsupported</li>
|
||||
<li>jsvalue:=IntfVar;</li>
|
||||
<li>TGUIDVar:=IntfType;</li>
|
||||
<li>TGUIDVar:=IntfVar;</li>
|
||||
<li>TGUIDVar:=stringconstant;</li>
|
||||
<li>TGUIDStringVar:=IntfVar;</li>
|
||||
<li>StringVar:=GuidVar;</li>
|
||||
</ul>
|
||||
<li>Equal/Inequal operator:</li>
|
||||
<ul>
|
||||
<li>IntfVar=nil;</li>
|
||||
<li>IntfVar=IntfVar2; - must be related</li>
|
||||
<li>jsvalue=IntfVar;</li>
|
||||
<li>TGUIDVar=IntfType;</li>
|
||||
<li>TGUIDVar=IntfVar;</li>
|
||||
<li>TGUIDVar=string;</li>
|
||||
<li>TGUIDStringVar=IntfVar;</li>
|
||||
</ul>
|
||||
<li>Passing an COMIntfVar to an untyped parameter does not trigger _AddRef, _Release.</li>
|
||||
<li>Assigned(IntfVar)</li>
|
||||
<li>RTTI</li>
|
||||
<li>RTTI, typeinfo(IntfType), typeinfo(IntfVar)</li>
|
||||
</ul>
|
||||
Not yet supported: array of intferfacetype, interface as record member.
|
||||
</div>
|
||||
@ -2446,6 +2464,8 @@ End.
|
||||
For example you can call the class function <i>TJSString.fromCharCode()</i>, but you cannot
|
||||
call <i>aJSString.fromCharCode()</i>.</li>
|
||||
<li>An external class can descend from another external class.</li>
|
||||
<li>Since class types are JS objects it is possible to typecast a class type
|
||||
to the JS Object, e.g. TJSObject(TObject)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user