tslediter/designer/utslsynmemo.tsf

2104 lines
72 KiB
Plaintext

unit UTslSynMemo;
interface
{**
@explan(说明) tsl语法编辑器库
**}
uses utslvclauxiliary,UTslMemo,TslVcl;
function FileSaveThreader(o,d);
type TTSLCompletion= class(TSynCompletion)
{**
@explan(说明) tsl提示自动完成类
**}
static FCodeBlocks;
function Create(AOwner);
begin
inherited;
GetTslParser();
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 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 := 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
//cfk "abstract","break","case","class","continue","delete","do","else","eval","false","goto","if","new","while","with","for","function","in","interface","finally","private","protected","public","return","static","true","try","var",
for i,v in array("arguments","boolean","byte","catch","char","const","debugger","default","double","enum","export","extends","final","float","implements","import","instanceof","int","let","long","native","null","package","short","super","switch","synchronized","this","typeof","throw","throws","transient","void","volatile","yield")
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 array("Date","hasOwnProperty","Infinity","isFinite","isNaN","isPrototypeOf","Math",
"NaN","name","Number","Object","prototype","String","toString","undefined","valueOf")
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 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")
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 array("onblur","onclick","onerror","onfocus","onkeydown","onkeypress","onkeyup","onmouseover","onload","onmouseup","onmousedown","onsubmit")
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
for i,v in 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")
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
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语法高亮类
**}
function Create(AOwner);
begin
inherited;
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 tslL_getfunctions_2_() do
begin
FBinFunc[v]:=v;
end
FJsKeyWords := array();
for i,v in 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")
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 array("$","alert","all","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","select","self","setInterval","setTimeout","status","submit","taint","text","textarea","top","unescape","untaint","window")
do
begin
FJsWindows[v]:=true;
end
FJsHtmlEvent := array();
for i,v in array("onblur","onclick","onerror","onfocus","onkeydown","onkeypress","onkeyup","onmouseover","onload","onmouseup","onmousedown","onsubmit")
do
begin
FJsHtmlEvent[v]:=true;
end
FCssPropertys := array();
for i,v in 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")
do
begin
FCssPropertys[v]:=true;
end
end
FLastDispathTime := 0;
end
function Clean();override;
begin
// { ' " %% 0
FTokens := array();
FSates := array(0); //状态
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 ;
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
d.FFColor := 0x8D9600;
end
'"',"'":
begin
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
d.FFColor := 0xFF0000;
end else
if FJsKeyWords[bttk] then // FE0064
begin
d.FFColor := 0xFF0000;
end else
if FJsSysClass[bttk] then //
begin
d.FFColor := 0xFF0000;
end else
if FJsHtmlEvent[bttk] then //
begin
d.FFColor := 0xFF0000;
end else
if FCssPropertys[bttk] then
begin
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
d.FFcolor := 0x8B008B;
donext := false;
end else
if tp="//" or tp="{" or tp="(*" then //if tp in array("//","{","(*") then
begin
d.FFcolor := 0x228B22;
donext := false;
end else
if FKeyWords[lwttk] then
begin
d.FFcolor := 0x0000FF;
end
else
if FBinFunc[lwttk] then
begin
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
end else
if lwttk="end" then
begin
FCBEState.GetRight();
d.FMATe:= FCBEState.GetSate();
end else
if StrIsANumber(ottk) then
begin
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 (lwttk in array("select","sselect","update","mselect","vselect","try","begin","type","case")) 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
begin
//FindRightChars
SetJsToken(tokens,"<!--",idx+3,"/*");
return ParserTslxTokenLines(s,idx+4,e,"<!--",tokens);
end
if pos(vi,jsfh) then
begin
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 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) then
begin
SetJsToken(tokens,vi,idx);
end else
begin
ttk+=vi;
end
idx++;
end
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
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
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
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
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,'{',idx,'{');
return ParserTokenLines(s,idx+1,e,'{',tokens);
end else
if vi="/" then
begin
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
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
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
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
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
//if vi in array("`","~","@","#","$","^","&","*",")","+","-",";",",",".","?",":","[","]","|","\\","=",">","<","%") then
begin
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
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();}
mtic;
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
FChangeDeal;
//语言分支
FSynBranch;
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
v.FFColor := 0x80CD43;
rem := true;
end
"if","else","echo","for","in","dir","cmd":
begin
v.FFColor := 0xFF0000;
end
"@","~","#","%","&","*","=":
begin
v.FFColor := 0x0000FF;
end else
begin
if i=0 then
begin
if pos("::",lvv) then
begin
v.FFColor := 0x80CD43;
rem := true;
end else
begin
v.FFColor := 0xFF9900;// #0099FF
end
end else
begin
if pos("%",lvv) then
begin
v.FFColor := 0xFF0000;
end
end
end
end
end
end
return r;
end
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
for i,v in r do
begin
v.FFColor := 0xE22B8A;
end
end else
if r[0].FValue in array(";","!","#") then
begin
for i,v in r do
begin
v.FFColor := 0x80CD43; //#43CD80
end
end else
if r[0].FValue = "@" then
begin
r[0].FFColor := 0x0000FF;
end else
begin
for i,v in r do
begin
if v.FValue="=" then
begin
v.FFColor := 0x0000F0;
break;
end
end
end
end
return r;
end
end
type TJsonSynHighLighter = class(TSynHighLighter)
function Create(AOwner);
begin
inherited;
Clean();
FChangeDeal := true;
end
function Clean();override;
begin
// { "
FTokens := array();
FSates := array(0); //状态
FBBStates := array(new TBBState(")"));
FBEStates := array(new TBBState("}"));
FMBStates := array(new TBBState("]"));
FSatesCount := 1; //改变的行
end
function Recycling();override;
begin
inherited;
Clean();
end
function SetInValidateIndex(idx); override; //当前改变的行
begin
idx := max(1,idx);
if not(FChangeDeal) and idx>FSatesCount then return ;
if length(FSates)>=idx then
FSatesCount := idx;
else FSatesCount := length(FSates)-1;
if FSatesCount = 1 then Clean();
FChangeDeal := false;
end
function ParserTokenLines(s,b,e,cst,tokens);
begin
label L_XCDG;
if cst=0 then
begin
idx := b;
ttk := "";
while idx<=e do
begin
vi := s[idx];
case vi of
" ","\t":
begin
SetTToken(tokens,ttk,idx-1);
end
"(",")":
begin
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,vi,idx,")");
end
"{","}":
begin
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,vi,idx,"}");
end
"[","]":
begin
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,vi,idx,"]");
end
":",",":
begin
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,vi,idx,vi);
end
'"':
begin
SetTToken(tokens,ttk,idx-1);
SetTToken(tokens,vi,idx,'"');
return ParserTokenLines(s,idx+1,e,'"',tokens);
end else
begin
ttk+=vi;
end
end ;
idx++;
end
SetTToken(tokens,ttk,idx-1);
end else //查找
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
begin
//消除递归
b := r+1;
cst := 0;
goto L_XCDG;
//return ParserTokenLines(s,r+1,e,0,tokens); //递归方式
end
end
end
end
function InsureTokenParserd(LastLine);override; //解析
begin
ls := Lines;
FChangeDeal := true;
for i:= FSatesCount-1 to LastLine do
begin
if i<0 then continue;
s := ls.GetStringByIndex(i);
cst := FSates[i];
tks := array();
FCBBState := FBBStates[i].Clone;
FCBEState := FBEStates[i].Clone;
FCMBState := FMBStates[i].Clone;
FSates[i+1] := ParserTokenLines(s,1,length(s),cst,tks);
FBBStates[i+1] :=FCBBState;//.Clone;
FBEStates[i+1] := FCBEState;//.Clone;
FMBStates[i+1] := FCMBState;
FSatesCount := i+1;
FTokens[i] := tks;
end
end
function GetLineTokens(idx);override;
begin
if idx<FSatesCount then
return FTokens[idx];
end
protected
function SetTToken(tokens,ttk,idx,ext);virtual; //设置token
begin
d := inherited;
if not d then return ;
tk := d.FValue;
if ext in array(")","]","}") then d.FFColor := 0xFF0000;
if ext="}" and tk="{" then
begin
FCBEState.GetLeft();
d.FMATe := FCBEState.GetSate();
end else
if ext="}" and tk="}" then
begin
FCBEState.GetRight();
d.FMATe := FCBEState.GetSate();
end else
if ext="]" and tk="[" then
begin
FCMBState.GetLeft();
d.FMATe := FCMBState.GetSate();
end else
if ext="]" and tk="]" then
begin
FCMBState.GetRight();
d.FMATe := FCMBState.GetSate();
end else
if ext=")" and tk="(" then
begin
FCBBState.GetLeft();
d.FMATe := FCBBState.GetSate();
end else
if ext=")" and tk=")" then
begin
FCBBState.GetRight();
d.FMATe := FCBBState.GetSate();
end else
if ext='"' then
begin
D.FFColor := 0x8B008B;
end else
if tk in array("true","false","null") then
begin
d.FFColor := 0x0000FF;
end else
if tk in array(":",",") then
begin
d.FFColor := 0x0000FF;
end else
if StrIsANumber(tk) then d.FFColor := 0x666666;
return d;
end
private
function StrIsANumber(s);
begin
if not s then return 0;
r := (1=ParseRegExpr("^[+-]?[\\d]+",s,"",result,MPos,Mlen)) ;
return r;
end
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
private
FTokens;
FSates;
FSatesCount;
FCBBState;
FCBEState;
FCMBState;
FBBStates;
FBEStates;
FMBStates ;
end
implementation
type TBBState =class //括号状态
function Create(t);
begin
FType := ifstring(t)?t:"";
FCJ := 0;
FState := 0;
FIndexs := array(0);
FIndex := 0;
FCstate := false;
end
function GetLeft();
begin
FCstate := true;
if FState then // 上一个是左括号
begin
FCJ++;
FIndex++;
FIndexs[FIndex]:=0;
end else //上一个非左括号
begin
FIndexs[FIndex]++;
end
FState := true;
end
function GetRight();
begin
FCstate := true;
//if FCJ=0 then return ;
if FState then // 上一个是左括号
begin
//FIndexs[FIndex]++;
end else //上一个非左括号
begin
if FCJ>0 then
begin
FCJ--;
DeleteIndex(FIndexs,FIndex);
FIndex--;
end else
begin
FCstate := false;
end
end
FState := false;
end
function GetSate();
begin
if FCstate then
begin
//return inttostr(FIndexs[FCJ])+FType;
return tostn(FIndexs)+FType;// inttostr(FCJ)+"+"+inttostr(FIndexs[FIndex])+FType; length(FIndexs)+FType ;//
end
end
function Show();
begin
echo "层级:",FCJ," 序号:",FIndexs[FIndex],"状态:", FCstate;
end
function Clone();
begin
r := new TBBState(FType);
r.FCstate := FCstate;
r.FState := FState;
r.FCJ := FCJ;
r.FIndexs := FIndexs;
r.FIndex := FIndex;
return r;
end
protected
FCstate;
FState;
FCJ;
FIndexs;
FIndex;
FType;
end
type TTsfFileParser = class //文件解析
function Create();
begin
FCacheDir :=TS_GetUserProfileHome()+"TslSynMemo"+ioFileseparator()+"cmpCaches";// d["value"];
//FCacheAbsFileName := FCacheDir+"\\cacheabstruct.stm";
//FFileWorker := new TThreadWorker("this.OnMessage :=findfunction('UTslSynMemo.FileSaveThreader') ;");
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
"getfinddirs":
begin
return FFindDirs;
end
"filechanged": //文件改变
begin
filechanged(d["value"]);
end
"getfullpath":
begin
if not ifarray(FFilePaths) then return "";
return FFilePaths[lowercase(d["value"])+".tsf"];
end
"getprojecttsfs":
begin
return getprojecttsfs();
end
"parserstring":
begin
mtic;
r := parserstring(o,d);
return r;
end
end
end
private
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 r["units"] do
begin
vfn := checknamespacename(v);
if m=(lowercase(vfn)+".tsf") then continue;
vi := LoadByName(vfn);
if vi then
begin
if vi["msg"] in dounits then
begin
continue;
end
dounits[length(dounits)] := vi["msg"] ;
us[length(us)] := vfn;
uso[length(uso)] := vi;
getinheriteds(vi,m,dounits,us,uso,cs,cso);
end
end
for i,v in r["class"] do
begin
vfn := checknamespacename(v);
if m=(lowercase(vfn)+".tsf") then continue;
vi := LoadByName(vfn);
if vi then
begin
if vi["msg"] in dounits then continue;
dounits[length(dounits)] := vi["msg"];
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 ;
r := 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);
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 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;
wd := vv["functions"][0];
if wd and ifarray(wd) and (wd0:=wd[0]) and wd0 and (v=lowercase(wd0)+vv["nspace"]+".tsf") then //
begin
t := Formatfparams(wd)+" <locfunc> "+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+vv["nspace"];
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)+vv["nspace"]+".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>" ;
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
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
mtic;
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");
end
end
function ParserFiles(dir,FFileNames,mf);
begin
dirs := FileList("",dir+ioFileseparator()+"*");
for i,v in dirs do
begin
fn := v["FileName"] ;
if pos("D",v["Attr"]) and not( fn in array(".","..")) then
begin
ParserFiles(dir+ioFileseparator()+fn,FFileNames,mf);
end
end
dirs := FileList("",dir+ioFileseparator()+"*.tsf");
for i,v in dirs do
begin
if not(pos("D",v["Attr"])) then
begin
fn := lowercase( v["FileName"]);
if FFileNames[fn] then continue;
if fn=mf then continue;
pfn := dir+ioFileseparator()+fn;
sz := filesize("",pfn);
fl := FileList("",pfn);
d := ReadParseredFileTime(fn);
FFileNames[fn] := pfn;
//echo "\r\n",tostn(fn),"===",v["Attr"];
if ifstring(d) and d=fl[0,"Time"] then
begin
//FCacheS[fn]
ReadParseredFile(fn);
continue;
end
if readFile(rwRaw(),"",pfn,0,sz,rdd) then
begin
if rdd then
begin
r := tsl_tokenizeex_2_(rdd,1);
end else
begin
r := array();
rdd :="";
end
r["fullpath"] := pfn;
r["name"] := fn;
if (aid := pos("@",fn)) then
begin
r["nspace"] := fn[aid:(length(fn)-4)];
r["name"] := fn[1:(aid-1)];
//echo "\r\nfn:",fn[aid:];
end else r["nspace"] := "";
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,fl[0,"Time"]);
end
end
end
end
function ModifyFname(n);
begin
nn := lowercase(n);
dg := getmsgd_Crc32(nn);//GetMsgdigest(nn,0);
return dg[1]+ioFileseparator()+n;
end
function WriteParseredFile(n,d,t);
begin
f1 := FCacheDir+ioFileseparator()+ModifyFname(n)+".p";
f2 := FCacheDir+ioFileseparator()+"lasttime"+ioFileseparator()+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+ioFileseparator()+"lasttime"+ioFileseparator()+ModifyFname(n)+".t";
if importfile(ftstream(),"",fn,d)=1 then return d;
end
end
function ReadParseredFile(n); //读取解析的文件
begin
if FCacheDir then
begin
if not ifarray(FFilePaths) then FFilePaths := array();
if not(FFileNames[lowercase(n)]) then return ;
if not ifarray(FCacheS ) then FCacheS := array();
d := FCacheS[lowercase(n)];
if d then
begin
FFilePaths[lowercase(n)] := d["fullpath"];
return d;
end
fn := FCacheDir+ioFileseparator()+ModifyFname(n)+".p";
if importfile(ftstream(),"",fn,d)=1 and ifarray(d) then
begin
FCacheS[lowercase(n)] := r;//new tparserdobject(d);
FFilePaths[lowercase(n)] := d["fullpath"];
return d;
end
end
end
function DirSet(d); //设置
begin
if not ifarray(d) then return FFindDirs;
if d=FFindDirs then return d;
r := FFindDirs;
FFinddirsseted := true;
if ifarray(d) and d then
begin
FFindDirs := d;
ClearCache();
end
return r;
end
function ClearCache(); //清空缓存
begin
DeleteAllFiles(FCacheDir);
FCacheS := array();
end
function filechanged(d);
begin
ParserFindDir(d);
end
private
FFinddirsseted;
FFileWorker;
FFilePaths;
FCacheS; //缓存
FCacheblk;
FFileNames; //文件名
FCacheDir; //缓存目录非 \结尾
FCacheList;//目录列表 以
//FCacheAbsFileName;//缓存概要
FFindDirs; //查找目录
end
function FileSaveThreader(o,d);
begin
if not ifarray(d) then return ;
m := d["method"];
f := d["file"];
c := d["content"];
if (m="exportfile") and ifstring(f) and f then
begin
exportfile(ftstream(),"",f,c);
end
end
type tparserdobject = class
function create(d);
begin
echo "\r\n create f object===";
if ifarray(d) then
FData := d;
end
function operator[](idx);
begin
if FData then
return FData[idx];
end
function operator[1](idx,v);
begin
if FData then
FData[idx] := v;
end
private
FData ;
end
end.