tslediter/designer/utslsynmemo.tsf

2410 lines
77 KiB
Plaintext

unit UTslSynMemo;
interface
{**
@explan(说明) tsl语法编辑器库
**}
uses utslvclauxiliary,UTslMemo;
type thighlitcolor = class(tcomponent)
function Create(AOwner);
begin
inherited;
intitcolors();
end
function gutterbkcolor();
begin
return FColors["行号背景"];
end
function selbkcolor();
begin
return FColors["选中背景"];
end
function curbkcolor();
begin
return FColors["当前行背景"];
end
function bkcolor(); //背景
begin
return FColors["back"];
end
function fontcolor();//字体颜色
begin
return FColors["字体"];
end
function keycolor();//关键字
begin
return FColors["关键字"];
end
function symcolor();//符号
begin
return FColors["符号"];
end
function commentcolor();//注释
begin
return FColors["注释"];
end
function strcolor(); //字符串
begin
return FColors["字符串"];
end
function numcolor();//数字
begin
return FColors["数字"];
end
function sysfunccolor();//系统函数
begin
return FColors["系统函数"];
end
property colors write setcolors;
private
function intitcolors(cls);
begin
if not FColors then
begin
FColors := array();
for i,v in
array("字体":
("font":0,"back":16448250),"关键字":
("font":255,"back":16448250),"符号":
("font":255,"back":16448250),"行号背景":
("font":0,"back":15000804),"注释":
("font":2263842,"back":16448250),"字符串":
("font":9109643,"back":16448250),"数字":
("font":6710886,"back":16448250),"系统函数":
("font":13434880,"back":16448250),"选中背景":
("font":0,"back":rgb(192,192,192)),"当前行背景":
("font":0,"back":rgb(232,232,255))) do
begin
if i="字体" then
begin
FColors["back"] := new tcolor(v["back"]);
end
if i in array("选中背景","当前行背景","行号背景") then
begin
FColors[i] := new tcolor(v["back"]);
end else
FColors[i] := new tcolor(v["font"]);
end
end
end
function transblk(c);
begin
return (c=0)?1:c;
end
function setcolors(cls);
begin
cgd := false;
for i,v in FColors do
begin
if i="back" then
begin
v.changed := false;
bc := cls["字体"]["back"];
v.color := transblk(bc);
if v.changed then
begin
cgd .|= 2;
end
end else
begin
v.changed := false;
if i in array("选中背景","当前行背景","行号背景") then
begin
v.color := transblk(cls[i]["back"]);
end else
v.color := transblk(cls[i]["font"]);
if v.changed then
begin
if i="字体" then
begin
cgd .|= 4;
end else
if i="选中背景" then
begin
cgd .|= 8;
end else
if i= "当前行背景" then
begin
cgd .|= 16;
end else
if i="行号背景" then
begin
cgd .|= 32;
end else
cgd .|= 1;
end
end
end
if cgd then
begin
p := Owner;
if p then p.Notification(self,array("value":cgd,"editer":1));
end
end
FColors;
end
type tcsssyncompletion = class(TSynCompletion)
function Create(AOwner);
begin
inherited;
IgnoreCase := false;
end
function PrepareCompletion(m);override;
begin
//解析
if not Memo then return ;
sd := static getcsswordsa();
d := gettextwords(Memo.Text);
if d then sd union=d;
SetCompData(sd);
end
function getcsswordsa();
begin
getcsskeywords(r);
return r;
end
function gettextwords(s);
begin
parseregexpr("[A-Zaz0-9_\\-]+",s,"mi",mched,mchpos,mathlen);
r := array();
for ri,v in mched do
begin
v0 := v[0];
lv := lowercase(v0);
if r[lv] then continue;
r[lv] := v0;
end
d := array();
i := 0;
for lv,v in r do
begin
d[i,"caption"] := v;
d[i,"value"] := v;
d[i,"lvalue"] := lv;
cl := length(v);
d[i,"clen"] := cl;
d[i,"vlen"] := cl;
i++;
end
return d;
end
end
type tjssyncompletion = class(TSynCompletion)
function Create(AOwner);
begin
inherited;
IgnoreCase := false;
end
function PrepareCompletion(m);override;
begin
//解析
if not Memo then return ;
sd := static getjswords();
d := gettextwords(Memo.Text);
if d then sd union=d;
SetCompData(sd);
end
function getjswords();
begin
getjskeywordstip(r);
getcsskeywords(r);
return r;
end
function gettextwords(s);
begin
parseregexpr("[A-Zaz0-9_\\-]+",s,"mi",mched,mchpos,mathlen);
r := array();
for ri,v in mched do
begin
v0 := v[0];
lv := lowercase(v0);
if r[lv] then continue;
r[lv] := v0;
end
d := array();
i := 0;
for lv,v in r do
begin
d[i,"caption"] := v;
d[i,"value"] := v;
d[i,"lvalue"] := lv;
cl := length(v);
d[i,"clen"] := cl;
d[i,"vlen"] := cl;
i++;
end
return d;
end
end
type TTSLCompletion= class(TSynCompletion)
{**
@explan(说明) tsl提示自动完成类
**}
static FCodeBlocks;
function Create(AOwner);
begin
inherited;
GetTslParser();
end
function getallfunctions();
begin
return FTslParser.DispatchMethod(0,array("method":"allfunctions"));
end
function GetFileFullPath(f);//获得全名
begin
return FTslParser.DispatchMethod(0,array("method":"getfullpath","value":f));
end
class function SetFindDirs(dirs); //设置搜索目录
begin
return GetTslParser().DispatchMethod(0,array("method":"finddirs","value":dirs));
end
class function SetCacheDir(dir); //设置缓存目录
begin
return GetTslParser().DispatchMethod(0,array("method":"cachedir","value":dir));
end
class function getdirtsfs();
begin
return GetTslParser().DispatchMethod(0,array("method":"getprojecttsfs"));
end
class function GetCodeBlocks();
begin
r := array();
{try
FCodeBlocks := GetTslCompletionCodeBlocks();
except
FCodeBlocks := array();
end}
if ifarray(FCodeBlocks) then
begin
idx := 0;
for i ,vv in FCodeBlocks do
begin
if not ifarray(vv) then continue;
cp := vv["caption"];
if not(cp and ifstring(cp)) then continue;
v := vv["value"];
if not(v and ifstring(v)) then continue;
ve := vv["valueext"];
if not(ve and ifstring(ve)) then continue;
r[idx]["caption"] := cp;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(cp);
r[idx]["order"] := 0;
r[idx]["valueext"] := ve;
if vv["prefix"] then r[idx]["prefix"]:=true;
idx++;
end
end
return r;
end
function getjumpinfo();
begin
return FTslParser.DispatchMethod(0,array("method":"allfunctions"));
end
function PrepareCompletion(m);override;
begin
//解析
if not Memo then return ;
//mtic;
{
setprofiler(7);
t := now();}
sd := static GetTslKeyWords();
d := FTslParser.DispatchMethod(0,array("method":"parserstring","value":Memo.Text,"minus":m));
if ifarray(d) and d then sd union=d;
sd union=GetCodeBlocks();
//sd[length(sd)] := array("caption":"try except end","value":"try","lvalue":"try","vlen":3,"clen":14,"order":0,"valueext":"\r\nexcept\r\nend;");
SetCompData(sd);
//echo "\r\ntime:",mtoc;
{if (now()-t)>(1/24/60/60/3) then
begin
except
end;
d := getprofilerinfo(true);
exportfile(ftstream(),"",format("d:\\tst\\profile\\%ssynprofile.stm",tostn(random())),d);
end}
//FTslParser
end
function GetTslKeyWords(); //关键字
begin
gjz := TSL_ReservedKeys2();
r := array();
idx := 0;
for i,v in gjz do
begin
c := v+" <key>";
r[idx]["caption"] := c;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(c);
r[idx]["order"] := 0;
idx++;
end
gjz := unit(utssvr_api_c).get_sys_functions();//tslL_getfunctions_2_();
for i,v in gjz do
begin
c := v+" <sysfun>";
r[idx]["caption"] := c;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(c);
r[idx]["order"] := 2;
idx++;
end
getjskeywordstip(r);
getcsskeywords(r);
return r;
end
private
class function GetTslParser();
begin
if not FTslParser then FTslParser := new TTsfFileParser();
return FTslParser;
end
static FTslParser;
end
type TTslSynHighLighter = class(TSynHighLighter)
{**
@explan(说明) tsl语法高亮类
**}
private
fpairbegin;
public
fforcehtml;
function forcehtml(h);
begin
if h then
begin
fforcehtml := true;
FSynBranch := "tslx";
end else
begin
fforcehtml := false;
FSynBranch := 0;
end
end
function Create(AOwner);
begin
inherited;
fforcehtml := 0;
fpairbegin := array("select":1,"sselect":1,"update":1,"mselect":1,"vselect":1,"try":1,"begin":1,"type":1,"case":1);
FSynBranch := 0;// 0, "tsl" "tslx"
Clean();
FChangeDeal := true;
if not ifarray(FKeyWords) then
begin
FKeyWords := array();
for i,v in TSL_ReservedKeys2() do
begin
FKeyWords[v] := v;
end
FBinFunc := array();
for i,v in unit(utssvr_api_c).get_sys_functions() do
begin
FBinFunc[v]:=v;
end
FJsKeyWords := array();
for i,v in getjskeywords() do
begin
FJsKeyWords[v]:=v;
end
FJsSysClass := array();
for i,v in array("Array","Date","eval","function","hasOwnProperty","Infinity","isFinite","isNaN","isPrototypeOf","length","Math","NaN","name","Number","Object","prototype","String","toString","undefined","valueOf")
do
begin
FJsSysClass[v]:=true;
end
FJsWindows := array();
for i,v in getjsfunwords() do
begin
FJsWindows[v]:=true;
end
FJsHtmlEvent := array();
for i,v in getdomeventwords() do
begin
FJsHtmlEvent[v]:=true;
end
FCssPropertys := array();
for i,v in getcsswords() do
begin
FCssPropertys[v]:=true;
end
end
FLastDispathTime := 0;
end
function Clean();override;
begin
// { ' " %% 0
FTokens := array();
FSates := array(0); //状态
if fforcehtml then
begin
FSynSates := array("tslx");
end else
FSynSates := array(0);
FBBStates := array(new TBBState(")"));
FBEStates := array(new TBBState("end"));
FMBStates := array(new TBBState("]"));
FJsxkhs := array(new TBBState(")"));
FJshkhs := array(new TBBState("}"));
FJsDkhs := array(new TBBState("]"));
FSatesCount := 1; //改变的行
end
function Recycling();override;
begin
Clean();
inherited;
end
function SetInValidateIndex(idx);override; //设置无效的数据
begin
idx := max(1,idx);
if not(FChangeDeal) and idx>FSatesCount then return ;
fdolastline := idx-2;
if length(FSates)>=idx then
FSatesCount := idx;
else FSatesCount := length(FSates)-1;
if FSatesCount = 1 then Clean();
FChangeDeal := false;
end
function SetJsToken(tokens,ttk,idx,tp);
begin
bttk := ttk;
if not ttk then return nil;
d := inherited SetTToken(tokens,ttk,idx,tp);
case tp of
'//','/*':
begin
if hightercolor then d.FFcolor := hightercolor.commentcolor() ;
else
d.FFColor := 0x8D9600;
end
'"',"'":
begin
if hightercolor then d.FFcolor := hightercolor.strcolor() ;
else d.FFcolor := 0x968080;
end
"{":
begin
if bttk="{" then
begin
FJshkh.GetLeft();
d.FMate := FJshkh.GetSate();
end else
begin
FJshkh.GetRight();
d.FMate := FJshkh.GetSate();
end
end
"(":
begin
if bttk="(" then
begin
FJsxkh.GetLeft();
d.FMate := FJsxkh.GetSate();
end else
begin
FJsxkh.GetRight();
d.FMate := FJsxkh.GetSate();
end
end
"[":
begin
if bttk="[" then
begin
FJsDkh.GetLeft();
d.FMate := FJsDkh.GetSate();
end else
begin
FJsDkh.GetRight();
d.FMate := FJsDkh.GetSate();
end
end
else
begin
if FJsWindows[bttk] then //
begin
if hightercolor then d.FFcolor := hightercolor.sysfunccolor() ;
else
d.FFColor := 0xFF0000;
end else
if FJsKeyWords[bttk] then // FE0064
begin
if hightercolor then d.FFcolor := hightercolor.keycolor() ;
else
d.FFColor := 0xFF0000;
end else
if FJsSysClass[bttk] then //
begin
if hightercolor then d.FFcolor := hightercolor.keycolor() ;
else
d.FFcolor := 0xcd0000;
end else
if FJsHtmlEvent[bttk] then //
begin
if hightercolor then d.FFcolor := hightercolor.sysfunccolor() ;
else
d.FFColor := 0xFF0000;
end else
if FCssPropertys[bttk] then
begin
if hightercolor then d.FFcolor := hightercolor.keycolor() ;
else
d.FFColor := 0x0000FF;
end
end
end
return d;
end
function SetTToken(tokens,ttk,idx,tp);override;
begin
if not ttk then return ;
ottk := ttk;
d := inherited;
tkl := d.FLen;
lwttk := lowercase(ottk);
donext := true;
//if tp in array("'",'"') then
if tp='"' or tp="'" or (tp=array("%%")) then
begin
if hightercolor then d.FFcolor := hightercolor.strcolor() ;
else d.FFcolor := 0x8B008B;
donext := false;
end else
if tp="//" or tp="{" or tp="(*" then //if tp in array("//","{","(*") then
begin
if hightercolor then d.FFcolor := hightercolor.commentcolor() ;
else
d.FFcolor := 0x228B22;
donext := false;
end else
if FKeyWords[lwttk] then
begin
if hightercolor then d.FFcolor := hightercolor.keycolor() ;
else
d.FFcolor := 0x0000FF;
end else
if FBinFunc[lwttk] then
begin
if hightercolor then d.FFcolor := hightercolor.sysfunccolor() ;
else
d.FFcolor := 0xcd0000;
//d.FFfacename := "MS Mincho";
//d["vtype"] := "function";
donext := false;
end
if donext then
begin
if (tkl=1) and pos(ottk,";.`~!@#$%^&*-+,><?/|:=") then
begin
if hightercolor then d.FFcolor := hightercolor.symcolor() ;
end else
if lwttk="end" then
begin
FCBEState.GetRight();
d.FMATe:= FCBEState.GetSate();
end else
if StrIsANumber(ottk) then
begin
if hightercolor then d.FFcolor := hightercolor.numcolor() ;
else
d.FFcolor := 0x666666;
end else
if tp = array("(") then
begin
d.FMate := FCBBState.GetSATe();
end else
if tp = array("[") then
begin
D.FMate := FCMBState.GetSate();
end else
if fpairbegin[lwttk] then
begin
FCBEState.GetLeft();
d.FMATe := FCBEState.GetSate();
end
end
return d;
end
function ParserTslxTokenLines(s,b,e,cst,tokens);
begin
idx := b;
ttk := "";
jsfh := " \t`~!#$%^&*()+[]{}|\\/?><.,=:;";
if cst=0 then
begin
while idx<=e do
begin
vi := s[idx];
viod := ord(vi);
//if vi="<" and ( e-b)>2 and s[idx+1:idx+3]="!--" then
if vi="<" and ( e-idx)>2 and s[idx+1:idx+3]="!--" then
begin
//FindRightChars
SetJsToken(tokens,"<!--",idx+3,"/*");
return ParserTslxTokenLines(s,idx+4,e,"<!--",tokens);
end
isjsfh := false;
if pos(vi,jsfh) then
begin
isjsfh := true;
if ttk then
SetJsToken(tokens,ttk,idx-1);
end else
if vi='"' or vi="'" then
begin
if ttk then
SetJsToken(tokens,ttk,idx-1);
end
if vi="[" then
begin
SetJsToken(tokens,vi,idx,"[");
end else
if vi="]" then
begin
SetJsToken(tokens,vi,idx,"[");
end else
if vi="{" then
begin
SetJsToken(tokens,vi,idx,"{");
end else
if vi="}" then
begin
SetJsToken(tokens,vi,idx,"{");
end else
if vi="(" then
begin
SetJsToken(tokens,vi,idx,"(");
end else
if vi=")" then
begin
SetJsToken(tokens,vi,idx,"(");
end else
if vi='"' then
begin
SetJsToken(tokens,vi,idx,'"');
if idx=e then return '"';
r := FindRightChar('"',s,idx+1,e,"\\");
if r = 0 then
begin
SetJsToken(tokens,s[idx+1:],e,'"');
return '"';
end else
begin
if r>idx+1 then
begin
SetJsToken(tokens,s[idx+1:r-1],r-1,'"');
end
SetJsToken(tokens,s[r:r],r,'"');
idx := r+1;
continue;
end
//return ParserTslxTokenLines(s,idx+1,e,'"',tokens);
end else
if vi="'" then
begin
SetJsToken(tokens,vi,idx,'"');
if idx=e then return "'";
r := FindRightChar("'",s,idx+1,e,"\\");
if r = 0 then
begin
SetJsToken(tokens,s[idx+1:],e,"'");
return "'";
end else
begin
if r>idx+1 then
begin
SetJsToken(tokens,s[idx+1:r-1],r-1,"'");
end
SetJsToken(tokens,s[r:r],r,"'");
idx := r+1;
continue;
end
//return ParserTslxTokenLines(s,idx+1,e,"'",tokens);
end else
if vi="/" then
begin
if idx=e then
begin
SetJsToken(tokens,"/",idx);
end else
begin
if s[idx+1]="/" then
begin
SetJsToken(tokens,s[idx:],e,"//");
return 0;
end else
if s[idx+1]="*" then //查找 */
begin
SetJsToken(tokens,"/*",idx+1,"/*");
return ParserTslxTokenLines(s,idx+2,e,"/*",tokens);
end else
begin
SetJsToken(tokens,"/",idx);
end
end
end else
if vi="<" then
begin
if not(fforcehtml) and idx+4<=e and s[idx+1]="?" and lowercase(s[idx+2:idx+4])="tsl" then
begin
if (idx+4=e) or(s[idx+5] in array(" ","\t")) then //结尾
begin
FSynBranch := "tsl";
SetJsToken(tokens,s[idx:idx+4],idx+4);
return ParserTslTokenLines(s,idx+5,e,0,tokens);
end
end
SetJsToken(tokens,vi,idx);
end else
if {pos(vi,jsfh)}isjsfh then
begin
if not(vi=" " or vi="\t") then
begin
td := SetJsToken(tokens,vi,idx);
if td and hightercolor then
td.FFcolor := hightercolor.symcolor() ;
end
end else
begin
ttk+=vi;
end
idx++;
end
if ttk then
SetJsToken(tokens,ttk,idx-1);
end else
if cst="'" or cst='"' then
begin
if b>e then return cst;
r := FindRightChar(cst,s,b,e,"\\");
if r=0 then //没找到
begin
SetJsToken(tokens,s[b:],e,cst);
return cst;
end else //找到
if r<=e then
begin
if b<r then
begin
SetJsToken(tokens,s[b:r-1],r-1,cst);
end
SetJsToken(tokens,s[r:r],r,cst);
//SetJsToken(tokens,s[b:r],r,cst);
if r<e then
return ParserTslxTokenLines(s,r+1,e,0,tokens);
return 0;
end
end else
if cst="/*" then
begin
if b>e then return cst;
r := FindRightChars("*/",s,b,e);
if r=0 then
begin
SetJsToken(tokens,s[b:],e,cst);
return cst;
end else
if r<=e then
begin
SetJsToken(tokens,s[b:r],r,cst);
if r<e then
return ParserTslxTokenLines(s,r+1,e,0,tokens);
return 0;
end
end else
if cst="<!--" then
begin
if b>e then return cst;
r := FindRightChars("-->",s,b,e);
if r=0 then
begin
SetJsToken(tokens,s[b:],e,"/*");
return cst;
end else
if r<=e then
begin
SetJsToken(tokens,s[b:r],r,"/*");
if r<e then
return ParserTslxTokenLines(s,r+1,e,0,tokens);
return 0;
end
end
end
function ParserTslTokenLines(s,b,e,cst,tokens);
begin
if cst=0 then
begin
idx := b;
ttk := "";
while idx<=e do
begin
vi := s[idx];
viod := ord(vi);
if ( viod>0x40 and viod<0x5B) or (viod>0x60 and viod<0x7B) or (viod>0x2F and viod<0x3A) then
begin
ttk+=vi;
end else
if FSynBranch="tsl" and vi="?" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
if idx<e and s[idx+1]=">" then
begin
SetTToken(tokens,"?>",idx+1);
FSynBranch := "tslx";
return ParserTslxTokenLines(s,idx+2,e,cst,tokens);
end else
begin
SetTToken(tokens,"?",idx);
end
end else
if (vi=" ") or (vi="\t") then //空格
begin
SetTToken(tokens,ttk,idx-1);
end else
if vi ="'" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,"'",idx,"'");
if idx=e then return "'";
r := FindRightChar("'",s,idx+1,e,"\\");
if r = 0 then
begin
SetTToken(tokens,s[idx+1:],e,"'");
return "'";
end else
begin
if r>idx+1 then
begin
SetTToken(tokens,s[idx+1:r-1],r-1,"'");
end
SetTToken(tokens,s[r:r],r,"'");
idx := r+1;
continue;
end
//return ParserTokenLines(s,idx+1,e,"'",tokens);
end else
if vi = '"' then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,'"',idx,'"');
if idx=e then return '"';
r := FindRightChar('"',s,idx+1,e,"\\");
if r = 0 then
begin
SetTToken(tokens,s[idx+1:],e,'"');
return '"';
end else
begin
if r>idx+1 then
begin
SetTToken(tokens,s[idx+1:r-1],r-1,'"');
end
SetTToken(tokens,s[r:r],r,'"');
idx := r+1;
continue;
end
//return ParserTokenLines(s,idx+1,e,'"',tokens);
end else
if vi="{" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,'{',idx,'{');
return ParserTokenLines(s,idx+1,e,'{',tokens);
end else
if vi="/" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
if idx=e then
begin
SetTToken(tokens,vi,idx);
end else
begin
if s[idx+1]="/" then
begin
SetTToken(tokens,s[idx:],e,"//");
return 0;
end else
begin
SetTToken(tokens,vi,idx);
end
end
end else
if vi="#" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
if idx=e then
begin
SetTToken(tokens,vi,idx);
end else
begin
if s[idx+1]="!" then
begin
SetTToken(tokens,s[idx:],e,"//");
return 0;
end else
begin
SetTToken(tokens,vi,idx);
end
end
end else
if vi="(" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
if idx=e then
begin
FCBBState.GetLeft();
SetTToken(tokens,"(",idx,array("("));
end else
begin
if s[idx+1]="*" then
begin
SetTToken(tokens,"(*",idx+1,"(*");
return ParserTokenLines(s,idx+2,e,"(*",tokens);
end else
begin
FCBBState.GetLeft();
SetTToken(tokens,"(",idx,array("("));
end
end
end else
if vi="%" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
idx++;
if idx<=e then
begin
tvi:=s[idx];
typeidx := idx-1;
if tvi="%" then //
begin
ccs := "%%";
while idx<=e do
begin
idx++;
if idx>e then
begin
SetTToken(tokens,const ccs,e,array("%%"));
return ccs;
end
tvi := s[idx];
if tvi=" " or tvi="\t" then
begin
SetTToken(tokens,const ccs,idx-1,array("%%"));
return ParserTokenLines(s,idx+1,e,ccs,tokens);
end
else ccs+=tvi;
end
end else
begin
SetTToken(tokens,"%",idx-1);
idx--;
end
end
else
begin
SetTToken(tokens,"%",idx-1);
end
end else
if vi="<" then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
if (idx+6<=e) and s[idx+1]="?" and lowercase(s[idx+2:idx+6])="tslx>" then
begin
d := SetTToken(tokens,s[idx:idx+6],idx+6);
d.FFColor := 0xFF00FF;
FSynBranch := "tslx";
if idx+6=e then
begin
return 0;
end
return ParserTSlxTokenLines(s,idx+7,e,0,tokens);;
end else
begin
SetTToken(tokens,"<",idx);
end
end else
if pos(vi,"`~@#$^&*)+-;,.?:[]|\\=><%/") then
begin
if ttk then
SetTToken(tokens,ttk,idx-1);
if vi=")" then
begin
FCBBState.GetRight();
SetTToken(tokens,")",idx,array("("));
end else
if vi="[" then
begin
FCMBState.GetLeft();
SetTToken(tokens,"[",idx,array("["));
end else
if vi="]" then
begin
FCMBState.GetRight();
SetTToken(tokens,"]",idx,array("["));
end
else
begin
SetTToken(tokens,vi,idx);
end
end else
begin
ttk+=vi;
end
idx++;
end
if ttk then
SetTToken(tokens,ttk,idx-1);
end else
if cst="'" or cst='"' then
begin
if b>e then return cst;
r := FindRightChar(cst,s,b,e,"\\");
if r=0 then //没找到
begin
Setttoken(tokens,s[b:],e,cst);
return cst;
end else //找到
if r<=e then
begin
if b<r then
begin
Setttoken(tokens,s[b:r-1],r-1,cst);
end
Setttoken(tokens,s[r:r],r,cst);
if r<e then
return ParserTokenLines(s,r+1,e,0,tokens);
return 0;
end
end else
if cst="{" then
begin
if b>e then return cst;
r := FindRightChar("}",s,b,e);
if r=0 then //没找到
begin
Setttoken(tokens,s[b:e],e,cst);
return cst;
end else //找到
if r<=e then
begin
Setttoken(tokens,s[b:r],r,cst);
if r<e then
return ParserTokenLines(s,r+1,e,0,tokens);
return 0;
end
end else
if pos("%%",cst)=1 then
begin
if b>e then return cst;
r := FindRightChars(cst,s,b,e);
if r=0 then
begin
Setttoken(tokens,s[b:e],e,array("%%"));
return cst;
end else
if r<=e then
begin
Setttoken(tokens,s[b:r],r,array("%%"));
if r<e then
return ParserTokenLines(s,r+1,e,0,tokens);
return 0;
end
end else
if cst="(*" then
begin
if b>e then return cst;
r := FindRightChars("*)",s,b,e);
if r=0 then
begin
Setttoken(tokens,s[b:],e,cst);
return cst;
end else
if r<=e then
begin
Setttoken(tokens,s[b:r],r,cst);
if r<e then
return ParserTokenLines(s,r+1,e,0,tokens);
return 0;
end
end
end
function ParserTokenLines(s,b,e,cst,tokens);
begin
case FSynBranch of
0,"tsl":
begin
return ParserTslTokenLines(s,b,e,cst,tokens);
end
"tslx":
begin
return ParserTslxTokenLines(s,b,e,cst,tokens);
end
end
return 0;
return cst;
end
function InsureTokenParserd(LastLine);override; //解析
begin
ls := Lines;
FChangeDeal := true;
{setprofiler(7);
t := now();}
if fdolastline>=LastLine then return ;
fdolastline := LastLine;
for i:= FSatesCount-1 to LastLine do
begin
if i<0 then continue;
s := ls.GetStringByIndex(i);
cst := FSates[i];
FSynBranch := FSynSates[i];
tks := array();
if FSynBranch ="tslx" then //减少对象构造
begin
FCBBState := FBBStates[i];//.Clone;
FCBEState := FBEStates[i];//.Clone;
FCMBState := FMBStates[i];//.Clone;
FJsHkh := FJsHkhs[i].Clone;
FJsDkh := FJsDkhS[i].Clone;
FJsXkh := FJsXkhS[i].Clone;
end else
begin
FCBBState := FBBStates[i].Clone;
FCBEState := FBEStates[i].Clone;
FCMBState := FMBStates[i].Clone;
FJsHkh := FJsHkhs[i];//.Clone;
FJsDkh := FJsDkhS[i];//.Clone;
FJsXkh := FJsXkhS[i];//.Clone;
end
FSates[i+1] := ParserTokenLines(s,1,length(s),cst,tks);
FJsHkhs[i+1] :=FJsHkh;//.Clone;
FJsDkhS[i+1] := FJsDkh;//.Clone;
FJsXkhS[i+1] := FJsXkh;
FSynSates[i+1] := FSynBranch;
FBBStates[i+1] :=FCBBState;//.Clone;
FBEStates[i+1] := FCBEState;//.Clone;
FMBStates[i+1] := FCMBState;
FSatesCount := i+1;
FTokens[i] := tks;
//TryDispatch();
end
{if (now()-t)>(1/24/60/60) then
begin
echo "\r\ntime:",mtoc;
d := getprofilerinfo(true);
exportfile(ftstream(),"",format("d:\\tst\\profile\\%ssynprofile.stm",tostn(random())),d);
end}
//if tks then echo "\r\ntokencount:",tks[0].FTokenCount,"\r\n";
end
function TryDispatch();
begin
t := now();
if (t-FLastDispathTime)>1.5e-5 then
begin
FLastDispathTime := t;
GetAndDispatchMessageA();
end
end
function GetLineTokens(idx);override;
begin
if idx<FSatesCount then
return FTokens[idx];
end
private
function FindRightChar(c,s,b,e,zy); //查找封闭的字符
begin
i := b;
while i<=e do
begin
si := s[i];
if si=zy then
begin
i+=2;
if i>e then return 0;
continue;
end
if s[i]=c then //找到了
begin
return i;
end
i++;
end
return 0; //没找到
for i := b to e do
begin
if s[i]=c then //找到了
begin
return i;
end
end
end
function FindRightChars(cs,s,b,e);
begin
lcs := length(cs)-1;
for i:= b to e-lcs do
begin
if s[i:i+lcs]=cs then return i+lcs;
end
return 0;
end
function StrIsANumber(s);
begin
if not s then return 0;
c1 := ord(s[1]);
return c1<58 and c1>47;
return (1=ParseRegExpr("^0x[0-9 a-f A-F]+$",s,"i",result,MPos,Mlen)) or (1=ParseRegExpr("^\\d+$",s,"i",result,MPos,Mlen));
//ParseRegExpr("0x\\d+|\\d+",s,"i",result,MPos,Mlen);
end
FTokens;
FSynSates;
FSates;
FSatesCount;
FJsxkhs;
FJsxkh;
FJshkhs;
FJsHkh;
FJsDkhs;
FJsDkh;
FBBStates;
FCBBState;
FBEStates;
FCBEState;
FCMBState;
FMBStates;
FLastDispathTime;
static FKeyWords;
static FBinFunc;
static FJSWindows;
static FJsKeyWords;
static FJsSysClass;
static FJsHtmlEvent;
static FCssPropertys;
private
fdolastline;
FChangeDeal;
//语言分支
FSynBranch;
end
type ThtmlSynHighLighter = class(TTslSynHighLighter)
function Create(AOwner);
begin
inherited;
forcehtml(1);
Clean();
end
end
type TBatSynHigLighter = class(TSynHighLighter)
function Create(AOwner);
begin
inherited;
end
function CharInSyn(v);override;
begin
if not(FSyns) then FSyns := "'`!@#$^&*()-+=[]{}|\\?/';,.><"+'"';
return pos(v,FSyns);
end
function SetInValidateIndex(idx); virtual;
begin
inherited;
end
function GetLineTokens(idx);override;
begin
r := inherited;
rem := false;
for i,v in r do
begin
if rem then
begin
v.FFColor := 0x80CD43;
end
else
begin
vv := v.FValue;
lvv := lowercase(vv);
case lvv of
"rem":
begin
if hightercolor then v.FFcolor := hightercolor.commentcolor();
else
v.FFColor := 0x80CD43;
rem := true;
end
"if","else","echo","for","in","dir","cmd","pause","not":
begin
if hightercolor then v.FFcolor := hightercolor.keycolor();
else
v.FFColor := 0xFF0000;
end
"@","~","#","%","&","*","=":
begin
if hightercolor then v.FFcolor := hightercolor.symcolor();
else
v.FFColor := 0x0000FF;
end else
begin
if i=0 then
begin
if pos("::",lvv) then
begin
if hightercolor then v.FFcolor := hightercolor.commentcolor();
else
v.FFColor := 0x80CD43;
rem := true;
end else
begin
if hightercolor then v.FFcolor := hightercolor.fontcolor();
else
v.FFColor := 0xFF9900;// #0099FF
end
end else
begin
if pos("%",lvv) then
begin
if hightercolor then v.FFcolor := hightercolor.sysfunccolor();
else
v.FFColor := 0xFF0000;
end
end
end
end
end
end
return r;
end
private
FSyns;
end
type TINISynHigLighter = class(TSynHighLighter)
function Create(AOwner);
begin
inherited;
end
function GetLineTokens(idx);override;
begin
r := inherited;
if r and ifarray(r) then
begin
if r[0].FValue="[" then
begin
if hightercolor then c := hightercolor.sysfunccolor();
else c := 0xE22B8A;
for i,v in r do
begin
v.FFColor := c;
end
end else
if r[0].FValue in array(";","!","#") then
begin
if hightercolor then c := hightercolor.commentcolor();
else c := 0x80CD43;
for i,v in r do
begin
v.FFColor := c; //#43CD80
end
end else
if r[0].FValue = "@" then
begin
if hightercolor then c := hightercolor.keycolor();
else c := 0x0000FF;
r[0].FFColor := c;
end else
begin
if hightercolor then
begin
c1 := hightercolor.strcolor();
c2 := hightercolor.keycolor();
end
else
begin
c1 := 0x0000F0;
c2 := 0xf0f0f0;
end
for i,v in r do
begin
if v.FValue="=" then
begin
v.FFColor := c1;
break;
end else
begin
v.FFColor := c2;
end
end
end
end
return r;
end
end
type TJsonSynHighLighter = class(tcustomsynhighlighter)
function create(AOwner);
begin
inherited;
ExecuteCommand("strings",array(('"',"\\"),("'","\\")));
ExecuteCommand("keywords",array("null","true","false"));
ExecuteCommand("rowannotes",array());
ExecuteCommand("blockannotes",array());
ExecuteCommand("syms",array("{","}","[","]","<",">",":",",","="));
ExecuteCommand("pairs",array(("{","}"),("[","]")));
end
end
type TxmlSynHighLighter = class(tcustomsynhighlighter)
function create(AOwner);
begin
inherited;
ExecuteCommand("strings",array(('"'),("'")));
ExecuteCommand("keywords",array());
ExecuteCommand("rowannotes",array());
ExecuteCommand("blockannotes",array(("<!--","-->")));
ExecuteCommand("syms",array("<",">","=","?","</","!","[","]"));
ExecuteCommand("pairs",array(("<",">"),("</",">"),("[","]")));
end
function SetTToken(tokens,ttk,idx,ext);override;
begin
st := ExecuteCommand("getcurrentpairstate",">");
st1 := st.state;
d := inherited;
if not d then return ;
if st1=1 and st.state=1 then
begin
st.subitemadd();
if st.subitemcount()>1 then
begin
end else
begin
end
case d.FFColor of
stringcolor,symcolor:
begin
end else
begin
if st.subitemcount()>1 then
begin
d.FFColor := keywordcolor;// 0x0000ff;
end else
d.FFColor := sysfuncolor;
end
end
end
return d;
//echo "\r\n>>>",st1,"====",st2;
end
end
type TJsSynHighLighter = class(tcustomsynhighlighter)
function create(AOwner);
begin
inherited;
keywordcolor := 0xff0000;
stringcolor := 0x968080;
annotationcolor := 0x8D9600;
ExecuteCommand("strings",array(('"',"\\"),("'","\\")));
ExecuteCommand("keywords",jskeywords1());
ExecuteCommand("rowannotes",array("//"));
ExecuteCommand("blockannotes",array(("/*","*/")));
ExecuteCommand("syms",array("{","}","[","]","<",">","(",")",":",",","=","?","+","-","*","/",".",";"));
ExecuteCommand("pairs",array(("{","}"),("[","]"),("(",")")));
ExecuteCommand("sysfun",jskeywords2());
end
function jskeywords1();
begin
return getjskeywords() union2 getdomeventwords();
end
function jskeywords2();
begin
return getjsclasswords() union2 getjsfunwords();
end
end
type TcssSynHighLighter = class(tcustomsynhighlighter)
function create(AOwner);
begin
inherited;
keywordcolor := 0xff0000;
stringcolor := 0x968080;
annotationcolor := 0x8D9600;
ExecuteCommand("strings",array(('"',"\\")));
ExecuteCommand("keywords",getcsswords());
ExecuteCommand("rowannotes",array());
ExecuteCommand("blockannotes",array(("/*","*/")));
ExecuteCommand("syms",array("{","}","[","]","<",">","(",")",";",":",",","=","?","+","*","/",".","#"));
ExecuteCommand("pairs",array(("{","}"),("[","]"),("(",")")));
ExecuteCommand("sysfun",array());
end
end
type ttfmhighlighter = class(tcustomsynhighlighter)
function create(AOwner);
begin
inherited;
ExecuteCommand("strings",array(('"',"\\")));
ExecuteCommand("keywords",array("object","end","inherited"));
ExecuteCommand("rowannotes",array());
ExecuteCommand("blockannotes",array(("{","}")));
ExecuteCommand("syms",array("{","}","[","]","<",">",":",",","="));
ExecuteCommand("pairs",array(("{","}"),("[","]"),("<",">"),("object","end"),("inherited","end")));
end
end
implementation
function getcsswords();
begin
return array("align-content","align-items","align-self","all","animation","animation-delay",
"animation-direction","animation-duration","animation-fill-mode","animation-iteration-count",
"animation-name","animation-play-state","animation-timing-function","appearance","backface-visibility",
"background","background-attachment","background-blend-mode","background-clip","background-color",
"background-image","background-origin","background-position","background-repeat","background-size",
"border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius",
"border-bottom-style","border-bottom-width","border-collapse","border-color","border-image",
"border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width",
"border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right",
"border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top",
"border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width",
"border-width","bottom","box-align","box-direction","box-flex","box-flex-group","box-lines","box-ordinal-group",
"box-orient","box-pack","box-shadow","box-sizing","caption-side","clear","clip","color","column-count","column-fill",
"column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width",
"columns","content","counter-increment","counter-reset","cursor","direction","display","empty-cells","filter","flex",
"flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","font","font-face","font-family",
"font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","grid-columns","grid-rows",
"hanging-punctuation","height","icon","justify-content","keyframes","left","letter-spacing","line-height","list-style",
"list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top",
"max-height","max-width","media","min-height","min-width","mix-blend-mode","object-fit","object-position","nav-down","nav-index",
"nav-left","nav-right","nav-up","opacity","order","outline","outline-color","outline-offset","outline-style","outline-width",
"overflow","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after",
"page-break-before","page-break-inside","perspective","perspective-origin","position","punctuation-trim","quotes","resize","right",
"rotation","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last",
"text-decoration","text-decoration-color","text-decoration-line","text-decoration-style","text-indent","text-justify",
"text-outline","text-overflow","text-shadow","text-transform","text-wrap","top","transform","transform-origin","transform-style",
"transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align",
"visibility","white-space","width","word-break","word-spacing","word-wrap","z-index","writing-mode");
end
function getcsskeywords(r);
begin
if not ifarray(r) then r := array();
idx := length(r);
for i,v in getcsswords()do
begin
c := v+" <css pro>";
r[idx]["caption"] := c;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(c);
r[idx]["order"] := 5;
idx++;
end
end
function getjskeywords();
begin
return array("abstract","arguments","boolean","break","byte","case","catch","char","class","const","continue",
"debugger","default","delete","do","double","else","enum","eval","export","extends","false","final","finally",
"float","for","function","goto","if","implements","import","in","instanceof","int","interface","let","long",
"native","new","null","package","private","protected","public","return","short","static","super","switch",
"synchronized","this","throw","throws","transient","true","try","typeof","var","void","volatile","while","with","yield");
end
function getjsclasswords();
begin
return array("Date","hasOwnProperty","Infinity","isFinite","isNaN","isPrototypeOf","Math",
"NaN","name","Number","Object","prototype","String","toString","undefined","valueOf");
end
function getjsfunwords();
begin
return array("$","alert","anchor","anchors","area","assign","blur","button","checkbox",
"clearInterval","clearTimeout","clientInformation","close","closed","confirm",
"constructor","crypto","decodeURI","decodeURIComponent","defaultStatus","document",
"element","elements","embed","embeds","encodeURI","encodeURIComponent","escape","event",
"fileUpload","focus","form","forms","frame","innerHeight","innerWidth","layer","layers",
"link","location","mimeTypes","navigate","navigator","frames","frameRate","hidden","history",
"image","images","offscreenBuffering","open","opener","option","outerHeight","outerWidth","packages",
"pageXOffset","pageYOffset","parent","parseFloat","parseInt","password","pkcs11","plugin","prompt",
"propertyIsEnum","radio","reset","screenX","screenY","scroll","secure","setInterval",
"setTimeout","status","submit","taint","text","textarea","top","unescape","untaint","window");
end
function getdomeventwords();
begin
return array("onblur","onclick","onerror","onfocus","onkeydown","onkeypress","onkeyup","onmouseover","onload","onmouseup","onmousedown","onsubmit");
end
function getjskeywordstip(r);
begin
if not ifarray(r) then r := array();
idx := length(r);
for i,v in getjskeywords() do
begin
c := v+" <js key>";
r[idx]["caption"] := c;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(c);
r[idx]["order"] := 4;
idx++;
end
//"Array","function","length","eval",
for i,v in getjsclasswords() do
begin
c := v+" <js class>";
r[idx]["caption"] := c;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(c);
r[idx]["order"] := 4;
idx++;
end
//"all","select","self",
for i,v in getjsfunwords()do
begin
c := v+" <js win>";
r[idx]["caption"] := c;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(c);
r[idx]["order"] := 4;
idx++;
end
for i,v in getdomeventwords() do
begin
c := v+" <html ev>";
r[idx]["caption"] := c;
r[idx]["value"] := v;
r[idx]["lvalue"] := lowercase(v);
r[idx]["vlen"] := length(v);
r[idx]["clen"] := length(c);
r[idx]["order"] := 4;
idx++;
end
end
type tcolor = class()
function create(c);
begin
fcolor := c;
end
changed;
property color read fcolor write setcolor;
private
function setcolor(cl);
begin
if (cl>=0 or cl<0) and cl<>fcolor then
begin
fcolor := cl;
changed := true;
end
end
fcolor;
end
type TBBState =class(tpairstate) //括号状态
function Create(t);
begin
inherited;
end
end
type TTsfFileParser = class() //文件解析
private
fiofs;
public
function Create();
begin
FNsCaches := array();
fmsgcaches := array();
fiofs := ioFileseparator();
FCacheDir :=TS_GetUserProfileHome()+"TslSynMemo"+fiofs+"cmpCaches";// d["value"];
//FCacheAbsFileName := FCacheDir+"\\cacheabstruct.stm";
FFindDirs := array();
end
function DispatchMethod(o,d);//分发消息
begin
if not ifarray(d) then return ;
case d["method"] of
"cachedir": //缓存目录
begin
scache := d["value"] ;
r := FCacheDir;
if not(scache and ifstring(scache)) then return r;
FCacheDir := scache;
Clearcache();
return r;
end
"getbyname": //获得
begin
return LoadByName(d["value"]);
end
"finddirs": //查找目录
begin
return DirSet(d["value"]);
end
"namespace":
begin
end
"getfinddirs":
begin
return FFindDirs;
end
"filechanged": //文件改变
begin
filechanged(d["value"]);
end
"getfullpath":
begin
if not ifarray(FFilePaths) then return "";
r := FFilePaths[lowercase(d["value"])+".tsf"];
return r;
end
"getprojecttsfs":
begin
return getprojecttsfs();
end
"allfunctions":
begin
return getallfunctions();
end
"parserstring":
begin
r := parserstring(o,d);
return r;
end
end
end
private
function addnsfile(us);
begin
if not ifarray(us) then return array();
r := us;
rl := length(r);
for i,v in us do
begin
for j,vj in FNsCaches[lowercase(v)] do
begin
if vj then
begin
r[rl++] := v+j;
end
end
end
return r;
end
function getinheriteds(r,m,dounits,us,uso,cs,cso);
begin
if not ifarray(us) then us := array();
if not ifarray(uso) then uso := array();
if not ifarray(cs) then cs := array();
if not ifarray(cso) then cso := array();
for i,v in addnsfile(r["units"]) do
begin
//vfn := checknamespacename(v);
vfn := v;
if m=(lowercase(vfn)+".tsf") then continue;
vi := LoadByName(vfn);
if vi then
begin
if dounits[vi["msg"]] then
begin
continue;
end
dounits[vi["msg"]] := 1 ;
us[length(us)] := vfn;
uso[length(uso)] := vi;
getinheriteds(vi,m,dounits,us,uso,cs,cso);
end
end
for i,v in addnsfile(r["class"]) do
begin
vfn := v;
//vfn := checknamespacename(v);
if m=(lowercase(vfn)+".tsf") then continue;
vi := LoadByName(vfn);
if vi then
begin
if dounits[vi["msg"] ] then continue;
dounits[vi["msg"]] := 1;
cs[length(cs)] := vfn;
cso[length(cso)] := vi;
getinheriteds(vi,m,dounits,us,uso,cs,cso);
end
end
end
function parserstring(o,d);
begin
rti := 0;
rt := array();
m := d["minus"];
if ifstring(m) then m := lowercase(m);
filechanged(m);
FormatFile(rti,FCacheS,rt,3,m);
if m and ifarray(FCacheS) then
begin
r := FCacheS[m];
end
if r then
begin
//echo "\r\nlodad";
vmsg := r["msg"];
end else
begin
s := d["value"];
if not(s and ifstring(s)) then return rt ;
if errtslcode(s) then return rt;
r := unit(utssvr_api_c).get_tsl_tokenizeex(s,1);//tsl_tokenizeex_2_(s,1);
if not( r and ifarray(r)) then return rt;
cls := array();
ScriptDelBlocks(r["blcks"],str2array(s,"\n"),cls);
r["blcks"] := cls;
vmsg := getmsgd_Crc32(s);//GetMsgdigest(s,0);
end
ext := array();
FormatFunction(rti,r["functions"],rt,"",r["lines"],ext,1);
FormatBlocks(rti,r["blcks"],rt,"",nil,ext,1);
FormatWords(rti,r["words"],rt,"",ext,1);
dounits := array(vmsg:1);
getinheriteds(r,m,dounits,us,uso,cs,cso);
for i,v in us do //单元
begin
vfn := v;
vi := uso[i];
ext := array();
FormatFunction(rti,vi["functions"],rt,vfn,vi["lines"],ext,4);
FormatBlocks(rti,vi["blcks"],rt,vfn,nil,ext,4);
FormatWords(rti,vi["words"],rt,vfn,ext,4);
end
for i,v in cs do //类
begin
vfn := v;
vi := cso[i];
ext:= array();
FormatFunction(rti,vi["functions"],rt,vfn,vi["lines"],ext,4);
FormatWords(rti,vi["words"],rt,vfn,ext,4);
end
//FormatFile(rti,FCacheS,rt,3,m);
return rt;
//return o.postmessage(r);
end
function getallfunctions();
begin
filechanged();
if not ifarray(FCacheS) then return array();
rti :=0;
rt := array();
ext := array();
for i,v in FCacheS do
begin
vfn := v["name"];
FormatFunction(rti,v["functions"],rt,vfn,v["lines"],ext);
FormatBlocks(rti,v["blcks"],rt,vfn,nil,ext);
end
return rt;
end
function checknamespacename(v);
begin
for ii in FCacheS do
begin
if pos(v+"@",ii)=1 then
begin
return ii[1:length(ii)-4];
end
end
return v;
end
function FormatFile(idx,r,d,od,m); //文件
begin
for v,vv in r do
begin
if v=m then continue;
//echo FFilePaths;
if FFilePaths and not(FFilePaths[v]) then continue; //已经排除
wd := vv["functions"][0];
nns := vv["nspace"];
if wd and ifarray(wd) and (wd0:=wd[0]) and wd0 and (v=lowercase(wd0)+nns+".tsf") then //
begin
t := Formatfparams(wd)+" <locfunc"+nns+"> "+inttostr(vv["lines"][0]);
d[idx]["value"]:= wd0;
d[idx]["lvalue"] := lowercase(wd0);
d[idx]["vlen"] := length(wd0);
d[idx]["clen"] := length(t);
d[idx]["jump"] := true;
d[idx]["caption"] :=t;
d[idx]["file"] := wd0+nns;
if od>=0 then d[idx]["order"] := od;
d[idx]["line"] := vv["lines"][0];
idx++;
continue;
end else
begin
if length(v)>4 then
begin
wd0 := vv["words"][0];
if wd0 and ( (lowercase(wd0)+nns+".tsf")=v) then
begin
end else
wd0 := v[1:length(v)-4];
d[idx]["value"]:= wd0;
d[idx]["lvalue"] := lowercase(wd0);
d[idx]["vlen"] := length(wd0);
t := wd0+" <file"+nns+ ">" ;
d[idx]["jump"] := true;
d[idx]["caption"] := t;
d[idx]["clen"] := length(t);
d[idx]["file"] := wd0+nns;
d[idx]["line"] := 1;
idx++;
end
end
continue;
wd0 := vv["words"][0];
if wd0 and ifstring(wd0) and ( v=lowercase(wd0)+vv["nspace"]+".tsf") then //
begin
d[idx]["value"]:= wd0;
d[idx]["lvalue"] := lowercase(wd0);
d[idx]["vlen"] := length(wd0);
t := wd0+" <file>" ;
d[idx]["jump"] := true;
d[idx]["caption"] := t;
d[idx]["clen"] := length(t);
d[idx]["file"] := wd0+vv["nspace"];
d[idx]["line"] := 1;
idx++;
end
end
end
function FormatWords(idx,r,d,f,ext,od); //单词
begin
if not ifarray(ext) then ext := array();
for i,v in r do
begin
llv := lowercase(v);
if ext[llv] then
begin
continue;
end
d[idx]["value"]:= v;
d[idx]["lvalue"] := llv;
d[idx]["vlen"] := length(v);
c := v+" <ident> ";
if f then
begin
c+= f;
end
d[idx]["caption"] := c;
d[idx]["clen"] := length(c);
if od>=0 then
d[idx]["order"] := od;
idx++;
end
end
function ScriptDelBlocks(blcks,strs,r);
begin
if not blcks then return ;
for i,v in blcks do
begin
if v["mtype"]=3 then
begin
idx := v["mbeg"]-1;
s := strs[idx];
if ifstring(s) and s then
begin
if ParseRegExpr("type\\s+(\\w+)\\s*=\\s*Class",s,"i",result,MPos,Mlen)=1 then
begin
r[length(r)] := array(result[0,1],idx+1);
end
end
end
ScriptDelBlocks(v["msub"],strs,r);
end
end
function FormatBlocks(idx,r,d,f,rr,ext,od);
begin
if not ifarray(ext) then ext := array();
for i,v in r do
begin
//if not(lines[i]>0) then continue;
v0 := v[0];
li := v[1];
d[idx]["jump"] := 1;
t := v0+" <class>";
d[idx]["value"]:= v0;
lvl := lowercase(v0);
d[idx]["lvalue"]:= lvl;
ext[lvl] := true;
d[idx]["vlen"] := length(v0);
if f then t+=" "+f;
if li>=0 then t+="("+inttostr(li)+")";
d[idx]["clen"] := length(t);
d[idx]["caption"] := t;
d[idx]["file"] := f;
d[idx]["line"] := li;
if od>=0 then
d[idx]["order"] := od;
idx++;
end
end
function FormatFunction(idx,r,d,f,lines,ext,od) //函数
begin
if not ifarray(ext) then ext := array();
for i,v in r do
begin
//if not(lines[i]>0) then continue;
v0 := v[0];
li := lines[i];
d[idx]["jump"] := 1;
if li .& 0x40000000 then //pro
begin
t := v0 +" <pro>";
li := li .& 0x3FFFFFFF;
//d[idx]["type"] := "pro";
end else
begin
if li>0 then t := Formatfparams(v)+ " <msfunc>";
else t := Formatfparams(v)+ " <mfunc>";
if li .& 0x80000000 then
begin
li := li .& 0x3FFFFFFF;
end
end
d[idx]["value"]:= v0;
lvl := lowercase(v0);
d[idx]["lvalue"]:= lvl;
ext[lvl] := true;
d[idx]["vlen"] := length(v0);
if f then t+=" "+f;
if li>=0 then t+="("+inttostr(li)+")";
d[idx]["clen"] := length(t);
d[idx]["caption"] := t;
d[idx]["file"] := f;
d[idx]["line"] := li;
if od>=0 then
d[idx]["order"] := od;
idx++;
end
end
function Formatfparams(d); //函数参数
begin
r := "";
r+=d[0];
lend := length(d)-1;
r+="(";
for i:= 1 to lend do
begin
r+=d[i];
if i<lend then r+=",";
end
r+=")";
return r;
end
function ParserFindDir(f); //解析缓存
begin
if FCacheDir then
begin
FFileNames := array();
FFilePaths := array();
for i,v in FFindDirs do
begin
ParserFiles(v,FFileNames,nil);
end
FFinddirsseted := false;
end
getprojecttsfs();
end
function getprojecttsfs();
begin
if FFinddirsseted then ParserFindDir();
r := array();
for i,v in FFileNames do
begin
r[i[1:length(i)-4]] := v;
end
return r;
end
function LoadByName(n); //获得名称
begin
if FCacheDir then
begin
return ReadParseredFile((n+".tsf"),true);
end
end
function parserafile(dir,v);
begin
fn := lowercase( v["FileName"]);
if FFileNames[fn] then return ;
//if fn=mf then return ;
pfn := dir+fiofs+fn;
sz := v["Size"];
flt := v["Time"];
d := ReadParseredFileTime(fn);
FFileNames[fn] := pfn;
if ifstring(d) and d=flt then
begin
if ReadParseredFile(fn,nil,pfn) then
return ;
end
if readFile(rwRaw(),"",pfn,0,sz,rdd) then
begin
if rdd then
begin
if errtslcode(rdd) then
begin
r := array();
rdd := "";
end else
r := unit(utssvr_api_c).get_tsl_tokenizeex(rdd,1);//tsl_tokenizeex_2_(rdd,1);
end else
begin
r := array();
rdd :="";
end
r["fullpath"] := pfn;
//r["name"] := fn;
if (aid := pos("@",fn)) then
begin
nn := fn[1:(aid-1)];
nns := fn[aid:(length(fn)-4)];
r["nspace"] := nns;
r["name"] := nn;
FNsCaches[nn][nns] := 1;
//echo "\r\nfn:",fn[aid:];
end else
begin
r["nspace"] := "";
r["name"] := fn[1:length(fn)-4];
end
r["msg"] := getmsgd_Crc32(rdd);//GetMsgdigest(rdd,0);
cls := array();
ScriptDelBlocks(r["blcks"],str2array(rdd,"\n"),cls);
r["blcks"] := cls;
if not ifarray(FCacheS) then FCacheS := array();
FCacheS[fn] := r;//new tparserdobject( r);
FFilePaths[fn] := pfn;
WriteParseredFile(fn,r,flt);
end
end
function ParserFiles(dir,FFileNames,mf);
begin
dirs := FileList("",dir+fiofs+"*");
for i,v in dirs do //解析文件
begin
fn := v["FileName"] ;
if not(pos("D",v["Attr"])) and (1=ParseRegExpr("\\.tsf$",fn,"i",m,mp,ml)) then //tsf文件处理
begin
parserafile(dir,v);
end
end
for i,v in dirs do //解析目录
begin
fn := v["FileName"] ;
if pos("D",v["Attr"]) and not( fn in array(".","..")) then //子目录查找
begin
ParserFiles(dir+fiofs+fn,FFileNames,mf);
end
end
end
function ModifyFname(n);
begin
nn := lowercase(n);
dg := fmsgcaches[nn];
if not dg then
begin
dg := getmsgd_Crc32(nn);//GetMsgdigest(nn,0);
fmsgcaches[nn] := dg;
end
return dg[1]+fiofs+dg[2]+fiofs+n;
end
function WriteParseredFile(n,d,t);
begin
iofs := fiofs;
f1 := FCacheDir+iofs+ModifyFname(n)+".p";
f2 := FCacheDir+iofs+"lasttime"+iofs+ModifyFname(n)+".t";
CreateDirWithFileName(f1);
CreateDirWithFileName(f2);
exportfile(ftstream(),"",f1,d);
exportfile(ftstream(),"",f2,t);
end
function ReadParseredFileTime(n);
begin
if FCacheDir then
begin
fn := FCacheDir+fiofs+"lasttime"+fiofs+ModifyFname(n)+".t";
if importfile(ftstream(),"",fn,d)=1 then
begin
return d;
end
end
end
function ReadParseredFile(n,g,pfn); //读取解析的文件
begin
if FCacheDir then
begin
ln := lowercase(n);
if not ifarray(FFilePaths) then FFilePaths := array();
if not(FFileNames[ln]) then return ;
if not ifarray(FCacheS ) then FCacheS := array();
fp := FCacheS[ln,"fullpath"];
if fp then
begin
FFilePaths[ln] := fp;
nns := FCacheS[ln,"nspace"];
if nns then
begin
nn := FCacheS[ln,"name"];
FNsCaches[nn][nns] := 1;
end
if g then return FCacheS[ln];
return 1;
end
fn := FCacheDir+fiofs+ModifyFname(n)+".p";
if importfile(ftstream(),"",fn,d)=1 and ifarray(d) then
begin
FCacheS[ln] := d;//new tparserdobject(d);
FFilePaths[ln] := d["fullpath"];
if pfn and ( pfn<>d["fullpath"]) then
begin
return 0;
end
nns := d["nspace"];
if nns then
begin
nn := d["name"];
FNsCaches[nn][nns] := 1;
end
if g then return d;
return 1;
end
end
end
function setnamespace(ns);
begin
if FNamespace<>ns then
begin
FNamespace := ns;
ClearCache(FFindDirs?true:false);
end
end
function DirSet(d_); //设置
begin
if not ifarray(d_) then return FFindDirs;
d := format_dirs(d_);
if d=FFindDirs then return d;
r := FFindDirs;
FFinddirsseted := true;
if ifarray(d) and d then
begin
cl := FFindDirs?true:false;
FFindDirs := d;
ClearCache(cl);
end
return r;
end
function format_dirs(d);
begin
r := array();
idx := 0;
for i,v in d do
begin
if ifstring(v) and v then
begin
vlen := length(v);
if v[vlen]=fiofs then r[idx] := v[1:(vlen-1)];
else r[idx] := v;
idx++;
end
end
return r;
end
function ClearCache(cl); //清空缓存
begin
if cl then
begin
DeleteAllFiles(FCacheDir);
end
FFileNames := array();
FFilePaths := array();
FCacheS := array();
FNsCaches := array();
end
function filechanged(d);
begin
ParserFindDir(d);
end
private
FFinddirsseted;
FFileWorker;
FFilePaths;
FCacheS; //缓存
FNsCaches;
FCacheblk;
FFileNames; //文件名
FCacheDir; //缓存目录非 \结尾
FCacheList;//目录列表 以
//FCacheAbsFileName;//缓存概要
FFindDirs; //查找目录
FNamespace; //别名
fmsgcaches;
function errtslcode(s); //判断 function procedure结尾搞不定
begin
return 0;
return 0;
end
end
initialization
end.